Skip to content

#1294 Specify artifact mutability and its sanctioned exceptions - #1297

Merged
williamthorsen merged 5 commits into
mainfrom
1294
Aug 12, 2026
Merged

#1294 Specify artifact mutability and its sanctioned exceptions#1297
williamthorsen merged 5 commits into
mainfrom
1294

Conversation

@williamthorsen

@williamthorsen williamthorsen commented Aug 12, 2026

Copy link
Copy Markdown
Owner

What

Adds a mutability rule for saved artifacts to the shared AGENTS.md and to artifact-conventions.md. A saved artifact is specified as a point-in-time record, not a document to be rewritten to match a later human edit or a rebase.

Separately, merge gains a definition in the ticket-level artifact-type lists, a type merge-gh-pr writes and capture-lede-decision reads.

Why

A saved artifact is the only record of what an agent produced at a given moment, and keeping one current collapses that record with the state it was later compared against. The capture-lede-decision corpus makes the cost concrete: it derives whether a lede was revised by diffing the pull-request artifact against the merge artifact, so a rewritten pull-request body reports no revision where one occurred, and the corruption raises no error. Nothing in the content tree had stated that a saved artifact is a point-in-time record, and the nearest statement covered re-export instead.

Details

🎉 Features

  • The shared AGENTS.md gains two paragraphs under ## Artifacts. The first states the saved-artifact rule and carries its exception in the same sentence, confining updates to where the next step in the flow reads the artifact or where a skill directs the write. The second gates alignment of a remote ticket's acceptance criteria on a conflict with the implementation or a gap that would mislead a reviewer, so an implementation that merely went further than the criteria named is not grounds for a rewrite.
  • artifact-conventions.md gains a ### Mutability subsection under ## Artifact lifecycle, naming three sanctioned mutations as the exhaustive set: frontmatter a skill's own step directs, artifacts declared mutable, and working input forwarded to an agent that acts on its contents. It specifies revision as writing a new artifact, with refine-plan's plan-v2 as the pattern, and records the capture-lede-decision breakage in full.
  • The prohibition on raising a divergence bars presenting it as a defect or as a repair for the user to weigh, rather than as any decision at all. A step that discloses which of two candidate sources it measured against is stated to be reporting its own input, which places review-branch's spec-source callout on the permitted side.
  • merge is defined in the ticket-level artifact-type lists in artifact-conventions.md and save-artifact/SKILL.md, and deferred-findings moves into alphabetical position in the same lists.

🐛 Bug fixes

  • The capture-lede-decision mechanism description names ## Body as the heading read from the merge artifact. The lede diff reads ## What from the pull-request artifact and ## Body from the merge artifact, an asymmetry carried in resolve-episode.ts as AGENT_LEDE_SOURCE and MERGED_LEDE_SOURCE; the sentence had elided the second heading, so it read as ## What on both sides.

Closes #1294

Adds two rules to the `## Artifacts` section of the shared agent instructions. A saved artifact records a moment: it is not rewritten to match a later human edit or a rebase, and its divergence from current state is not raised as a defect or as a decision for the user. Updates are confined to the cases where the next step in the flow reads the artifact, or where a skill directs the write.

The second rule gates alignment of a remote ticket's acceptance criteria on a conflict with the implementation or a gap that would mislead a reviewer. An implementation that merely went further than the criteria named is not grounds for a rewrite.
Adds a `### Mutability` subsection to `artifact-conventions.md`, stating that a saved artifact is a point-in-time record, that it is never reconciled with anything downstream of it, and that its divergence from current state is neither a defect nor a decision to put to the user. Three mutations are named as the exhaustive set of exceptions: frontmatter a skill's own step directs, artifacts declared mutable, and working input forwarded to an agent that acts on it. Revision is specified as writing a new artifact, with `refine-plan`'s `plan-v2` as the pattern.

The subsection also records the concrete consumer breakage: `capture-lede-decision` derives the agent's side of a lede episode by diffing the `pull-request` artifact against the `merge` artifact, so a rewritten `pull-request` body reports `differ: false` for a revised lede and invites an `accepted` verdict the author never gave.

