iceboundrock / iceboundrock/AutoForge
Redact `_block` reasons before they are persisted, like the agent-message path
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- Avg merge
- 8h 56m
- Merged PRs (30d)
- 40
Description
Problem
ControllerEngine._block (src/autoforge/engine.py, _block) writes its reason to state.block_reason as given. Several of its ~40 call sites embed external text in that reason, most often a GitHubError message (f"... cannot be read: {exc}"), which is gh stderr. The two agent-message paths that also set block_reason (engine.py around lines 1587 and 1772) pass the text through redact() first, with the comment "same redaction boundary as the run log", so persistence is currently redacted for agent text but not for controller-composed reasons.
Reproduced in tests/test_cli.py::test_run_terminal_line_redacts_a_block_reason_the_engine_persisted_raw (added on PR #97): with FakeGitHub.get_pr_error = GitHubError("HTTP 401: Bad credentials (Authorization: Bearer ghp_...)") and a state referencing a PR, resume blocks at ANALYZE_EXECUTE entry and state.json holds the token in the clear. The CLI output (_finish terminal line, status, status --json) is redacted, so nothing is printed, but the file on disk is not.
Why not in PR #97
PR #97 closes #6 / #67, whose scope is what the CLI prints from state; it deliberately never rewrites state.json, and its docs paragraph states that persisted state is not a redaction boundary of its own. Redacting at the persistence side is a separate, engine-level change with its own tests, and state.json is local, untracked, per-operator runtime state, so it is not a leak in the sense of #6. It is still inconsistent with the two agent-message writers and with docs/agent-guides/secrets-and-logging.md.
Recommended direction
Redact once in _block (state.block_reason = redact(reason), and the StepOutcome.message it returns), rather than at each call site, so a new call site is covered by construction. Consider whether GitHubClient should redact error text at construction instead, which would also cover VerificationError paths that quote gh output and reach verification_failures. Keep the CLI output-side redaction from PR #97 as defense in depth; do not remove it.
Relevant files
src/autoforge/engine.py:_block,_loop_block_reason, the tworedact(...)agent-message writerssrc/autoforge/github.py:GitHubErrorconstruction sitesdocs/agent-guides/secrets-and-logging.mdtests/test_cli.py::test_run_terminal_line_redacts_a_block_reason_the_engine_persisted_raw(asserts the current raw persistence; flip it when this lands)
Acceptance criteria
- A
_blockreason that embeds aGitHubErrorcarrying a baseline-pattern secret is persisted redacted instate.jsonand reported redacted in theStepOutcomeand run log. verification_failuresentries that quoteghoutput are redacted before persistence.- The CLI output-side redaction from PR #97 remains in place and tested.
docs/agent-guides/secrets-and-logging.mdsays which writers redact before persistence.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with _block in src/autoforge/engine.py, then inspect the agent-message redaction paths and _loop_block_reason. Run tests/test_cli.py::test_run_terminal_line_redacts_a_block_reason_the_engine_persisted_raw, and review GitHubError construction in src/autoforge/github.py. Done means controller and verification-failure reasons are redacted in state.json, StepOutcome, and logs, while CLI tests remain passing and the secrets documentation names the persistence writers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100