agent-wrap-up · v24 · 2026-09-27 · sha256 de158426416c8fbf
agent-wrap-up v24A
Immutable. This exact content never changes and is served at /api/v1/blob/de158426416c8fbf.
---
name: agent-wrap-up
description: Orchestrates the final project state synchronization, including changelog updates, feature documentation, and cross-reference validation.
version: 24
updated: 2026-09-28
---
# Agent Wrap-Up Skill
## Persona
You are the **Lead Context Architect**. Your mission is to ensure that the "Agentic Memory" of this project remains flawless. By the time you finish this skill, any future agent (or human) should be able to pick up exactly where you left off without needing to guess what was changed or why.
## Trigger Conditions
Activate this skill whenever:
1. A primary development task is completed.
2. The user says "wrap up", "we're done", "ship it", "archive this", or "good job".
3. You are closing out a major feature branch or bug fix.
---
## Token Economy & Delegation Model
Wrap-up's token cost is concentrated in *reads* (wiki docs, backlog index), not edits. Two rules keep it lean without losing any benefit.
### Phase-Gating (Skip What Doesn't Apply)
Immediately after Phase 0, triage the diff and declare skips explicitly:
- Diff touches no `src/` files (docs/process-only session) → skip Phases 2–3.
- No plan in `.devops/plans/` was followed this session → skip Phase 4.
- Nothing new surfaced (orphans, debt, backlog matches, tribal knowledge) → skip Phases 5–6 with a one-line declaration in the run's record — a **plan run** records it in the plan's `## Completion Note`; a **planless session** records it in the changelog index line's summary text (`:87-91`). Never the retired `Why:` field.
- Phases 0, 1, and 7 are always mandatory.
### Subagent Delegation (Phases 2–6)
Phases 2–6 are read-heavy and parallelizable. On feature-scale sessions, dispatch two subagents **concurrently** after Phase 0. Each prompt must carry the wiki-first mandate (AGENTS.md rule 6) and the agent's exclusive write scope to prevent collisions:
| Agent | Owns (exclusive write scope) | Phases | Returns (summary only — never file contents) |
|-------|------------------------------|--------|----------------------------------------------|
| **A — Wiki Agent** | `.wiki/**` | 2, 3, plus Phase 5 `defer` rows and Phase 6 **app-domain** knowledge-capture | One-line-per-doc summary: created/updated/promoted + stale refs fixed + deviations logged |
| **B — Process Agent** | `.devops/plans/`, `.devops/archive/`, `.devops/backlog/`, `.devops/rules/process-lessons.md` | 4, 5 (minus `defer` rows), Phase 6 **machinery** knowledge-capture | Counts only: plans archived, backlog entries created/resolved/annotated, process lessons routed |
Delegation rules:
- Main agent retains Phases 0, 1 (changelog synthesis from the two returned summaries), and 7.
- Both subagents must follow the `@wiki-writer` discipline for any prose edits they make.
- On small sessions (a handful of files, no plan), running Phases 2–6 inline is acceptable — delegation pays off only when the read surface is large.
---
## Batch Scope (sprint batch wrap-up)
Wrap-up normally closes **one** plan. The **batch scope** closes a sprint's whole batched set in one pass. It is the follow-up step the `@sprint-run` batch defers to: that batch ends at `PHASE_9` with `claim_status: GATE_D_USER_APPROVAL` and never wraps itself up.
**Trigger — separate, operator-invoked.** Runs **after** the batch Gate D verdict and **outside** the batch loop — a distinct invocation, never an inline continuation of `@sprint-run`. Either the ordinary wrap-up path (any orchestrator) or `parcel-sprint` itself, which may spawn `wiki-writer` for the read-heavy wiki reconciliation.
**Input.** A list of plan codes. Omitted → every plan in `.devops/plans/` carrying `claim_status: GATE_D_USER_APPROVAL`. An empty list is a no-op, not an error.
**Rule — every phase once, except Phase 4.** Phases 0, 1, 2, 3, 5, 6 and 7a/7b run **once for the batch** exactly as written below: one diff, one index line per plan, one wiki reconciliation, one backlog sweep, one consolidation, one gate pass. Only **Phase 4** iterates, once per plan in the input list. Batch scope is a *scope* on this skill — this skill remains the **only** wrap-up owner. Never create a second wrap-up skill.
**Rule — one `machinery-version` increment for the whole batch.** The counter is **template-owned and sync-stamped — a satellite never bumps it**; this is its single writer for a batch (`.devops/rules/plan-lifecycle.md` § Claim Protocol → *Counter Ownership*). Read the live value from `.devops/sync-manifest.yaml` **at the moment of the bump** — never a value read earlier, and never a value a member plan recorded — increment once, and record that literal in `.devops/logs/version-history.md`. **Apply the level rule when incrementing** and record the level with the row: **patch** = a routine improvement (the default, and a one-line row); **minor** = a new capability surface (a path with no prior registry/manifest row); **major** = an operator-contract change — the diff intersects the reserved-surfaces set — which takes a full row + a `CHANGELOG.md` entry + a tag, and is a mandatory pull milestone for every satellite. N per-plan runners each reading the same base is the collision this removes; per-skill `version:` bumps remain **per modified file**. If a member plan already bumped under the legacy per-plan rule, do not treat that as a conflict: increment once anyway, because the contract is *strictly increasing values, each recorded*, not a count. The prefix regenerate is **not** part of this — it stays with the plan that edited a reserved prefix surface.
**Confirmation gate — safety-critical, not simplifiable.** Before a plan is marked complete, assert **each** of the following for it, individually and from file/git evidence — never from the batch report:
1. bottom `Status` is `PHASE_9`;
2. front-matter `claim_status` is `GATE_D_USER_APPROVAL`;
3. the plan's per-plan runner outcome was `DONE <code>` (a `SKIP`, a `HALT`, or a missing outcome fails);
4. Phase 9 verification evidence is present (commands + exit codes) **and** the acceptance-criteria table is populated;
5. a commit with the exact literal `plan: <code>` exists on the trunk.
Then run the repo gates **once for the batch** - tests / lint / build, `check-parcel-prefix.ps1`, `check-utf8-agents.ps1`, `wiki_lint.py`, `wiki_claims.py coverage`, `wiki_claims.py check`. Those once-per-batch repo gates are the consolidated full-suite pass; each plan's Phase 9 evidence keeps its own `Suite scope` record (canonical: `.devops/rules/plan-lifecycle.md` § Gate Invocation Hygiene). A red gate is a hard stop: it blocks the **whole** batch wrap-up, and a red tree is **never** auto-cleaned.
A plan failing **any** assertion is **carry-forward** — excluded from the batch, left exactly where it is, **never** marked complete. Report it with the failed assertion named. `ponytail:` the carry-forward report is prose, not a schema; upgrade path is a machine-readable per-plan verdict row if the batch ever needs to be driven programmatically.
---
## Execution Phases
### Phase 0: Mechanical Diff (Evidence, Not Memory)
Before writing anything, establish **what actually changed** — never rely on recall.
1. **Enumerate changed files mechanically**: run `git diff --name-only <last-wrap-up-ref>..HEAD`. The baseline is the last commit that touched the changelog — `git log --oneline -1 -- .devops/logs/agent-changelog.md` (an index entry carries no hash; the plan it links does). If no prior ref exists, diff against the session's starting commit.
2. **Classify each changed file** into a wiki domain: `.wiki/` target (features / components / logic / database / core), `.devops/` process file, or other.
3. **Carry this list into Phases 2 and 3** — it is the authoritative work inventory. Every `src/` file in the diff MUST map to a wiki doc update or an explicit "no doc needed" decision recorded in the changelog entry.
> **Why this phase exists:** wrap-up used to rely on the working agent's memory of "what's new". Memory-based inventories silently drop files, which is how entire feature areas (e.g., the proposals engine suite) went undocumented while lint stayed green.
### Phase 1: The Audit Log (`.devops/logs/agent-changelog.md`)
The changelog is a **thin index**, not a record: one line per change, **written from the plan**. The Why is authored once, in the plan — never re-authored here. The index exists for one job only: the cold-start recent-state signal (`AGENTS.md` rule 5, *"read the last 3 entries"*), which the append-only order makes the 3 **most recent** changes.
1. **Add index line**: append **one line per change** to the end of the file's `## Index` block, in the exact format:
```markdown
- **YYYY-MM-DD** · `CODE` · <one-line summary> · [plan](<path relative to this file>)
```
- Read the summary **from the plan** (its Completion Note / Phase 9 record) — the Why is never composed here. A session with no plan cites its direct-fix commit instead of a plan link.
- A batch appends **one line per plan**, never one line for the theme.
- No `**Why:**`, no `**Skips:**`, no `**Ref:**`, no file list, no "Agent" line — deep detail already lives in the archived plan and git history, and the plan link is the ref.
- Entries dated before 2026-09-25 are the pre-index narrative record: **preserved as history, never retro-edited** (`.devops/rules/process-lessons.md`).
2. **Size check (warning only)**: after adding the line, check `(Get-Content .devops/logs/agent-changelog.md).Count`. If it exceeds **500 lines**, warn the user in one line — "agent-changelog is over the 500-line guideline (currently _n_ lines); consider archiving old entries manually" — and stop. **Never auto-prune or move entries**: automated pruning was tried on 2026-09-09 and corrupted the log's structure; the cap is a soft guideline enforced by human judgment only.
### Phase 2: Wiki Docs (Reconcile Code Against Spec)
With the spec-first pipeline, docs for planned behavior were already written in parcel Phase 4 (marked `status: in-progress`). Wrap-up **reconciles** rather than retro-documents.
1. **Reconcile against the spec**: for every doc written in parcel Phase 4, verify the implemented code matches the documented behavior and acceptance criteria. Log every deviation in the plan's Completion Note (`Spec Reconciliation`) — then fix the DOC to match reality (the code that shipped is the truth).
2. **Promote**: flip each reconciled doc from `status: in-progress` to `status: stable`. A doc that could not be reconciled stays `in-progress` with a logged deviation — never promote an unreconciled claim.
3. **Cover the leftovers**: review the Phase 0 diff for assets the spec didn't anticipate:
- New React Hooks (`src/hooks/`)
- New UI Components (`src/components/`)
- New Utility Functions (`src/utils/`)
- New API Routes or Database Collections
4. **Create/Update Docs** for those leftovers: Follow the `@wiki-writer` skill for all wiki prose — read the full target doc first, integrate at the semantically correct section, never append to the end.
- If a new feature was added: Create a doc in `.wiki/features/<feature-name>.md`.
- If a component was added: Create/Update `.wiki/components/<component-name>.md`.
- If logic changed: Update the relevant doc in `.wiki/logic/`.
- **Standard**: Include inputs (props/params), outputs, side effects, and a brief "Why this exists" section.
### Phase 3: Cross-Reference Synchronization (The "Context Web")
Ensure the rest of the documentation doesn't become "stale" or misleading.
1. **Search for References**: Use `grep` to find all mentions of the functions, components, or files you modified within the `.wiki/` and `docs/` directories.
2. **Validate Accuracy**:
- Does the architecture diagram in `.wiki/core/00-system-index.md` still hold?
- Do the state shapes in `.wiki/core/04-state-context.md` need updating?
- Are there "Usage Examples" in other docs that now use an old API signature?
3. **Update**: Apply surgical edits to ensure every doc reflects the current reality. Where an edit changes prose structure (not a one-line fact fix), follow the `@wiki-writer` discipline: rebalance the affected section so it reads as if written at once.
### Phase 4: Plan Finalization
> **Batch scope:** in a batch wrap-up this phase runs **once per plan in the input list**; every other phase stays once-per-batch. See § Batch Scope — including its confirmation gate, which must pass for a plan before Step 1 below.
1. **Update Implementation Plans**: If you were following a plan in `.devops/plans/`, finalize it in this strict order:
- **Step 1 — Mark Complete:** Open the plan file and set **both** `claim_status: COMPLETE` (front-matter) and the bottom State Dashboard `Status` to `COMPLETE`. Do this **before** moving the file.
- **Step 2 — Add Completion Note:** At the bottom of the plan, add a `## Completion Note` section explaining the actual outcome and any deviations from the original plan.
- **Step 3 — Archive:** Move the completed plan with `git mv` from `.devops/plans/[plan-name].md` to `.devops/archive/[plan-name].md` — no stub is left at the old location. The plan stays at the archive **root**; its `sprint:` front-matter field is what links it to a sprint. The sprint's `sprint.md` archives separately to `.devops/archive/sprints/sprint-{n}-<slug>/` at sprint close (see `.devops/rules/plan-lifecycle.md`).
- **Step 4 — Confirm in-place state:** verify the working tree is the trunk; there is no plan branch and no worktree — nothing to merge or prune. Commit in place.
> **Archival is mandatory, not optional.** A plan that is done but still sitting in `.devops/plans/` is a ghost — it pollutes future agents' context. Every completed plan **MUST** be archived before wrap-up is considered complete.
### Phase 5: Backlog Reconciliation (`.devops/backlog/`)
Sweep the session for unfinished business, then reconcile it against the open backlog. Both halves own the same surface — one read pass, one mental model. Do not let discovered issues disappear into the archive.
Item detail lives in the `t{n}-<slug>-backlog.md` theme registers; `backlog-index.md` holds the Themes table + Triage Panel. Reconcile both.
**5a — Capture new discoveries**
1. **Orphan files / dead code**: if the session found orphan files, dead code, or ghost components, create a backlog plan at `.devops/backlog/{code}-{slug}-backlog.md` (`type: backlog`, `claim_status: QUEUED`) with affected file paths and a terse description, and add a row to the matching `t{n}-<slug>-backlog.md` theme register. Follow the `@backlog` skill.
2. **Spaghetti Triage rows**: dispose each row — `escalate-monster` (flag for the user to invoke `spaghetti-monster` directly), `new-parcel` (one backlog plan per row, same format as step 1), `defer` (log to `.wiki/core/18-knowledge-capture.md` — a `.wiki/` write, Agent A's scope under the Delegation Model), `inline-minor` (confirm resolved in the execution trace).
3. **Known issues / tech debt**: if any known limitations, workarounds, or debt were accepted during the session, create a backlog entry for each.
4. **Invariants shipped without a check**: when the session added a contract surface (a front-matter row, an asserted predicate, a prose non-negotiable) with **no deterministic check** behind it, name the missing gate and park it as a backlog item **in this same wrap-up**. An unrecorded honour-system link is a silent decision; the parking turns it into a recorded one. *(process-lessons, 2026-09-23)*
5. **Grep the backlog before parking a new discovery.** A "new" tension may already be held: the 2026-09-27 knowledge consolidation surfaced *"KC's machinery boundary contradicts its own body"* and nearly parked it afresh, but `T2-E2.04` had carried exactly that item since the `T1-E3.23` wrap-up. Check the theme registers and the parked files for the tension's vocabulary **first** — a hit means this session either **resolves** the existing item or appends a note to it, never makes a duplicate copy. *(process-lessons, 2026-09-27)*
**5b — Reconcile the open backlog** (theme registers + `.devops/backlog/backlog-index.md`)
1. **Read the registers**: always read the full index and the theme registers before deciding nothing applies — items may be worded differently than the task; match by intent, not exact name.
2. **Match Against Completed Work**: an item qualifies for removal if the work fully implemented it, or explicitly superseded or made it irrelevant.
3. **Take Action**: **Move** fully-resolved items from the theme register's open table to its Completed table (no strike-through left behind); append `> Partially addressed by [task name] — remaining: [what's left]` to partials; leave unrelated items untouched.
4. **If no matches found**: state "No backlog items resolved by this session" and move on.
### Phase 6: Knowledge Capture & Consolidation
1. **Log Tribal Knowledge**: Review the conversation for any specific user preferences, "gotchas", or architectural decisions that aren't captured in formal documentation but should be remembered. Apply the `@knowledge-capture` **Admission Gate strictly** — only real deviations and valuable tribal knowledge qualify; everything else stays in the plan's Phase 10 log and Completion Note. **Budget: at most one new entry per session** — capture the lesson with the widest future reach; a second entry must be a genuinely different rule, not a restatement.
2. **Route and Update**: Use the `@knowledge-capture` skill to route each entry to its home — **app-domain** → `.wiki/core/18-knowledge-capture.md`; **machinery/process/tooling** (parcel/sprint pipeline, dev toolchain, scripts, docs tooling) → `.devops/rules/process-lessons.md`. Do **not** put machinery lessons in KC; that is the one-way ratchet this routing exists to stop.
3. **Consolidate (mandatory)**: Run `@knowledge-consolidation` in **tidy mode** (see its Modes table for scope). This is the step that keeps the log lean — skipping it makes KC growth one-way. Full audits are NOT part of wrap-up; they fire only on the consolidation skill's own triggers (KC above **25 entries**).
### Phase 7a: Coverage Gate (Hard Stop — all three scripts must exit 0; the trunk-CI read must not be red)
Run the mechanical gates. **Wrap-up is not complete until all three scripts exit 0 and the trunk-CI read (item 4) is not red.** The gates are cheap (measured <1s each, tiny output) — run them inline in the main context; do NOT delegate them. Use `--quiet` on the lint gate for clean runs.
1. **Doc-graph lint**: `python scripts/wiki_lint.py --quiet` — structure anchors, body links, frontmatter fields/status, frontmatter `related-to`/`dependencies` links, hub→spoke coverage, index cataloguing (`[UNINDEXED]`/`[MISSING]`), hub reachability, orphans, encoding. (Omit `--quiet` when diagnosing failures.)
2. **Code-coverage gate**: `python scripts/wiki_claims.py coverage` — every non-test file in `src/utils`, `src/hooks`, `src/components`, `src/views` must carry wiki evidence: its domain index cites a real exported symbol (preferred), OR a wiki doc claims-binds its path, OR the retained filename/folder match. On gaps: add an index row citing a real exported symbol, add a `claims: source:` binding, or add to the gate's `ALLOWLIST` with an explicit reason. The subcommand's docstring is canonical. Never skip silently.
3. **Grounded-claims drift gate**: `python scripts/wiki_claims.py check` — every doc's `claims:` hash re-verified against its source file; `STALE`/`MISSING`/`UNRESOLVED-SYMBOL` rows exit `1`. On failure: run `python scripts/wiki_claims.py update` to re-stamp, then re-run `check` — but never blind-stamp a real contradiction: if the source changed meaning (not just bytes), fix the wiki doc (or log the deviation) first, then re-stamp. *(This is the one home of the claims-drift gate — Phase 9 never runs it, so runners stay cheap and the wrap-up that reconciles the wiki is the same surface that repairs it.)*
On a failure, fix and re-run. **Do not proceed to 7b on a red gate.**
4. **Trunk-CI read — the remote, at close-out.** Items 1-3 run **locally**; this one reads the **remote**. Ask GitHub Actions — the remote the repository at `origin` points at — what it made of the trunk's current HEAD:
```
gh run list --commit "$(git rev-parse HEAD)" --json workflowName,conclusion,headSha,databaseId,status
```
and when a run is red, `gh run view <databaseId> --log-failed`. Read **every** run returned for that commit, never just the newest: one push often fires more than one workflow, and green means **every** run for the commit is `success` **and** its `headSha` equals `git rev-parse HEAD`. A run still in progress, a run for a different commit, and no run at all are each **not** green. The command is repository-scoped, so name no branch and no workflow file — a satellite whose trunk is not `main` reads its own run. Record **exactly one** verdict:
- `CI green — all <n> run(s) @ <headSha> succeeded` — all of them passed; done.
- `CI red — <workflowName> run <databaseId> @ <headSha>: <steps>` — **a hard stop**: wrap-up does not complete. In plain words: one named automated check (the workflow) failed at the named step inside it.
- `CI status unreadable — <reason>` — a reported limitation, **never** a pass. `gh` absent or unauthenticated is the usual reason: then open the repository's Actions page for the trunk HEAD and read the top run by eye, and record what you actually saw under one of the two verdicts above. Never write a green you did not see.
This is a close-out **read**, not a push cadence: a trunk never pushed lands on the third verdict and says so plainly. It does **not** decide whether a red trunk blocks a *claim*, and it does **not** rule on `gh workflow` / `act` scope — both are `T1-E3.22`'s (`.devops/backlog/t1-e3.22-manual-claim-baseline-backlog.md`), deliberately left to it.
### Phase 7b: State Stamps (Checklist — easy to forget, not gated)
Mutations that keep downstream tooling honest. Do all three, then close out.
1. **Stamp freshness**: update the `Last Verified` date in the `.wiki/core/00-system-index.md` Quick Reference for every core doc touched this session.
2. **Machinery version bump — template repo only.** The counter is template-owned and sync-stamped — a satellite never bumps it (`.devops/rules/plan-lifecycle.md` § Claim Protocol → *Counter Ownership*), so a satellite run records one line — `Machinery version bump — skipped: satellite inherits; the next pull stamps the manifest` — and skips the rest of this step. In the template repo, for each modified file under `.devops/skills/` or `.devops/templates/`, bump its frontmatter `version:` by 1 and refresh `updated:` to today; for each modified file under `scripts/`, `.devops/agents/`, `.devops/rules/`, or `.wiki/rules/`, bump `machinery-version:` once in `.devops/sync-manifest.yaml` — applying the **level rule** (patch = routine improvement, the default; minor = a new capability surface; major = an operator-contract change, i.e. the diff intersects the reserved-surfaces set) and recording the level with the release row (`.devops/rules/plan-lifecycle.md` § Claim Protocol → *Counter Ownership*; scheme in `.devops/logs/version-history.md` § *Machinery Versioning Strategy*). Without this, satellites see `DRIFT` instead of `UPGRADE` on the next `-Check`. A satellite run of this skill skips this step entirely: the next pull stamps the satellite's manifest with the source `machinery-version`, so a satellite-side bump is inert and is stamped back down. **Batch scope override:** the `machinery-version:` increment happens **once for the whole set**, from the value live at that moment (see § Batch Scope — *one `machinery-version` increment*); the per-file skill `version:` bumps are unchanged and stay per modified file. The prefix `-Sync` is **not** wrapped up here — it belongs to the plan that edited a reserved prefix surface, so a red `check-parcel-prefix.ps1` is never carried into this step.
3. **Record the wrap-up ref**: the index line links the plan, whose Phase 9 record carries the exact commit — nothing more is written into the changelog; the commit that lands the changelog is the next Phase 0 baseline (`git log --oneline -1 -- .devops/logs/agent-changelog.md`).
---
## Hard Stop
**Coverage Gate is a hard stop**: Phase 7a must exit 0 on all three scripts — **and** the trunk-CI read must not be `CI red` — before wrap-up is declared complete. A green lint with red coverage — or a green coverage with red claims — is a failed wrap-up. No placeholders — finish every phase you did not explicitly skip.
**Batch wrap-up is a hard stop too**: the § Batch Scope confirmation gate must pass for a plan before it is marked complete. A plan failing any assertion is carry-forward, never `COMPLETE`; a red repo gate blocks the whole batch wrap-up.