The existing statement that exported artifacts are immutable stays where it is, covering re-export rather than mutability.
Adds `merge` to the ticket-level artifact-type lists in `artifact-conventions.md` and `save-artifact/SKILL.md`. `merge-gh-pr` saves a `{timestamp}_{slug}_merge.md` artifact and `capture-lede-decision` reads it as a first-class input, so both lists named a type neither defined. `deferred-findings` moves into alphabetical position in the same lists.
Restricts the prohibition on raising a saved artifact's divergence: it bars presenting the divergence as a defect or as a repair for the user to weigh, rather than as any decision at all. `artifact-conventions.md` states the boundary directly, so a step that discloses which of two candidate sources it measured against is reporting its own input. `review-branch`'s spec-source divergence callout falls on the permitted side.
Corrects the `capture-lede-decision` mechanism description in `artifact-conventions.md`. The lede diff reads `## What` from the `pull-request` artifact and `## Body` from the `merge` artifact; the sentence elided the second heading, so it read as `## What` on both sides. `resolve-episode.ts` carries the asymmetry in `AGENT_LEDE_SOURCE` and `MERGED_LEDE_SOURCE`, and this passage is the only description of it in the content tree.
@williamthorsen williamthorsen added feature Added or improved external functionality scope:agents labels Aug 12, 2026
@github-actions

Copy link
Copy Markdown

Dependency audit

Production dependency audit passed.

@williamthorsen
williamthorsen marked this pull request as ready for review August 12, 2026 02:00
@williamthorsen
williamthorsen merged commit ba1a443 into main Aug 12, 2026
3 checks passed
@williamthorsen
williamthorsen deleted the 1294 branch August 12, 2026 02:01
williamthorsen added a commit that referenced this pull request Aug 13, 2026
…e-v0.3.0 codeassembly-v0.9.0 factory-v0.2.6 codeassembly-mcp-v0.2.5

codeassembly-v0.9.0
- #1288 feat: State mutability and name the lede reader at the artifact type lists (#1303)
- #1285 fix: Require plain bullets for checklists on both update-jira-ticket paths (#1302)
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1294 feat: Specify artifact mutability and its sanctioned exceptions (#1297)
- #1293 fix: Present and classify discretionary findings as actionable (#1295)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1280 feat: Add a refresh path that edits an existing AGENTS.md instead of redrafting it (#1287)
- #1055 feat: Replace the lede doctrine with corpus-derived guidance and retire the changelog-writer (#1286)
- deps: Upgrade all deps to latest version
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)
- #1263 refactor: Retire the deferred-lint mechanism and adopt toolbelt.errors in agents (#1279)
- #1262 refactor: Hoist unreadable for-of expressions and promote the lint rule to an error (#1276)
- #1267 fix: Extend the no-hard-wrapping instruction to every GitHub composer (#1275)
- #1177 fix: Rewrite links, tokens, and template variables in a Markdown file support entry (#1273)
- #1176 feat: Add a ticketing-preferences hook to the skills that split and create tickets (#1268)
- #1252 fix: Keep a skill's own sections out of injected guidance (#1266)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)
- #1247 feat: Add a personal tooling-preferences rulebook (#1257)
- #1251 feat: Let a rulebook declare that a guidance hook is how it is reached (#1259)
- #1246 feat: Guard home-domain writes and record their provenance (#1254)
- #1175 feat: Link new tickets to their blockers and parents (#1249)

factory-v0.2.6
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- deps: Upgrade all deps to latest version
- deps: Upgrade all deps to latest version
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)

kb-v0.6.0
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)
- #1261 feat: Attach causes to kb's loader errors and retire its lint deferral (#1272)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)

codeassembly-lifecycle-v0.4.0
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1261 feat: Attach causes to kb's loader errors and retire its lint deferral (#1272)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)

codeassembly-mcp-v0.2.5
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)

codeassembly-run-core-v0.3.0
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)
- #1261 feat: Attach causes to kb's loader errors and retire its lint deferral (#1272)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Added or improved external functionality scope:agents

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stop unnecessarily updating historical artifacts

1 participant