mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-31 22:14:25 +01:00
* fix(make-pdf,design): real TOC page numbers and anchors; design models move to gpt-5.5 + gpt-image-2 (#2903, #2807) * ci: pin every action to a SHA, Scorecard, checksummed Bun, scoped Codex CLI in the CI image, macOS named-regressions job (#1948, #1706, #1997) * fix(cso,browse): Windows/macOS lease identity, retention skips bad runs, truthful 'not assessed' reports, env.kv false positive, Windows browse spawn fixes (#2894, #2912, #2048, #2637, #2805) * fix(outside-voice): one Codex model precedence for probe and dispatch, bounded timeouts with KILL escalation, probe cache identity, guarded mktemp, skills hidden in nested Codex (#2776, #2914, #2787, #2881, #2847) * feat(setup): install registry, ./setup --status, staged activation, per-scope migrations, host tiers and conformance kit, OpenCode/Hermes fixes, Copilot CLI (experimental), disabled_skills, slimmer CLAUDE.md (#1925, #2879, #2347, #2338, #2626, #2629, #2825, #2015, #393, #1206, #2096) Co-authored-by: Andrey Esipov <61357035+andrey-esipov@users.noreply.github.com> Co-authored-by: Matthew Williams <5863886+ridermw@users.noreply.github.com> Co-authored-by: Rocky Wu <92764750+lolisaigao1234@users.noreply.github.com> * fix(preamble): skills start in worktree-isolated Claude Code sessions — one literal skill-start line, context-recovery helper, no eval in skill blocks, $N token tripwire, honest plan-mode precedence (#2763, #2896, #2851) * fix(setup): per-install renders for renamed, vendored and custom-config installs, space-safe alias roots, per-host /cso launcher path (#1882, #2906) * test: free tests never write the real HOME (home-write tripwire), no orphaned browse daemons, symlinked-TMPDIR (macOS) fixes, gbrain-on-PATH isolation (#2895, #2816, #2829, #2841, #2982, #2911, #2909, #2908, #2910) * chore: integrate wave follow-ups — regenerate all hosts, README model docs, TODOS, touchfiles, duration seeds, Bun 1.3 telemetry test fix, replay fixtures pinned to their recorded bytes * v1.91.14.0: release metadata * test(browse): group-kill cleanup falls back to the leader when macOS returns EPERM for a live group * ci: Codex login steps run under bash (the CI container's default sh rejects pipefail) * fix: full-suite repairs — private state roots for 7 real-HOME writers, truthful home-guard attribution with --attribute-home, gstack-paths shim in ship-hook fixtures, Copilot in team-init probes, test-of-test detector, cookie review fixture pinned to the approved excerpt * fix(windows): LF for Dockerfiles, normalized home-guard exclusions, path.relative fixture containment, ship push test spawn timeouts * test(design-detect): widen the whole-scan budget test's timing margins so a loaded macOS runner can't time out the single-batch call * fix(evals): qa protocol names defined for the judge, async PTY judge so overlapping sessions keep their cleanup deadline, bws setup cases use the standard JUDGE_MS tier * test(pty): the non-blocking judge case is POSIX-only (its fake judge is a shebang script, like the PTY harness it covers) * test(evals): ship-coverage-audit names absolute skill paths, uses Read, and skips the Step 7 artifact nothing consumes (removes the mechanism behind 3 of 4 historical timeouts) * test: deflake terminal-agent concurrent startup (write the placeholder record before spawning, like the product) and qa-evidence resumed pipe (barrier on a full high-water mark instead of a sleep) * fix(design): daemon log stream handles open errors instead of crashing the daemon; shutdown test awaits the stubbed exit * test(evals): skillify checks the product's resolved state root (no GSTACK_HOME bypass), negative cases check every root; tpa shims live outside the agent's cwd and answer consistently * test(evals): coverage-audit detector splits parallel columns at │ rails and [+] groups; coverage prompts name absolute skill paths; TODOs from the gate eval census * fix(plan-eng-review): scope gate always sends the menu (no headless 'Scope pending' exit); PTY harness ends idle turn-ends and API-error panels promptly with a precise diagnostic * test(evals): one position-bound coverage-read rule credits read-only && chains (labels, context ranges, git displays in either order) and still rejects forged output * fix(ship): documentation section has one saved source inserted by cat (never retyped); spawned-marker evidence is the child output; refreshed codex/factory ship goldens * test(docsync): the byte-exact insert positive is POSIX-only (the bash-command observer refuses backslash paths by design) * test(evals): plan-design-with-ui focus-title rule accepts the comma-less 'dimensions or focus' wording (replayed on the captured CI run, negative controls kept) * fix(qa-callers): exploratory preflight says the scope/method Reads come after exploratory.md; design-review scan check credits an executed scan proven by one engine run over the changed files --------- Co-authored-by: Andrey Esipov <61357035+andrey-esipov@users.noreply.github.com> Co-authored-by: Matthew Williams <5863886+ridermw@users.noreply.github.com> Co-authored-by: Rocky Wu <92764750+lolisaigao1234@users.noreply.github.com>
92 lines
5.2 KiB
TypeScript
92 lines
5.2 KiB
TypeScript
/** Current /review testing-specialist and /plan-eng-review test-review audits.
|
|
* Both use source-extracted instructions and the same billing coverage fixture.
|
|
* The diagram is an explicit user request for the targeted /review specialist;
|
|
* /review no longer has the historical Step 4.75 coverage-diagram section.
|
|
*/
|
|
import { afterAll } from 'bun:test';
|
|
import { randomUUID } from 'node:crypto';
|
|
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import * as os from 'node:os';
|
|
import { JUDGE_MS, CAPTURE_MS } from './helpers/eval-budgets';
|
|
import { runSkillTest } from './helpers/session-runner';
|
|
import { ROOT, runId, describeIfSelected, testIfSelected, copyDirSync, logCost,
|
|
createEvalCollector, finalizeEvalCollector } from './helpers/e2e-helpers';
|
|
import { extractSkillBody } from './helpers/skill-fixture';
|
|
import { createCoverageAuditFixture } from './fixtures/coverage-audit-fixture';
|
|
import type { CoverageFile } from './helpers/coverage-audit';
|
|
import { coverageAuditVerdict } from './helpers/coverage-audit-evidence';
|
|
import { runRecordedOfficeHoursAttempt, OFFICE_HOURS_BUN_GRACE_MS } from './helpers/office-hours-attempt';
|
|
import { resolveEvalModel } from '../lib/eval-model';
|
|
|
|
const evalCollector = createEvalCollector('e2e');
|
|
const CASES = [
|
|
{ id: 'review-coverage-audit', skill: 'review', suite: 'Review Coverage Audit E2E',
|
|
instructions: (dir: string) => `Read ${dir}/review/SKILL.md and ${dir}/review/sections/review-army.md for the current review workflow.
|
|
Apply ONLY the testing specialist checklist in ${dir}/review/specialists/testing.md to the supplied source and tests.
|
|
This is a targeted --testing request, even though this fixture has no branch diff.
|
|
Run that checklist directly; do not dispatch other specialists or perform fixes.` },
|
|
{ id: 'plan-eng-coverage-audit', skill: 'plan-eng-review', suite: 'Plan Eng Review Coverage Audit E2E',
|
|
instructions: (dir: string) => `Read ${dir}/plan-eng-review/SKILL.md and ${dir}/plan-eng-review/sections/review-sections.md.
|
|
Run ONLY section "3. Test review": codepath tracing and the ASCII coverage diagram.
|
|
For this targeted audit, treat the two supplied billing functions as the proposed codepaths.
|
|
Skip architecture, code quality, performance, test generation and all other workflow steps.` },
|
|
] as const;
|
|
|
|
for (const entry of CASES) describeIfSelected(entry.suite, [entry.id], () => {
|
|
testIfSelected(entry.id, async () => {
|
|
let cwd: string | undefined;
|
|
let files: CoverageFile[] = [];
|
|
try {
|
|
await runRecordedOfficeHoursAttempt({
|
|
collector: evalCollector, name: entry.id, suite: entry.suite,
|
|
model: process.env.EVALS_MODEL ?? resolveEvalModel('capture'),
|
|
// Keep the original 300s Bun cap and 120s runner work budget. Reuse the
|
|
// existing helper's bounded abort/drain/record reserve inside that cap.
|
|
budgetMs: CAPTURE_MS - OFFICE_HOURS_BUN_GRACE_MS,
|
|
run: async signal => {
|
|
cwd = fs.mkdtempSync(path.join(os.tmpdir(), `skill-e2e-${entry.skill}-coverage-`));
|
|
copyDirSync(path.join(ROOT, entry.skill), path.join(cwd, entry.skill));
|
|
fs.writeFileSync(path.join(cwd, entry.skill, 'SKILL.md'), extractSkillBody(path.join(ROOT, entry.skill)));
|
|
createCoverageAuditFixture(cwd);
|
|
files = ['src/billing.ts', 'test/billing.test.ts'].map(relative => {
|
|
const file = path.join(cwd!, relative);
|
|
// Fresh per attempt, outside the prompt. Seeing the complete file
|
|
// with this marker proves actual tool output rather than guessing.
|
|
fs.appendFileSync(file, `\n// coverage-read-evidence: ${randomUUID()}\n`);
|
|
return { path: file, content: fs.readFileSync(file, 'utf8') };
|
|
});
|
|
return runSkillTest({
|
|
prompt: `${entry.instructions(cwd!)}
|
|
|
|
You are on the feature/billing branch. The base branch is main.
|
|
This is a test project — there is no remote, no PR to create.
|
|
The source code is in ${cwd}/src/billing.ts.
|
|
Existing tests are in ${cwd}/test/billing.test.ts.
|
|
|
|
Produce the ASCII coverage diagram showing which code paths are tested and which have gaps.
|
|
Output the diagram directly, name both billing functions, and include a coverage summary.
|
|
End with one JSON line listing the functions with and without test coverage:
|
|
{"tested": ["<function>", ...], "untested": ["<function>", ...]}
|
|
Do not modify the supplied source or tests.`,
|
|
workingDirectory: cwd, maxTurns: 15,
|
|
allowedTools: ['Bash', 'Read', 'Write', 'Edit', 'Glob', 'Grep'],
|
|
timeout: JUDGE_MS, testName: entry.id, runId, signal,
|
|
});
|
|
},
|
|
validate: result => {
|
|
logCost(entry.id, result);
|
|
const verdict = coverageAuditVerdict(result, { cwd: cwd!, source: files[0]!, tests: files[1]! });
|
|
console.log('Coverage audit evidence:', JSON.stringify(verdict));
|
|
if (!verdict.passed) throw new Error(`Coverage audit: ${verdict.failures.join('; ')}`);
|
|
},
|
|
});
|
|
} finally {
|
|
// Each configured retry owns a fresh fixture and fresh read markers.
|
|
if (cwd) try { fs.rmSync(cwd, { recursive: true, force: true }); } catch {}
|
|
}
|
|
}, CAPTURE_MS);
|
|
});
|
|
|
|
afterAll(async () => { await finalizeEvalCollector(evalCollector); });
|