docs: plain-language pass over the config menu, and three walk fixes #235

Merged
john merged 2 commits from docs/plain-language-config-menu into main 2026-08-22 20:53:36 +00:00
Owner

Running /cad-config as a user surfaced both halves of this: the text it renders is written in Cadence's own vocabulary, and the walk that renders it hides which value is actually in force.

Wording

config-catalog.md is the literal source of each menu question and each option description. Ten rows rewritten for a reader who has never opened Cadence's internals.

Key Was Now
stakes "What does a break here cost? (routing asks this, not what a dispatch costs)" "How bad is it if something here breaks?"
stakescritical "a break is not a bug report" "a break costs more than a bug report: money, security, safety or data loss"
review.reviewers "Which reviewer backends fire() resolves" "Which reviewers should run? (pick any number)"
<t>.gatedeferred "persist a queue member and carry on" "run it, save the findings, and let the work continue - /cad-land refuses to publish until you rule on them"
memory.backend "zero-dep BM25 recall" "built-in search over your .planning/ docs, no setup and no dependencies"
git.issue_check "run no forge CLI" "never call the hosting CLI"

critical was the worst of them: defined only by negation, it never said what it IS. fire() was a literal function name inside a question a user reads.

Three walk fixes

Found by running the menu rather than reading it.

  • Two labels, never zero. In the repo file is (current); inherited is (in force), and its description says so and says picking it writes here. The old rule dropped the label to stop an inherited value being mislabelled (current) and pinned - but dropping it entirely left the user choosing with nothing on screen saying what is active.
  • A pick equal to the value in force writes nothing, on both arms. Without this the walk pins the whole global layer into the repo file one page at a time, because agreeing with an inherited value reads as choosing to override it.
  • Over four values does not fit the seam. review.triggers.<t>.gate has five values and the ask-user cap is four, so one value was reachable only by free-typing, with nothing saying it existed. Omitted values are now named in the last option's description as "reachable via Other".

Budgets

Raised rather than the prose shaved: config.md 14593 → 15705, config-catalog.md 10077 → 10452. Plainer wording is longer, and 1,487B is the accepted cost.

deferred-reads.test.mjs splices its probe sentence onto the literal opening of walk step 3, so its anchor is repointed to a prefix that survives the rewording. 2,644 tests pass, self-verify clean.

Not fixed

workflow.max_plan_tasks still asks its question with a byte count, a percentage and a decision date in it - the densest prompt in the file. PLN-01 requires that text to carry the same figures as the schema so the two surfaces cannot argue different numbers, which is a real invariant. Making it plain means moving the rationale to a footnote and repointing that test; that is a change to what the check reads and wants its own decision.

Also here

git.auto_close=true for this repo, chosen through the walk and committed separately. /cad-milestone will now chain into /cad-land and run the close end to end with no per-step prompts.

Running `/cad-config` as a user surfaced both halves of this: the text it renders is written in Cadence's own vocabulary, and the walk that renders it hides which value is actually in force. ## Wording `config-catalog.md` is the literal source of each menu question and each option description. Ten rows rewritten for a reader who has never opened Cadence's internals. | Key | Was | Now | |---|---|---| | `stakes` | "What does a break here cost? (routing asks this, not what a dispatch costs)" | "How bad is it if something here breaks?" | | `stakes` → `critical` | "a break is not a bug report" | "a break costs more than a bug report: money, security, safety or data loss" | | `review.reviewers` | "Which reviewer backends fire() resolves" | "Which reviewers should run? (pick any number)" | | `<t>.gate` → `deferred` | "persist a queue member and carry on" | "run it, save the findings, and let the work continue - `/cad-land` refuses to publish until you rule on them" | | `memory.backend` | "zero-dep BM25 recall" | "built-in search over your `.planning/` docs, no setup and no dependencies" | | `git.issue_check` | "run no forge CLI" | "never call the hosting CLI" | `critical` was the worst of them: defined only by negation, it never said what it IS. `fire()` was a literal function name inside a question a user reads. ## Three walk fixes Found by running the menu rather than reading it. - **Two labels, never zero.** In the repo file is `(current)`; inherited is `(in force)`, and its description says so and says picking it writes here. The old rule dropped the label to stop an inherited value being mislabelled `(current)` and pinned - but dropping it entirely left the user choosing with nothing on screen saying what is active. - **A pick equal to the value in force writes nothing**, on both arms. Without this the walk pins the whole global layer into the repo file one page at a time, because agreeing with an inherited value reads as choosing to override it. - **Over four values does not fit the seam.** `review.triggers.<t>.gate` has five values and the ask-user cap is four, so one value was reachable only by free-typing, with nothing saying it existed. Omitted values are now named in the last option's description as "reachable via `Other`". ## Budgets Raised rather than the prose shaved: `config.md` 14593 → 15705, `config-catalog.md` 10077 → 10452. Plainer wording is longer, and 1,487B is the accepted cost. `deferred-reads.test.mjs` splices its probe sentence onto the literal opening of walk step 3, so its anchor is repointed to a prefix that survives the rewording. 2,644 tests pass, `self-verify` clean. ## Not fixed `workflow.max_plan_tasks` still asks its question with a byte count, a percentage and a decision date in it - the densest prompt in the file. `PLN-01` requires that text to carry the same figures as the schema so the two surfaces cannot argue different numbers, which is a real invariant. Making it plain means moving the rationale to a footnote and repointing that test; that is a change to what the check reads and wants its own decision. ## Also here `git.auto_close=true` for this repo, chosen through the walk and committed separately. `/cad-milestone` will now chain into `/cad-land` and run the close end to end with no per-step prompts.
Running `/cad-config` as a user surfaced both halves of this: the text it
renders is written in Cadence's own vocabulary, and the walk that renders it
hides which value is actually in force.

