mirror of https://github.com/garrytan/gstack.git
85 lines
3.9 KiB
TypeScript
85 lines
3.9 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
const ROOT = path.resolve(import.meta.dir, '..');
|
|
|
|
function read(relativePath: string): string {
|
|
return fs.readFileSync(path.join(ROOT, relativePath), 'utf8');
|
|
}
|
|
|
|
describe('/bug-report skill', () => {
|
|
test('is report-only and requires explicit approval before publication', () => {
|
|
const template = read('bug-report/SKILL.md.tmpl');
|
|
|
|
expect(template).toContain('REPORT, DO NOT FIX');
|
|
expect(template).toContain('NO SURPRISE PUBLICATION');
|
|
expect(template).toContain('does not fix code or publish the report without explicit approval');
|
|
expect(template).not.toMatch(/allowed-tools:[\s\S]*?\n - Edit\n/);
|
|
});
|
|
|
|
test('requires reproducible evidence and distinguishes fact from hypothesis', () => {
|
|
const template = read('bug-report/SKILL.md.tmpl');
|
|
|
|
expect(template).toContain('## Steps to reproduce');
|
|
expect(template).toContain('## Evidence');
|
|
expect(template).toContain('### Confirmed facts');
|
|
expect(template).toContain('### Root-cause hypothesis');
|
|
expect(template).toContain('Not reproduced');
|
|
});
|
|
|
|
test('protects sensitive histories and scans the report at the sink', () => {
|
|
const template = read('bug-report/SKILL.md.tmpl');
|
|
|
|
expect(template).toMatch(/shell history as\s+sensitive activity records/);
|
|
expect(template).toContain('{{REDACT_INVOCATION_BLOCK:pre-issue:retain}}');
|
|
expect(template).toContain('{{REDACT_INVOCATION_BLOCK:pre-pr-body:brief:retain}}');
|
|
expect(template).toContain('Never run bare `env`, `printenv`, `set`');
|
|
expect(template).toContain('Never copy an entire tool home');
|
|
expect(template).toContain('SQLite state');
|
|
expect(template).toContain('Treat every evidence file as its own persistence sink');
|
|
expect(template).toContain('separate sinks');
|
|
expect(template).toContain('finally-style cleanup step');
|
|
expect(template).toContain('Rerun the PR-body scan');
|
|
expect(template).toContain('Screenshots and other binary evidence require a separate visual privacy gate');
|
|
expect(template).toContain('Never upload raw captures');
|
|
});
|
|
|
|
test('generated workflow retains scanned bytes until persistence succeeds', () => {
|
|
const generated = read('bug-report/SKILL.md');
|
|
expect(generated).toContain('Retain `$REDACT_FILE` for the immediate destination write');
|
|
expect(generated).toContain('Never delete or reconstruct it before the write');
|
|
expect(generated).toContain('Retain `$REDACT_FILE` until the destination write succeeds');
|
|
});
|
|
|
|
test('drafts honest maintainer guidance without pretending a fix exists', () => {
|
|
const template = read('bug-report/SKILL.md.tmpl');
|
|
|
|
expect(template).toContain('{YYYY-MM-DD}-{slug}-pr-body.md');
|
|
expect(template).toContain('Not implemented in this report-only run');
|
|
expect(template).toContain('Verify generator idempotency by snapshotting');
|
|
});
|
|
|
|
test('is included in the router and documentation inventories', () => {
|
|
const router = read('SKILL.md.tmpl');
|
|
expect(router).toContain('"this doesn\'t work"');
|
|
expect(router).toMatch(/"this doesn't work"[^\n]+invoke `\/investigate`/);
|
|
expect(router).toMatch(/Explicit precedence exception:[^\n]+invoke `\/bug-report`/);
|
|
expect(read('AGENTS.md')).toContain('`/bug-report`');
|
|
expect(read('docs/skills.md')).toContain('## `/bug-report`');
|
|
});
|
|
|
|
test('produces PR guidance without manufacturing an empty PR', () => {
|
|
const template = read('bug-report/SKILL.md.tmpl');
|
|
expect(template).toContain('-pr-body.md');
|
|
expect(template).toContain('How maintainers can verify');
|
|
expect(template).toContain('Do not manufacture an');
|
|
expect(template).toContain('Open a remote draft PR only when');
|
|
});
|
|
|
|
test('generated catalogs include the skill', () => {
|
|
expect(read('gstack/llms.txt')).toContain('[/bug-report](bug-report/SKILL.md)');
|
|
expect(read('scripts/proactive-suggestions.json')).toContain('"bug-report"');
|
|
});
|
|
});
|