mirror of
https://github.com/garrytan/gstack.git
synced 2026-06-18 15:50:11 +02:00
e884617b7c
3 new gate-tier test files closing the most important coverage gaps in
the brain-aware planning layer:
test/schema-version-migration.test.ts (D4 A4):
- Cache file with mismatched schema_version triggers wipe-and-rebuild
- Matching version + fresh TTL stays warm-hit (no unnecessary rebuild)
- Rebuild wipes ALL files in scope, not just the one being read
test/takes-fence-fallback.test.ts:
- Every preflight skill mentions both takes_add (preferred) and
put_page fence-block (fallback for pre-T8 gbrain versions)
- All 5 skills gate on BRAIN_CALIBRATION_WRITEBACK flag + personal
trust policy
- Per-skill weight matches SKILL_CALIBRATION_WEIGHTS (E5)
- Write-back emits the kind=bet frontmatter shape and invalidates
affected cache digests
test/skill-preflight-budget.test.ts (T21 / D7):
- Per-skill BRAIN_* instruction bytes stay under 3x the runtime
digest budget (resolver bloat catch)
- Autoplan total instruction bytes stay under 75 KB (3x of 25 KB
runtime cap)
- Non-preflight skills emit zero brain bytes
- Per-skill subset references are present in the preflight bash
Note on the 3x multiplier: SKILL_PREFLIGHT_BUDGET_BYTES governs runtime
digest data (enforced by cache CLI truncateToBudget). Instruction text
emitted by the resolver gets a separate 3x headroom — anything beyond
that signals the instructions themselves are bloated and need a trim.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
88 lines
3.3 KiB
TypeScript
88 lines
3.3 KiB
TypeScript
/**
|
|
* Phase 2 calibration write-back fence-block fallback (T19).
|
|
*
|
|
* The BRAIN_WRITE_BACK resolver output describes two paths:
|
|
* 1. Preferred: mcp__gbrain__takes_add op (upstream gbrain v0.42+, T8)
|
|
* 2. Fallback: mcp__gbrain__put_page with a gstack:takes fence block
|
|
*
|
|
* Until T8 ships, the fallback is the only path. Verify the resolver output
|
|
* mentions the fence-block fallback explicitly so the agent knows what to
|
|
* do when takes_add returns MCPMethodNotFound.
|
|
*
|
|
* Gate-tier, free, pure import + render.
|
|
*/
|
|
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { generateBrainWriteBack } from '../scripts/resolvers/gbrain';
|
|
import { SKILL_DIGEST_SUBSETS, SKILL_CALIBRATION_WEIGHTS } from '../scripts/brain-cache-spec';
|
|
import { HOST_PATHS } from '../scripts/resolvers/types';
|
|
import type { TemplateContext } from '../scripts/resolvers/types';
|
|
|
|
function buildCtx(skillName: string): TemplateContext {
|
|
return {
|
|
skillName,
|
|
tmplPath: `/tmp/${skillName}/SKILL.md.tmpl`,
|
|
host: 'claude',
|
|
paths: HOST_PATHS.claude,
|
|
};
|
|
}
|
|
|
|
describe('Phase 2 write-back fence-block fallback', () => {
|
|
test('every preflight skill emits write-back with fallback path documented', () => {
|
|
for (const skill of Object.keys(SKILL_DIGEST_SUBSETS)) {
|
|
const out = generateBrainWriteBack(buildCtx(skill));
|
|
// Mentions takes_add (preferred)
|
|
expect(out).toContain('takes_add');
|
|
// Mentions put_page fallback
|
|
expect(out).toContain('put_page');
|
|
// Mentions the takes fence-block syntax
|
|
expect(out).toContain('takes');
|
|
}
|
|
});
|
|
|
|
test('write-back guidance gates on BRAIN_CALIBRATION_WRITEBACK feature flag', () => {
|
|
for (const skill of Object.keys(SKILL_DIGEST_SUBSETS)) {
|
|
const out = generateBrainWriteBack(buildCtx(skill));
|
|
expect(out).toContain('BRAIN_CALIBRATION_WRITEBACK');
|
|
}
|
|
});
|
|
|
|
test('write-back guidance gates on brain_trust_policy == personal', () => {
|
|
for (const skill of Object.keys(SKILL_DIGEST_SUBSETS)) {
|
|
const out = generateBrainWriteBack(buildCtx(skill));
|
|
expect(out).toContain('personal');
|
|
expect(out).toContain('brain_trust_policy');
|
|
}
|
|
});
|
|
|
|
test('write-back emits the kind=bet take frontmatter shape', () => {
|
|
const out = generateBrainWriteBack(buildCtx('plan-ceo-review'));
|
|
expect(out).toContain('kind: bet');
|
|
expect(out).toContain('holder:');
|
|
expect(out).toContain('claim:');
|
|
expect(out).toContain('weight:');
|
|
expect(out).toContain('since_date:');
|
|
expect(out).toContain('expected_resolution:');
|
|
expect(out).toContain('source_skill:');
|
|
});
|
|
|
|
test('per-skill weight matches SKILL_CALIBRATION_WEIGHTS', () => {
|
|
for (const skill of Object.keys(SKILL_DIGEST_SUBSETS)) {
|
|
const weight = SKILL_CALIBRATION_WEIGHTS[skill];
|
|
if (weight == null) continue;
|
|
const out = generateBrainWriteBack(buildCtx(skill));
|
|
expect(out).toContain(`weight: ${weight}`);
|
|
}
|
|
});
|
|
|
|
test('write-back invalidates affected cache digests after write', () => {
|
|
const out = generateBrainWriteBack(buildCtx('plan-ceo-review'));
|
|
expect(out).toContain('gstack-brain-cache invalidate');
|
|
});
|
|
|
|
test('non-preflight skill gets empty write-back (no Phase 2 path)', () => {
|
|
expect(generateBrainWriteBack(buildCtx('ship'))).toBe('');
|
|
expect(generateBrainWriteBack(buildCtx('qa'))).toBe('');
|
|
});
|
|
});
|