iceboundrock / iceboundrock/AutoForge

Cap the persisted block_reason (LOCAL 'unresolved' rationales are concatenated, worst case 50 x 6000 characters)

Open
#88 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
0
Forks
0
Avg merge
8h 56m
Merged PRs (30d)
40

Description

Severity: LOW · Area: state / operator output

Follow-up recorded from the #86 PR body ("Out of scope / observations") and the post-merge review on #86 (https://github.com/iceboundrock/AutoForge/pull/86#issuecomment-5706882455, "Observations"). Both noted it; neither decided it. This issue records the options so the decision is not lost.

Current state

In LOCAL mode, when a FIX round leaves findings unresolved, _apply_local_fix (src/autoforge/engine.py, around the unresolved = [...] block) builds the block_reason by concatenating "<finding_id>: <redacted rationale>" for every unresolved finding. Since #77 (PR #86) each rationale is bounded at the parser (MAX_FIX_RATIONALE_CHARS = 2000) and the count at MAX_RESOLUTIONS_PER_FIX (50); after redaction a rationale can grow to MAX_REQUIRED_RESOLUTION_CHARS (6000). So the concatenation is bounded, but only at roughly 50 x 6000 = 300 000 characters, plus the fixed prefix.

state.block_reason itself has no bound (src/autoforge/state.py). It is persisted in state.json on every save, re-read on every load, and printed by autoforge status.

Other block_reason sources are already small: the UPDATE_EPIC re-selection reason now carries a URL of at most MAX_URL_CHARS (#87), the merge-gate and replan block reasons are controller text.

Why it might deserve a cap

  • status output of up to ~300 kB for one block is unreadable for the operator it is meant for.
  • Every later state load and atomic rewrite carries it until the run is unblocked.
  • It is the one place where agent text is persisted without its own bound; every other agent-derived field has one.

Why it might not

  • It is already bounded, by construction, through the parser bounds; the worst case needs an agent that emits 50 unresolved resolutions each at the rationale bound.
  • The text is redacted before it is persisted.
  • block_reason is operator diagnostics, not work the next phase acts on, so the "rejection, never clipping" policy for findings does not force a rejection here.

Options

  1. Cap at the LOCAL unresolved site: keep the first N rationales (or the first M characters of the joined text) and end with a marker naming how many were omitted. The full rationales stay available in last_fix_resolutions, which is already persisted whole and bounded, so nothing is lost; the block reason becomes a pointer plus a sample.
  2. Cap at the state layer: block_reason clipped with a truncation marker wherever it is set (a single helper), so no future producer can regrow it. Clipping is acceptable here for the reason above (diagnostics, not work), unlike findings.
  3. No cap: document the worst case and leave it.

Suggested direction: option 1 or 2, as a small, separate change with a test that a LOCAL FIX with 50 unresolved resolutions at the bound produces a block_reason under the chosen cap and a state file that still loads. Not urgent.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at _apply_local_fix in src/autoforge/engine.py and inspect block_reason persistence in src/autoforge/state.py, along with the autoforge status output. Choose and confirm the capping approach, then add the suggested LOCAL FIX test with 50 unresolved resolutions at the bound and verify the resulting state file still loads.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, cli
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.