From f85aa27a62a021cf282f9f890bda038484e1da52 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Tue, 11 Aug 2026 18:20:54 -0700 Subject: [PATCH 1/5] agents|feat: Add shared guidance against post-hoc artifact updates 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. --- packages/agents/content/guidance/shared/AGENTS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/agents/content/guidance/shared/AGENTS.md b/packages/agents/content/guidance/shared/AGENTS.md index 0b64db5c..60e29e19 100644 --- a/packages/agents/content/guidance/shared/AGENTS.md +++ b/packages/agents/content/guidance/shared/AGENTS.md @@ -66,6 +66,10 @@ Read-only exercises (`--dry-run`, help text, preview tables, `--list`, exit-code When creating an artifact (plan, devlog, review, change summary, chat summary, etc.), invoke the `save-artifact` skill to resolve path and naming. Do not place artifacts in ad-hoc locations. +A saved artifact records a moment, not a running state. Once written it stands: never rewrite one to match a later human edit, a rebase, or any other event downstream of it, and never raise its divergence from current state as a defect or as a decision for the user. Update a saved artifact only where the next step in the flow reads it, or where a skill directs the write (stamping a PR URL into a change summary, for instance). + +The same restraint governs the remote ticket. Align its acceptance criteria to the implementation only where the two conflict, or where the gap would mislead a reviewer. Small improvements arrive as a matter of course, and the ticket is not rewritten to pretend they were foreseen. + ## Commits Invoke the `commit` skill before writing a commit message. It carries the title and body conventions, the work-type taxonomy, and the branch-naming format. From 2dfb19eb0de9eaad7000df91113e25fd4a93c888 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Tue, 11 Aug 2026 18:21:54 -0700 Subject: [PATCH 2/5] agents|feat: Specify artifact mutability and its sanctioned exceptions 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. --- .../content/skills/_data/artifact-conventions.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/agents/content/skills/_data/artifact-conventions.md b/packages/agents/content/skills/_data/artifact-conventions.md index 3a20effb..3bc3eece 100644 --- a/packages/agents/content/skills/_data/artifact-conventions.md +++ b/packages/agents/content/skills/_data/artifact-conventions.md @@ -864,6 +864,20 @@ Insights never carry criticality, never block a merge, and never count toward a - **Active**: Artifact is current and relevant - **Stale**: Branch has been merged or deleted, and artifact is 30+ days old +### Mutability + +A saved artifact is a point-in-time record of what its author produced at the moment of writing. It is never reconciled with anything downstream of it: not a later human edit to the remote it was published to, not a rebase that leaves `baseSha` and `commit` unresolvable, not a subsequent turn of the session that wrote it. Divergence from current state is the artifact doing its job, so it is never reported as a defect or raised as a decision for the user. + +These mutations are sanctioned, and no others: + +- **Frontmatter a skill's own step directs**: `create-pr` backfills a `pr:` line into the change summary, and `plan-orchestrable-steps` prepends resolved frontmatter to the planner's markdown snapshot. A pointer added after the fact is provenance the artifact could not carry at write time, which is what separates it from a content rewrite. +- **Artifacts declared mutable**: `orchestration-plan.json` is overwritten each planning iteration, while its `.md` counterparts are versioned snapshots. +- **Working input forwarded to another agent**: the receiving agent acts on the contents, so staleness would misdirect real work. + +Revision writes a new artifact rather than editing one. `refine-plan` saves its output as `plan-v2` under a later timestamp, leaving the plan it refines intact. + +Overwriting a record also breaks consumers. `capture-lede-decision` derives the agent's side of a lede episode by diffing the `pull-request` artifact's `## What` against the `merge` artifact's; a `pull-request` body rewritten to match a human's later edit reports `differ: false` for a lede that was in fact revised, inviting an `accepted` verdict the author never gave. The corruption raises no error and is undetectable in any session that no longer holds the original text. + ## Portability Every level degrades gracefully: From d5819970254ddf76d0b71c3dbdba2fb3aa22b5b2 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Tue, 11 Aug 2026 18:36:52 -0700 Subject: [PATCH 3/5] agents|feat: Define the `merge` artifact type in the ticket-level lists 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. --- packages/agents/content/skills/_data/artifact-conventions.md | 3 ++- packages/agents/content/skills/save-artifact/SKILL.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/agents/content/skills/_data/artifact-conventions.md b/packages/agents/content/skills/_data/artifact-conventions.md index 3bc3eece..3f8937cf 100644 --- a/packages/agents/content/skills/_data/artifact-conventions.md +++ b/packages/agents/content/skills/_data/artifact-conventions.md @@ -686,7 +686,9 @@ The first `coder_change-summary` in a run has no dispositions (nothing to respon ### Ticket-level artifacts - `change-summary` — Branch change summary for PRs +- `deferred-findings` — Record of findings deferred during a `wrap-up` session, with cross-references to created tickets (falls back to non-ticket path when no ticket is in session) - `devlog` — Development log entry (falls back to non-ticket path when no ticket is in session) +- `merge` — Record of a merged pull request - `orchestration-plan` — Orchestration plan (`orchestration-plan.json` is a **mutable** artifact overwritten each planning iteration; `{timestamp}_planner_orchestration-plan.md` files are versioned human-readable snapshots) - `plan` — Implementation plan document - `plan-review` — Plan review findings (completeness and correctness analysis) @@ -694,7 +696,6 @@ The first `coder_change-summary` in a run has no dispositions (nothing to respon - `pull-request` — PR description file - `review` — Code review (ticket-level, commit scope) - `ticket` — Issue ticket -- `deferred-findings` — Record of findings deferred during a `wrap-up` session, with cross-references to created tickets (falls back to non-ticket path when no ticket is in session) ### Non-ticket artifacts diff --git a/packages/agents/content/skills/save-artifact/SKILL.md b/packages/agents/content/skills/save-artifact/SKILL.md index 8be2c565..259b51ec 100644 --- a/packages/agents/content/skills/save-artifact/SKILL.md +++ b/packages/agents/content/skills/save-artifact/SKILL.md @@ -52,7 +52,9 @@ Run artifacts are saved by the skills that produce them (`review-branch`, `respo ### Ticket-level - `change-summary` — Branch change summary for PRs +- `deferred-findings` — Record of findings deferred during a `wrap-up` session, with cross-references to any tickets created (ticket-scoped when a ticket is in session; falls back to project-scoped `deferred-findings/` otherwise) - `devlog` — Development log entry (ticket-scoped when a ticket is in session; falls back to project-scoped `devlogs/` otherwise) +- `merge` — Record of a merged pull request - `orchestration-plan` — Orchestration plan for the orchestrate engine - `plan` — Implementation plan document - `plan-review` — Plan review findings (completeness and correctness analysis) @@ -60,7 +62,6 @@ Run artifacts are saved by the skills that produce them (`review-branch`, `respo - `pull-request` — PR description file - `review` — Code review (ticket-level, commit scope) - `ticket` — Issue ticket -- `deferred-findings` — Record of findings deferred during a `wrap-up` session, with cross-references to any tickets created (ticket-scoped when a ticket is in session; falls back to project-scoped `deferred-findings/` otherwise) ### Run artifacts From 2414adcc6a9912f3e30ab3709b905e9c900d47f3 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Tue, 11 Aug 2026 18:37:01 -0700 Subject: [PATCH 4/5] agents|feat: Narrow the artifact-divergence rule to exclude disclosure 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. --- packages/agents/content/guidance/shared/AGENTS.md | 2 +- packages/agents/content/skills/_data/artifact-conventions.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/agents/content/guidance/shared/AGENTS.md b/packages/agents/content/guidance/shared/AGENTS.md index 60e29e19..e4f7cbbd 100644 --- a/packages/agents/content/guidance/shared/AGENTS.md +++ b/packages/agents/content/guidance/shared/AGENTS.md @@ -66,7 +66,7 @@ Read-only exercises (`--dry-run`, help text, preview tables, `--list`, exit-code When creating an artifact (plan, devlog, review, change summary, chat summary, etc.), invoke the `save-artifact` skill to resolve path and naming. Do not place artifacts in ad-hoc locations. -A saved artifact records a moment, not a running state. Once written it stands: never rewrite one to match a later human edit, a rebase, or any other event downstream of it, and never raise its divergence from current state as a defect or as a decision for the user. Update a saved artifact only where the next step in the flow reads it, or where a skill directs the write (stamping a PR URL into a change summary, for instance). +A saved artifact records a moment, not a running state. Once written it stands: never rewrite one to match a later human edit, a rebase, or any other event downstream of it, and never raise its divergence from current state as a defect or as a repair for the user to weigh. Update a saved artifact only where the next step in the flow reads it, or where a skill directs the write (stamping a PR URL into a change summary, for instance). The same restraint governs the remote ticket. Align its acceptance criteria to the implementation only where the two conflict, or where the gap would mislead a reviewer. Small improvements arrive as a matter of course, and the ticket is not rewritten to pretend they were foreseen. diff --git a/packages/agents/content/skills/_data/artifact-conventions.md b/packages/agents/content/skills/_data/artifact-conventions.md index 3f8937cf..ecccfa29 100644 --- a/packages/agents/content/skills/_data/artifact-conventions.md +++ b/packages/agents/content/skills/_data/artifact-conventions.md @@ -867,7 +867,7 @@ Insights never carry criticality, never block a merge, and never count toward a ### Mutability -A saved artifact is a point-in-time record of what its author produced at the moment of writing. It is never reconciled with anything downstream of it: not a later human edit to the remote it was published to, not a rebase that leaves `baseSha` and `commit` unresolvable, not a subsequent turn of the session that wrote it. Divergence from current state is the artifact doing its job, so it is never reported as a defect or raised as a decision for the user. +A saved artifact is a point-in-time record of what its author produced at the moment of writing. It is never reconciled with anything downstream of it: not a later human edit to the remote it was published to, not a rebase that leaves `baseSha` and `commit` unresolvable, not a subsequent turn of the session that wrote it. Divergence from current state is the artifact doing its job, so it is never reported as a defect or raised as a repair for the user to weigh. A step that discloses which of two candidate sources it measured against is reporting its own input, not proposing a reconciliation. These mutations are sanctioned, and no others: From 43939ad286b7fa3fb88dc4fd3b8a8ca14e3fd140 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Tue, 11 Aug 2026 18:37:08 -0700 Subject: [PATCH 5/5] agents|fix: Name the merge artifact's actual heading in the lede diff 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. --- packages/agents/content/skills/_data/artifact-conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/agents/content/skills/_data/artifact-conventions.md b/packages/agents/content/skills/_data/artifact-conventions.md index ecccfa29..95cf10cd 100644 --- a/packages/agents/content/skills/_data/artifact-conventions.md +++ b/packages/agents/content/skills/_data/artifact-conventions.md @@ -877,7 +877,7 @@ These mutations are sanctioned, and no others: Revision writes a new artifact rather than editing one. `refine-plan` saves its output as `plan-v2` under a later timestamp, leaving the plan it refines intact. -Overwriting a record also breaks consumers. `capture-lede-decision` derives the agent's side of a lede episode by diffing the `pull-request` artifact's `## What` against the `merge` artifact's; a `pull-request` body rewritten to match a human's later edit reports `differ: false` for a lede that was in fact revised, inviting an `accepted` verdict the author never gave. The corruption raises no error and is undetectable in any session that no longer holds the original text. +Overwriting a record also breaks consumers. `capture-lede-decision` derives the agent's side of a lede episode by diffing the `pull-request` artifact's `## What` against the `merge` artifact's `## Body`; a `pull-request` body rewritten to match a human's later edit reports `differ: false` for a lede that was in fact revised, inviting an `accepted` verdict the author never gave. The corruption raises no error and is undetectable in any session that no longer holds the original text. ## Portability