Skip to content

feat(tests): add the context-file hygiene test that §7 promised and never had - #87

Merged
DuqueOM merged 1 commit into
mainfrom
fix/context-hygiene-test
Sep 4, 2026
Merged

feat(tests): add the context-file hygiene test that §7 promised and never had#87
DuqueOM merged 1 commit into
mainfrom
fix/context-hygiene-test

Conversation

@DuqueOM

@DuqueOM DuqueOM commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Second of three PRs closing the residue from #84.

The gap

docs/agentic/contextualization.md §7 says, as settled policy:

The test templates/service/tests/test_context_files_hygiene.py enforces at every PR: [four properties]

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.yaml and nothing in the repo would object.

What now runs

32 cases across the seven *.example.yaml files and their three schemas:

Property (verbatim from §7) How it is enforced
No *_context.local*.yaml tracked by git git ls-files scan, plus a check that the pattern is actually gitignored — being untracked today is luck, being ignored is the control
*.example.yaml parse against the schema each example validated against the schema that governs it
No real-looking secret patterns AKIA / AIza keys, PEM blocks, bearer tokens, credential-laden URLs — scanned in raw text
Placeholders use {PlaceholderName} checked against parsed values

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, but adopter_context and service_spec carry 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.json declares service_slug with pattern: ^[a-z][a-z0-9_]*$; service_spec.example.yaml sets 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_shapes asserts 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

Test Result
Plant AKIAIOSFODNN7EXAMPLE in an example ✅ fails, AWS access key id at line 64
Plant a <TeamName> value ✅ fails, names the offending key
Clean tree ✅ 32 passed

Baseline: 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 properties docs/agentic/contextualization.md §7 declares, plus a self-check on the secret patterns.

Evidence — Real Execution Output

$ python3 -m pytest templates/service/tests/test_context_files_hygiene.py -q
32 passed, 1 warning in 1.03s

$ # with AKIAIOSFODNN7EXAMPLE planted in company_context.example.yaml
E   AssertionError: templates/config/company_context.example.yaml looks like it
    carries a real secret: [%27AWS access key id at line 64%27]

$ # with a <TeamName> value planted
E   AssertionError: templates/config/company_context.example.yaml uses a placeholder
    style other than {PlaceholderName}, which the validator cannot detect as
    unreplaced: ["owner_placeholder = %27<TeamName>%27"]

Evidence — CI Run Link

See the checks on this PR.

🤖 Generated with Claude Code

…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
DuqueOM force-pushed the fix/context-hygiene-test branch from 3df445a to f867989 Compare September 4, 2026 20:47
@DuqueOM
DuqueOM merged commit 930587a into main Sep 4, 2026
25 checks passed
@DuqueOM
DuqueOM deleted the fix/context-hygiene-test branch September 4, 2026 20:51
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