Skip to content

Commit c212916

Browse files
anandgupta42claude
andcommitted
fix: remove dead accepted/rejected fields, add training tips, expand limitations
Gaps found by simulation team: 1. Remove `accepted`/`rejected` counters from TrainingBlockMeta — they were never incremented anywhere in the codebase (dead code since inception) 2. Add 5 training discoverability tips to TUI tips (was 0 mentions in 152 tips) 3. Expand limitations section in docs with honest, complete list: context budget, 20/kind limit, no approval workflow, SQL-focused, git discipline required Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a072801 commit c212916

File tree

7 files changed

+43
-36
lines changed

7 files changed

+43
-36
lines changed

docs/docs/data-engineering/training/index.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,13 @@ Training doesn't replace CLAUDE.md. They complement each other:
146146

147147
## Limitations
148148

149-
- **Not a linter.** Training is advisory — the agent follows it, but it's not enforced at build time. For critical rules, also add dbt tests.
150-
- **Not an audit trail.** No approval workflows or change tracking beyond git history.
151-
- **Not automatic.** The agent proposes, you confirm. This is intentional.
152-
- **SQL-focused scanning.** The `/teach` skill works best with SQL/dbt files. Python patterns must be taught manually.
149+
- **Advisory, not enforced.** Training guides the agent, but it's not a hard gate. For critical rules, also add dbt tests or sqlfluff rules that block CI.
150+
- **No approval workflow.** Anyone with repo access can save training to project scope. Use code review on `.altimate-code/memory/` changes for governance.
151+
- **No audit trail** beyond git history. Training doesn't track who saved what — use `git blame` on the training files.
152+
- **Context budget.** Training competes for context space. Under pressure, least-relevant entries are excluded. Run `/training-status` to see what's included.
153+
- **20 entries per kind.** Hard limit. Consolidate related rules into one entry rather than saving many small ones.
154+
- **SQL-focused file analysis.** The `/teach` skill works best with SQL/dbt files. Python, PySpark, and other patterns must be taught manually via conversation.
155+
- **Team sync requires git discipline.** Training saves to disk but doesn't auto-commit. Commit `.altimate-code/memory/` changes to share with your team.
153156

154157
## Quick Reference
155158

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
refactor: cut training_scan and training_validate, simplify docs
2+
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.
7+
8+
Removed:
9+
- training_scan (255 lines) — regex pattern counting, not discovery
10+
- training_validate (315 lines) — keyword grep, not validation
11+
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.
19+
20+
Net: -753 lines. 152 tests pass.
21+
22+
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

packages/opencode/src/altimate/training/store.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ export namespace TrainingStore {
4343
kind: input.kind,
4444
source: input.source,
4545
applied: prevMeta?.applied ?? 0,
46-
accepted: prevMeta?.accepted ?? 0,
47-
rejected: prevMeta?.rejected ?? 0,
4846
}
4947

