@printpractical/cruze 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@ It works with any agent that supports the [Agent Skills](https://agentskills.io)
10
10
 
11
11
  ## Status
12
12
 
13
- Version 0.0.5 is the fifth preview. It cuts the ceremony per change: reviews bring you only the findings that are yours to decide, plans are approved once their review closes, a rethink re-stamps the work it didn't change, and changes are sized to be worth their review and verify. Early development. The CLI is complete for the V1 lifecycle. The document formats ship as the `cruze-formats` skill, the standards an agent designs and codes to ship as knowledge skills, and the whole workflow, from explore to land, ships as workflow skills. Claude Code is the agent tested so far.
13
+ Version 0.0.6 is the sixth preview. It cuts the waiting per change: the full test suite runs once per commit, with an optional fast tier for the task loop, the design walkthrough is one overview followed by the documents to read in full, the agent checks a review's round 2 when the fixes follow the proposals, and research checks every claim the design relies on. Early development. The CLI is complete for the V1 lifecycle. The document formats ship as the `cruze-formats` skill, the standards an agent designs and codes to ship as knowledge skills, and the whole workflow, from explore to land, ships as workflow skills. Claude Code is the agent tested so far.
14
14
 
15
15
  ## Why
16
16
 
@@ -35,7 +35,7 @@ The skills run `cruze` commands, so the agent needs `cruze` on its path. Install
35
35
  From a GitHub Release, without npm. Each release attaches the packed package:
36
36
 
37
37
  ```sh
38
- npm install -g https://github.com/PrintPractical/cruze/releases/download/v0.0.5/printpractical-cruze-0.0.5.tgz
38
+ npm install -g https://github.com/PrintPractical/cruze/releases/download/v0.0.6/printpractical-cruze-0.0.6.tgz
39
39
  ```
40
40
 
41
41
  From npm, once a version is published there:
@@ -47,7 +47,7 @@ npm install -g @printpractical/cruze
47
47
  From the git repository, at a tag or `#main`. This needs git and access to the repository. npm 11 needs `--install-links` for a global git install, and the first `cruze` command builds the CLI, which takes a moment:
48
48
 
49
49
  ```sh
50
- npm install -g --install-links github:PrintPractical/cruze#v0.0.5
50
+ npm install -g --install-links github:PrintPractical/cruze#v0.0.6
51
51
  ```
52
52
 
53
53
  ### 2. Set up a repository
@@ -61,7 +61,7 @@ cruze init
61
61
  When you didn't install from npm, tell `init` where Cruze came from, so the CI it writes runs the same source instead of the npm package:
62
62
 
63
63
  ```sh
64
- cruze init --package https://github.com/PrintPractical/cruze/releases/download/v0.0.5/printpractical-cruze-0.0.5.tgz
64
+ cruze init --package https://github.com/PrintPractical/cruze/releases/download/v0.0.6/printpractical-cruze-0.0.6.tgz
65
65
  ```
66
66
 
67
67
  `init` asks for the project name, and which coding agent you use: `claude` for Claude Code, or `other` for any agent that reads `AGENTS.md` and `.agents/skills/`, such as Codex or OpenCode. It doesn't ask when you pass `--agent claude` or `--agent other`, or when the repository already has `CLAUDE.md` or `.claude/`. With `--yes`, or without a terminal, it sets up Claude Code. Then it creates:
@@ -28,7 +28,7 @@ import { appendJournal, loadView, } from "../project_context.js
28
28
  export async function createWorkItem(deps , request ) {
29
29
  const view = await loadView(deps.files);
30
30
  const date = deps.clock.today();
31
- const values = { id: "", title: request.title, date, project_name: "" };
31
+ const values = { id: "", title: request.title, title_quoted: JSON.stringify(request.title), date, project_name: "" };
32
32
  if (request.title.trim() === "") throw new CruzeError("missing-title", "a title is required");
33
33
 
34
34
  if (request.kind === "adr") {
@@ -15,12 +15,13 @@ export const RECORDED_EVENTS = {
15
15
  override: ["gate", "reason"],
16
16
  bug: ["summary", "cause"],
17
17
  verification: ["result", "summary"],
18
+ checks: ["commit"],
18
19
  };
19
20
 
20
21
  /** Fields an event may carry beyond its required ones, checked when present. A defect rethink must say which step missed it. */
21
22
  const OPTIONAL_FIELDS = {
22
23
  rethink: ["missed_by"],
23
- review: ["nits"],
24
+ review: ["nits", "checked_by"],
24
25
  disposition: ["decided"],
25
26
  };
26
27
 
@@ -34,6 +35,7 @@ export const FIELD_VALUES = {
34
35
  decided: ["agent", "user"],
35
36
  review: ["design", "plan", "code", "realign"],
36
37
  result: ["accepted", "sent-back"],
38
+ checked_by: ["agent", "reviewer"],
37
39
  found_by: STEPS,
38
40
  missed_by: STEPS,
39
41
  };
@@ -79,6 +81,9 @@ export function recordedEventProblems(event , fields
79
81
  if (allowed !== undefined && !allowed.includes(value)) problems.push(`${field} must be one of ${allowed.join(", ")}`);
80
82
  if (COUNT_FIELDS.includes(field) && !/^\d+$/.test(value)) problems.push(`${field} must be a whole number`);
81
83
  }
84
+ if (event === "checks" && fields["commit"] !== undefined && !/^[0-9a-f]{7,40}$/.test(fields["commit"])) {
85
+ problems.push("commit must be a commit hash, such as the output of git rev-parse --short HEAD");
86
+ }
82
87
  if (event === "disposition" && fields["decided"] === "agent" && fields["disposition"] !== "fixed") {
83
88
  problems.push("the agent decides only fixes; the user waives, defers or rejects a finding (decided=user)");
84
89
  }
@@ -66,7 +66,7 @@ function projectStep(view ) {
66
66
  {
67
67
  path: PATHS.architecture,
68
68
  missing: { step: "architect", reason: "the project has no architecture yet" },
69
- unapproved: { step: "architect", reason: "finish the architecture, walk through it and approve it" },
69
+ unapproved: { step: "architect", reason: "finish the architecture, review it and approve it" },
70
70
  changed: { step: "rethink", target: "architecture", reason: "the architecture changed since its approval" },
71
71
  },
72
72
  {
@@ -89,7 +89,7 @@ function itemSteps(view , item , branch )
89
89
  if (item.kind === "standalone") return [changeStep(view, item, branch)];
90
90
  const state = evaluateApproval(view, item.path);
91
91
  if (readChangesTable(item.doc).length === 0) return [{ step: "architect", target: item.ref, reason: "the feature has no design or changes yet" }];
92
- if (state.state === "unapproved") return [{ step: "architect", target: item.ref, reason: "review the feature's design, walk through it and approve it" }];
92
+ if (state.state === "unapproved") return [{ step: "architect", target: item.ref, reason: "review the feature's design and approve it" }];
93
93
  if (state.state !== "approved") return [{ step: "rethink", target: item.ref, reason: `the feature changed since its approval${state.changed.length > 0 ? ` (${state.changed.join(", ")})` : ""}` }];
94
94
  const changes = changesOf(view.items, item);
95
95
  const landed = new Set(changes.filter((c) => readProgress(c.doc).landed !== undefined).map((c) => c.folderName));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@printpractical/cruze",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Spec-driven development for coding agents: one living model of the system, small deltas, convergent review.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Chris Buchter",
@@ -5,7 +5,7 @@ description: Decides how to build and how big, at project scope (domain model, c
5
5
 
6
6
  # Architect
7
7
 
8
- Architect decides the how and the how big. It designs the domain, the ports and adapters, and where every element lives in the source tree, before any code exists. It ends with the one heavy human gate, the design walkthrough, where the user sees the entities, their interactions, the ports and the files, and approves the design.
8
+ Architect decides the how and the how big. It designs the domain, the ports and adapters, and where every element lives in the source tree, before any code exists. It ends with the one heavy human gate, the design walkthrough: a short overview in plain terms, after which the user reads the design documents in full and approves or comments.
9
9
 
10
10
  ## Steps
11
11
 
@@ -25,7 +25,7 @@ Architect decides the how and the how big. It designs the domain, the ports and
25
25
  - `.agents/skills/cruze-formats/reference/architecture.md`
26
26
  5. **Design.** Follow the scope's procedure: [project.md](project.md), [feature.md](feature.md) or [tweak.md](tweak.md). Tweak scope ends there and hands off to `plan`.
27
27
  6. **Review the design.** Run the design review in `.agents/skills/cruze-roles/SKILL.md`, with the design reviewer role. Done when every finding has a journaled disposition and no blocker is open without the user's decision.
28
- 7. **Walk the user through it.** Follow [walkthrough.md](walkthrough.md). Apply what the user changes, run `cruze validate` again, and repeat the parts of the walkthrough those changes affect.
28
+ 7. **Hand the design to the user.** Follow [walkthrough.md](walkthrough.md): one overview message, then the documents to read in full. Apply what the user changes, run `cruze validate` again, and say what changed.
29
29
  8. **Record the approval.** Only after the user says they approve, run the scope's `cruze approve` command and quote its result, then commit. At project scope, the roadmap follows as its own approval, described in [project.md](project.md).
30
30
 
31
31
  ## Rules
@@ -33,4 +33,6 @@ The result is a `feature.md` with a complete architecture delta and an ordered l
33
33
 
34
34
  The thresholds are the defaults under `changes:` in `.cruze/config.yaml`; a project can tune them.
35
35
 
36
+ Done when `cruze validate` reports no `change-too-small`, `change-too-large` or `feature-size` warning, or the user has accepted one and a `D<n>` line under the feature's `## Decisions` records why. After approval, only a rethink can split a change.
37
+
36
38
  Then continue with the review and walkthrough steps of the skill. When the user approves, run `cruze approve <feature>` and quote its result. The command takes the feature's full ID, such as `2026-09-25-open-console`, or its slug when no other active item shares it.
@@ -1,29 +1,32 @@
1
1
  # The design walkthrough
2
2
 
3
- The walkthrough is where the user comes to understand the design well enough to explain it without you. It is the one heavy gate before code. Show the design as it stands in the files, one part at a time, in the order below. Pause after each part for questions.
3
+ The walkthrough hands the design to the user in one message: a short overview in plain terms, then the documents to review in full. The documents are the design, and the user reads them faster than you can retell them, so present the whole design at once and wait for one answer: approval, or comments.
4
4
 
5
- At feature scope, show only what the feature adds, changes or removes, next to the current elements it touches. At project scope, show the whole architecture.
5
+ At feature scope, cover only what the feature adds, changes or removes. At project scope, cover the whole architecture, the layer rules, the roadmap and the walking skeleton.
6
6
 
7
- ## Order
7
+ ## The overview
8
8
 
9
- 1. **What it does.** The intent in two sentences, then each requirement with its scenarios' titles.
10
- 2. **Where it sits.** The `VIEW-context` diagram, or at feature scope, the contexts the feature touches.
11
- 3. **The domain.** The domain-model class diagram, then each new or changed entity: its invariants, its states and who owns it.
12
- 4. **How it runs.** For each key flow, show its `sequenceDiagram` and walk one scenario through it step by step, including one failure path. This is the part the user must be able to retell.
13
- 5. **The seams.** Each new or changed port with its operations and their contracts, then the adapter behind each one and the library it adopts.
14
- 6. **Dependencies.** Every new dependency, named out loud with its purpose and the approval behind it. Also the components you chose to build yourself, with the reason.
15
- 7. **Where the code goes.** Each new element next to its module, file path and layer, and the layer rules those files must obey. At project scope, also the `layers:` in `.cruze/config.yaml`.
16
- 8. **The slices.** The changes in order, with what each delivers and builds, and why the first is first. At project scope, the roadmap's phases and the walking skeleton instead.
17
- 9. **Decisions and review.** The settled decisions and ADRs, each review finding with its disposition, and the points where a fresh implementer could still build something different.
9
+ Write it in the glossary's terms, as what callers can do and what happens when they do, not as a list of elements. Keep it to what the user can read in a minute.
18
10
 
19
- ## Showing diagrams
11
+ 1. **What it does.** The intent in two sentences. Then one line per use case, or at feature scope per requirement: who asks for what, what they get, and the main way it fails.
12
+ 2. **What it touches.** Each new external system, and each new dependency named with its purpose and the approval behind it. Also each component you chose to build yourself, with the reason.
13
+ 3. **The slices.** The changes in order, one line each, saying what each delivers and why the first is first. At project scope, the roadmap's phases and the walking skeleton instead.
14
+ 4. **What is yours to decide.** The review findings the roles skill brings to the user, any `cruze validate` warning still standing, such as a change over its size limit, any point where a fresh implementer could still build something different, and any rule you challenged that the user overrode.
20
15
 
21
- Mermaid diagrams live in the documents, so point to the file and line of each one, and paste its source into the conversation. When the user can render Mermaid (an editor preview, or GitHub), say where to open it. Keep each diagram under 15 nodes; split a bigger picture instead of shrinking it.
16
+ ## The documents
17
+
18
+ List each file the user should read in full, with the sections that changed:
19
+
20
+ - Feature scope: the feature's `feature.md`, and the ADRs it adds.
21
+ - Project scope: `docs/architecture.md`, the `layers:` in `.cruze/config.yaml`, `docs/roadmap.md`, the walking-skeleton `change.md`, and the ADRs in `docs/adr/`.
22
+
23
+ The diagrams are Mermaid inside those files. Say where the user can render them, such as an editor preview or GitHub, rather than pasting them.
24
+
25
+ End the message with: "Read these in full, then tell me what to change, or approve. Do you approve this design?"
22
26
 
23
27
  ## Ending
24
28
 
25
- 1. Ask the user to explain one flow back in their own words, or to name what they would still find surprising in the code. Treat their answer as the check that the walkthrough worked, and go back over any part they can't retell.
26
- 2. Ask for approval in these words: "Do you approve this design?"
27
- 3. A request for changes is not an approval. Apply the changes and run `cruze validate`. When they touch placement, dependency direction, adopt-or-build decisions, port contracts or flows, run a new design review on the diff alone. Then walk through only the parts that changed, and ask again.
28
- 4. When the user rejects the design outright, don't approve anything. Ask what is wrong. When the problem is what to build, go back to `envision`; when it is the whole approach, restart this step's design; when the user wants to stop, leave the work unapproved and say how to resume.
29
- 5. Done when the user says they approve.
29
+ 1. Answer a question from the documents, pointing to the file and section, and answer only what was asked.
30
+ 2. A request for changes is not an approval. Apply the changes and run `cruze validate`. When the user edited the documents themselves, read their diff and run `cruze validate` on it. When the changes touch placement, dependency direction, adopt-or-build decisions, port contracts or flows, run a new design review on the diff alone. Then say in a few lines what changed and where, and ask again.
31
+ 3. When the user rejects the design outright, don't approve anything. Ask what is wrong. When the problem is what to build, go back to `envision`; when it is the whole approach, restart this step's design; when the user wants to stop, leave the work unapproved and say how to resume.
32
+ 4. Done when the user says they approve.
@@ -19,10 +19,11 @@ Build turns an approved plan into code, one task at a time. Each task starts wit
19
19
  3. **Read the plan and the design.** Read the change's `change.md` and its feature's `feature.md`. Read the full body of every element the change builds, and every scenario it delivers. Read `commands:` in `.cruze/config.yaml`.
20
20
  4. **Build each open task in order,** following the task loop below. Skip the tasks already ticked in `## Progress`.
21
21
  5. **Finish.** When every task is ticked:
22
- - Run the full test suite, the formatter and the linter, using the project's commands.
22
+ - Run the format, lint and build commands and the full suite, as `.agents/skills/cruze-formats/reference/config.md` defines it under `commands`.
23
23
  - Run `cruze check` and `cruze trace`, and quote their results.
24
+ - When all of them pass, record the commit they ran at with `cruze journal add checks --set commit=<commit> --item <ref>`, where the commit is the output of `git rev-parse --short HEAD`. Verify quotes this instead of running the suite again.
24
25
  - Commit the progress record with a message such as `chore: record progress on <change>`.
25
- - Done when all of them pass.
26
+ - Done when all of them pass and the checks are recorded.
26
27
 
27
28
  ## The task loop
28
29
 
@@ -31,7 +32,7 @@ For task `T<n>`:
31
32
  1. **Read it.** Note its owner, its files, the IDs it proves, and the test plan rows for those IDs.
32
33
  2. **Red.** Write the tests for the IDs it proves, at the seams the test plan names, carrying the IDs. Run them, and see them fail for the reason you expect.
33
34
  3. **Green.** Write the least code that makes them pass, in the task's files. Code that belongs to another task, or another change, waits for it, even when the next change will need it.
34
- 4. **Check.** Run `cruze check <the task's files>`, the formatter and the linter, and fix what they report. Run the tests the task touched, and the rest of the suite when they are quick.
35
+ 4. **Check.** Run `cruze check <the task's files>`, the formatter and the linter, and fix what they report. Run the tests the task touched. When `commands:` has a `test_full`, run `test` too, since it is the fast tier. Otherwise run the rest of the suite only when it is quick.
35
36
  5. **Commit** with a Conventional Commit message naming the task, such as `feat(access): console session state machine (T2)`.
36
37
  6. **Tick it.** Run `cruze task done T<n>`, which records the commit. Its progress edit rides along in the next commit.
37
38
 
@@ -43,10 +44,10 @@ Done for a task when its tests pass, `cruze check` passes for its files, the com
43
44
 
44
45
  The plan is design. Within a task you decide only what is local and reversible.
45
46
 
46
- - **Record it and carry on** for a task-level choice: a private helper in another file of the same module, a private type, or two tasks' commits swapped for a reason. Run `cruze task deviation T<n> "<what you did and why>"`.
47
+ - **Record it and carry on** for a task-level choice: a private helper in another file of the same module, a private type, a fixture or harness added to the test support module that the task's tests need, or two tasks' commits swapped for a reason. The test support module is in every test-writing task's scope, so extend it rather than writing a private helper in a test file. Run `cruze task deviation T<n> "<what you did and why>"`.
47
48
  - **Stop and offer `rethink`** when the code needs any of these:
48
49
  - a new element, port operation or scenario;
49
- - a file outside the owner's module;
50
+ - a file outside the owner's module, other than the test support module;
50
51
  - a change to an approved scenario's behaviour, or to its test;
51
52
  - a dependency the design doesn't name.
52
53
 
@@ -56,7 +56,7 @@ layers:
56
56
  | `check.max_types` | Budget of top-level types per source file. |
57
57
  | `check.exceptions` | Files allowed past a budget, or Rust test files allowed under `src/` (`test-placement`), each with a `path` and a `reason`. `realign` adds entries whose reason ends `scheduled in <ref>`, and landing that change removes them. |
58
58
  | `layers` | Each layer has a `name`, the `paths` it covers, and `may_import`, the layers it may depend on. |
59
- | `commands` | The project's commands by name, such as `test` or `run`. The walking-skeleton change fills them in, and `cruze land` copies them into the Commands section of `AGENTS.md`. |
59
+ | `commands` | The project's commands by name, such as `test` or `run`. The walking-skeleton change fills them in, and `cruze land` copies them into the Commands section of `AGENTS.md`. When the suite has a slow tier, such as UI, device or end-to-end tests, `test` runs only the fast tier and `test_full` runs everything. The full suite is `test_full` when it is set, and `test` otherwise. |
60
60
  | `review.command` | The program and arguments `cruze review` runs to start an agent in a fresh context, with the prompt on standard input. Optional. `cruze init` sets it for Claude Code to run in print mode, allowed to read the project and run `git diff`, `git log`, `git show` and `cruze`. The verifier runs the system, so add the project's build and run commands. When it is unset, or its program isn't installed, `cruze review` hands the role's prompt back to the calling agent to run in a helper. |
61
61
  | `review.decide` | Which review findings the user decides. `exceptions`, the default: only findings whose fix changes behaviour, a designed port or contract, or another decision the user owns, and any the agent wouldn't simply fix as proposed. The agent fixes the rest and lists them. `all`: the user decides every finding. |
62
62
  | `changes.min_builds` | A feature's change that builds fewer elements than this gets a `change-too-small` warning: merge it into the change it continues. Default `3`. |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  id: {{id}}
3
- title: {{title}}
3
+ title: {{title_quoted}}
4
4
  ---
5
5
 
6
6
  # Change: {{title}}
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  id: {{id}}
3
- title: {{title}}
3
+ title: {{title_quoted}}
4
4
  roadmap: <roadmap item slug>
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  id: {{id}}
3
- title: {{title}}
3
+ title: {{title_quoted}}
4
4
  roadmap: <roadmap item slug, when the change is on the roadmap>
5
5
  ---
6
6
 
@@ -13,7 +13,7 @@ Land makes finished work part of the living model. `cruze land` merges the chang
13
13
  2. **Bring in main.** Merge or rebase the branch onto an up-to-date main, and resolve conflicts.
14
14
  - `journal.jsonl` files merge by keeping every line; `cruze init` sets that up in `.gitattributes`. When that file lacks the rule, keep both sides' lines.
15
15
  - When an `approvals.json` conflicts, take main's version of it. Then run `cruze status`, and re-approve what it shows stale, as step 3 describes.
16
- - Resolve code conflicts as usual, then run the tests.
16
+ - Resolve code conflicts as usual, then run the full suite. When main came in without code conflicts, leave the full suite to CI.
17
17
  3. **Run `cruze status`.** When the change or its feature shows `upstream changed`, another branch landed changes to elements it cites. Then:
18
18
  - Show the user the diff of each changed element, and check that the change's code and tests still hold against it.
19
19
  - When they still hold, re-approve the stale documents: the feature first, then the change. The change's verification carries over when its own design didn't change.
@@ -44,7 +44,7 @@ Say what is missing and why, then send the change to `rethink` at feature level.
44
44
 
45
45
  The walking-skeleton change also makes CI and the project's tooling real. Its plan adds:
46
46
 
47
- - `commands:` in `.cruze/config.yaml`: the format, lint, build, test and run commands, as the language's standard tooling runs them.
47
+ - `commands:` in `.cruze/config.yaml`: the format, lint, build, test and run commands, as the language's standard tooling runs them. When some tests are much slower than the rest, such as UI or device tests, `test` runs the fast tier and `test_full` the whole suite, so build can run `test` after every task.
48
48
  - A task that adds the language's format, lint, build and test steps to CI (`.github/workflows/ci.yml`), before the Cruze steps `cruze init` put there. The task proves the flow its smoke test runs.
49
49
 
50
50
  ## Next step
@@ -9,6 +9,7 @@ A task is one owner, the files it writes, and the IDs it proves. Build does them
9
9
  - The composition root comes last.
10
10
  - Put fakes just before the first task whose test needs them.
11
11
  - Each task's test can fail first and then pass, using only what earlier tasks built.
12
+ - A test that expects a default or empty result, such as no prompt, an empty list, `nil` or `0`, passes against a stub that returns it. Name in the task the break it is first seen failing against, such as "fails against a model that always shows the prompt".
12
13
  - When the project's lint rejects unused code, such as `cargo clippy -- -D warnings`, put each new item in the task of its first user, or in a task whose own test uses it. Each task then commits green on its own.
13
14
  3. **Write one line per task:**
14
15
 
@@ -17,7 +18,7 @@ A task is one owner, the files it writes, and the IDs it proves. Build does them
17
18
  - T7: `OpenConsole` in `src/access/app/open_console.rs`, proves UC-access.open-console, SCN-access.direct-serial
18
19
  ```
19
20
 
20
- - Owner and paths in backticks. Every path is a file the architecture assigns to that owner, or a test or support file.
21
+ - Owner and paths in backticks. Every path is a file the architecture assigns to that owner, or a test or support file. List the test support files the task extends, such as a shared harness or fixture, so its tests reuse them.
21
22
  - A task proves the elements it builds, and each scenario whose test goes green in it.
22
23
  - A task that only sets up tooling proves the flow or scenario its checks run.
23
24
  4. **Find the callers.** For each signature, default or setting a task changes, search the code for every use of it, including tests that start the real binary or read the setting. Add each file that must change to the task. Done when no task will need a file it doesn't list.
@@ -0,0 +1,44 @@
1
+ # Realign notes: 0.0.6
2
+
3
+ ## New work only
4
+
5
+ ### suite-once-per-commit: The full test suite runs once per commit, and verify quotes build's result
6
+ - Applies to: new work only
7
+ - Rule: `.agents/skills/cruze-verify/SKILL.md`, "Steps", step 2
8
+
9
+ ### test-tiers: A project with slow tests can split them into test and test_full
10
+ - Applies to: new work only
11
+ - Rule: `.agents/skills/cruze-formats/reference/config.md`
12
+ - Fix: when the full suite takes more than a few minutes, move it to `test_full` under `commands:` and make `test` the fast tier
13
+
14
+ ### test-support-in-scope: Build extends the test support module without a rethink
15
+ - Applies to: new work only
16
+ - Rule: `.agents/skills/cruze-build/SKILL.md`, "Deviations"
17
+
18
+ ### name-the-break: Plan names the break for a test that passes against a stub
19
+ - Applies to: new work only
20
+ - Rule: `.agents/skills/cruze-plan/tasks.md`, step 2
21
+
22
+ ### round-2-by-agent: The agent checks round 2 when every blocker was fixed as proposed
23
+ - Applies to: new work only
24
+ - Rule: `.agents/skills/cruze-roles/SKILL.md`, "Running a review", round 2
25
+
26
+ ### size-before-approval: Size warnings are cleared or accepted before a feature is approved
27
+ - Applies to: new work only
28
+ - Rule: `.agents/skills/cruze-architect/feature.md`, step 12
29
+
30
+ ### verify-every-claim: Research checks claims about the language, platform and external systems
31
+ - Applies to: new work only
32
+ - Rule: `.agents/skills/cruze-research/SKILL.md`, "Adopt or build", step 7
33
+
34
+ ### cross-section-consistency: The design reviewer checks cross-cutting rules, interleavings and stale prose
35
+ - Applies to: new work only
36
+ - Rule: `.agents/skills/cruze-roles/design-reviewer.md`, "Rubric", item 8
37
+
38
+ ### one-message-walkthrough: The design walkthrough is one overview, then the documents in full
39
+ - Applies to: new work only
40
+ - Rule: `.agents/skills/cruze-architect/walkthrough.md`
41
+
42
+ ### quoted-titles: New features and changes quote their title in the header
43
+ - Applies to: new work only
44
+ - Rule: `.agents/skills/cruze-formats/templates/change.md`
@@ -8,6 +8,7 @@ Each release that changes what Cruze expects of a project ships a notes file, `n
8
8
  - [0.0.3](notes/0.0.3.md)
9
9
  - [0.0.4](notes/0.0.4.md)
10
10
  - [0.0.5](notes/0.0.5.md)
11
+ - [0.0.6](notes/0.0.6.md)
11
12
 
12
13
  ## Format
13
14
 
@@ -17,7 +17,13 @@ Run these steps for each component in a design that isn't domain logic. Domain l
17
17
  4. Recommend one. Adopt a library, or build with a concrete reason: the behaviour is specific to this product, no candidate meets a stated constraint, every candidate brings disproportionate risk or complexity, or the capability is the product itself. Avoiding a dependency is not a reason on its own.
18
18
  5. Record the result as a row in the `## Adopt or build` table of the feature or standalone change, as Component, Decision, Choice and Reason. At project scope, record it as the adapter's `Adopts` fact, and put rows for anything no adapter owns in the walking-skeleton change's `## Adopt or build`. When the evidence runs longer than the reason, write it to `.cruze/notes/<date>-<slug>.md` and cite that note in the reason.
19
19
  6. Take the recommendation to the user. Adopting means a new dependency, which follows `.agents/skills/cruze-dependency-approval/SKILL.md`. Building commodity functionality is the user's call as well.
20
- 7. Verify what the design will rely on. List each claim the design makes about an adopted library or tool: the features or flags it needs, and each command the design spells out, such as a CI step. Once the user has approved the dependency, check each claim by running it: build a scratch project outside the repository with exactly the declared features, and run each command there or with `--help`. When a claim can't be run, check it in that version's source. Write the features into the `Adopts` fact or the row's Choice.
20
+ 7. Verify what the design will rely on. List each claim the design or its testing approach makes about anything it doesn't build:
21
+ - an adopted library or tool: the features or flags it needs, and each command the design spells out, such as a CI step;
22
+ - the language or runtime, such as whether a trait with async methods can be used as a trait object;
23
+ - the platform's test environment, such as which permissions a test process gets;
24
+ - an external system the product talks to, such as what a broker logs or how it answers.
25
+
26
+ Once the user has approved any dependency involved, check each claim by running it: build a scratch project outside the repository with exactly the declared features, and run each command there or with `--help`, or run the external system and watch it. When a claim can't be run, check it in that version's source, and say so. Write the features into the `Adopts` fact or the row's Choice.
21
27
 
22
28
  Done when every non-domain component in the design has a row with a decision and a reason, and every claim the design relies on is verified, with how.
23
29
 
@@ -11,7 +11,7 @@
11
11
 
12
12
  1. Edit the feature's `## Spec delta`, `## Architecture delta` or `## Changes`. For a standalone change, edit its own deltas and scope. Write complete bodies, as `architect` does, and keep the scope rules.
13
13
  2. Run `cruze validate`. Done when it reports no errors for the feature or its changes.
14
- 3. Run the design review from the roles skill on the diff alone, with `review=design`. Walk the user through the changed parts, following `.agents/skills/cruze-architect/walkthrough.md`.
14
+ 3. Run the design review from the roles skill on the diff alone, with `review=design`. Run the walkthrough of the changed parts, following `.agents/skills/cruze-architect/walkthrough.md`.
15
15
  4. Re-approve the feature. For each of its changes that shows as stale, check it against the diff. When the amendment touches the change's scope, test plan or tasks, update them to match, reopen touched tasks, run the plan review on the diff, and re-approve it with `cruze approve <change> --by-agent`. When it doesn't, re-stamp the change as the skill's step 6 describes.
16
16
  5. When a change hasn't been created yet, only the feature's Changes row changes; `plan` picks it up.
17
17
 
@@ -53,11 +53,13 @@ A review has at most two rounds. Only blockers can force the second one.
53
53
 
54
54
  ### Round 2
55
55
 
56
- Run round 2 only when a round-1 blocker was fixed.
56
+ Run round 2 only when a round-1 blocker was fixed. It checks only whether those blockers are fixed, and raises nothing new.
57
57
 
58
- 1. Run the reviewer again with its usual inputs, plus the round-1 blockers and the diff of their fixes. It may be the round-1 reviewer resumed, since that context never saw the conversation that produced the work (with `cruze review`: `--round 2 --blockers <file> --base <round-1 commit>`). It checks only whether those blockers are fixed, and raises nothing new.
59
- 2. Record the round with `round=2`.
60
- 3. Take any blocker still open to the user, who fixes it now, waives it or starts a rethink. There is no round 3.
58
+ 1. **Choose who checks.** When every blocker was fixed exactly as the reviewer proposed, check the fixes yourself: a fresh reviewer re-reading a fix it proposed finds nothing new. When any blocker was fixed differently from the proposal, or its fix reaches past what the finding names, run the reviewer.
59
+ 2. **Check them yourself:** read each blocker's finding against the diff of its fix, and run `cruze validate`. A blocker is fixed when the diff does what the proposal says and validate reports no new errors.
60
+ 3. **Or run the reviewer** again with its usual inputs, plus the round-1 blockers and the diff of their fixes. It may be the round-1 reviewer resumed, since that context never saw the conversation that produced the work (with `cruze review`: `--round 2 --blockers <file> --base <round-1 commit>`).
61
+ 4. Record the round with `round=2`, the blockers still open, `concerns=0`, and `checked_by=agent` or `checked_by=reviewer`.
62
+ 5. Take any blocker still open to the user, who fixes it now, waives it or starts a rethink. There is no round 3.
61
63
 
62
64
  Done when every finding has a journaled disposition, and every exception, and every blocker left open in round 2, has the user's decision.
63
65
 
@@ -28,8 +28,11 @@ Review against these items and nothing else. Each finding names one.
28
28
  8. **Consistency.** The design agrees with `docs/architecture.md`, the accepted ADRs and what earlier changes landed, or changes them explicitly through a `MODIFIED` operation or a new ADR. Its own elements agree with each other. Check every pair, not a sample:
29
29
  - each use case's `Output` and `Errors` against the `FLOW`s that serve it and the `XC` rules that apply to it;
30
30
  - each adapter's duties against the port it implements and the `XC` rules it follows;
31
- - each guarantee, such as "always fits" or "never returns", against the limits and failures that bound it.
32
- 9. **Slicing.** Each change is a vertical slice that delivers scenarios end to end and can land on its own. The order respects `Depends on`, and the first change proves the design end to end. Each change carries enough work to be worth its own plan review, code review and verify: changes that build one or two elements each on the same adapters or screens, in a chain, are one change split too fine. A change that one verifier run can't hold is split too coarse. A change `Builds` an element only when its delivered scenarios prove the whole body; an element whose duties arrive in several changes is split into elements that each arrive whole. `Depends on` names every earlier change that builds something this change's scenarios need. At project scope, the roadmap starts with the walking skeleton, and every goal in the release is covered.
31
+ - each guarantee, such as "always fits" or "never returns", against the limits and failures that bound it;
32
+ - each `XC` rule against the other `XC` rules, the `RULE` elements and the `layers:` in `.cruze/config.yaml`, such as a logging rule that every module logs against a build rule that forbids the logging import;
33
+ - each pair of use cases that change the same state, for an interleaving that leaves it wrong, against the concurrency rule in `XC`;
34
+ - at feature scope, the prose in `docs/architecture.md` the delta makes untrue, such as an Overview sentence or a `D<n>` line describing an element the delta splits or replaces.
35
+ 9. **Slicing.** Each change is a vertical slice that delivers scenarios end to end and can land on its own. The order respects `Depends on`, and the first change proves the design end to end. Each change carries enough work to be worth its own plan review, code review and verify: changes that build one or two elements each on the same adapters or screens, in a chain, are one change split too fine. A change that one verifier run can't hold is split too coarse. A `change-too-small`, `change-too-large` or `feature-size` warning from `cruze validate` is a finding, unless a decision records the user accepting it. A change `Builds` an element only when its delivered scenarios prove the whole body; an element whose duties arrive in several changes is split into elements that each arrive whole. `Depends on` names every earlier change that builds something this change's scenarios need. At project scope, the roadmap starts with the walking skeleton, and every goal in the release is covered.
33
36
  10. **Ambiguity.** Name each point where a fresh implementer could reasonably build something different from what the user expects.
34
37
 
35
38
  ## Plan rubric
@@ -6,11 +6,12 @@ You check that a change actually works when someone uses it. The tests passing i
6
6
 
7
7
  - The change's `change.md`, and its `feature.md` when it belongs to a feature. The scenarios it delivers are listed under `Delivers` in its scope, and written out in the spec delta.
8
8
  - The project's commands, from `commands:` in `.cruze/config.yaml`, and from `README.md` when they aren't there.
9
+ - The mechanical checks' results, with the commit they ran at.
9
10
  - The flows in `docs/architecture.md` that serve those scenarios.
10
11
 
11
12
  ## Work
12
13
 
13
- 1. **Build.** Build the system and run the full test suite with the project's commands. Record each command and whether it passed.
14
+ 1. **Build.** Build the system with the project's build command, and record whether it passed. The test suite already ran at the commit in your inputs, and CI runs it again before the merge, so don't run it. Run a single test only when it is how a scenario reaches its real front door, such as a UI test that drives the app.
14
15
  2. **Trace.** Run `cruze trace --change <ref>` and record its result.
15
16
  3. **Run each scenario.** For every scenario the change delivers:
16
17
  - Set up its GIVEN with real things where you can: configuration files, directories, a local test server, a pseudo-terminal. Put them in a temporary directory outside the project.
@@ -35,4 +36,4 @@ One block per scenario:
35
36
  - Notes: <surprises from probing, or what a person needs to run it>
36
37
  ```
37
38
 
38
- Before the blocks, list the build, test and trace commands with their results. End with one line: `Pass: <n>. Fail: <n>. Could not run: <n>.`
39
+ Before the blocks, list the build and trace commands with their results, and the commit the mechanical checks ran at. End with one line: `Pass: <n>. Fail: <n>. Could not run: <n>.`
@@ -10,18 +10,22 @@ Verify answers one question: does this change work when someone uses it? Green t
10
10
  ## Steps
11
11
 
12
12
  1. **Check it is ready.** Run `cruze next`. It must name `verify` for this change, on this branch. Find the base commit the change branched from with `git merge-base main HEAD`.
13
- 2. **Run the mechanical checks.** Run the project's format, lint, build and test commands from `commands:` in `.cruze/config.yaml`, then `cruze validate`, `cruze check --ci` and `cruze trace --change <ref>`. Quote each result. When one fails, fix the code in a commit and run them again. When a fix needs design, stop and offer `rethink`.
13
+ 2. **Run the mechanical checks.** Run `cruze validate`, `cruze check --ci` and `cruze trace --change <ref>`, and quote each result.
14
+ - Run `cruze journal list --event checks --item <ref>`. When its last entry's commit has no code changes since, that is when `git diff --quiet <commit> HEAD -- . ':(exclude)docs' ':(exclude).cruze'` succeeds, quote that entry for the format, lint, build and test commands instead of running them again.
15
+ - Otherwise run the format, lint and build commands and the full suite, as `.agents/skills/cruze-formats/reference/config.md` defines it under `commands`. When they pass, record them with `cruze journal add checks --set commit=<commit> --item <ref>`, where the commit is the output of `git rev-parse --short HEAD`.
16
+ - When one fails, fix the code in a commit and run them again. When a fix needs design, stop and offer `rethink`.
14
17
  3. **Check the dependencies.** Follow "Checking" in `.agents/skills/cruze-dependency-approval/SKILL.md` against the base commit. An unrecorded dependency is a blocker.
15
- 4. **Run the verifier.** Run the verifier role from `.agents/skills/cruze-roles/SKILL.md` for the change. It must be able to build and run the system. When it runs through `cruze review`, check that `review.command` in `.cruze/config.yaml` allows the project's build and run commands, and add them with the user's agreement. Done when you have its report, with a result for every delivered scenario.
16
- 5. **Review the code.** Run the review in the roles skill with the code reviewer, `review=code`, `--item <ref>` and the base commit. Fix each finding whose disposition is `fixed` in a commit, then check the fixes in round 2.
18
+ 4. **Run the verifier.** Run the verifier role from `.agents/skills/cruze-roles/SKILL.md` for the change, with the mechanical checks' results and the commit they ran at. It must be able to build and run the system. When it runs through `cruze review`, check that `review.command` in `.cruze/config.yaml` allows the project's build and run commands, and add them with the user's agreement. Done when you have its report, with a result for every delivered scenario.
19
+ 5. **Review the code.** Run the review in the roles skill with the code reviewer, `review=code`, `--item <ref>` and the base commit. Fix each finding whose disposition is `fixed` in a commit, running the tests each fix touches, and `test` when `commands:` has a `test_full`. Then check the fixes in round 2.
17
20
  6. **Write the manual test script** as `manual-test.md` in the change folder, following [manual-test.md](manual-test.md). Commit it.
18
- 7. **Report.** Show the user four things:
21
+ 7. **Check the fixes once.** When code changed since the last `checks` entry, run the format, lint and build commands and the full suite once more, and record them as in step 2. Done when the last `checks` entry is at a commit with no code changes since.
22
+ 8. **Report.** Show the user four things:
19
23
  - The mechanical checks, one line each.
20
24
  - The verifier's result for every scenario.
21
25
  - The review's outcome, with each finding's disposition.
22
26
  - The path to `manual-test.md`, with a recommendation to run it before accepting.
23
- 8. **Ask for the decision:** "Do you accept this change, or send it back?"
24
- 9. **Record it** with `cruze journal add verification --set result=accepted --set summary="<one line>" --item <ref>`, or `result=sent-back`. On sent-back, say what goes back:
27
+ 9. **Ask for the decision:** "Do you accept this change, or send it back?"
28
+ 10. **Record it** with `cruze journal add verification --set result=accepted --set summary="<one line>" --item <ref>`, or `result=sent-back`. On sent-back, say what goes back:
25
29
  - A defect in code a task already built: `cruze task reopen T<n> "<reason>"`, then `build`.
26
30
  - A design that can't deliver the scenario: `rethink`.
27
31
 
@@ -28,7 +28,7 @@ export interface NewReport {
28
28
  export async function createWorkItem(deps: ProjectDeps, request: NewRequest): Promise<NewReport> {
29
29
  const view = await loadView(deps.files);
30
30
  const date = deps.clock.today();
31
- const values = { id: "", title: request.title, date, project_name: "" };
31
+ const values = { id: "", title: request.title, title_quoted: JSON.stringify(request.title), date, project_name: "" };
32
32
  if (request.title.trim() === "") throw new CruzeError("missing-title", "a title is required");
33
33
 
34
34
  if (request.kind === "adr") {
@@ -15,12 +15,13 @@ export const RECORDED_EVENTS: Record<string, string[]> = {
15
15
  override: ["gate", "reason"],
16
16
  bug: ["summary", "cause"],
17
17
  verification: ["result", "summary"],
18
+ checks: ["commit"],
18
19
  };
19
20
 
20
21
  /** Fields an event may carry beyond its required ones, checked when present. A defect rethink must say which step missed it. */
21
22
  const OPTIONAL_FIELDS: Record<string, string[]> = {
22
23
  rethink: ["missed_by"],
23
- review: ["nits"],
24
+ review: ["nits", "checked_by"],
24
25
  disposition: ["decided"],
25
26
  };
26
27
 
@@ -34,6 +35,7 @@ export const FIELD_VALUES: Record<string, string[]> = {
34
35
  decided: ["agent", "user"],
35
36
  review: ["design", "plan", "code", "realign"],
36
37
  result: ["accepted", "sent-back"],
38
+ checked_by: ["agent", "reviewer"],
37
39
  found_by: STEPS,
38
40
  missed_by: STEPS,
39
41
  };
@@ -79,6 +81,9 @@ export function recordedEventProblems(event: string, fields: Record<string, stri
79
81
  if (allowed !== undefined && !allowed.includes(value)) problems.push(`${field} must be one of ${allowed.join(", ")}`);
80
82
  if (COUNT_FIELDS.includes(field) && !/^\d+$/.test(value)) problems.push(`${field} must be a whole number`);
81
83
  }
84
+ if (event === "checks" && fields["commit"] !== undefined && !/^[0-9a-f]{7,40}$/.test(fields["commit"])) {
85
+ problems.push("commit must be a commit hash, such as the output of git rev-parse --short HEAD");
86
+ }
82
87
  if (event === "disposition" && fields["decided"] === "agent" && fields["disposition"] !== "fixed") {
83
88
  problems.push("the agent decides only fixes; the user waives, defers or rejects a finding (decided=user)");
84
89
  }
@@ -66,7 +66,7 @@ function projectStep(view: ProjectView): NextStep | null {
66
66
  {
67
67
  path: PATHS.architecture,
68
68
  missing: { step: "architect", reason: "the project has no architecture yet" },
69
- unapproved: { step: "architect", reason: "finish the architecture, walk through it and approve it" },
69
+ unapproved: { step: "architect", reason: "finish the architecture, review it and approve it" },
70
70
  changed: { step: "rethink", target: "architecture", reason: "the architecture changed since its approval" },
71
71
  },
72
72
  {
@@ -89,7 +89,7 @@ function itemSteps(view: ProjectView, item: WorkItem, branch: string | null): Ne
89
89
  if (item.kind === "standalone") return [changeStep(view, item, branch)];
90
90
  const state = evaluateApproval(view, item.path);
91
91
  if (readChangesTable(item.doc).length === 0) return [{ step: "architect", target: item.ref, reason: "the feature has no design or changes yet" }];
92
- if (state.state === "unapproved") return [{ step: "architect", target: item.ref, reason: "review the feature's design, walk through it and approve it" }];
92
+ if (state.state === "unapproved") return [{ step: "architect", target: item.ref, reason: "review the feature's design and approve it" }];
93
93
  if (state.state !== "approved") return [{ step: "rethink", target: item.ref, reason: `the feature changed since its approval${state.changed.length > 0 ? ` (${state.changed.join(", ")})` : ""}` }];
94
94
  const changes = changesOf(view.items, item);
95
95
  const landed = new Set(changes.filter((c) => readProgress(c.doc).landed !== undefined).map((c) => c.folderName));