mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-07 17:28:23 +01:00
test: ledger-driven learnings expectations in gen-skill-docs.test (GST-1088 lane C)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
bd24f76ece
commit
9b0d53432e
1 file changed
+16
-11
+16
-11
@@ -10,9 +10,15 @@ import * as os from 'os';
|
||||
import { spawnSync } from 'child_process';
|
||||
import { runCapturedCommand } from './helpers/sync-command-capture';
|
||||
import { between, expectAbsent, expectMentions, expectOrdered, expectTokens } from './helpers/prompt-structure';
|
||||
import { loadCutLedger } from '../scripts/cut-ledger';
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, '..');
|
||||
const MAX_SKILL_DESCRIPTION_LENGTH = 1024;
|
||||
/** GST-1088: R56 cuts (modules/cuts.json) remove learnings blocks from /investigate and /review; their absence is test/cut-ledger.test.ts's job. */
|
||||
const CUT_IDS = new Set(loadCutLedger().cuts.map(c => c.id));
|
||||
const notCut = (skill: string, part: string) => !CUT_IDS.has(`part:${skill}/${part}`);
|
||||
const SEARCH_SAMPLE = notCut('review', 'learnings-search') ? 'review' : 'office-hours';
|
||||
const LOG_SAMPLE = notCut('review', 'capture-learnings') ? 'review' : 'retro';
|
||||
|
||||
// Carved-skill aware (v2 plan T9): ship is now a skeleton SKILL.md + sections/*.md.
|
||||
// Read the union so assertions about content that MOVED into a section still pass.
|
||||
@@ -375,8 +381,7 @@ describe('gen-skill-docs', () => {
|
||||
});
|
||||
|
||||
test('generated SKILL.md with LEARNINGS_LOG contains operational type', () => {
|
||||
// Check a skill that has LEARNINGS_LOG (e.g., review)
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, LOG_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('operational');
|
||||
});
|
||||
|
||||
@@ -3456,7 +3461,7 @@ describe('Factory generation (--host factory)', () => {
|
||||
});
|
||||
|
||||
test('Factory preamble uses .factory paths', () => {
|
||||
const content = fs.readFileSync(path.join(FACTORY_DIR, 'gstack-review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(FACTORY_DIR, `gstack-${SEARCH_SAMPLE}`, 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('GSTACK_ROOT');
|
||||
expect(content).toContain('_r=$(git rev-parse --show-toplevel 2>/dev/null)/.factory/skills/gstack');
|
||||
expect(content).toContain('$GSTACK_BIN/gstack-config');
|
||||
@@ -4302,7 +4307,7 @@ describe('codex commands must not use inline $(git rev-parse --show-toplevel) fo
|
||||
// ─── Learnings + Confidence Resolver Tests ─────────────────────
|
||||
|
||||
describe('LEARNINGS_SEARCH resolver', () => {
|
||||
const SEARCH_SKILLS = ['review', 'ship', 'plan-eng-review', 'investigate', 'office-hours', 'plan-ceo-review'];
|
||||
const SEARCH_SKILLS = ['review', 'ship', 'plan-eng-review', 'investigate', 'office-hours', 'plan-ceo-review'].filter(s => notCut(s, 'learnings-search'));
|
||||
|
||||
for (const skill of SEARCH_SKILLS) {
|
||||
test(`${skill} generated SKILL.md contains learnings search`, () => {
|
||||
@@ -4313,13 +4318,13 @@ describe('LEARNINGS_SEARCH resolver', () => {
|
||||
}
|
||||
|
||||
test('learnings search includes cross-project config check', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, SEARCH_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('cross_project_learnings');
|
||||
expect(content).toContain('--cross-project');
|
||||
});
|
||||
|
||||
test('learnings search includes AskUserQuestion for first-time cross-project opt-in', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, SEARCH_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('Enable cross-project learnings');
|
||||
expect(content).toContain('project-scoped only');
|
||||
});
|
||||
@@ -4349,13 +4354,13 @@ describe('LEARNINGS_SEARCH resolver', () => {
|
||||
});
|
||||
|
||||
test('learnings search mentions prior learning applied display format', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, SEARCH_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('Prior learning applied');
|
||||
});
|
||||
});
|
||||
|
||||
describe('LEARNINGS_LOG resolver', () => {
|
||||
const LOG_SKILLS = ['review', 'retro', 'investigate'];
|
||||
const LOG_SKILLS = ['review', 'retro', 'investigate'].filter(s => notCut(s, 'capture-learnings'));
|
||||
|
||||
for (const skill of LOG_SKILLS) {
|
||||
test(`${skill} generated SKILL.md contains learnings log`, () => {
|
||||
@@ -4366,21 +4371,21 @@ describe('LEARNINGS_LOG resolver', () => {
|
||||
}
|
||||
|
||||
test('learnings log documents all type values', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, LOG_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
for (const type of ['pattern', 'pitfall', 'preference', 'architecture', 'tool']) {
|
||||
expect(content).toContain(type);
|
||||
}
|
||||
});
|
||||
|
||||
test('learnings log documents all source values', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, LOG_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
for (const source of ['observed', 'user-stated', 'inferred', 'cross-model']) {
|
||||
expect(content).toContain(source);
|
||||
}
|
||||
});
|
||||
|
||||
test('learnings log includes files field for staleness detection', () => {
|
||||
const content = fs.readFileSync(path.join(ROOT, 'review', 'SKILL.md'), 'utf-8');
|
||||
const content = fs.readFileSync(path.join(ROOT, LOG_SAMPLE, 'SKILL.md'), 'utf-8');
|
||||
expect(content).toContain('"files"');
|
||||
expect(content).toContain('staleness detection');
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user