design-flow · diff

git:20260905.c7945f5 to git:20260919.cdf15ac

59 added, 106 removed. Audit A to A.

---
name: design-flow
description: Use when progressing IC design through stages, checking module status, or routing rework decisions; not for single-stage execution or artifact authoring.
---
- # Design Flow Orchestrator
-
- You are the **Orchestrator**. Every turn you run one deterministic step against the
- kernel tool `python3 <skill>/../../framework/scripts/kernel.py` (written `kernel.py` below).
- `<skill>` is this skill's own base directory, named on the first line of this file.
-
- ```text
- loop:
- a = kernel.py decide --module {module} [--wake <rule>:<run>] [--closing]
- execute(a) # a.action ∈ {DISPATCH, REAP, YIELD, DONE, ESCALATE}
- # non-blocking for `execution: task`
- if a.action in {YIELD, DONE, ESCALATE}: end turn
- ```
-
- `{module}` is the path to the module's directory — the one holding `events.jsonl` and
- `brainstorm.md`, with every stage's tree beneath it. Pass the same one every call; an
- absolute path works from any working directory.
-
- `kernel.py` is the **sole writer** of `{module}/events.jsonl` and the sole decider.
- `decide` reads on-disk state and returns exactly one action as a JSON object on exit 0. All
- routing lives inside it — you never re-derive the next stage yourself, and you carry nothing
- between turns: what to build is derived from the log every call, so a compaction or a crash
- costs you nothing but the turn.
-
- Every verb prints a JSON envelope. An `ok: false` is a contract signal, not an obstacle:
- hand the error to the user and stop that line of work. A non-zero exit means the
- call could not be made sense of at all (today: no module directory at the resolved path,
- which is a wrong working directory) — follow the printed error, don't debug the script.
-
- `kernel.py status --module {module}` prints the per-stage projection plus `signed_off`. It
- is a read-only query for the user, outside the loop.
+ # Design Flow
- ## Iron Rule
+ Coordinate stage work through `python3 <skill>/../../framework/scripts/kernel.py`, written
+ `kernel.py` below. `<skill>` is this skill's directory; `{module}` contains `events.jsonl`,
+ `intent/brainstorm.md` and the stage trees.
- - Do not run EDA tools (make / vcs / dc_shell / pt_shell / spyglass) yourself — that is the stage subagent's job.
- - Do not hand-edit `events.jsonl` or any stage `result.json` / artifact. A main-thread write to either is an isolation violation.
- - **Scripts are black boxes — never Read their source.** Invoke `kernel.py` per this skill's documented command lines (flags via `<verb> --help`). Sole exception: debugging a suspected bug in the script itself.
+ The kernel owns events and scheduling. Stage executors own their workdir artifacts and close
+ through the stage CLI. An executor may run in this conversation or in a subagent; its stage
+ responsibilities are the same. While orchestrating, use the kernel rather than editing events
+ or stage results directly. Inspect source when needed to understand an operation.
- ## `DISPATCH` — start a run, then loop
+ ## Run the work
- The action carries `dispatch_args`, the exact argv for this dispatch. Run `kernel.py` with
- it as-is:
+ Query the next action:
```bash
- python3 <skill>/../../framework/scripts/kernel.py <action.dispatch_args…>
+ kernel.py decide --module {module} [--wake <rule>:<run>] [--closing]
```
- It re-checks dispatchability at this instant, records the dispatch event, and returns
- `{ok, rule, run, workdir, skill, execution}`. Branch the executor on `execution`, never on a
- stage list you keep yourself:
+ For `DISPATCH`, invoke the returned `dispatch_args` through the kernel CLI. The response prepares
+ the workdir and identifies the executor; it does not start that executor.
- | `execution` | executor |
+ | `execution` | Start the work |
|---|---|
- | `main-thread` | `Skill()`, passing the dispatch return's `skill` verbatim. |
- | `task` | Render `<skill>/../../framework/references/prompts/stage-subagent.md.tpl`, filling **every** template slot: `{module}`; the stage and skill lines from the dispatch return's `rule` / `skill`; `{workdir}` from the dispatch return. Then `Task(run_in_background=True, prompt=<rendered template>)`. |
-
- Every task dispatch renders identically, including `simulation-triage`: what the round is
- about is in the kernel-written `{workdir}/dispatch.json`, never in the prompt.
-
- ## `REAP` — close a run, then loop
-
- ```bash
- kernel.py reap --module {module} --rule <rule> --run <run>
- ```
+ | `main-thread` | Invoke the returned skill in this conversation, acting as that stage's executor. |
+ | `task` | Render [the stage prompt](../../framework/references/prompts/stage-subagent.md.tpl) with the module, rule, skill and workdir from dispatch; launch it with `Task(run_in_background=True, prompt=<rendered>)`. |
- `reap` derives the verdict from the run's own `result.json`. Whether a stage passed is not
- yours to decide.
+ After launching a background executor, query `decide` again so other ready work can proceed.
+ After an executor exits, pass `--wake <rule>:<run>` to `decide`. Carry out the returned action:
- ## `YIELD` — report what is running, end the turn
+ - `REAP`: run `kernel.py reap --module {module} --rule <rule> --run <run>`, then query again.
+ Reap uses that run's result; an absent result is handled as an incomplete execution.
+ - `YIELD`: report the running work and wait for an executor completion before resuming.
+ - `ESCALATE`: resolve the reported decision under the authorization below; resume after recording
+ it, or wait when information or a human decision is needed.
+ - `DONE`: report what the evidence establishes and its limits; complete signoff if it is in scope.
- The action returns `in_flight[]`, each entry `{rule, run}` — the only place a run *number*
- surfaces, and what you need to name one. Reply the list to the user and end the turn. (A
- triage-pending `YIELD` carries the triage run — say a triage subagent is running.)
+ Executor completion comes from the host; `YIELD` and a result file alone do not establish that
+ an executor has exited. Wait for exit before waking or reaping its run. Use
+ `kernel.py status --module {module}` for a read-only status query. A failed CLI operation leaves
+ its reported cause to resolve; it does not constitute a completed action.
- Only the harness can tell you an executor died; the kernel cannot see it, and a `YIELD` never
- implies it. Never reap a run whose executor is still alive: it will write `result.json` into
- a workdir whose outcome has already landed. The opposite mistake is harmless — `reap` reads
- the file at the moment you call it, so a run that finished in the meantime is reaped on its
- own envelope, not as `blocked`.
+ ## Decisions and authorization
- ## `ESCALATE` — hand the decision to the user, end the turn
+ Assess the evidence and the user's actual authorization. Present the specific decision, basis and
+ unresolved issues when human input is needed, and wait for that decision. Within an existing
+ explicit delegation, decide and act in scope. A refusal or a reserved decision remains binding.
+ Record who decided and the authorization basis in `--provenance`, and the engineering grounds in
+ `--reason`. A host's permission to execute a command is separate from authorization for its decision.
- `decide` returns a `reason` (and, for an unreliable-diagnosis case, `candidates[]`). Give the
- user the reason, any `candidates`, and — to show the blast radius of a proposed
- change — `kernel.py consequences --module {module} --paths <path…>` (the currently-valid
- proofs a path change would invalidate). Offer 2–3 concrete next steps.
+ ## `ESCALATE` — resolve the decision
- Recovery is **exclusively a human `kernel.py diagnose`**, and you never author one yourself:
- the verb stamps every diagnosis it writes `source=human`, so one you mint is recorded as a
- human's judgment. Surface the command for the user to approve/author:
+ `decide` returns a reason and, where relevant, candidates. Inspect the evidence and identify what
+ needs deciding. `kernel.py consequences --module {module} --paths <path…>` shows the valid proofs
+ a proposed change would invalidate. Record a resolved repair attribution with:
```bash
kernel.py diagnose --module {module} --id <diag-id> \
--subject-proof <failed proof> --subject-run <run> \
- --attribution <stage> --fix-owner <producer inside the subject's input closure> \
- --provenance "<the identity that vouches>" --reason "<the reasoning>" \
+ --attribution <stage> --fix-owner <subject stage or its input producer> \
+ --provenance "<decision maker and authorization>" --reason "<evidence and reasoning>" \
[--supersedes <prior diag-id>]
```
- `--provenance` and `--reason` are both required and are different things: the bare identity
- that vouches, and the reasoning, which is what `dispatch.json` carries verbatim to the fix
- owner. `fix-owner` must produce an artifact inside the subject proof's transitive input
- closure (the kernel rejects it otherwise); omitting `--fix-owner` records a self-pointing
- attribution that `decide` will escalate again rather than auto-rebuild.
-
- A human's own judgment is not yours to relay. It lands as its own event through this verb,
- with the identity in `--provenance`, and reaches the fix owner from there.
-
- ## `DONE` — report, end the turn
-
- Every stage proof is valid. Reply a completion summary.
+ This records `source=decision`; simulation-triage records `source=triage`. Both support the failed
+ stage itself or an input producer as repair owner. Omit ownership when the evidence cannot settle it.
## Closing: pin, reopen, signoff
- Signoff is a deliberate act, not a stage. When the user asks to close the module, pass
- `--closing` on every `decide` for that episode. It changes nothing about which proofs are
- required; it arms the signoff gate at `DONE`: every proof valid, every oracle pinned
- (`grade ∈ {tool, human}`), no unknown recorded version, no out-of-band added input.
+ When the task includes signoff, pass `--closing` to `decide`. Closure requires valid proofs,
+ `tool` or `endorsed` oracles and no unrecorded stage artifacts. Apply the authorization
+ above to each decision:
- - `decide --closing` returning `ESCALATE` "signoff blocked: `<proof>` oracle is proposed (pin
- it)" means a proposed-oracle proof (specification / simulation-plan / rtl-design /
- simulation) is blocking the gate. Present the option; only with the user's approval run
- `kernel.py pin --module {module} --rule <proof> --provenance <user> --reason "<…>"`, which
- records the oracle's current content fingerprint (upgrading its grade to `human` while that
- content is unchanged).
- - `kernel.py reopen --module {module} --pin-ref <oracle_ref> --reason "<…>"` retires a pin —
- same ask-gate, same explicit-approval rule.
- - `decide --closing` returning `DONE` means the gate is clear and the module is ready to
- close — but nothing is signed off until a human says so. **Lay out the returned `basis`
- first, per proof: the oracle ref and its live grade, the fingerprint a `human` pin named,
- the recorded tool identities, and the input set.** The gate says a signature is admissible;
- `basis` is the proposition being signed, and a human cannot take on what they were not
- shown. Then, only with their approval, run `kernel.py signoff --module {module}
- --provenance <user> --reason "<…>"`.
+ - `kernel.py pin --module {module} --rule <proof> --provenance "<decision maker and authorization>"
+ --reason "<basis>"` endorses the oracle's current content. A content change expires that endorsement.
+ - `kernel.py reopen --module {module} --pin-ref <oracle_ref> --reason "<decision and basis>"`
+ withdraws an endorsement.
+ - `decide --closing` returning `DONE` provides the basis ready for signoff. Assess the listed proofs,
+ oracle fingerprints, requirement verdicts and inputs, alongside the effective tool and library
+ conditions in the reports. Record the authorized
+ decision with `kernel.py signoff --module {module} --provenance "<decision maker and authorization>"
+ --reason "<basis>"`.
+
+ `DONE` alone is not signoff. `endorsed` means a recorded, content-bound endorsement; its provenance
+ identifies the decision maker and delegation, rather than implying personal review by the user.
+ Signoff applies to the accepted stage evidence. New conclusions need a new signoff under the
+ actual authorization; repeating collection or endorsement of unchanged evidence does not.