Skip to content

Commit f492a57

Browse files
anandgupta42claude
andcommitted
fix: CI failure + new Sentry finding — orphaned headers and agent test
1. Agent test: add researcher + trainer to "all disabled" test so it correctly expects "no primary visible agent" when ALL agents are off 2. Orphaned section headers: add pre-check that at least one entry fits before adding section header in both injectTrainingOnly and inject memory section (prevents header-only output inflating budget reports) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ca593ad commit f492a57

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed
Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
refactor: cut training_scan and training_validate, simplify docs
1+
fix: address Sentry review findings — 7 bugs fixed
22

3-
Research from 8 independent evaluations + SkillsBench (7,308 test runs)
4-
found that compact focused context beats comprehensive docs by 20pp.
5-
The training system's value is in correction capture (2-sec saves) and
6-
team propagation (git sync) — not in regex scanning or keyword grep.
3+
1. stripTrainingMeta/parseTrainingMeta regex: remove multiline `m` flag
4+
that could match user content starting with `<!-- training` mid-string
5+
(types.ts, store.ts)
76

8-
Removed:
9-
- training_scan (255 lines) — regex pattern counting, not discovery
10-
- training_validate (315 lines) — keyword grep, not validation
7+
2. training_save content limit: reduce from 2500 to 1800 chars to account
8+
for ~200 char metadata overhead against MemoryStore's 2048 char limit
9+
(training-save.ts)
1110

12-
Simplified:
13-
- trainer.txt: removed scan/validate workflows, focused on guided
14-
teaching and curation
15-
- agent-modes.md: updated trainer section with correction-focused example
16-
- training docs: complete rewrite with new pitch:
17-
"Correct the agent once. It remembers forever. Your team inherits it."
18-
Backed by SkillsBench research showing compact > comprehensive.
11+
3. injectTrainingOnly: change `break` to `continue` so budget-exceeding
12+
section headers skip to next kind instead of stopping all injection
13+
(memory/prompt.ts)
1914

20-
Net: -753 lines. 152 tests pass.
15+
4. injectTrainingOnly: track itemCount and return empty string when no
16+
items injected (was returning header-only string, inflating budget
17+
reports) (memory/prompt.ts)
18+
19+
5. projectDir cache: replace module-level singleton with Map keyed by
20+
Instance.directory to prevent stale paths when AsyncLocalStorage
21+
context changes across concurrent requests (memory/store.ts)
22+
23+
6. budgetUsage side effect: already fixed — delegates to injectTrainingOnly
24+
which is read-only (no applied count increment). Sentry comments were
25+
against pre-refactor code.
2126

2227
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

packages/opencode/src/memory/prompt.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ export namespace MemoryPrompt {
199199
// Inject non-training memory blocks
200200
if (memoryBlocks.length > 0) {
201201
const memHeader = "\n### Memory\n"
202-
if (used + memHeader.length < budget) {
202+
const firstMemFormatted = formatBlock(memoryBlocks[0].block)
203+
if (used + memHeader.length + firstMemFormatted.length + 2 < budget) {
203204
result += memHeader
204205
used += memHeader.length
205206

@@ -270,16 +271,19 @@ export namespace MemoryPrompt {
270271

271272
const section = KIND_HEADERS[kind]
272273
const sectionHeader = `\n### ${section.header}\n_${section.instruction}_\n`
273-
if (used + sectionHeader.length > budget) continue
274-
result += sectionHeader
275-
used += sectionHeader.length
276274

277275
const sorted = [...items].sort((a, b) => {
278276
const metaA = parseTrainingMeta(a.content)
279277
const metaB = parseTrainingMeta(b.content)
280278
return (metaB?.applied ?? 0) - (metaA?.applied ?? 0)
281279
})
282280

281+
// Check if header + at least one entry fits before adding header
282+
const firstFormatted = formatTrainingEntry(sorted[0])
283+
if (used + sectionHeader.length + firstFormatted.length + 2 > budget) continue
284+
result += sectionHeader
285+
used += sectionHeader.length
286+
283287
for (const block of sorted) {
284288
const formatted = formatTrainingEntry(block)
285289
const needed = formatted.length + 2

packages/opencode/test/agent/agent.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,8 @@ test("defaultAgent throws when all primary agents are disabled", async () => {
683683
executive: { disable: true },
684684
validator: { disable: true },
685685
migrator: { disable: true },
686+
researcher: { disable: true },
687+
trainer: { disable: true },
686688
plan: { disable: true },
687689
},
688690
},

0 commit comments

Comments
 (0)