Skip to content

Canon audit: bring the corpus into line with the design canon - #582

Merged
m2ux merged 11 commits into
workflowsfrom
workflow/corpus-canon-audit
Sep 3, 2026
Merged

Canon audit: bring the corpus into line with the design canon#582
m2ux merged 11 commits into
workflowsfrom
workflow/corpus-canon-audit

Conversation

@m2ux

@m2ux m2ux commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Every workflow in the corpus was walked against the design canon — the design principles, the anti-pattern catalog, the schema construct inventory, convention conformance, and the repo's guard suite. Seventeen workflows, 987 definition files, measured against origin/workflows at 131e2942c15cbcf16680980be7e15b107abf051d.

The mechanical layer was already clean: all thirty guards pass on the corpus, before and after this change. What this branch fixes is the layer no guard reaches — prose that stands in for a construct the schema already provides, facts written down in a second place, and six checkpoints whose answer was never recorded anywhere.

Seventy-five confirmed defects across thirteen workflows. Most are local prose rewrites. Six are not, and one group of those has a live consequence.

The part that matters most

Four checkpoints offered the reader a way to stop, and stopped nothing. The option carried no effect, so the run continued exactly as if the reader had said yes.

Two of them guard a stealth-mode push. In work-package's submit-for-review activity, a gate headed as a final isolation check asks whether the push target is the verified private remote, and offers "No, abort push". A second gate immediately after asks to confirm or cancel the prepared push. Neither option recorded anything, so answering "No, abort push" fell through to signature verification and then to push-commits — against the remote the reader had just said was wrong.

What makes this a wiring gap rather than a missing feature is that the machinery was already there and unused. That activity declares an abort exit marked immediate, the workflow graph routes it to the completion activity, and a third gate later in the same file selects it correctly. The two isolation gates simply never pointed at it. They do now.

remediate-vuln's start activity had the same shape with no exit to reach for: its two isolation gates offered "No, fix remote" and "No, abort — stop immediately", and both fell through into planning-folder setup and onward. That activity now declares an abort exit, immediate, routed to __terminal__ — a run whose private remote or advisory branch is not the isolated pair has produced nothing to complete.

A fifth gate, work-package's symbol-provenance check, offered to "pause the loop and investigate" a symbol whose provenance could not be confirmed, and then ran the next task either way. Both of its options now resolve has_uncertain_symbols, and the task cycle breaks while that holds.

What else happens today

A checkpoint asks a question instead of stating its subject. Ten gates across five workflows end in a question mark or open with a confirm imperative — "Is this continuing previous work or a new initiative?", "Publish this review to the PR as a formal review comment?". The options underneath already hold the decision space, so the question is a second copy of it, phrased differently.

A message narrates where the run goes next. Eleven messages and option descriptions say what the workflow graph, the declared exits, autoAdvanceMs and defaultOption already say — "Proceeding to area derivation in 30s unless you want to revise the scope", "(default — auto-accepts after 30s)", "proceed to attestation". Change the timeout in the schema and the sentence goes quietly wrong.

A variable description runs on past the value. Twenty descriptions across eight workflows carry tails naming which operation sets the value, which checkpoint reads it, and why a borrowed slot stays empty in this workflow — "read by initialize-session and passed as parent_session_index when create-session creates the client session"; "set during scope-intake, gates the publish-decision checkpoint and the publish-review activity". Every one of those facts already has a home, so each is a copy that has to be edited whenever the other side moves.

An activity carries prose rules. work-package's lean-coding audit declares four, covering the safety floor, the read-only-before-apply ordering, honest gain reporting, and the boundary against strategic review. An activity is pure mechanics. All four are already stated elsewhere, and one restates the validate action sitting eight lines above it.

A Capability cannot be read on its own. Twenty-three technique Capability sections need something else loaded before they make sense: a hyperlink into another technique or resource, or a braced designator whose meaning sits on Inputs and Outputs. Two are container contracts listing their child operations, which is what the folder is for; six name the activity step that dispatches them, which a technique cannot know.

A technique presents to a person. setup-planning-folder's fourth phase presented the created structure to a user for confirmation. Techniques are session-blind; the activity that binds them owns delivery.

A durable artifact is named but not linked. midnight-system-review's verdict gate said the report "is in review-report.md", leaving the reader to find the file.

