docs(meta): add the context glossary and the plumbing-contract ADR - #249
Conversation
Review call on #249: ADR numbers become unique across the whole repo rather than per directory, so meta/docs/adr/0001-... is renumbered to 0002 behind docs/adr/0001-.... This diverges from the /domain-modeling skill's ADR-FORMAT.md, which scans a single directory and would hand you a number that is already taken. docs/agents/domain.md is the durable place to say so -- the skill ships from a read-only plugin cache that npx skills update overwrites, and it is the file the skills are already pointed at. check_adr_numbers.py enforces uniqueness and the NNNN-kebab-slug.md filename shape. It takes check_go_work.py's profile -- CI job plus an on-save task, no pre-commit hook -- because it is the closest sibling: a tree walk over checked-in files with nothing to fix. The filename shape rides along because a malformed name has no number to compare, so silently skipping it would leave a hole in the very property being enforced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Update: ADR numbering is now global, and enforcedThe numbering question I flagged for review is resolved in The convention is documented where it survivesThis diverges from the The check
Wiring follows
Verified rather than assumed
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #249 +/- ##
==========================================
+ Coverage 83.60% 83.86% +0.25%
==========================================
Files 40 41 +1
Lines 2025 2076 +51
Branches 99 111 +12
==========================================
+ Hits 1693 1741 +48
- Misses 316 318 +2
- Partials 16 17 +1
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
Two artifacts the repo's documented structure called for but had never gained: meta/ is the first context with a CONTEXT.md, and the base image's contract is the first decision scoped to a single context rather than the repo. The ADR records what the code already did and the docs denied. The library reads host-git-common-path and host-timezone by name and links to /host-git-common; those are contract terms, so the README's claim that the stub 'does not constrain where the host keeps anything' was only half true. It constrains the names, not the sources. Syndic/.dotfiles is the evidence: presenting the same host state in a different shape let its copy diverge in kind rather than in detail. The glossary also disambiguates 'plumbing' from git's own plumbing/porcelain sense, which .git-plumbing/ maximises the collision with. The term stays -- it is apt in the ordinary sense and renaming it would reach the command, the env prefix, the function prefix, both repos' docs and an unadopted consumer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review call on #249: ADR numbers become unique across the whole repo rather than per directory, so meta/docs/adr/0001-... is renumbered to 0002 behind docs/adr/0001-.... This diverges from the /domain-modeling skill's ADR-FORMAT.md, which scans a single directory and would hand you a number that is already taken. docs/agents/domain.md is the durable place to say so -- the skill ships from a read-only plugin cache that npx skills update overwrites, and it is the file the skills are already pointed at. check_adr_numbers.py enforces uniqueness and the NNNN-kebab-slug.md filename shape. It takes check_go_work.py's profile -- CI job plus an on-save task, no pre-commit hook -- because it is the closest sibling: a tree walk over checked-in files with nothing to fix. The filename shape rides along because a malformed name has no number to compare, so silently skipping it would leave a hole in the very property being enforced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
23749a7 to
f690d07
Compare
Global numbering left no way to find the next number except scanning every docs/adr/ directory, which the convention documented but never told anyone how to do. --next prints the number alone, so it substitutes into a filename, and it answers while a collision exists -- that is precisely when it is needed. It is max+1 rather than count+1: a gap left by a deleted ADR stays unused, because handing the number out again would break every reference to the original. A duplicate now reports a free number to move to, so the failure carries its own fix. Both modes share one number parser, so the check and the suggestion cannot disagree about what counts as a number. No counter file. The numbers already live in the filenames; a second copy would be a derived file needing its own freshness check, and a merge conflict on every concurrent ADR PR. The race that usually justifies one is already closed here -- the ruleset requires up-to-date branches, so a second PR must rebase onto the first and then fails this check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Added:
|
Output of a design review of the devcontainer base image work. Two artifacts the repo's documented
structure called for but had never gained, plus the map entry that registers one of them.
meta/CONTEXT.md— the first context glossaryCONTEXT-MAP.mdhas listed both contexts as (CONTEXT.mdnot yet written) since it was created.This writes the first one. Nine terms across two clusters — the base image and repo health — kept
to a glossary, with no implementation detail.
The one worth calling out: "plumbing" collides with git's own vocabulary. git's
plumbing/porcelain split means low-level commands, and
.git-plumbing/pairs the two words in theway most likely to mislead. The term stays — it is apt in the ordinary sense, and renaming would
reach the
devcontainer-plumbingcommand, thePLUMBING_*env prefix, theplumbing_*functionprefix, the directory, both repos' docs, and a consumer that hasn't adopted yet. Disambiguating it
in the glossary is the cheap fix.
Also opinionated where the code isn't:
meta/scripts/README.mdcalls these things both "gates" and"guards". The glossary picks check, since that is what the filenames and the on-save labels
already say, and records that whether one blocks is a property of where it runs.
meta/docs/adr/0001-…— the plumbing contractThe first decision scoped to a single context rather than the repo, so it exercises the
<context>/docs/adr/pathdocs/agents/domain.mddocuments.It records something the code already did and the docs denied.
plumbing_apply_git_commonreads
$PLUMBING_DIR/host-git-common-pathby name and links it to/host-git-common;plumbing_apply_allreadshost-timezoneby name. Those are contract terms whether or not anyonewrote them down — so the base image README's claim that the host stub "does not constrain where the
host keeps anything" was only half true. It constrains the names; it leaves the sources free,
which is what the symlink indirection is for.
Syndic/.dotfilesis the evidence for why the distinction matters. It presentsknown_hostsandallowed_signersas snapshot files where this repo presents them as bind-mounted symlinks, and itscopy of the plumbing consequently diverged in kind rather than in detail. Under this ADR, adoption
is conformance: that shape is an artefact of age, not a variant to support.
Numbering note for review
This is
meta/docs/adr/0001-…whiledocs/adr/0001-…(the Go-pure/Python-impure policy) alreadyexists.
ADR-FORMAT.mdnumbers per directory, so two0001s in different scopes is what thedocumented structure produces. Flagging it because it is the kind of thing that is cheap to change
now and annoying later — say the word if you would rather ADR numbers be globally unique.
What this does not do
The extraction itself — moving the four
post-start.shsteps and the timezone parsing into theshared library, and renaming
lib.shtoplumbing.sh— is a separate PR. Filed alongside thisreview: #247 (the
ssh -Gcall on everyup) and #248 (how consumers share what the image cannotcarry).
Validation
bazel test //...23/23,pre-commitclean.🤖 Generated with Claude Code