* chore: wire docs/agents config into AGENTS.md Agent skills section
Add the `## Agent skills` discovery block pointing the engineering
skills at the existing docs/agents/{issue-tracker,triage-labels,domain}.md
files (issue tracker, triage label mapping, single-context domain docs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(#214): make gsd-phase-researcher survive OpenCode write-tool truncation
OpenCode caps model output at OUTPUT_TOKEN_MAX=32000 and the thinking
budget shares that pool (upstream opencode#18108). A single oversized
`write` tool call for RESEARCH.md is truncated mid-payload, yielding
`JSON Parse error: Expected '}'`, which OpenCode misclassifies and then
doom-loops retrying identically. Short content writes fine; long
content fails 100% (reproducible, OpenCode 1.15.10).
Add a Step 6 write contract to agents/gsd-phase-researcher.md: keep the
single-Write default (no behavior change for Claude Code and other
runtimes that don't truncate), but on a truncation/invalid-tool failure
build the file incrementally via a sentinel-based Write -> Read -> Edit
sequence so no single tool-call payload is large enough to truncate;
never silently fall back to returning content (which truncates
identically). This is the upstream-recommended mitigation (write in
smaller chunks; use edit for follow-on writes).
Locked with a prompt-contract regression test mirroring the bug-222
write-contract pattern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore(#214): add changeset for OpenCode write-truncation fix
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// allow-test-rule: source-text-is-the-product
|
||||
'use strict';
|
||||
|
||||
const { test, describe } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
const RESEARCHER_PATH = path.join(REPO_ROOT, 'agents', 'gsd-phase-researcher.md');
|
||||
|
||||
function readResearcherPrompt() {
|
||||
return fs.readFileSync(RESEARCHER_PATH, 'utf8');
|
||||
}
|
||||
|
||||
describe('bug #214: phase researcher must survive OpenCode write-tool truncation', () => {
|
||||
test('Step 6 documents the large-file / truncation fallback write contract', () => {
|
||||
const prompt = readResearcherPrompt();
|
||||
|
||||
assert.match(
|
||||
prompt,
|
||||
/truncat/i,
|
||||
'Step 6 must name the truncation failure mode.'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/incrementa/i,
|
||||
'Step 6 must instruct incremental construction on large files.'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/<!-- gsd:write-continue -->/,
|
||||
'Step 6 must define the continuation sentinel for incremental writes.'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/do NOT retry the same oversized call/i,
|
||||
'Step 6 must forbid identical retry of the oversized write (doom-loop guard).'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/do NOT silently fall back to returning content/i,
|
||||
'Step 6 must forbid silent fallback to returning content.'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/`Read` the file, then `Edit`/i,
|
||||
'Step 6 must require Read before Edit (OpenCode edit requires a prior Read).'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/no trailing sentinel/i,
|
||||
'Step 6 must instruct removing the sentinel on the final section.'
|
||||
);
|
||||
assert.match(
|
||||
prompt,
|
||||
/write the whole file in a single `Write` call/i,
|
||||
'Step 6 must keep single-Write as the default path (no regression for non-truncating runtimes).'
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user