A gate collects an acknowledgement nothing reads. requirements-refinement's terminal failure gate had a single "Acknowledged" option, no effect, and no exits — it stopped the run so a person could say they had looked.

Two hygiene defects the catalog names against itself. The engine's finalize-activity cites one of its own Protocol phases as "see Protocol step 2", and that ordinal already points at the wrong phase, since the value it describes is folded in the phase before. And the catalog's own entry for unescaped dollars carries three unescaped dollars in rendered prose, which GitHub-flavored Markdown reads as inline math.

The fix

Ten commits, one per class. Every replacement was written against the catalog entry's own Fix and Do not flag text rather than checked against it afterwards, and the corpus was re-scanned after each class: every fixed class now returns zero hits.

Where a fix removed a sentence, the fact it carried was located first. The lean-coding commit body names all four survivors with the surface that holds each — the ladder resource's Safety Floor section and the validate-safety-floor action; the step order itself; the honesty-boundary resource and the rule citing it; and review-over-engineering's Capability. The midnight two-probe floor stays in the workflow rule that already states it. work-package's "edits never happen under the host repo path" survives on the target_path declaration. setup-planning-folder's delivery survives on the gate that links the planning folder. Every anchored resource citation removed from a Capability survives in the Protocol phase that consults it.

Verification

  • Guards: 30 pass, 0 fail, 0 unmeasured, run against this worktree before the change and after every class. All 117 activities and all 17 workflow files validate.

  • Option-coverage walk: run (21 minutes), because this branch changes routing — a new exit and graph edge in remediate-vuln, a new loop breakCondition in work-package, and four options that now select an exit. The coverage assertion passed: every declared option is still reachable, and all five re-wired gates report full coverage — submit-for-review/private-remote-confirmation 2/2, submit-for-review/push-confirmation 2/2, start/confirm-security-remote 2/2, start/verify-isolation 2/2, implement/symbol-provenance-confirmed 2/2.

    The run's second assertion, stamp freshness, fails — and does so independently of this branch. tests/e2e/__snapshots__/corpus-sha.json on main records corpus c56b51ca671c, while origin/workflows is already at 131e2942, so the check is red for any corpus checkout at or after the current corpus head, including an untouched one. That stamp moves on the code branch's adoption commit, together with the submodule pointer and the walk baseline, per the sequencing AGENTS.md sets out. Nothing in this branch can clear it and nothing in this branch caused it.

  • Each hand-scan was confirmed against a known positive before its empty result was trusted, and negatives were re-derived from the file rather than from the scan.

  • The High findings were re-derived independently from the file and the entry alone before driving a fix. One withdrew on re-derivation: verify-artifact-conforms's "Surface the Exceptions" phase composes {artifact_conformance}, a declared output, which is the entry's own Do-not-flag carve-out — the scan had matched the heading word rather than the behaviour. It is not changed here.

Scope

Thirteen of the seventeen workflows carry at least one fixed defect: cicd-pipeline-security-audit, codebase-wiki, meta, midnight-system-review, plain-language, prism, remediate-vuln, requirements-refinement, substrate-node-security-audit, work-package, work-packages, workflow-authoring, workflow-design. The other four were walked and had none.

Non-goals

Two classes are confirmed and filed rather than fixed, because each is a design decision rather than a rewrite.

  • #585 — the remaining 22 decisionless checkpoints. Sixteen revise-or-redraft forks, three input-collection gates, three provide-or-skip forks. Five need only an effect line because their activity already declares a suitable exit; the rest need a destination decided and a graph edge added. The issue carries the per-gate classification.
  • #584 — Protocol Apply chains. 102 sites across 74 technique files where a technique's Protocol applies another operation instead of the activity binding both as steps. Seventeen are the identical resolve-repo-coordinates line opening the github-cli-protocol group. The issue carries the counts and the three-way classification the work needs first.

Also left: five Present-phase techniques (four named for presenting, so retiring the phase retires the technique), and codebase-wiki's lint naming the downstream re-ingest decision from inside the technique.


🤖 Generated with Claude Code

m2ux added 8 commits September 2, 2026 13:39
Ten checkpoint messages carried the decision instead of the subject —
a trailing question mark, or a confirm/is-this/would-you-like opener.
The options already hold the decision space.

statement-not-question. remediate-vuln also gains backticked code
tokens on the two isolation gates.
Checkpoint messages and option descriptions narrated where the run
goes next and when a soft gate auto-advances. The graph, exits,
autoAdvanceMs and defaultOption already carry those.

