mirror of https://github.com/garrytan/gstack.git
39 lines
1.7 KiB
TypeScript
39 lines
1.7 KiB
TypeScript
import { describe, test, expect } from 'bun:test';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
const SHIP_SKILL = path.join(__dirname, '..', 'ship', 'SKILL.md');
|
|
|
|
describe('ship/SKILL.md — Plan Completion gate invariants (VAS-449 remediation)', () => {
|
|
const skill = fs.readFileSync(SHIP_SKILL, 'utf8');
|
|
|
|
test('Path concreteness rule: filesystem-pathed items must be test -f checked', () => {
|
|
expect(skill).toContain('**Path concreteness rule.**');
|
|
expect(skill).toMatch(/concrete filesystem path/);
|
|
expect(skill).toMatch(/MUST be classified DONE or NOT DONE based on `\[ -f/);
|
|
});
|
|
|
|
test('Validator detection: project package.json validate-* scripts are auto-run', () => {
|
|
expect(skill).toContain('**Validator detection.**');
|
|
expect(skill).toMatch(/package\.json/);
|
|
expect(skill).toMatch(/validate-\*/);
|
|
});
|
|
|
|
test('Per-item UNVERIFIABLE confirmation: blanket-confirm is forbidden', () => {
|
|
expect(skill).toContain('**Per-item confirmation is mandatory.**');
|
|
expect(skill).toMatch(/Do NOT use a single AskUserQuestion to blanket-confirm/);
|
|
expect(skill).toMatch(/VAS-449/);
|
|
});
|
|
|
|
test('Subagent failure: fail-closed, not silent fail-open', () => {
|
|
expect(skill).not.toMatch(/Never block \/ship on subagent failure\.\s*$/m);
|
|
expect(skill).toMatch(/Silent fail-open is the failure shape that VAS-449 surfaced/);
|
|
expect(skill).toMatch(/Stop and fix the audit/);
|
|
});
|
|
|
|
test('CONTENT-SHAPE dispatch invokes validator before falling back to UNVERIFIABLE', () => {
|
|
expect(skill).toMatch(/CONTENT-SHAPE in another repo.*validator/s);
|
|
expect(skill).toMatch(/passing validator promotes the item from UNVERIFIABLE to DONE/);
|
|
});
|
|
});
|