docs: audit docs, comments, and the validate gate#52
Merged
Conversation
Sweep of architecture/, README.md, and in-code comments against actual behavior. Every finding reproduced against the code. Headline: decisions/2026-07-10-reject-parse-dont-validate.md rests on the premise that validate() owns every shape emit reads, and that premise is false -- environment, env_file, and volumes are structural keys with no shape validator, so emit walks them raw and crashes (AttributeError, TypeError, and character-wise destructuring of a string volumes). Plus a raw ValueError on --artifact with no colon. Also: --add-host seeds hosts document-wide but layers extra_hosts closure-scoped and conflict-checks across the seam, so a service that never runs can veto a valid config. Doc drift: a dead _MAP_FLAGS citation, glossary/subset contradicting each other on KeySpec's arity, 19 supported keys missing from the supported list. Compaction: secrets/configs are 123 lines of near-verbatim twins; supported-subset.md can go 537 -> ~300 with nothing lost. Spawns four changes (two Full, two Lightweight).
This was referenced Jul 14, 2026
This was referenced Jul 14, 2026
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.
Sweep of
architecture/,README.md, and in-code comments against actual behavior, hunting inconsistencies, redundancies, bugs, and compaction candidates. Every finding was reproduced or grepped against the code, not read off the prose.Full findings:
planning/audits/2026-07-13-docs-and-gate-audit.md.Headline
decisions/2026-07-10-reject-parse-dont-validate.mdargues against a typed model on the grounds thatvalidate()already owns every shapeemitreads, so a malformed document "fails withUnsupportedComposeError, not a raw crash." That premise is false.environment,env_file, andvolumesare structural keys with noKeySpecand no hand-written validator, soemitwalks them raw:environment: "FOO=bar"AttributeError: 'str' object has no attribute 'items'env_file: 5TypeError: 'int' object is not iterablevolumes: "/data:/data"anonymous volume 'd' must be an absolute path--artifact nocolonValueError: not enough values to unpackout ofemit.py:209volumesalso has a silent-corruption face:volumes: "/"is accepted and emits-v "/". Restoring the invariant makes the decision true again rather than reopening it, and needs no structural-key registry, sodecisions/2026-07-12also stands.Also
--add-hostscope seam. Hosts are seeded document-wide (graph.hostnames) butextra_hostsis layered closure-scoped, and the two are conflict-checked against each other, so a service that never runs can veto a valid config. Every other emit-path aggregate (dns, sysctls, stores) is closure-scoped._MAP_FLAGScitation;glossary.mdandsupported-subset.mdcontradicting each other onKeySpec's arity (triple vs pair); 19 supported keys missing from the supported list; the README subset paragraph predating extends, secrets, configs, and resource limits.supported-subset.mdgoes 537 → ~300 lines with nothing lost.Spawns four changes (two Full, two Lightweight). This PR is planning-only: no code changes.
🤖 Generated with Claude Code