Repository navigation
fix(preflight): break retry loops and give usable hints (#340, #334, #347, #305, #304) - #356
Merged
Merged
Conversation
The runner's except-branch after exec(MODULE_CODE) set only result["error"], dropping everything the script reported before the exception. Copy messages and summary on that path too, mirroring run_scan's error path. closes #347 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The write branch of the zero-discovery gate inlined get_object_api docs for the detected entities and told the model to resubmit, but never recorded them, so the identical resubmit took the same branch again. Record the inlined entities the way get_object_api does (methods and properties into discovered_apis, the entity into validated_apis) and make the copy name them. The read-only redirect grants the entities it inlines on the auto-discovery set only (write isolation, #47). closes #340 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Detect a byte-identical resubmit of just-rejected code (sha256 snapshot per submission) and attach _assistance on the first repeat, for every gate; the 5-in-a-row detector never fired on the 2-4 long streaks. - operations.jsonl assistance_triggered now previews what the response carries instead of being hardcoded False. - Lead the rejection with a mechanical bare-snippet auto_fixed_code (def Main line named, body dedented, lone scaffold piece removed) when safe; otherwise say why and keep skip_module_check first. - With a user_intent, point at the closest recipes via rank_recipes. closes #334 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Read the installed flexicon statically (find_spec + ast, never imported; index fallback judging only Operations-shaped names; fail open) and reject 'from flexicon import X' / 'import flexicon.X' when X does not exist, with did-you-mean on the Operations stem (WfiWordformOperations -> WordformOperations) and access_path for FLExProject accessors imported as classes. A runtime flexicon ImportError gets the same candidates (UnknownImportError). New error code: detail model, golden, TOOL-CONTRACT row, count 47 -> 48; validate_only and the eval preflight runner carry the gate too. closes #305 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ccessor - _accessor_to_ops_map resolves documented import aliases to the indexed class (Wordforms -> WfiWordformOperations -> WordformOperations), closing the gap PR #342 called out: project.Wordforms typos are now checked. check_doc_snippets.py uses the same resolver. - invalid_api_chain always flags project.<Name>Operations: exact index mapping -> did_you_mean the accessor at ratio 1.0, else nearest accessors below the auto-fix threshold, still blocking. - missing_imports no longer suggests importing a name only used as project.<Name>. - search_by_capability / get_object_api derive access_path when the index lacks it; the generator records the real class behind an aliased facade import. closes #304 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Byte-identical code can legitimately pass on resubmit: #340 records the inlined discovery, and skip_module_check lifts partial_module_structure. The 'same answer' message was then false. Fire only when the new error code equals the previous rejection's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Inlining Main's body runs it where def Main stood, before the rest of the module loads. Decline auto_fixed_code when the body reads a name bound only after Main (NameError, possibly after earlier writes), reads a scaffold name the fix deletes (docs), or holds a multi-line string the dedent would rewrite. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings in #353 (recipe surfacing, #335) and #354 (write-gate fixes). Conflicts resolved keeping both sides: - execution.py _attach_assistance_if_loop: #334's record_failure_and_detect (identical-resubmit detection) plus #335's closest-recipe pointer. - session.py: #334 identical-resubmit fields/methods plus #335's intent_failure_streak; reset_op_signals clears both. - CHANGELOG.md: both sets of Unreleased entries. Dropped the branch's own #334 _closest_recipes_step: #335's _closest_recipes_for_failure already covers partial_module_structure (and skips the recipe the code came from), so a reject got two recipe pointers. The #334 test now asserts exactly one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
MattGyverLee
added a commit
that referenced
this pull request
Oct 2, 2026
Brings in #354 (write-gate fail-opens), #353 (surface recipes), #355 (docs), #356 (preflight retry loops). Conflict resolution keeps both sides: unknown_import (#305) and requires_exclusive_access sit side by side and the error-code count moves to 49 everywhere (response_models, both count tests, TOOL-CONTRACT, CHANGELOG). execution.py keeps main's #334 assistance-log ordering with the gate's requires_exclusive_access key. test_issue55 ladder test stubs the exclusive-access detector so it still exercises Rung 3 (gate covered in test_exclusive_access_gate.py). Full offline suite: 5273 passed, 4 skipped.
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.
Fixes five preflight/recovery problems that sent models (especially weaker ones) into retry loops or left them without a usable hint.
Closes #340
Closes #334
Closes #347
Closes #305
Closes #304
Changes
api_discovery_requiredloop. When the gate inlinesget_object_apidocs, the inlined entities are now recorded as discovered, so the "resubmit" hint is true and an identical resubmit passes. The read-only redirect only grants them on the auto-discovery set (write isolation, Discover-and-run: execute read-only code with inline discovery instead of rejecting #47).partial_module_structureretry loops._assistanceon the first repeat, for every gate. It fires only when the answer would repeat, so a resubmit that now legitimately passes (bug: api_discovery_required inline discovery says 'resubmit' but identical resubmit is rejected again (loop) #340,skip_module_check) isn't mislabeled.operations.jsonlassistance_triggerednow reflects what the response carries; it was hardcodedFalse.auto_fixed_code, naming thedef Mainline removed. It is declined, withauto_fix_unavailable_reason, when inlining would change when names bind, delete a scaffold name the body reads, or rewrite a multi-line string.messagesandsummaryalongsideerror, asrun_scanalready did.from flexicon import Xnames (and flexicon.Lexicon) with did-you-mean instead of raw ImportError #305 -- invented flexicon imports.unknown_importrejectsfrom flexicon import X/import flexicon.Xwhen X doesn't exist, with did-you-mean suggestions (WfiWordformOperations->WordformOperations,flexicon.Lexicon->flexicon.code.Lexicon) and anaccess_pathfor accessors imported as classes.ImportErrorgets the same candidates.tool-responses/1.x. The code count goes from 47 to 48, with a detail model, golden, TOOL-CONTRACT row and eval case.project.<X>Operationsaccessors: missing_imports gives circular import advice and invalid_api_chain misses sub-threshold names; map Operations suffix to facade accessor, emit access_path in search #304 -- guessedproject.<X>Operations.invalid_api_chainalways flagsproject.<Name>Operationsand maps it to the facade accessor (WordformOperations->project.Wordforms).missing_importsno longer suggests importing a name that is only used asproject.<Name>.project.Wordforms/WfiWordformOperationsgap left by fix(preflight,index): #306 follow-ups -- real Operations class in chain gate, delegated/transaction writes marked mutating, stale gate counts #342.search_by_capabilityandget_object_apideriveaccess_pathwhen the index lacks it.Merge with main
Merged
origin/main(#353 recipes, #354 write gate). Conflicts were inexecution.py(_attach_assistance_if_loop),session.pyandCHANGELOG.md; both sides were kept. The branch's own #334 recipe helper was dropped in favor of #335's_closest_recipes_for_failure, which already coverspartial_module_structureand leaves out the recipe the code came from. Before that, a reject carried two recipe pointers; a test now asserts one.Pattern audit
project.<X>Operationsaccessors: missing_imports gives circular import advice and invalid_api_chain misses sub-threshold names; map Operations suffix to facade accessor, emit access_path in search #304/[WM] Preflight-checkfrom flexicon import Xnames (and flexicon.Lexicon) with did-you-mean instead of raw ImportError #305: other accessor and import resolution sites.scripts/check_doc_snippets.pynow uses the same alias resolver as the chain gate.run_scan's error path already copied messages; no other runner template drops them.Tests
-m "not requires_flex"): 5090 passed, 4 skipped.scripts/validate_integrity.py serverclean; pre-commit clean.Live verification
None. These are offline preflight and response-shape changes; no FLEx project was opened.
Merge interactions
#343 (exclusive-access gate, draft) also adds an error code and edits
execution.py. Whichever lands second needs the code count (48 here) and goldens reconciled.🤖 Generated with Claude Code