Skip to content

story-043: An undeclared config key is refused - #41

Merged
jerodw merged 2 commits into
mainfrom
story/story-043
Aug 16, 2026
Merged

story-043: An undeclared config key is refused#41
jerodw merged 2 commits into
mainfrom
story/story-043

Conversation

@jerodw

@jerodw jerodw commented Aug 16, 2026

Copy link
Copy Markdown
Owner

The harness declared the thirteen keys it reads and never checked a config against that declaration. declared_config_keys' own docstring said so: "no unknown key is refused". So a mistyped key ran, silently used the default, and the developer found out from the behaviour.

It also refused exactly one key by name — clean_clone_python, retired by story-041 — which meant a language name had to live in orchestration/ in order to be rejected.

What changed

undeclared_config_problems refuses any key the schema does not declare, at the same pre-flight point the retired-key refusal used: decidable the moment the config loads, so no run directory, no state.json, no log, no branch and no agent invoked.

RETIRED_CONFIG_KEYS, retired_config_problems and _refuse_retired_config_keys are deleted. A config still carrying clean_clone_python is refused as one more undeclared key, without the harness naming it.

orchestration/ now holds no target-stack tie. Running harness_source.scan() reports two findings there, both on PERMANENT_MENTIONS and both statements about this harness's own implementation language rather than about any target.

It found a key nobody read

Enabling the refusal exposed project, which every config carried and nothing ever read. It could not simply be declared: story-039's coverage asserts set equality between the declared keys and the keys the harness actually reads, so declaring a key nothing reads fails that check. It is removed instead — from .harness/config.yaml, from what l5-init writes, and from the fixture configs across roughly twenty test modules, which is the one-line deletion repeated through the diff.

That is the risk the request named — "a harness that refuses its own config is a bad afternoon" — found and resolved rather than discovered in a run.

The retry is worth reading

Verification failed once and routed to the tester on validation. The finding was a self-reference the acceptance criteria created: the criterion says the three deleted names must not appear anywhere outside .harness/runs/, and the tester's own module spelled all three as string literals in order to assert their absence. The test making the claim was an instance of the thing it denied.

Resolved by composing them:

_STEM = "retired" + "_config_"
DELETED_NAMES = ((_STEM + "keys").upper(), _STEM + "problems", "_refuse_" + _STEM + "keys")

with SURVIVING_NAME = "undeclared_config_problems" as the control, so the same scan over the same files is known to be able to see a name at all — without which the absence would be indistinguishable from a search that had stopped matching.

Verification

  • 2316 passed, 44 written; verification passed on the second iteration; one retry, routed to validation; clean-clone green with the story committed
  • TEMPORARY_TIES is unchanged at 3 — those are the-test-location-comes-from-configuration's, and emptying that list closes the audit

🤖 Generated with Claude Code

jerodw and others added 2 commits August 15, 2026 17:54
Implemented by the l5 harness story workflow.
The documenter wrote 'it replaced tests/test_retired_config_keys.py', which
this story deletes. story-038's check requires every tests/ path the document
names to exist, and it does not, so the suite went red on main's CI.

The sentence was true and the rule is right: a reader following a path in the
document should find something. Reworded to keep the history without the
dangling path.

Nothing in the run could have caught this. The documenter runs after the
verifier and after the clean-clone check, so its output is the only stage
output no check ever sees. Filed as
.harness/requests/the-clean-clone-check-runs-after-the-documenter.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jerodw
jerodw merged commit 85a9dc0 into main Aug 16, 2026
3 checks passed
@jerodw
jerodw deleted the story/story-043 branch August 16, 2026 00:30
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