fix(#571): forbid Write in doc-writer fix mode; add workflow truncation guard
* fix(#571): forbid Write in doc-writer fix mode; add workflow truncation guard gsd-doc-writer in fix mode only had Write in its tools list, so when correcting a specific failing claim it would re-emit the whole file with only the lines it had in context — truncating untracked docs with no git recovery path. Fix 1 (root cause): add Edit to the agent tools frontmatter and rewrite fix_mode instructions to mandate Edit for surgical corrections and explicitly forbid Write on existing files. Also reinforced in critical_rules. Fix 2 (safety net): add a post-fix line-count guard in the fix_loop step of docs-update.md. If the file shrank by >90% after a fix agent runs, the orchestrator restores the file from the existing_content it captured before dispatch and logs a WARNING. This makes the previously unrecoverable case recoverable. Regression test: tests/bug-571-doc-writer-fix-mode-edit-only.test.cjs covers both the agent contract and the workflow guard. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: add changeset for fix #571 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#571): address codex adversarial review findings - Quote {doc_path} in shell snippets to handle paths with spaces (#SECURITY) - Clarify corrupted doc re-verification vs re-fix distinction (#CORRECTNESS) - Strengthen regression tests with structural ordering assertions (#REGRESSION) - Move docs-update.md from global ALLOWLIST to SIZE_ONLY_WORKFLOWS so injection scanning still runs while only the 50K size finding is exempt (#SECURITY) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -902,7 +902,10 @@ Correct flagged inaccuracies by re-sending failing docs to the doc-writer in fix
|
||||
**For each iteration (while iteration < MAX_FIX_ITERATIONS and there are docs with failures):**
|
||||
|
||||
1. For each doc with `claims_failed > 0` in the latest verification_results:
|
||||
a. Read the current file content from disk.
|
||||
a. Read the current file content from disk. Record the pre-fix line count:
|
||||
```bash
|
||||
PRE_FIX_LINES=$(wc -l < "{doc_path}" 2>/dev/null || echo 0)
|
||||
```
|
||||
b. Spawn `gsd-doc-writer` agent (or invoke sequentially) with a fix assignment:
|
||||
```xml
|
||||
<doc_assignment>
|
||||
@@ -919,6 +922,15 @@ Correct flagged inaccuracies by re-sending failing docs to the doc-writer in fix
|
||||
</doc_assignment>
|
||||
```
|
||||
c. One agent spawn per doc with failures. Do not batch multiple docs into one spawn.
|
||||
d. **Post-fix truncation guard:** After the fix agent completes, check for file corruption:
|
||||
```bash
|
||||
POST_FIX_LINES=$(wc -l < "{doc_path}" 2>/dev/null || echo 0)
|
||||
```
|
||||
If `POST_FIX_LINES` is less than 10% of `PRE_FIX_LINES` (i.e. the file shrank by more than 90%), the fix agent corrupted the file via a full-file Write. Restore it immediately:
|
||||
- Write the `existing_content` captured in step 1a back to `"{doc_path}"` using the Write tool
|
||||
- Log: `WARNING: Fix agent corrupted {doc_path} ({POST_FIX_LINES} lines after fix, was {PRE_FIX_LINES}). Restored from pre-fix content. Failures for this doc require manual correction.`
|
||||
- Mark this doc as `"fix-corrupted"` in the manifest; it will appear in remaining failures at the end
|
||||
- Do NOT attempt to fix this doc again this iteration. It is still included in the step 2 re-verification (so its failures are counted) but no further fix agent will be dispatched for it in this iteration.
|
||||
|
||||
2. After all fix agents complete, re-verify ALL docs (not just the ones that were fixed):
|
||||
- Re-run the same verification process as verify_docs step.
|
||||
|
||||
Reference in New Issue
Block a user