5048
const enriched = embedTrainingMeta(input.content, meta)
@@ -144,8 +142,6 @@ export namespace TrainingStore {
144142
const meta = parseTrainingMeta(block.content) ?? {
145143
kind,
146144
applied: 0,
147-
accepted: 0,
148-
rejected: 0,
149145
}
150146
return {
151147
id: block.id,

packages/opencode/src/altimate/training/types.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ export const TrainingBlockMeta = z.object({
1414
kind: TrainingKind,
1515
source: z.string().optional(),
1616
applied: z.number().int().min(0).default(0),
17-
accepted: z.number().int().min(0).default(0),
18-
rejected: z.number().int().min(0).default(0),
1917
})
2018
export type TrainingBlockMeta = z.infer<typeof TrainingBlockMeta>
2119

@@ -62,8 +60,6 @@ export function embedTrainingMeta(content: string, meta: TrainingBlockMeta): str
6260
`kind: ${meta.kind}`,
6361
...(meta.source ? [`source: ${meta.source}`] : []),
6462
`applied: ${meta.applied}`,
65-
`accepted: ${meta.accepted}`,
66-
`rejected: ${meta.rejected}`,
6763
"-->",
6864
].join("\n")
6965
// Strip existing training meta block if present

packages/opencode/src/cli/cmd/tui/component/tips.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,11 @@ const TIPS = [
149149
"Run {highlight}/help{/highlight} or {highlight}Ctrl+X H{/highlight} to show the help dialog",
150150
"Use {highlight}/rename{/highlight} to rename the current session",
151151
"Press {highlight}Ctrl+Z{/highlight} to suspend the terminal and return to your shell",
152+
// altimate_change start - training discoverability tips
153+
"Correct me once and I'll remember forever — say {highlight}yes{/highlight} when I ask to save a correction",
154+
"Use {highlight}/teach @file.sql{/highlight} to teach me patterns from your code",
155+
"Use {highlight}/train @docs/style-guide.md{/highlight} to load team standards from documentation",
156+
"Use {highlight}/training-status{/highlight} to see what your team has taught me",
157+
"Switch to {highlight}trainer{/highlight} mode to systematically teach me about your project",
158+
// altimate_change end
152159
]

packages/opencode/test/training/tools.test.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,29 +106,26 @@ describe("training meta roundtrip through content", () => {
106106
expect(parsed!.kind).toBe("pattern")
107107
expect(parsed!.source).toBe("stg_orders.sql")
108108
expect(parsed!.applied).toBe(5)
109-
expect(parsed!.accepted).toBe(3)
110-
expect(parsed!.rejected).toBe(1)
111109
})
112110

113111
test("preserves content after embedding meta", () => {
114112
const content = "Rule: Use NUMERIC(18,2)\n\nDetails:\n- For all *_amount columns"
115-
const meta: TrainingBlockMeta = { kind: "rule", applied: 0, accepted: 0, rejected: 0 }
113+
const meta: TrainingBlockMeta = { kind: "rule", applied: 0 }
116114
const embedded = embedTrainingMeta(content, meta)
117115
expect(embedded).toContain("Rule: Use NUMERIC(18,2)")
118116
expect(embedded).toContain("- For all *_amount columns")
119117
})
120118

121119
test("replaces existing meta on re-embed", () => {
122-
const meta1: TrainingBlockMeta = { kind: "pattern", applied: 1, accepted: 0, rejected: 0 }
123-
const meta2: TrainingBlockMeta = { kind: "pattern", applied: 10, accepted: 8, rejected: 2 }
120+
const meta1: TrainingBlockMeta = { kind: "pattern", applied: 1 }
121+
const meta2: TrainingBlockMeta = { kind: "pattern", applied: 10 }
124122
const content = "Pattern content"
125123

126124
const embedded1 = embedTrainingMeta(content, meta1)
127125
expect(parseTrainingMeta(embedded1)!.applied).toBe(1)
128126

129127
const embedded2 = embedTrainingMeta(embedded1, meta2)
130128
expect(parseTrainingMeta(embedded2)!.applied).toBe(10)
131-
expect(parseTrainingMeta(embedded2)!.accepted).toBe(8)
132129

133130
// Should not have duplicate meta blocks
134131
const metaBlocks = embedded2.match(/<!-- training/g)
@@ -137,7 +134,7 @@ describe("training meta roundtrip through content", () => {
137134

138135
test("handles content with special characters", () => {
139136
const content = "Use `{{ source('schema', 'table') }}` macro\n<!-- not training -->"
140-
const meta: TrainingBlockMeta = { kind: "pattern", applied: 0, accepted: 0, rejected: 0 }
137+
const meta: TrainingBlockMeta = { kind: "pattern", applied: 0 }
141138
const embedded = embedTrainingMeta(content, meta)
142139
expect(embedded).toContain("{{ source('schema', 'table') }}")
143140
expect(embedded).toContain("<!-- not training -->")

packages/opencode/test/training/types.test.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,12 @@ describe("embedTrainingMeta", () => {
107107
kind: "pattern",
108108
source: "stg_orders.sql",
109109
applied: 3,
110-
accepted: 2,
111-
rejected: 1,
112110
}
113111
const result = embedTrainingMeta("Pattern content here", meta)
114112
expect(result).toContain("<!-- training")
115113
expect(result).toContain("kind: pattern")
116114
expect(result).toContain("source: stg_orders.sql")
117115
expect(result).toContain("applied: 3")
118-
expect(result).toContain("accepted: 2")
119-
expect(result).toContain("rejected: 1")
120116
expect(result).toContain("-->")
121117
expect(result).toContain("Pattern content here")
122118
})
@@ -125,20 +121,16 @@ describe("embedTrainingMeta", () => {
125121
const meta: TrainingBlockMeta = {
126122
kind: "rule",
127123
applied: 0,
128-
accepted: 0,
129-
rejected: 0,
130124
}
131125
const result = embedTrainingMeta("Rule content", meta)
132126
expect(result).not.toContain("source:")
133127
})
134128

135129
test("replaces existing meta block", () => {
136-
const existing = "<!-- training\nkind: pattern\napplied: 1\naccepted: 0\nrejected: 0\n-->\nOld content"
130+
const existing = "<!-- training\nkind: pattern\napplied: 1\n-->\nOld content"
137131
const meta: TrainingBlockMeta = {
138132
kind: "pattern",
139133
applied: 5,
140-
accepted: 3,
141-
rejected: 0,
142134
}
143135
const result = embedTrainingMeta(existing, meta)
144136
expect(result).toContain("applied: 5")
@@ -150,22 +142,20 @@ describe("embedTrainingMeta", () => {
150142

151143
describe("parseTrainingMeta", () => {
152144
test("parses embedded meta", () => {
153-
const content = "<!-- training\nkind: pattern\nsource: stg_orders.sql\napplied: 3\naccepted: 2\nrejected: 1\n-->\nPattern content"
145+
const content = "<!-- training\nkind: pattern\nsource: stg_orders.sql\napplied: 3\n-->\nPattern content"
154146
const meta = parseTrainingMeta(content)
155147
expect(meta).toBeDefined()
156148
expect(meta!.kind).toBe("pattern")
157149
expect(meta!.source).toBe("stg_orders.sql")
158150
expect(meta!.applied).toBe(3)
159-
expect(meta!.accepted).toBe(2)
160-
expect(meta!.rejected).toBe(1)
161151
})
162152

163153
test("returns undefined for content without meta", () => {
164154
expect(parseTrainingMeta("Just plain content")).toBeUndefined()
165155
})
166156

167157
test("handles meta without source", () => {
168-
const content = "<!-- training\nkind: rule\napplied: 0\naccepted: 0\nrejected: 0\n-->\nRule"
158+
const content = "<!-- training\nkind: rule\napplied: 0\n-->\nRule"
169159
const meta = parseTrainingMeta(content)
170160
expect(meta).toBeDefined()
171161
expect(meta!.kind).toBe("rule")
@@ -177,17 +167,13 @@ describe("parseTrainingMeta", () => {
177167
kind: "standard",
178168
source: "docs/style-guide.md",
179169
applied: 7,
180-
accepted: 5,
181-
rejected: 2,
182170
}
183171
const embedded = embedTrainingMeta("Test content", original)
184172
const parsed = parseTrainingMeta(embedded)
185173
expect(parsed).toBeDefined()
186174
expect(parsed!.kind).toBe(original.kind)
187175
expect(parsed!.source).toBe(original.source)
188176
expect(parsed!.applied).toBe(original.applied)
189-
expect(parsed!.accepted).toBe(original.accepted)
190-
expect(parsed!.rejected).toBe(original.rejected)
191177
})
192178
})
193179

0 commit comments

Comments
 (0)