story-039: Every configurable value is proven configurable - #37
Merged
Conversation
Implemented by the l5 harness story workflow.
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.
Thirteen keys are read out of
.harness/config.yamland nothing established that any of them was obeyed. A value moved into configuration and then hardcoded to the same literal behaves identically in this repository, so the suite could not tell the two apart.What changed
The key set is declared.
schemas/harness-config.schema.json, in the manifest, withdeclared_config_keysas its only reader. Until nowbase_branchandclean_clone_pythonwere discoverable only by grepping forconfig.get(.Every key has a proof that sets it to a value the harness would never pick.
That is the whole mechanism. A fixture that set
branch_prefix: story/would prove nothing, and the reason today's coupling was invisible is that the hardcoded literal and the configured value agreed.Coverage is set equality in both directions, with a control for each:
The fourth was not asked for and is the one that closes the obvious hole: a proof naming a function that does not exist would otherwise satisfy the completeness check vacuously.
It found a tie on its first run
Varying both interpreter keys at once shows the clean-clone path building
/xyzzy/bin/interpreter --all: the configured test command's leading word is discarded and the configured interpreter substituted for it, so the check does not run the command the target configured. That substitution is only correct if the leading word is known to be a Python interpreter — which is the assumptionthe-interpreter-is-not-assumed-to-be-pythonexists to remove.Recorded rather than fixed, as the request asked.
test_test_command_is_the_command_the_clean_clone_path_buildsasserts what is true today, and the finding was written into that request, correcting a "not in scope" line that had assumedtest_commandreached the check intact.Verification
2196 passed, 83 written; verification passed on the first iteration, no retries; clean-clone green with the story committedOne caveat the verifier logged
The mutation control for
allowed_toolsrewrites both call sites at once, so it demonstrates red when both stop reading the key rather than when either does alone. The verifier checked whether that weakens the proof and concluded it does not: the proof asserts the runner argument and the rendered prompt separately, so a single hardcoded site still fails exactly one of the two assertions.🤖 Generated with Claude Code