Skip to content

Epic: Rebuild prepare-changesets as carve-changesets, a suite-native stateless-first skill #28

Description

@shaug

Outcome

Build skills/carve-changesets as a new skill occupying prepare-changesets' space — the old skill remains untouched throughout the epic and is deleted once the new skill is complete. The result: a suite-idiom operating contract (authority matrix, named terminal states, capability gates), a stateless-first architecture that derives truth from live git and GitHub instead of caching it in .prepare-changesets/state.json, a hardened safety posture, one consolidated CLI surface, defined seams with babysit-pr and review-code-change, and modernized tests and evals.

Motivation

prepare-changesets was written first (last touched 2026-01-27) and predates every convention the rest of the suite now follows (operating contracts, authority models, terminal handoffs, delegation boundaries, fail-closed capability checks). A comprehensive review found:

  • no result contract, authority model, or stop conditions — yet Phase 2 merges PRs gated only by --no-dry-run;
  • a cached-state design (state.json) that is guaranteed to drift: only create_chain records heads, so validate --strict false-positives after every legitimate propagation;
  • safety violations of AGENTS.md: the base branch is force-pushed by push_chain and propagate --push; preflight auto-executes a test command scraped from repo files with shell=True; git reset --hard is used in mergeability checks;
  • accidental complexity: 16 documented entry points, 12 of them identical shims over cli.py, plus parser duplication, dead code, and the db_compare.py/dbcompare.py near-collision;
  • references/SPEC.md contains pasted LLM chat residue and essay content alongside its (sound) behavioral rules;
  • a bespoke eval system (prompts.csv + codex exec runner) that matches neither of the repo's two established eval patterns, whose default path self-tests the helpers rather than agent behavior;
  • no integration with the composed suite: Phase 2 overlaps babysit-pr's ownership of the post-publication PR lifecycle, and per-changeset review via review-code-change is undefined.

Architectural decisions

  1. No backwards compatibility. No migration of existing state.json, old plan files, or chains created by the old implementation. Old artifacts are ignored or rejected with a clear message.
  2. Truth-promotion state model. A changeset's truth migrates forward as it progresses: proposed (plan file) → materialized (branch + commit trailers) → published (PR metadata) → merged (mainline). Later phases must never depend on earlier, weaker records.
  3. Stateless-first litmus test: delete .carve-changesets/ after PRs are open, and Phase 2 (merge and propagate) still works from rehydrated git + GitHub state.
  4. Live git/GitHub state is execution state; local records are for orientation and authoring only. Every invariant (chain ancestry, source equivalence) is checked against ground truth, never against a cached copy.
  5. Explicit authority matrix: decompose-only (local branches, no remote writes) / publish (push changeset branches, open PRs) / merge-and-propagate (merge PRs, update bases, force-with-lease downstream branches only). Merge authority is explicit, never inferred.
  6. Named terminal states with required evidence: plan_ready, chain_ready, prs_open, all_merged, blocked.
  7. Seams: babysit-pr owns each changeset PR's post-publication lifecycle when delegated; review-code-change is the per-changeset review mechanism; this skill uniquely owns decomposition and propagation mechanics. No lifecycle mechanics are duplicated across skills.
  8. The source branch remains immutable — carried over unchanged from the original design.
  9. The base branch is never force-pushed by any code path. Discovered test commands are proposed, never auto-executed.
  10. The new skill is named carve-changesets and is built greenfield. A changeset is the suite's human-shaped reviewable, mergeable unit; a PR is the mechanical GitHub representation of one. The verb names the differentiated act — carving cohesive changesets out of an existing monolithic branch — and avoids collision with the JS ecosystem's changesets release tooling.
  11. skills/prepare-changesets/ is never modified by this epic. It stays frozen as reference material: its hunk-extraction engine, plan checks, equivalence machinery, and tests are worth porting; its documented defects are what must not be ported. All implementation children build under skills/carve-changesets/. The packaging child deletes the old skill (directory, justfile targets, README references) once the new skill is complete. File/line references to the old implementation in child issues identify porting sources and defects, not code to modify in place.

Scope

  • Author the carve-changesets behavioral contract (superseding the old references/SPEC.md) defining the state model, terminal states, authority matrix, and seams.
  • Consolidate the script surface into one cli.py dispatcher with a classified, uniformly dry-run-defaulted mutation surface and a single gh chokepoint.
  • Stamp materialized changesets with commit trailers and PR metadata blocks; add a rehydration module that reconstructs the chain from git + GitHub alone.
  • Delete state.json in favor of live invariant checks.
  • Rebuild merge/propagate on rehydrated state, with merge verification and PR targeting by explicit number.
  • Define the babysit-pr delegation and per-changeset review-code-change packet construction in reference docs; update the README dependency picture.
  • Write the new skill's SKILL.md in the suite contract idiom with standard frontmatter and agents/openai.yaml, and delete skills/prepare-changesets/ once the new skill is complete.
  • Modernize tests and evals: behavioral cases.json coverage, forward-eval executor pattern instead of a hardcoded codex dependency, regression tests for every fixed bug.

Non-goals

  • Support VCS hosts other than GitHub/gh, or non-git VCS.
  • Build a general-purpose stacked-PR tool (ghstack/Graphite replacement); scope stays "decompose one review-ready branch."
  • Change the decomposition philosophy (additive-first, rename separation, cognitive-load guardrails, DB migration rules) — that content is sound and carries forward.
  • Migrate or convert any artifact produced by the old implementation.
  • Modify babysit-pr or review-code-change themselves.

Required child sequence

  1. Define the operating contract and truth-promotion state model (anchor; blocks everything below).
  2. Consolidate the scripts into one CLI with a hardened mutation surface (absorbs the preflight and push-chain safety fixes).
  3. Make changesets self-describing with commit trailers and PR metadata.
  4. Replace state.json with live derived-state validation (after 3).
  5. Rebuild merge and propagation on rehydrated GitHub state (after 3 and 4; builds on 2; absorbs the propagate safety fixes).
  6. Define the seams with babysit-pr and review-code-change (after 1 and 5; docs/contract only).
  7. Write the new skill's SKILL.md in the suite contract idiom, finish packaging, and delete the old prepare-changesets skill (after 1–6).
  8. Modernize tests and evals (after 4 and 5; finalizes after 7).

Children 2 and 3 may proceed in parallel once the contract is complete.

Epic acceptance criteria

  • Every required child is closed with its acceptance criteria satisfied.
  • The stateless-first litmus test passes: with .carve-changesets/ deleted after PRs are open, merge and propagation complete correctly in an integration test.
  • No code path force-pushes the base branch, auto-executes a discovered command, or uses git reset --hard; each guard has a regression test.
  • skills-ref validate passes and the SKILL.md matches the suite's contract anatomy (frontmatter, capability gates, operating contract, stop conditions, terminal handoff).
  • state.json no longer exists in code or docs; all invariants are checked against live git state.
  • README.md includes prepare-changesets in the composed dependency picture, including its delegation path to babysit-pr and review-code-change.
  • The skill lives at skills/carve-changesets/ with name: carve-changesets; skills/prepare-changesets/ is deleted, and no code, docs, or justfile references to it remain.
  • skills/prepare-changesets/ received no modifications during the epic prior to its deletion.
  • just format, just lint, and just test pass on the final integrated mainline; the skill's eval target runs with no codex binary present.
  • CHANGELOG.md records the rebuild per repository conventions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions