Skip to content

docs(decisions): adopt and guard the change-proposal practice - #63

Merged
josephjang merged 3 commits into
mainfrom
docs/adopt-change-proposal
Sep 13, 2026
Merged

josephjang merged 3 commits into
mainfrom
docs/adopt-change-proposal

Conversation

@josephjang

@josephjang josephjang commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Motivation

This PR implements the proposal at docs/decisions/2026-09-13-adopt-change-proposal.md, written in the new Unified form so it is the first document in this repository to satisfy the new guard.

The change-proposal practice (https://github.com/josephjang/change-proposal, upstream revision 8fba2af) was being described twice, once here and once upstream, and the two descriptions had diverged in four costly ways: the trigger for writing a document was a judgment call, there was no cheap form for small changes, the template and the guard test contradicted each other on whether a spec needs a sibling PRD, and Verification sections recorded which commands to run rather than what actually happened when they ran.

Modifications

  • Replaces the judgment-based trigger with a mechanical one: a change needs a proposal when it alters observable behavior (decided from the diff); a PR that does not says so and how that was checked. CLAUDE.md's "Documentation & Decision Docs" section is renamed "Documentation & Change Proposals"; docs/decisions/README.md, docs/README.md, and the PR template all restate this trigger.
  • Introduces two proposal forms: Unified (YYYY-MM-DD-<slug>.md, the default) and Split (.requirements.md plus .design.md, linking each other), replacing the old PRD/spec pair. There is no design-only shape; /deliver now applies only to Split proposals.
  • Swaps templates: prd-template.md and spec-template.md are deleted, replaced by change-proposal.md, product-requirements.md, and technical-design.md, each naming the upstream revision they came from. Structural shifts include splitting the old single "Verification" section into "Test Strategy" (planned checks) and "Verification" (what actually ran), and replacing the Created header field with the date in the filename.
  • Rewrites docs/decisions/README.md as repo-specific conventions layered on the upstream practice, adding a legacy-to-new naming map and a lifecycle rule: a draft stays revisable while its change is open, and append-only applies only after the change's last PR merges.
  • Retitles the deliver and code-guide skills, the deliver plan template, and the /deliver command to the new vocabulary ("Split change proposal" instead of "decision-doc pair"), and updates the deliver workflow to read planned checks from Technical Design's Test Strategy and to require Verification to record what actually ran.
  • Adds TarkovHelper.Tests.ChangeProposalFormat, a new public static helper encoding the shape rules (legal dated file names, per-form title prefixes, fixed section lists and order, Split-pair counterpart naming and bidirectional linking) as pure functions over a file name and its text.
  • DecisionDocsTests gains five new guard facts (Templates_exist_for_each_form, Undated_docs_are_the_pre_adoption_set, Dated_docs_take_one_of_the_three_names, Dated_docs_and_templates_follow_their_forms_layout, Every_split_pair_is_complete_and_links_both_ways), for 9 facts total. The undated names are a closed set of the twenty-seven changes recorded before the adoption, so a document written in the old form fails whatever tool wrote it. Pre-adoption feature-*/fix-*/*.spec.md documents keep the old form and only the four original invariants; archive/ stays out of scope.
  • ChangeProposalFormatTests (46 tests) proves each rule against fixture text, including that the three shipped templates conform to their own forms.
  • Breaking (process-level only): new documents must use dated filenames with fixed, per-form section names and order; the guard fails any dated document, or .requirements.md/.design.md without its linked counterpart, that does not conform, and any new undated document. The two old templates are gone. New documents are English only, so a dated document may not have a .ko.md twin.
  • Three merged process documents get "Superseded in part by 2026-09-13-adopt-change-proposal.md" notes: feature-decision-docs-process.md, feature-decision-docs-process.spec.md, and feature-decisions-folder-rename.md. Nothing already merged is moved, renamed, or reformatted.

Result

  • Writers get one mechanical question ("does this change observable behavior?") instead of a judgment call, plus a cheap Unified form for changes too small to warrant a full Split proposal.
  • The guard test suite rejects malformed change-proposal documents at build time instead of relying on review to catch a wrong file name, a missing section, a wrong section order, a one-sided Split pair, or a new document in the old form.
  • The spec-template and guard contradiction on "does a spec need a sibling PRD" is resolved in the guard's favor: there is no design-only shape, and Split pairs must exist and link both ways.

Verification

  • dotnet build TarkovHelper.sln: 0 warnings, 0 errors.
  • dotnet test TarkovHelper.sln --no-build --filter "Category!=E2E": 1927 passed, 0 failed (before the third commit; the two guard suites were rerun after it).
  • DecisionDocsTests (9 facts) and ChangeProposalFormatTests (46 tests) pass.
  • Manually verified the guard rejects malformed input: four probe files, a wrong name shape, a wrong title and section order, a .requirements.md without its .design.md, and an undated feature-new-thing.md, were each rejected with the intended failure message, then removed.

Residuals

  • The upstream change-proposal Split guide's statement that this exact form has not yet been used in TarkovHelper becomes out of date once this merges.

  • Names the change proposal this PR implements, or states that the change alters no observable behavior and how that was checked

The decision docs were the source the change-proposal practice was
generalized from, and the two descriptions had drifted: the trigger was
a per-change judgment, small changes had no cheap form, the spec
template contradicted the guard, and Verification held commands rather
than results. This adopts the practice at upstream revision 8fba2af.

- A change that alters observable behavior gets a proposal; otherwise
  the PR body says so and how it was checked
- The Unified form (one dated document) is the default; the PRD and
  spec pair becomes the Split form (Product Requirements + Technical
  Design), and there is no design-only shape
- New files take dated names in the same docs/decisions/ folder; merged
  documents keep their names, titles, and format
- Three adapted templates replace prd-template.md and spec-template.md
- CLAUDE.md, the folder README, docs/README.md, the PR template, and
  the deliver and code-guide skills use the practice's vocabulary
- Supersede notes on the process pair and the folder-rename PRD
DecisionDocsTests gains four facts for dated documents: the three name
shapes, the title prefix and fixed section layout per form, the
required sections, and two-way Split pairing with mutual links. The
rules are pure functions in ChangeProposalFormat so that
ChangeProposalFormatTests can prove each one rejects bad input; the
tree-level facts alone would only ever have run against conforming
files.
The proposal and the deliver skill named a drafting skill and the
repository it lives in, neither of which a reader of this repository
has. The residual they described, a document written in the old form
merging unnoticed because the guard only saw dated files, is closed
instead of described: the undated names are now a closed set of the
twenty-seven changes recorded before the adoption, so a new undated
file fails whatever tool wrote it.

- Drop the machine-local Non-Goal and Risk from the proposal; extend
  R4 and D7 with the closed set
- Reword the deliver skill's note to be tool-agnostic
- Add Undated_docs_are_the_pre_adoption_set and LegacyStem, with the
  stem list mirroring the LegacyFlattenedDocs precedent
@josephjang
josephjang merged commit b81e869 into main Sep 13, 2026
1 check passed
@josephjang
josephjang deleted the docs/adopt-change-proposal branch September 13, 2026 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant