feat(tests): add the context-file hygiene test that §7 promised and never had - #87
Merged
Conversation
…ever had
docs/agentic/contextualization.md §7 states that
templates/service/tests/test_context_files_hygiene.py "enforces at every
PR" four properties of the agentic context files. It was cited as the
enforcing control and did not exist, so those properties were documented
and unchecked — a contributor could commit a real AWS key inside
company_context.example.yaml and nothing would object.
32 cases across the seven *.example.yaml files and their three schemas:
- no *_context.local*.yaml tracked, and the pattern is actually
gitignored rather than merely untracked today
- every example validates against the schema that governs it
- no real-looking secret in the raw text (AKIA / AIza keys, PEM blocks,
bearer tokens, credential-laden URLs)
- placeholders use the {PlaceholderName} form
Two places where §7 is looser than code can be, resolved explicitly in the
docstring rather than silently:
§7 names context.schema.json, but adopter_context and service_spec carry
their own schemas. Each example is validated against the schema that
governs it, discovered by filename — what §7 means rather than what it
says.
Properties 2 and 4 contradict each other on placeholder-bearing fields:
service_spec declares service_slug with pattern ^[a-z][a-z0-9_]*$ while
the example sets {service_slug}. An example file is by construction not
filled in, so it cannot satisfy value-level constraints on the fields it
deliberately leaves blank. The resolution: structure is enforced,
placeholder values are exempt — a schema error is tolerated only when the
failing instance is exactly a {Placeholder} string, and anything else
fails.
Secrets are scanned in raw text because a key leaked in a comment is still
leaked; placeholder style is checked against parsed values only, because
comment prose naming a file pattern (<service_slug>_context.local.yaml) is
documentation, not an unreplaced value.
The secret patterns are themselves pinned by a test. A scanner that
silently stops matching passes everything, which is the failure mode this
whole line of work has been about.
Verified negatively: planting AKIAIOSFODNN7EXAMPLE in an example fails the
secret check with a line number, and a <TeamName> value fails the
placeholder check naming the offending key.
Baseline: 5 entries -> 4.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
DuqueOM
force-pushed
the
fix/context-hygiene-test
branch
from
September 4, 2026 20:47
3df445a to
f867989
Compare
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.
Second of three PRs closing the residue from #84.
The gap
docs/agentic/contextualization.md§7 says, as settled policy:It was cited as the enforcing control and did not exist. The properties were documented and unchecked — a contributor could commit a real AWS key inside
company_context.example.yamland nothing in the repo would object.What now runs
32 cases across the seven
*.example.yamlfiles and their three schemas:*_context.local*.yamltracked by gitgit ls-filesscan, plus a check that the pattern is actually gitignored — being untracked today is luck, being ignored is the control*.example.yamlparse against the schema{PlaceholderName}The test discovers files rather than hard-coding a layout, so it runs both here and inside a scaffolded service.
Two places where §7 is looser than code can be
Resolved explicitly in the test docstring rather than silently:
Which schema. §7 names
context.schema.json, butadopter_contextandservice_speccarry their own. Each example is validated against the schema that governs it, discovered by filename — what §7 means rather than what it says.Properties 2 and 4 contradict each other.
service_spec.schema.jsondeclaresservice_slugwithpattern: ^[a-z][a-z0-9_]*$;service_spec.example.yamlsets it to{service_slug}. Correct under property 4, invalid under property 2. An example file is by construction not filled in, so it cannot satisfy value-level constraints on fields it deliberately leaves blank.The resolution taken: structure is enforced, placeholder values are exempt. Required keys, types and every non-placeholder value must satisfy the schema; a validation error is tolerated only when the failing instance is exactly a
{Placeholder}string. Anything else fails. This is a judgement call §7 did not make, so it is written down where the next reader will find it.Why the two scopes differ: secrets are scanned in raw text because a key leaked in a comment is still leaked. Placeholder style is checked against parsed values only, because comment prose naming a file pattern —
<service_slug>_context.local.yaml— is documentation, not an unreplaced value. Checking placeholders in raw text would have failed on three legitimate comments.The scanner is itself pinned
test_secret_patterns_actually_match_known_shapesasserts each of the five patterns still matches its own sample. A scanner that silently stops matching passes everything — which is the failure mode this entire line of work has been about.Verified negatively
AKIAIOSFODNN7EXAMPLEin an exampleAWS access key id at line 64<TeamName>valueBaseline: 5 entries → 4.
Evidence — Schema / Contract Test
templates/service/tests/test_context_files_hygiene.py— this PR is the contract test; it pins the four propertiesdocs/agentic/contextualization.md§7 declares, plus a self-check on the secret patterns.Evidence — Real Execution Output
Evidence — CI Run Link
See the checks on this PR.
🤖 Generated with Claude Code