no-next-step-narration. Two messages also enumerated their own
options, which the option labels state.
Twenty variable descriptions across eight workflows ran to producer,
consumer, gate and rationale tails: which operation sets the value,
which checkpoint reads it, why a borrowed slot stays empty here.

variable-description-one-line. Each tail already has a home — the
producing operation's Outputs, the gate's own condition, and for the
midnight two-probe floor the workflow rule that states it.
The activity carried four prose rules. Each already holds elsewhere,
so the activity is pure mechanics again.

no-activity-prose-rules. What still has to hold, and where:

- safety floor — the ladder resource's Safety Floor section, walked by
  ponytail apply-ladder's "Hold the safety floor" phase, and validated
  structurally by the validate-safety-floor action inside the
  simplification-apply-cycle
- read-only before apply — the step order itself: the review, harvest
  and gain steps precede the gate, and code changes only inside
  simplification-apply-cycle, which runs on needs_simplification
- honest gain reporting — the honesty-boundary resource's Rule
  section, cited by report-gain's honesty-boundary-on-reporting rule
- the lens boundary against strategic review — review-over-engineering's
  Capability, which states the lens it applies

The gate message also stops enumerating its own options.
Twenty-three Capability sections needed something else loaded to be
understood: a hyperlink into another technique or resource, or a
braced designator whose meaning sits on Inputs and Outputs.

procedure-in-capability. Each is now a self-contained statement of
what the operation yields. The two dispatch container contracts stop
enumerating their child operations, which the folder holds
(capability-as-op-inventory), and the brief-composition operations
stop naming the activity step that dispatches them
(technique-stage-agnostic). Every anchored resource citation removed
here survives in the Protocol phase that consults it.
Two hygiene defects the catalog names against itself and the engine.

phase-cited-by-ordinal: finalize-activity's selected_exit output
pointed at "Protocol step 2", which resolves to next-activity
resolution while the value is folded in the phase before it. The
recognition criterion stands on its own without the pointer.

escape-literal-dollar: the entry's own exemplar and framing line
carried three unescaped dollars in rendered prose, which GFM reads as
inline math. Two are escaped and the designator is backticked, so the
displayed text is unchanged.
setup-planning-folder's fourth phase presented the created structure
to a user for confirmation, and its Capability said so.

session-interaction-in-technique. The operation now ends at the two
skeleton writes and emits its declared outputs. The delivery survives
on the binding activity: folder-setup's folder-created gate states
the subject and links the planning folder path.
The verdict gate named review-report.md in prose, leaving a reader to
find a durable artifact by filename.

link-named-artifacts. render-review now declares review_report_path
beside the report it writes, the activity declares the write, and the
gate interpolates the link.
m2ux added 3 commits September 2, 2026 14:19
Four gates offered a stop and continued anyway, because the option
carried no effect. Two of them guard a stealth-mode push.

checkpoint-requires-decision. In work-package's submit-for-review the
machinery was already there and unused: the activity declares an
abort exit marked immediate, the graph routes it to the complete
activity, and a later gate in the same activity selects it correctly.
The two isolation gates now select it too, so answering "No, abort
push" at the final isolation check ends the activity instead of
falling through to verify-push-signatures and push-commits.

remediate-vuln's start activity had no such exit. It gains one,
marked immediate and routed to the terminal state, because a run
whose private remote or advisory branch is not the isolated pair has
produced nothing to complete. Both isolation gates select it.

The four messages also state their subject rather than instructing
the reader to select (statement-not-question, no-next-step-narration).
The symbol-provenance gate offered to pause the loop and investigate,
and recorded nothing, so both answers ran the next task.

checkpoint-requires-decision. Both options now resolve
has_uncertain_symbols, the same variable the gate is raised on, and
the task cycle breaks while it holds. Confirming that the symbols
were intentional clears it and the cycle continues; leaving them
unaccounted for stops the run implementing further tasks on top of
them.

The gate reads that variable now as well as writing it, so the
activity declares it under reads.
The terminal failure gate had a single Acknowledged option and no
effect, so it stopped the run to collect an answer nothing reads.

checkpoint-requires-decision. The step above it already messaged the
same report, so the gate is gone and its one distinct clause — that
no specification is staged for promotion — folds into that message,
which keeps the link to the failure report.
@m2ux
m2ux merged commit 7d53c85 into workflows Sep 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant