Skip to content

fix(meta,work-package): the artifacts checkout is the git target for planning artifacts (#343 corpus) - #360

Merged
m2ux merged 7 commits into
workflowsfrom
workflow/343-artifacts-checkout-defect-class
Jul 30, 2026
Merged

fix(meta,work-package): the artifacts checkout is the git target for planning artifacts (#343 corpus)#360
m2ux merged 7 commits into
workflowsfrom
workflow/343-artifacts-checkout-defect-class

Conversation

@m2ux

@m2ux m2ux commented Jul 30, 2026

Copy link
Copy Markdown
Owner

The corpus PR #343 routes: the artifacts-checkout defect class, closed at every site it lives at, plus the three ride-alongs that share no files with it.

Definition changes only. The paired main commit — submodule pointer bump plus npm run baseline:stamp — is not here; sequence it after this merges.

The class

The engineering planning folder is a checkout of its own in this repo. A commit aimed at the host repo therefore puts the artifacts nowhere a published link resolves — which is why a posted review's report links went stale twice in the #346 run, and why commit-and-persist has been prescribing the wrong git primitive on every walk.

Five surfaces stated the single-layout model. #319 item 6 named four; #338 W2 named the fifth and is the general case the review path's own fix did not cover. Fixing any subset leaves the class live, so they land together.

Site Was Now
meta/techniques/workflow-engine/commit-and-persist.md step 5 + commit-after-activity Applies commit-regular-files for everything under .engineering/artifacts/ Picks the primitive from the layout, resolved through infrastructure-submodule-pathscommit-submodule when .engineering is its own checkout, commit-regular-files when the artifacts are ordinary files of the host checkout
same, third note No answer for where the parent's pointer bump lands States that it lands in a PR where the host branch takes changes only through one, and that the engineering push already satisfies the step without it
meta/techniques/agent-conduct.md orchestrator-component-path-scope "MUST be performed in the host repo where that directory lives" Cites commit-and-persist step 5 for which checkout and which primitive; keeps its own unique duty (no new branch)
work-package/techniques/manage-artifacts/TECHNIQUE.md committed-to-parent "regular files in the parent repo… pushed to the parent repo" Deleted. It and push-before-linking were one rule written twice — overlapping-rule-scopes, and its single citer cited both in one sentence. The surviving rule names manage-git::artifact-commits as the home for which checkout the commit lands in
work-package/techniques/update-pr/TECHNIQUE.md engineering-link-mandatory Resolves from "the parent repo's git remote get-url origin" Resolves from the checkout that holds the planning folder, citing render step 3, which already carried the two-arm resolution the rule contradicted
work-package/resources/pr-description.md link-row form Hardcoded /.engineering/artifacts/planning/ {ENG_PLANNING_PATH}, defined as relative to the root of the checkout the ref belongs to

The rule this closes is the one a verifier greps, which is what made it the likeliest re-introduction vector.

review-mode's two Lows (#319 items 3–5)

  • The Reports base-URL fence slotted every variable part of the link except the layout-dependent path segment, while the prose two lines below stated both arms. A renderer copying the fence in the in-tree layout dropped .engineering/ and 404'd — the same defect this PR closes, inside the resource that defines the fix. The segment is now {ENG_PLANNING_PATH}, so the fence cannot be read as single-arm.
  • "artifacts checkout" → "engineering checkout", the term workflow.yaml, both techniques and artifact-commits already use.

The third Low — io-agnostic-contract on review-summary.md's Input naming its producer — is already fixed on workflows; the entry now states the meaning without the caller name. Verified, no change here.

Publishing is two steps (#319 AP-114)

publish-review-artifacts's Protocol applied manage-git::artifact-commits for work — pass-orchestration-in-technique, whose Fix directs each sibling operation to its own activity step.

Split by what each half produces:

  • resolve-artifact-publish (renamed from publish-review-artifacts, since a technique named publish that does not publish is the next reader's trap) resolves the engineering checkout, emits {artifact_publish_ref} and {publishable_files}. One produce path, no :: work invoke.
  • Activities 13 and 14 each bind manage-git::artifact-commits as the following step, with files and branch bound from those two outputs.

Supplying files from a declared output is what makes this conversion clean rather than a trade: binding artifact-commits directly without it would have added an undeclared-seed finding, the class #336 tracks and which is sequenced behind #342.

resolve-before-linking records why the order is not incidental: the link is written only after the step that pushed its target ran.

D-6 — the activity-13 diagram (#319)

cpSummaryApproval --> postReview omitted four steps the definition walks, and #274 made it staler still. The review arm now reads the definition's order, grouping straight runs into one block per the convention f39c1f52 established for the other diagrams. Activity 14's publish node is redrawn for the same split.

#320 C-2 — the end-workflow bindings, and the operation that was missing

The first pass read this as a contract defect: verify-outcomes and generate-summary both read the session through inspect_session in their own Protocols, so state and execution_trace looked like inputs no caller supplies, and the fix was to delete them.

Review found the better reading. The inputs were right; the producer was missing. Reading the live session had no owner anywhere in the tree, and the evidence is a citation pointing sideways:

  • conduct-retrospective/retrospective.md — "capture session history via inspect_session (same stance as generate-summary / verify-outcomes — not by reading session.json)"
  • conduct-retrospective/select-next.md — "use inspect_session per generate-summary / verify-outcomes"

Two work-package techniques reached across a workflow boundary to cite two homes for one fact, using the exact bridge phrasing single-rule-authority names as the tell. And the tool's permitted view values were enumerated at two sites, which is tool-contract-restated-in-protocol.

workflow-engine::read-session owns it now — one Protocol phase naming inspect_session, declaring session_state and execution_trace as its products, with session-file-is-not-a-source and the reconcile stance cited rather than restated. meta/04-end-workflow and work-package/14-complete bind it ahead of its consumers, so all four former callers declare what they read and take it by name. Composition is an activity steps[] bind, not a Protocol Apply from each consumer — otherwise it would be the pass-orchestration-in-technique defect this same PR removes from publish-review-artifacts.

session_state also retires the bare state id on the way through, which io-id-shape lists among the single-word generics.

meta/workflow.yaml still drops client_state and client_trace — those named the same two values a second time, and the producer now carries them. The third binding stands and was never a defect: target_workflow_outcomes is produced, seeded by the client (work-package/workflow.yaml:133).

pr-body-conformance — the guide owns what a conforming body is

Raised in review, and two defects were stacked in one rule block.

issue-link-or-explicit-placeholder restated a form pr-description.md already carried — the Issue-skipped placeholder, italicised, no link, "so reviewers can tell the omission was intentional", written out in both files. That is no-technique-resource-dual-home.

Underneath it, the block as a whole was seven criteria describing the shape of a generated document, living in a technique's ## Rules with no resource home — operative-criteria-need-a-home, whose Fix homes a positive checklist in a resource and leaves the technique a walker. The document already has a creation guide, so the guide is the home.

pr-description.md gains ## Rules with one ### per criterion, each citable by anchor. The technique's rule keeps the name its walker and its two variables reference, now stating the obligation and citing the home. verify-body stops re-authoring the mandated-sections check — the split it already had for the templates — and render cites the placeholder form instead of a rule that described it.

The model was already inside the block: all-mandated-sections-present cited the templates rather than restating them. Its six siblings now read the same way.

Nothing about the verdict changes: verify-body still emits body_conforms and body_findings, and activity 13 still loops on them. rule_id keeps its name inside body_findings — renaming the field is churn this change does not need.

One nuance, since a literal reading of operative-criteria-need-a-home would send three of these elsewhere: no-commit-headings-in-changes, no-files-changed-list and no-code-in-changes are prohibitions, and that entry prefers a catalogue entry for a prohibited pattern. But the catalogue governs authored workflow content, not the artifacts workflows produce. A PR body is an output, so the guide is right.

#310 Part 2 — what the graph can answer

Three empirical caveats, none of them stated anywhere an agent reads, now in gitnexus-operations:

  • graph-answers-code-not-prose — for workflows/, docs/, .engineering/ the graph locates a file by path but cannot answer which text states a claim, and query returns unrelated matches rather than nothing, so a miss does not read as a miss.
  • keyword-shaped-queries — the semantic half of the ranking contributes only where the index carries embeddings, which the query cannot assert; keyword-shaped input works either way.
  • index-freshness-first extended rather than duplicated — a freshness check before any operation whose answer turns on the current tree, because a stale index answers in the same shape as a fresh one.

Part 1 stays out per #343: its target is deprecated, and the gap reproduces in workflow-authoring against four activities, not the three #310 names. That is an enhancement with its own scope.

Verification

npx tsx scripts/check-all.ts --root <this tree>17/17 pass, no baseline or triage file modified.

Two things the guards caught in this change, both fixed here rather than triaged:

  • Dropping the state / execution_trace bindings surfaced them as orphan-input. Triaging would have recorded the contract fiction as debt; the fix was to stop declaring inputs the technique resolves itself.
  • The first draft of engineering-link-mandatory read {eng_git_dir} in a group-inherited rule, where the local is declared in render.md and cannot resolve. Three read-resolution findings. The rule now cites the resolution instead of reading its local.

binding-fidelity reads 177 triaged, 0 live, 0 untriaged, 0 stale.

Deliberately out of scope

Item Why
#336 69 of its 125 findings sit in work-package/techniques/, the files this PR edits semantically. A mechanical sweep over the same files makes the diff unreviewable, and each cleared seam needs a paired prune of scripts/binding-fidelity-triage.json in main. Its own PR, after this one, and after #342 repairs the meter.
#358 ~100 citation-grain edits over an overlapping surface. It also wants #359's canon clause first — that clause decides each site's verdict, so doing #358 now means re-opening every site.
#338 W3 Gated on the server-side usage aggregate in #337. Worth noting #351 already delivered its artifact home: render-token-usage runs on both paths and token-usage.md is cost's only home.
#338 W4 The five content defects are not enumerated in the issue — they point at a #189 register. Same unknown-scope blocker #343 flags for #319, unresolved for this one.
#317 Needs a design call between four directions, one of them server work.
#341 / #342 Server tree — scripts/check-binding-fidelity.ts. #343 sequences them before this PR, because #342's masking defect is currently dropping real entries out of the ledger. Read this PR's binding-fidelity delta with that caveat.

Issue dispositions

🤖 Generated with Claude Code


Canon audit

Run against the change surface per the workflow-canon Audit path, after the first commit. The second commit is its remediation.

Surface

  • Changed files — 18, attributed by git diff --name-only origin/workflows. A finding in one of those arrived with this change; anything else pre-existed it.
  • Consumer surface — the references other workflows hold into meta and work-package, each resolved to the file it names. publish-review-artifacts had three (two in activity 13, one in activity 14, all updated); committed-to-parent had one (update-pr/create-pr.md:35, repointed); workflow-engine::verify-outcomes and ::generate-summary are bound only at meta/activities/04-end-workflow.yamlprism-audit/activities/03-audit-finalize.yaml:22 has a step named verify-outcomes, but it is a kind: action, not a bind of the meta op, so the contract change reaches no second consumer.
  • Base reforigin/workflows at 6bc46faf.
  • Reference workflowsmeta/techniques/version-control/ for the primitive pair, work-package/techniques/manage-git/ for the engineering-checkout resolution.

Mechanical guards

npx tsx scripts/check-all.ts --root <this tree>18 guards, 17 pass, 1 fail.

check:delta is blocked for a corpus-only change: it materialises a merge-base in the server repo, and there is none between that repo's HEAD and origin/workflows. Attribution is by the diff above instead.

The one failure is an obligation on the paired main PR

binding-fidelity: 161 violations — 73 harmless, 88 fix-later, 0 live, 0 untriaged, 4 stale triage entries.

The four are activity_name, branch, files and issue_key on work-package :: manage-git::artifact-commits (scripts/binding-fidelity-triage.json:963-990, all harmless / shared-op-caller-argument). They are stale because the AP-114 conversion gave that op real producers for all four inputs — it was previously reached by a Protocol Apply with nothing bound, so the guard saw four unproduced inputs and the triage file absorbed them as accepted debt.

That is a result rather than a side effect: the conversion pays down four ledger entries. It also means this PR cannot land alone. The triage file lives in the server tree, so the paired main PR must delete those four entries alongside the pointer bump and re-baseline — the same coupling #352 carried for #351: the binds without the prune report four stale entries, the prune without the binds four untriaged findings.

Coverage ledger

Unit Disposition
Structural walked
Interaction not-applicable — no checkpoint construct added, removed or reordered
Schema Expressiveness walked
Rule Hygiene walked — 1 finding
Description Hygiene walked — 1 finding
Coupling walked — 3 findings
Tool-Technique-Doc Consistency walked
Execution walked
Output Economy walked — 1 finding
Canon Hygiene walked
Technique Protocol walked — 1 finding
Authoring Guidance (MR) walked — 1 finding
Creation Rules walked — this change adds AP-136, so the unit reaches the surface
Design Principles (30) walked
Construct Inventory (6) walked
Convention Conformance walked

Nothing is blocked except check:delta, recorded above.

Findings — eight, all in text this branch authored, all fixed

Entry Site Verdict
technique-stage-agnostic resolve-artifact-publish.mdresolve-before-linking named an activity step from inside a technique rule CONFIRMED — rule deleted
overlapping-rule-scopes graph-answers-code-not-prose sat beside query-not-grep; both triggers hold for a markdown tree, the prescribed handling differed, and nothing ordered them CONFIRMED — folded into query-not-grep
dotted-rule-address commit-and-persist.md step 5 cited a rule with the :: form, which invokes a technique CONFIRMED — dotted address
no-duplicated-guidance the {ENG_PLANNING_PATH} two-arm enumeration landed in both pr-description.md and review-mode.md CONFIRMED — enumerated once in review-mode, glossed in pr-description
must-use-operations (the group's own rule) a Cypher fragment in the container's Rules PLAUSIBLE — that rule says "technique protocols" and this was a Rules body; fixed regardless
variable-description-one-line target_workflow_outcomes carried a "read by…" consumer tail CONFIRMED — one line
no-resource-caller-backlink pr-description.md named the host caller ("The rendering step resolves which") CONFIRMED — clause dropped
constraint-as-blockquote step 5's > notes lacked the two trailing spaces that fold them into the parent bullet CONFIRMED — added
phase-cited-by-ordinal (new — AP-136) three rules cited a Protocol phase by positioncommit-after-activity ("the primitive step 5 resolves"), orchestrator-component-path-scope ("commit-and-persist step 5"), engineering-link-mandatory ("render step 3") CONFIRMED — cite the home, drop the number

No Highs, so the adversarial pass re-derived each Medium from the cited file and construct alone. The one that did not survive re-derivation is marked PLAUSIBLE.

The positional-reference finding came from review, not from my walk, and it is now catalogued as AP-136 phase-cited-by-ordinal because it sat in a seam four entries leave open: no-rule-protocol-restatement tests whether the sentence could stand as a Protocol phase unaltered, and a pointer to a phase cannot; dotted-rule-address governs how a rule is addressed, not how a phase is; anchored-protocol-references asks whether a reference resolves, and an ordinal does resolve — to whichever phase now holds that index; and stale-restatement-after-change fires only once a renumber has already made the claim false. A correct walk of all four passes over it, which is why the entry keys on the ordinal itself and carries an insert-a-phase test.

workflow-design's own version stays where it is: the deprecated tree prints a mismatch warning to every session still running against it (#339), and adding a resource entry is not a reason to pay that.

A second entry, from the same route

Review also found that the session read had no owner (see #320 C-2 above). That gap was invisible to three entries, each for a different reason:

  • canonical-technique-reference fires when a raw tool is named where a wrapping op exists. None existed, so every site was individually correct.
  • duplicate-shared-capability explicitly carves out "adding a new shared op when no shared capability exists yet".
  • no-duplicated-guidance says keep one home and reference it — and referencing a fellow consumer satisfies that literally. Following its Fix is how the two-home state was reached.

So AP-137 unowned-harness-capability keys on the absence rather than the misuse: one tool named for one capability at two or more sites with no operation declaring that capability's product. Its test asks the reader to name the operation a caller would bind; the sideways citation is the written tell. Both new entries are checked against this change, which is where each was found. A phase number in a rule rots on the next renumber, and the invariant does not need it: commit-after-activity constrains which scopes must be committed and pushed before transitions, and which primitive each scope takes is what the Protocol phases are for. The parentheticals naming the primitives came out with it. One pre-existing instance in the same sentence — Apply sync-progress-status (step 1) — is fixed in passing rather than left beside its own remedy; it now carries the hyperlink that resolves.

Worth naming: three of these are defects this PR deletes elsewhere — a rule duplicating another rule's invariant, one fact with two homes, and a rule reaching into a Protocol.

Evidenced negatives

  • stale-restatement-after-change — the retired claim (parent repo as the artifacts git target) was swept tree-wide, not only across the change's file list. 0 surviving occurrences. The four remaining parent repo hits are each accurate: version-control/TECHNIQUE.md:8 describes the group's scope, commit-regular-files.md:8,29 is the op that genuinely is parent-repo scoped, the anti-patterns.md hit is exemplar text, and 06-plan-prepare.yaml:14 concerns the workflows worktree. This is the sweep Outstanding and deferred items from the review-mode friction continuation session #319 F-3 found missing last time, when it had been run for the retired symbol and not the retired claim.
  • preserve-readme-content — the activity-13 review arm went from five nodes to three, so the preservation audit: every step name previously drawn (Consolidate review findings, Generate review summary, review-summary-approval, Post PR review) survives, and four the diagram had omitted are now named. Content increased; only node count fell.
  • no-invented-naming — three new names, each reusing an established convention: {ENG_PLANNING_PATH} beside {ENG_REPO_OWNER} / {ENG_REPO_NAME} / {ENG_BRANCH}; the technique id resolve-artifact-publish beside resolve-host-repo / resolve-target; kebab-case rule slugs.
  • The rename strands no session. 18 work-package sessions exist, five running — plan-prepare ×2, start-work-package ×2, post-impl-review ×1 (scripts/count-workflow-sessions.ts --workflow work-package --list). None sits at submit-for-review or complete, so no in-flight worker fetches the retired technique id.
  • checkpoint-entry passes — the guard that matters for a change reordering steps in activities 13, 14 and meta 04.

m2ux added 7 commits July 30, 2026 13:59
…planning artifacts

The engineering planning folder is a checkout of its own in this repo, so
a commit aimed at the host repo puts the artifacts nowhere a published
link resolves. Five surfaces stated the single-layout model; each now
states the layout it resolves, or cites the one op that owns the choice.

commit-and-persist picks the primitive from the layout — commit-submodule
when .engineering is its own checkout, commit-regular-files when the
artifacts are ordinary files of the host checkout — and states that the
parent's pointer bump lands in a PR where that branch takes changes only
through one. agent-conduct and manage-artifacts cite the resolving op
instead of restating a location; committed-to-parent and
push-before-linking were one rule written twice, so the surviving rule is
push-before-linking. The Engineering link row and the review-mode Reports
base URL carry the planning root as a slot, so a renderer cannot copy
either as if one layout were the only one.

Publishing is two steps, not a technique that calls another: the
technique resolves the ref and the file set, the activity binds
manage-git::artifact-commits to put them on the branch. Activity 13 and
14 both bind the pair, and the activity-13 diagram draws the review arm
the definition actually walks.

verify-outcomes and generate-summary read the session themselves, so the
state and trace they read are protocol locals rather than inputs a caller
supplies, and meta drops the two variables nothing produced.

gitnexus-operations states what the graph answers: code symbols and file
paths, not which prose states a claim; keyword-shaped queries; and a
freshness check before any operation whose answer turns on the tree.

Refs #319, #338, #320, #310
… text

The canon audit over the change surface found eight defects in prose this
branch authored. Each is fixed here.

resolve-before-linking named an activity step from inside a technique
rule, scoped to one protocol phase, and restated push-before-linking's
invariant; the step order and that rule already carry it, so it goes.

The graph's markdown limit folds into query-not-grep rather than sitting
beside it: a second rule about when to reach for the graph left the pair
intersecting on markdown with opposite consequences and no ordering. The
Cypher fragment goes with it, since raw queries live in the operations.

infrastructure-submodule-paths is a rule, so it is cited by dotted
address rather than the :: form that invokes a technique. The blockquote
notes under step 5 gain the trailing spaces that fold them into their
parent bullet.

target_workflow_outcomes states what the value is, without the reader
tail. The engineering planning root is enumerated once, in review-mode;
pr-description glosses the slot without restating the arms or naming the
step that resolves it.
A rule that points into a Protocol by position rots on the next
renumber, and the invariant it carries does not need the position:
commit-after-activity constrains which scopes must be committed and
pushed before transitions, and which primitive each scope takes is what
the Protocol phases are for. The parentheticals naming the primitives
come out with the positional reference.

agent-conduct and engineering-link-mandatory cite the technique that
owns each resolution, without the phase number. sync-progress-status
gains the hyperlink that resolves in place of the phase it sat in.
A rule pointing at a Protocol phase by its number sits in a seam four
entries leave open. no-rule-protocol-restatement tests whether the
sentence could stand as a phase unaltered, and a pointer to a phase
cannot. dotted-rule-address governs how a rule is addressed, not how a
phase is. anchored-protocol-references asks whether a reference resolves,
and an ordinal does resolve — to whichever phase now holds that index.
stale-restatement-after-change catches it only once a renumber has
already made the claim false.

So the entry keys on the ordinal itself, with the insert-a-phase test,
and carves out the numbering's own Protocol, heading anchors that fail a
guard instead of drifting, and rules addressed by name.

The workflow-design version stays where it is: the deprecated tree prints
a mismatch warning to every session still running against it (#339).
Reading the live session had no owner. verify-outcomes and
generate-summary each named inspect_session and each enumerated the views
it accepts, and two work-package techniques cited those two as their
home — a citation pointing sideways at fellow callers, which is what an
author writes when no operation owns the capability.

workflow-engine::read-session owns it now, declaring the variable bag and
the execution trace as its products and naming the tool once. The
activities bind it ahead of its consumers, so verify-outcomes,
generate-summary, retrospective and select-next declare what they read
and take it by name.

That also repairs #320 C-2 properly. The unproduced state and trace
bindings were not contract fiction to delete: the inputs were right and
the producer was missing. session_state replaces the bare state id on the
way through.
Three entries assume the wrapping operation already exists.
canonical-technique-reference fires when a raw tool is named where a
wrapper exists; duplicate-shared-capability carves out the case where no
shared capability exists yet; and no-duplicated-guidance says to keep one
home and reference it, which is satisfied by referencing a fellow
consumer — the state this catalogue entry was written from, where two
techniques cited two others that also called the tool.

So the entry keys on the absence: one tool named for one capability at
two or more sites with no operation declaring that capability's product.
Its test asks the reader to name the operation a caller would bind, and
the sideways citation is the written tell.
…ng body is

pr-body-conformance held seven criteria describing the shape of a rendered
PR body, inside a technique's Rules. One of them restated a form the guide
already carried: the Issue-skipped placeholder, rationale and all, was
written out in both files.

The criteria are fill rules for a generated document, and that document
already has a creation guide, so the guide is where they live — one `###`
per criterion, each citable by anchor. The technique keeps the rule name
its walker and its two variables reference, now stating the obligation and
citing the home.

verify-body stops re-authoring the mandated-sections check and cites it
instead, which is the split it already had for the templates. render cites
the placeholder form rather than a rule that described it.

Nothing about the verdict changes: verify-body still emits body_conforms
and body_findings, and activity 13 still loops on them.
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