git:20261028.e64d3fb to git:20261107.deab533

275 added, 166 removed. Audit A to A.

---
name: fsl-requirements
- description: Write and verify FSL requirements-layer specs for PMs/PdMs from natural-language product requirements, acceptance criteria, forbidden flows, requirement IDs, traceability, and NFRs such as permissions, audit, capacity, reliability, and SLA/deadline behavior. Use when the deliverable is a requirements specification, not business process discovery, software architecture, internal design, or implementation conformance.
+ description: Write and verify FSL requirements-layer specs for PMs/PdMs from natural-language product requirements, acceptance criteria, forbidden flows, requirement IDs, traceability, decision tables, and NFRs such as permissions, audit, capacity, reliability, and SLA/deadline behavior, in English and optionally with a Japanese glossary and Japanese keywords. Use when the deliverable is a requirements specification, not business process discovery, software architecture, internal design, or implementation conformance.
---
# FSL Requirements Layer
+ A headerless document is FSL 4; to migrate it, see the migration guide in `docs/manual/LANGUAGE.md` ("FSL 4 to FSL 5 migration").
+
Use this skill to formalize PM/PdM requirements as a `requirements Name { ... }`
- FSL file. The deliverable is a requirements contract that development can consume:
- requirement IDs, source text, operations, guards, acceptance criteria, forbidden
- flows, and optional conformance to an upper business layer.
+ FSL file headed `fsl 5`. The deliverable is a requirements contract that
+ development can consume: the vocabulary (actors, entities, their lifecycles),
+ the events, the rules and decision tables with their requirement IDs and
+ source text, acceptance and forbidden scenarios, and optional conformance to an
+ upper business layer.
- Before writing syntax, read `../fsl/SKILL.md`, then use its reference index to
- load only the needed language and verifier detail. The complete requirements
- example (process+data profile, `implements` of a business spec, `covers`
- traceability, `kpi`, `acceptance`, and the `verify { instances / values }`
- bound) is in `../fsl/references/layers.md`, section "requirements (the
- requirements layer)". Read the NFR section of `../fsl/references/impl.md` only
- when SLA/deadline behavior is in scope.
+ This skill owns the syntax of this layer:
+ - `references/syntax.md` — every requirements member, one checked spec walked
+ through member by member;
+ - `references/keywords.md` — the English / Japanese keyword table and the
+ particles;
+ - `references/glossary.md` — how to write a `glossary` and the Japanese
+ spelling of the example below.
+
+ Expressions (`and`, `or`, `not`, comparisons, arithmetic), the `verify { }`
+ block, and kernel members are those of `../fsl/references/syntax.md`. The shared
+ `../fsl/references/layers.md` covers edition-aware seams and delegates requirements
+ syntax here. **Do not use earlier requirements `process` / `transition` forms**:
+ `fsl 5` rejects them (`mixed_requirements_forms`). `fslc migrate --edition 5`
+ rewrites an existing process-form file into the forms below.
+ To maintain an existing headerless (FSL 4) requirements document as it is,
+ without migrating it, use the FSL 4 forms in
+ [`../fsl/references/layers.md`](../fsl/references/layers.md#requirements-the-requirements-layer).
+
+ An inline `implements` seam is fail-closed. How a failing seam changes the
+ top-level result and exit is in the core's
+ ["Inline `implements` failures are fail-closed"](../fsl/SKILL.md#how-to-run);
+ reading `implements.result` and the seam fields is in
+ [fsl-verify §2](../fsl-verify/SKILL.md#2-results-that-look-green-but-are-not) and
+ [§3](../fsl-verify/SKILL.md#3-reading-the-deciding-fields-per-result).
+
+ ## English is canonical
+
+ - Write the spec with English names and English keywords. The names on the
+ left of every declaration are the **canonical names**: ASCII, and the only
+ names the kernel, generated tests, conformance vectors and implementations
+ ever see.
+ - Japanese is a reading layer on top: a `glossary` gives a canonical name a
+ Japanese alias, every keyword of the table has a Japanese spelling, and the
+ particles が・を・で・は mark the words of a phrase. Add it after the English
+ spec checks, never instead of it. Both spellings lower to the same kernel.
+ - Requirement, scenario and policy IDs stay ASCII (`REQ-RET-001`). Quoted
+ source text is kept verbatim in its own language.
+ - Event names (`event request = …`) and the spec name are declared canonical;
+ they reach implementations.
+
## Faithfulness gate (definition of done)
The two failures this layer exists to prevent are **dropping** a requirement (a
thin spec) and **inventing** a rule the source never stated. Hold both ends:
- - **Cover the source.** Every requirement in the document maps to at least one
- transition / invariant / acceptance / forbidden, or is recorded in the memo as
- out-of-scope or needs-decision. The step-1 coverage map forces the hard
- requirements in instead of stopping at the happy path.
- - **Ground the spec.** Every declaration carries provenance — process
- `covers REQ-CHECKOUT-001 "..."` to source text, or the typed annotation
- `@requirement("REQ-CHECKOUT-001", "...")` on a declaration that links to an ID
- a `requirement` block owns, with a `MODEL-`/`ASSUME-`prefixed id for an
- explicit modeling choice. Those two are the canonical forms; the
- `"REQ-1: text"` string slot is non-canonical
- migration input, so never write it. An untagged declaration is an ungrounded
- guess, not a style nit.
- - **Do not invent to reach green.** If `check`/`verify` needs a guard, bound,
- state, actor, deadline, or exception the source does not state, that is a step-1
- question for the human — not a default you may pick to reach `verified`.
- - **Make it mechanical.** `fslc check <file> --strict-tags` flags every `untagged`
- declaration (an invented rule) and every `unreferenced_requirement` (a
- requirement nothing checks); **done = zero of both**. Add `--requirements ids.txt`
- (the memo's source IDs in a file, one per line — not a comma list) to also
- catch requirements omitted entirely. Keep
- provenance in the `.fsl` as tags, not a separate file.
+ - **Cover the source.** Every source requirement maps to at least one checked
+ declaration — a `rule`, a `decide` table or one of its rows, an event's
+ `covers`, a `scenario`, a `forbidden`, a `goal`, a `policy` — or is recorded
+ in the memo as out-of-scope or needs-decision.
+ - **Ground the spec.** A `rule ID "text"` and a `decide ID "text"` own their
+ ID and carry the verbatim text; a decision row or an event adds
+ `covers ID "text"` for the requirement it serves. Use a `MODEL-` / `ASSUME-`
+ prefixed ID for an explicit modeling choice the source does not state.
+ - **Do not invent to reach green.** If `check` / `verify` needs a guard,
+ bound, stage, actor, deadline or exception the source does not state, that
+ is a question for the human, not a default you may pick.
+ - **Make it mechanical.** `fslc check <file> --strict-tags --requirements
+ ids.txt` (the memo's IDs in a file, one per line) warns
+ `unreferenced_requirement` for an ID nothing carries; done = zero of those
+ and zero `untagged`, read from `warnings[]` of an exit-0 `ok`. `fslc lint`
+ must also report no findings (`non_canonical_id` for an ID outside the ID
+ policy).
## Boundary
- Produce requirements-layer artifacts only:
-
- - A `requirements` spec, preferably using the process+data profile:
- `process Entity with field: Type { transition ... with/when/set/covers ... }`
- - `acceptance` and `forbidden` blocks for positive and negative flows
- - Optional `implements BusinessName from "business.fsl" { }`, `maps auto`, or
- explicit maps when a confirmed business layer exists
- - Scenario/test skeleton output from `fslc scenarios` when requested
-
- Do not write internal design state, architecture, queues/outboxes, service modules,
- database schemas, implementation adapters, or design-to-requirements refinement
- maps unless the user explicitly moves to design work. If a requirement implies a
+ Produce requirements-layer artifacts only: the `requirements` spec, its
+ scenarios and forbidden traces, the `implements` seam to a confirmed business
+ layer, and `fslc scenarios` output when requested. Do not write internal design
+ state, architecture, queues/outboxes, service modules, database schemas,
+ implementation adapters, or design-to-requirements refinement maps unless the
+ user explicitly moves to design work (`fsl-design`). If a requirement implies a
design decision but does not state it, ask rather than choosing.
- Once this spec is checked, generating a stakeholder-facing requirements document
- from it is a separate downstream activity, not part of this skill — use
- `fsl-requirements-document` (`fslc document generate`/`claims`/`check`) for that.
- It edits only the document's non-normative slot; it never edits the `.fsl` this
- skill produced.
+ Generating a stakeholder-facing requirements document from the checked spec is
+ a separate activity (`fsl-requirements-document`).
## Workflow
1. Post a requirements formalization memo in chat before writing `.fsl`:
- - glossary: externally visible entities, states, actors, operations, enums
- - requirement normalization: trigger, constraint, exception, boundary
- implication for each requirement
- - coverage map: every source requirement ID → the FSL element that will carry
- it; mark anything you cannot cover out-of-scope or needs-decision (this is
- what keeps the spec from silently dropping requirements)
+ - terms: actors, entities, the stages each entity goes through, the verbs
+ (one per thing an actor does), inputs and their ranges; with a Japanese
+ source, the Japanese term next to each English name (this becomes the
+ glossary, step 6)
+ - requirement normalization: trigger, constraint, exception, boundary for
+ each requirement
+ - coverage map: every source requirement ID → the declaration that will
+ carry it (rule, decide row, event covers, scenario, forbidden, goal,
+ policy), or out-of-scope / needs-decision
- acceptance and forbidden traces, with expected outcome
- - upper business contract, if any, and candidate `implements` mapping
+ - upper business contract, if any
- assumptions and questions that affect behavior
- 2. Preserve source fidelity. Requirement IDs and verbatim text belong in
- `covers REQ-CHECKOUT-001 "..."` on process transitions, or in a
- `requirement REQ-CHECKOUT-001 "..."` block that owns the ID for kernel-wrapper
- declarations, so diagnostics and scenarios trace back to the PM document. Any
- other declaration links to an owned ID with the typed annotation
- `@requirement("REQ-CHECKOUT-001", "...")` — and one carrying a
- `MODEL-`/`ASSUME-`prefixed id when it is not a direct source requirement, so
- the strict-tags gate can tell intended modeling from fabrication. Do not use
- the non-canonical `"REQ-1: text"` string slot.
- 3. Encode only externally observable product behavior. State names should describe
- product/system states, not engineering mechanisms.
- 4. Use the process+data profile first for a single-entity lifecycle:
- `number Amount`, `process Claim with amount: Amount`, transition `with`
- inputs, `when` guards, `set` field updates, and `covers` traceability. Put
- finite bounds in a top-level `verify` block with `instances Claim = N` and
- `values Amount = lo..hi`. Carried fields also accept `Bool` and enum types
- declared in the spec: `number` keeps an optional initializer
- (`f: Amount = <const-expr>`, defaults to the domain's `lo`), `Bool`/enum
- fields require one (`retried: Bool = false`, `f: T = Member`) — this covers
- simple history flags without routing to kernel-wrapper.
- 5. Use the kernel-wrapper form (`struct` / `state` / `init`, `fair action`)
- only for hard cases: multi-entity behavior,
- conservation rules, SLA/time, history that needs kernel state (multiple
- entities, sequences, etc. — a simple flag fits in a carried field, see step 4),
- or a user-visible operation whose data-dependent outcomes need separate upper
- correspondences. Legacy `branches` with inline `maps` remain accepted in the
- current edition but are rejected for next. For next, split each condition into
- an explicit fair action and put its correspondence in `implements`, preserving
- guards, updates and fairness; see `submit_small` / `submit_large` in
- `examples/layers/return_system.fsl`.
- 6. Put positive examples in `acceptance`; put must-reject procedures in
- `forbidden`. Use `forbidden` for missing-guard risk because a safety invariant
- often stays silent when an invalid operation is accepted. Prefer
- `expect Entity id in Stage` for process-stage checks; use `expect <expr>` for
- other predicates. `acceptance`/`forbidden` action arguments accept enum member
- names, not numeric ordinals (`paint(1)` is not `paint(Blue)`); const names work
- where their values match the parameter's kind. An action parameter may also be typed
- `Bool` (a first-class boolean, not a 0/1 int — `Int` is still rejected as
- unbounded).
- 7. For `implements`:
- - `implements BusinessName from "business.fsl" { }` auto-generates identity
- refinement when process/action/stage names match
- - `maps auto` is allowed inside `implements` for same-name kernel-wrapper
- state/actions; explicit `map` and action correspondences override it
- - whenever the seam is evaluated (not in a `verify` scoped with
- `--property` and the like), a process transition auto-mapped to a
- same-named business action is actor-checked; a requirements transition
- whose actor differs from that business action's actor is a check-time
- error even with covers (its text is not an actor declaration; #1441); a
- transition with no same-named business action maps to `stutter` and is not
- actor-checked
- - requirement actions inside a block or standalone (including `X__bN` branches)
- use only their own metadata's `by X` actor, never block or `@requirement`
- text, and are not actor-compared when that actor is absent (#1456).
- - the inline block also accepts action correspondence items —
- `action impl(...) -> abs(...) | stutter` — including an arity change
- between impl and abs params, the same syntax a separate refinement file uses
- 8. For NFRs:
- - permissions: role guard plus invariant when needed
- - audit/capacity/reliability: ordinary invariants and response properties
- - SLA/deadline: use requirements `time` and `deadline`; confirm non-vacuity by
- checking that a tighter deadline fails
- 9. Run `fslc check --strict-tags` as the faithfulness gate — not done until it
- reports zero `untagged` and zero `unreferenced_requirement` (add
- `--requirements ids.txt` — the memo's IDs in a file, one per line, not a comma
- list — to also catch fully omitted requirements).
- `--strict-tags` counts a legacy `"REQ-1: text"` string as tagged, so also run
- `fslc lint <file>`: it exits 1 with `legacy_string_metadata` and a
- machine-applicable `@requirement(...)` replacement for every non-canonical
- form, and with `non_canonical_id` for an ID outside the active policy.
- Not done until `fslc lint` also reports no findings.
- `--strict-tags` findings are warnings on an exit-0 `ok` result, so read
- `warnings[]`, not only the exit code.
- Then `fslc verify --depth 8` (read `implements.result`), and for stable
- requirements `fslc verify --engine induction`. Run `fslc scenarios` to hand
- development the acceptance/forbidden skeletons. Reading those results,
- repairing from them, measuring strength with `mutate`, and the completion
- report format are in `../fsl-verify/SKILL.md`.
+ 2. Write the vocabulary and the lifecycles: `number`, `const`, `enum`,
+ `actor`; one `entity` per thing with a lifecycle, each field with an
+ initial value; one `lifecycle A -> B -> C` line per path. Then one `event`
+ per lifecycle edge (`Actor verb Entity A -> B`), or `in S` for one that
+ stays in its stage; `with field` for an input; `set` for other updates;
+ `fault event` for something that happens to the system rather than a step
+ anyone takes (not fair).
+ 3. Write each rule the source states as a `rule ID "text" { … }` with the
+ statement that says it: `allow … only when / only for`, `never … when /
+ for`, `P only after Q`, `E enters T only from S`, `always …`, `deadline`.
+ A rule that rejects an operation is a guard **and** a `forbidden` trace
+ that tries it (`check` warns `never_rule_without_forbidden` when the trace
+ is missing). Name every `always` / `enters` statement (`AmountPositive:
+ always …`): the name is the property's name in results and diagnostics.
+ 4. Where the source decides "who handles it / which way" by case, write a
+ `decide ID "text" for Stage Entity { Case => Actor verb … }` table. `check`
+ proves over the field domains that the rows cover every case
+ (`decide_not_exhaustive`, with the uncovered values) and never overlap
+ (`decide_overlap`, with the shared values). Close a real gap with a row or
+ `otherwise`; close a gap no reachable state has with `assuming Q`, which
+ `verify` then proves. Do not add a row the source does not state to make
+ the table exhaustive — ask.
+ 5. Add `measure`, `goal`, `policy`, then `scenario` (positive) and `forbidden
+ … then rejected` (negative) traces, then the `verify { instances … values
+ … }` bounds. If the spec has intended stopping points, declare them in
+ `terminal { }` (step 7 shows why).
+ 6. Optional Japanese layer: a `glossary` as the first item, Japanese keywords
+ and particles (`references/glossary.md`). Re-run the whole check loop.
+ 7. Check loop: `fslc check` → `fslc check --strict-tags --requirements
+ ids.txt` → `fslc lint` → `fslc verify --depth 8` (read
+ `implements.result` when there is an upper layer) → `fslc verify --engine
+ induction` → `fslc scenarios`. A requirements spec of this edition gets no
+ derived `terminal { }`: a run that ends with every entity in a final stage
+ is reported as a `deadlock` warning until `terminal { }` names those
+ stages. Reading the results, the origin self-check with `fslc explain`,
+ `mutate`, and the completion report are in `../fsl-verify/SKILL.md`.
+ 8. For SLA / deadline requirements, use `deadline` inside the rule with a
+ `time { }` block (`references/syntax.md`) and confirm the deadline can
+ fail: the variant without its `urgent` event must be `violated`.
+ ## Example
+
+ A complete spec of this layer (checked as written):
+
+ ```fsl check
+ fsl 5
+ requirements ReturnRequirements {
+ number Amount
+ const AUTO_LIMIT = 1
+ actor Customer, System, Manager, Finance
+
+ entity Return {
+ amount: Amount = 0
+ lifecycle Draft -> Requested -> Approved -> Refunded
+ lifecycle Requested -> Rejected
+ }
+
+ concept SmallReturn = Return where amount <= AUTO_LIMIT
+ concept LargeReturn = Return where amount > AUTO_LIMIT
+
+ event request = Customer requests Return with amount Draft -> Requested
+ event auto_approve = System approves Return Requested -> Approved
+ event mgr_approve = Manager approves Return Requested -> Approved
+ event reject = Manager rejects Return Requested -> Rejected
+ event refund = Finance refunds Return Approved -> Refunded
+
+ rule REQ-RET-001 "A return is requested with a positive amount" {
+ allow Customer requests Return only when input amount > 0
+ }
+
+ decide REQ-RET-002 "Who decides a requested return" for Requested Return {
+ SmallReturn => System approves
+ covers REQ-RET-003 "Returns at or below AUTO_LIMIT are approved by the system"
+ LargeReturn => Manager approves or rejects
+ covers REQ-RET-004 "Returns above AUTO_LIMIT are approved or rejected by a manager"
+ }
+
+ rule REQ-RET-005 "A requested return keeps a positive amount" {
+ AmountPositive: always Return not in Draft has amount > 0
+ }
+
+ terminal { forall r: Return { stage(r) == Refunded or stage(r) == Rejected } }
+
+ measure refunded_returns = count Return in Refunded
+ goal GOAL-RET-001 "A return can be refunded" some Return can reach Refunded
+ policy POL-RET-001 "Every requested return is eventually decided"
+ every Return in Requested must eventually be Approved or Rejected
+
+ scenario AC-RET-001 "A small return is approved by the system and refunded" {
+ Customer requests r1 with amount 1
+ System approves r1
+ Finance refunds r1
+ then r1 is Refunded
+ }
+ scenario AC-RET-002 "A large return is rejected by a manager" {
+ Customer requests r1 with amount 2
+ Manager rejects r1
+ then r1 is Rejected
+ }
+ forbidden FB-RET-001 "A return of zero is not requested" {
+ Customer requests r1 with amount 0
+ then rejected
+ }
+ forbidden FB-RET-002 "A manager does not decide a small return" {
+ Customer requests r1 with amount 1
+ Manager approves r1
+ then rejected
+ }
+ }
+ verify {
+ instances Return = 2
+ values Amount = 0..3
+ }
+ ```
+
+ What the lowering makes of it, which `fslc explain --readable` prints:
+
+ - `Return` becomes an identity type of 2 instances; its fields become
+ `return_amount: Map<Return, Amount>` and `return_stage: Map<Return,
+ ReturnStage>`, and the stages, in the order they first appear in the
+ `lifecycle` lines, become the enum `ReturnStage`.
+ - Each event becomes a fair action of the same name with the entity instance
+ as its first parameter (`request(r, amount)`). Its stage move becomes a
+ `requires` and an assignment; `with amount` stores the input in the field.
+ - The `allow` adds `requires amount > 0` to `request`; the table adds
+ `requires return_amount[r] <= AUTO_LIMIT` to `auto_approve` and the other
+ row's condition to `mgr_approve` and `reject`. `AmountPositive` becomes an
+ invariant.
+ - The `scenario` / `forbidden` blocks are acceptance and forbidden traces
+ over those actions; `r1` is instance 0.
+
+ These lowered names are what a design layer maps to (`../fsl-design/`) and
+ what an `implements` block below this spec's business layer is written in.
+
+ ## The seam to a business layer
+
+ `implements BusinessName from "business.fsl" { … }` is written at the top of
+ the spec (after the `glossary`, which must be the first item). `verify` checks
+ the seam and reports it as `implements.result`; it passes only on `refines`. For the example above
+ against the business spec of `../fsl-business/SKILL.md`:
+
+ ```fsl-fragment
+ requirements ReturnRequirements {
+ implements ReturnToBe from "return_tobe.fsl" {
+ action request(r, amount) -> request(r)
+ action auto_approve(r) -> decide_ok(r)
+ action mgr_approve(r) -> decide_ok(r)
+ action reject(r) -> decide_ng(r)
+ action refund(r) -> refund(r)
+ map return_stage_via_Approved[r: Return] =
+ return_stage[r] == Approved or return_stage[r] == Refunded
+ }
+ …
+ }
+ ```
+
+ - The block is written in **canonical, lowered names** (`return_stage`, the
+ action parameters). A glossary alias there is an error
+ (`alias_in_implements`).
+ - An event whose name matches a business transition is matched
+ automatically only when the parameters match too; the business transition's
+ parameter is `c`, so write the correspondence explicitly.
+ An automatically matched event whose actor differs from the business
+ transition's actor is a check-time `kind: "type"` error (`maps auto actor mismatch …`).
+ - The stage enum must be the same on both sides: list the lifecycle so the
+ stages first appear in the order of the business `stages` line (otherwise
+ `type 'ReturnStage' is declared differently in the impl and abs specs`).
+ - A business no-bypass policy (`must have passed through Approved`) adds a
+ history flag to the business kernel (`return_stage_via_Approved`); map it.
+
## Guardrails
- Completeness is part of the contract: a spec that formalizes only some
- requirements is not "minimal," it is unfinished. Cover every source requirement
- or record why not (out-of-scope / needs-decision) — but never close a gap by
- inventing a rule the source does not state.
+ requirements is unfinished. Cover every source requirement or record why
+ not — but never close a gap by inventing a rule the source does not state.
- Carry every rejection rule the source states in a checked declaration, not
- in prose alone. Put the rejecting condition on the operation it restricts —
- the transition's source stage, a `when` guard, or a kernel action's
- `requires`, whichever expresses it — and add a `forbidden` trace that
- exercises the rejection (Workflow step 6). A rule that lives only in
- `requirement` block text, `covers` / `@requirement` text, or a `//` comment
- is not checked by `verify`, `mutate`, or conformance, and does not reach a
- reader or tool that takes the declarations without the prose. An omitted
- rejecting condition is not a neutral gap: the model then accepts every call
- the operation's remaining conditions allow, which can include calls the
- source rejects. If an invariant or a `forbidden` trace catches that,
- `verify` fails — add the condition the source states (or ask, if it states
- none) rather than deleting the invariant or the trace to get green. If
- nothing catches it, `verify` stays green, and scenarios, generated tests,
- and conformance vectors can then encode the acceptance as expected behavior.
- - Stop at the requirements contract. Do not continue into design just because a
- design could be inferred. The handoff downward is a **refinement seam, not a plain
- baton pass**: when design work begins, this spec becomes the frozen contract the
- design layer refines via `fslc refine`, so author it as a contract a lower layer can
- honor. Upward, `implements BusinessName` is the same kind of seam to the business
- layer — `verify` checks it and reports it under `implements` in the result JSON.
- - Do not add retries, storage rules, asynchronous jobs, queues, screen internals,
- or API shape unless the source explicitly requires them.
- - A green `implements` result means the requirements contract conforms to the
- agreed business layer. It does not prove any design or implementation. Green
- means `implements.result == "refines"` in the result JSON. A
- `refinement_failed` / `impl_violated` seam makes `check`/`verify` exit 1 with
- that value at the top level. Assert the field, or gate with `fslc chain`.
+ in prose alone: an `allow` / `never` / `only after` / decision row on the
+ event it restricts, plus a `forbidden` trace that tries the rejected call.
+ A rule that lives only in a quoted text or a `//` comment is checked by
+ nothing, and the model then accepts every call the remaining guards allow.
+ If an invariant or a forbidden trace catches the gap, add the rule the
+ source states (or ask) — never delete the invariant or the trace.
+ - A decision table states the whole case split. If `check` reports a gap or
+ an overlap, the source is ambiguous or the concepts are wrong; fix the
+ concepts or ask. `otherwise` is for a source that says "everything else";
+ `assuming` is for a gap that the rest of the spec already excludes, and
+ `verify` must prove it.
+ - Stop at the requirements contract. The handoff downward is a **refinement
+ seam**: the design layer refines this spec with `fslc refine`, so author it
+ as a contract a lower layer can honor. Upward, `implements` is the same kind
+ of seam to the business layer.
+ - Do not add retries, storage rules, asynchronous jobs, queues, screen
+ internals, or API shape unless the source explicitly requires them.
+ - A green `implements` result means this contract conforms to the agreed
+ business layer. It does not prove any design or implementation.
- When a counterexample suggests a repair, decide whether it is a missing
- requirement, a wrong interpretation, or an intentional exception before changing
- guards or invariants.
+ requirement, a wrong interpretation, or an intentional exception before
+ changing a guard, a row or an invariant.