diff --git a/rules/patterns/app-binary/contract.md b/rules/patterns/app-binary/contract.md index 741c7be..b6db189 100644 --- a/rules/patterns/app-binary/contract.md +++ b/rules/patterns/app-binary/contract.md @@ -1,6 +1,6 @@ # Contract: Application Binary -Version: 1.0 +Version: 1.1 ## Purpose @@ -21,4 +21,7 @@ See `README.md` for deployment examples and a sample config template. - For local SQLite mode, the database file lives next to the config and its path is derived by the application, not configured separately. - On first run with no config, the application must create the config, print its path, exit 0, and stop. It must not continue startup with a fresh placeholder config. - The binary must not depend on the caller's working directory. +- Assets bundled at compile time (`//go:embed` and equivalents) do not hot-reload. Before diagnosing + a bug reported against a generated or served artifact, confirm the running process was rebuilt and + restarted after the last change; use the displayed build version (`build-version-display`) to check. - Build with `CGO_ENABLED=0` when possible. Enable CGO only when the chosen storage/runtime actually requires it, such as SQLite drivers that need CGO. diff --git a/rules/patterns/controls-selection/contract.md b/rules/patterns/controls-selection/contract.md index aa4b9f9..4d25c43 100644 --- a/rules/patterns/controls-selection/contract.md +++ b/rules/patterns/controls-selection/contract.md @@ -1,6 +1,6 @@ # Contract: Controls + Selection -Version: 1.2 +Version: 1.3 ## Shared Base @@ -16,6 +16,11 @@ Version: 1.2 - Button text should describe the action outcome, not implementation detail. - Buttons are text-first; icons are optional and must not replace labels on primary/danger actions. - Base examples must show both `disabled` and `loading` states. +- Any control that triggers a network or database call must show a visible busy state for the whole + duration of that call (spinner on the control, disabled control, or an equivalent indicator), and + must not be re-triggerable while busy. Without it, "slow" is indistinguishable from "broken". +- This applies to every call, not only to long-running background tasks. The server-side half of the + rule — a bounded timeout on the call itself — is owned by `go-api`. - Do not use a hyperlink (``/link-styled text) to open a modal, drawer, detail view, or any other in-page element. Use a `button` (or button-styled control) instead, unless the user explicitly asks for a hyperlink. Hyperlinks are reserved for navigation to another URL/page. diff --git a/rules/patterns/go-api/contract.md b/rules/patterns/go-api/contract.md index 122126e..83ac796 100644 --- a/rules/patterns/go-api/contract.md +++ b/rules/patterns/go-api/contract.md @@ -1,6 +1,6 @@ # Contract: REST API Conventions (Go Web Applications) -Version: 1.1 +Version: 1.2 ## URL Naming @@ -68,6 +68,16 @@ All non-2xx responses return a consistent JSON body: - File uploads use `multipart/form-data`. - Query parameters for filtering and pagination: `?page=1&per_page=50&search=abc&status=active`. +## Timeouts + +- Every outbound network or database call must run under a bounded `context.Context` deadline. + No call reachable from a user action may block indefinitely. +- The deadline is set by the handler or service that owns the request, not by the caller of the app. +- On timeout, return a real error status (`504` for an upstream timeout, `500` for an internal one) + with a human-readable message. Never let a timed-out call fall through as an empty success. +- The UI side of the same rule — visible busy state for the duration of the call — is owned by + `controls-selection`. + ## Health and Utility Endpoints Every application must expose: diff --git a/rules/patterns/import-export/contract.md b/rules/patterns/import-export/contract.md index 5dae1e9..c3cd887 100644 --- a/rules/patterns/import-export/contract.md +++ b/rules/patterns/import-export/contract.md @@ -1,6 +1,6 @@ # Contract: Import / Export Workflows -Version: 1.0 +Version: 1.1 See `README.md` for the reference export handler and locale examples. @@ -11,6 +11,17 @@ See `README.md` for the reference export handler and locale examples. - Warnings and errors should be visible per row and in aggregate. - The confirm step must communicate scope and side effects clearly. +## Parsing Real-World Formats + +- Before writing a parser for a third-party text export (1C, CSV, vendor reports), enumerate the + actual format variants present in a real sample file: delimiters, encodings, decimal and date + formats, header repetitions, multi-line and merged records, trailing summary rows. +- Write the parser against the enumerated variant list. Do not assume a single convention and repair + it reactively per bug report. +- Record the enumerated variants next to the parser (test fixtures or a short comment) so later + changes know which shapes must keep working. +- Unrecognized lines must be reported as explicit per-row errors, never silently skipped. + ## Export Rules - The user must explicitly choose export scope when ambiguity exists, such as `selected`, `filtered`, or `all`. diff --git a/rules/patterns/task-discipline/contract.md b/rules/patterns/task-discipline/contract.md index fcee1e0..baf56dd 100644 --- a/rules/patterns/task-discipline/contract.md +++ b/rules/patterns/task-discipline/contract.md @@ -1,11 +1,19 @@ # Contract: Task Discipline -Version: 1.0 +Version: 1.1 ## Principle Finish before switching. A task is not done until it reaches a logical end. +## Scope Definition + +- Before implementation starts, the task description must state the target platform and language + explicitly: CLI, server-rendered web app, desktop app, library, and the language/runtime it runs on. +- If the platform is not stated, ask before writing code. Do not infer it from the surrounding repo. +- A platform pivot after implementation invalidates connection, config, and transport plumbing built + around the previous shape. Treat such a pivot as a new task, not as a continuation. + ## Rules - Do not start a new task while the current one is unfinished. Switching mid-task leaves half-done work that is harder to recover than if it had never been started.