feat: scaffold-seeded plan creation and a scaffold receipt contract - #22
Merged
Conversation
…receipt and per-file write semantics
…nts the same diff receipt and types its scalars
…from core.groom_playbook.scaffold
…d plan frontmatter partials
…nd the shared stdout contract
…e accepted groom snapshot baseline
`type:` rendered raw, so a missing `--set type=` produced a YAML null with no
error and the run continued with a plan carrying no task type. It now goes
through the same `default('') | tojson` seam `title:` already used.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…t suites Scalar typing, frontmatter-update diff receipts and scaffold stdout receipts were one function per case. Each block is now a single parametrized test over an input/expected table, so a new case is a row. Assertions got stronger, not weaker: scalar rows check the reloaded value's exact type, and the append and removal rows assert the full `--- / +++ / @@` header. `import yaml as pyyaml` moves to module level; the eight function-local copies are gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The review artifact, the plan's `code_reviews:` back-link, and two lessons the run produced — top-level imports over lazy ones, and code-only review scope. The back-link is hand-corrected: `frontmatter-update --append` into an empty inline `[]` list emitted the old `[]` as the first element. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… list The exit hook parses plan frontmatter with a regex — it is stdlib-only by design — and its inline-value branch knew only `null` and `~`. A plan carrying `code_reviews: []` had that `[]` inserted as the list's first element; a populated `[a]` would have landed as one element literally named `[a]`. `_inline_items()` now reads the flow form: `[]` yields nothing, `[a, b]` yields its elements, `null`/`~` mean unset, anything else is a lone scalar. The hook has no tests, so the new module drives it as a subprocess the way `playbook-transition` does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`0014` broadens from lazy imports alone to the project's code style practices, picking up the parametrized-tests preference the same review raised. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Groom now seeds a plan directory with one
booping scaffoldcall instead of asking the model to transcribe a literal frontmatter block, and both writers that touch a plan's frontmatter answer with the same receipt.Changes
booping scaffoldreports a unified diff per file it writes. A new file diffs against/dev/null; a file whose rendered content matches what is on disk produces no output. A rendered prompt can act on the receipt without reading the file back.difflibfrom the stdlib — scaffold's primary caller targets a vault that is not a git repository yet.--forceoverwrites the files the tree names, and a destination already holding part of the tree exits 0 instead of erroring.booping frontmatter-updateadopts the same stdout contract — the diff of the change it made, silence on a no-op — keeping itsupdated {path}: {keys}summary and errors on stderr, with arguments, flags and exit codes unchanged.frontmatter-updatewrites scalars with their YAML type.sp=23lands as an integer,retro=nullas a YAML null; a string whose plain form would reload as another type (yes) keeps its quotes.core.groom_playbook.scaffoldtree seedsindex.mdand an emptyrequest.md, takingtitleandtypefrom--setandcreated/commitfrom macros — so a plan carries the repo HEAD from the moment it is created rather than stayingnulluntil a sprint starts. Both--setvariables render throughdefault('') | tojson, so an omitted one cannot produce a null field or a broken document._partials/plan_frontmatter.md,_partials/plan_structure.mdanddocs/template_plan_frontmatter.mdare deleted; the surviving template mechanics fold into_partials/plan_templates.md, which names thefrontmatter-updateinvocation that writes the drafter'sspandsummary.documentation/project_config.mdcovers the third tree, the shared stdout contract, the skip rule and--force's narrowed meaning.Review follow-ups
frontmatter-updatereceipt and scaffold receipt suites are each one parametrized test over an input/expected table instead of one function per case. Assertions got stronger: scalar rows check the reloaded value's exact type, and the append and removal rows assert the full--- / +++ / @@header.import yaml as pyyamlmoved to module level.vault/.code-reviewexit hook parsed an inlinecode_reviews:value knowing onlynulland~, so a plan carryingcode_reviews: []had that[]inserted as the list's first element. It now reads the flow form, and the script — previously untested — has a test module driving it as a subprocess.Plan:
vault/plans/202608091310_scaffold-seeded-plan-creation/.🤖 Generated with Claude Code