Wording, in config-catalog.md - the literal source of each menu question and
each option description. Ten rows rewritten for a reader who has never opened
Cadence's internals: `fire()` is gone from the question a user reads; `stakes`
asks "How bad is it if something here breaks?" and its `critical` option says
what it IS rather than only what it is not; the five gate values say what
happens to the findings instead of "persist a queue member"; BM25, "forge CLI",
"union all" and two dotted key references leave the option text.

Three walk fixes, in config.md:

- Two labels, never zero. In the repo file is `(current)`; inherited is
  `(in force)`, and its description says so and says picking it writes here.
  The old rule dropped the label to stop an inherited value being mislabelled
  and pinned, but dropping it left the user choosing with nothing on screen
  saying what is active.
- A pick equal to the value in force writes nothing, on both arms. Without it
  the walk pins the whole global layer into the repo file one page at a time,
  because agreeing with an inherited value reads as choosing to override it.
- Over four values does not fit the seam. `review.triggers.<t>.gate` has five
  and the cap is four, so one value was reachable only by free-typing with
  nothing saying it existed. Omitted values are now named as "reachable via
  `Other`".

The budgets for both surfaces are raised rather than the prose shaved: plainer
wording is longer, and 1,487B is the accepted cost. deferred-reads.test.mjs
splices its probe onto the literal opening of walk step 3, so its anchor is
repointed to a prefix that survives the rewording.

Not fixed: workflow.max_plan_tasks still asks its question with a byte count, a
percentage and a decision date in it. PLN-01 requires that text to carry the
same figures as the schema so the two surfaces cannot argue different numbers.
Making it plain means moving the rationale to a footnote and repointing that
test, which is a change to what the check reads.
chore: turn on git.auto_close for this repo
All checks were successful
test / node-test (git, 22) (pull_request) Successful in 29s
test / node-test (git, 24) (pull_request) Successful in 32s
test / node-test (other, 22) (pull_request) Successful in 1m10s
test / node-test (other, 24) (pull_request) Successful in 1m6s
test / node-test (planning, 22) (pull_request) Successful in 1m31s
test / node-test (planning, 24) (pull_request) Successful in 1m48s
test / node-test (prose, 22) (pull_request) Successful in 37s
test / node-test (prose, 24) (pull_request) Successful in 33s
test / node-test (review, 22) (pull_request) Successful in 18s
test / node-test (review, 24) (pull_request) Successful in 18s
test / node-test (routing, 22) (pull_request) Successful in 40s
test / node-test (routing, 24) (pull_request) Successful in 50s
test / self-verify (pull_request) Successful in 16s
test / typecheck (pull_request) Successful in 18s
c862e4a258
Chosen through the `/cad-config` walk. `/cad-milestone` now chains into
`/cad-land` and runs the close end to end - PR, merge, tag, reset - with no
per-step prompts, stopping only on a surviving blocker/high `risk_surface`
finding from this branch's own fires.
john merged commit 92ee72d15f into main 2026-08-22 20:53:36 +00:00
Sign in to join this conversation.
No description provided.