mirror of
https://github.com/garrytan/gstack.git
synced 2026-06-17 07:10:12 +02:00
fix: address pre-landing review (codex) on the carve
- cso section: add a scope-gate header so '--owasp' (and other scoped modes)
run only their selected phases, not every phase bundled in the section
('execute in full' no longer overrides Mode Resolution).
- carve-guard-checks: gateAfterStop now compares against the LAST STOP, not the
first, so a gate stranded between two STOPs in a multi-STOP skeleton fails.
- TODOS: behavioral section-loading hermeticity (verifier matches global-install
path, not the fixture) — pre-existing in auq-sdk-capture.ts, deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2312,3 +2312,25 @@ from there.
|
||||
**Effort:** M (human ~2d, CC ~4h).
|
||||
|
||||
**Depends on:** `transcript-section-logger.ts` real-session-drift rework.
|
||||
|
||||
### P2: Harden behavioral section-loading test hermeticity
|
||||
|
||||
**What:** `captureSectionReads` in `test/helpers/auq-sdk-capture.ts` accepts ANY
|
||||
Read whose path matches `sections/<file>.md`. The skeleton's STOP-Read directive
|
||||
points at the gstack-root install path (`scripts/resolvers/sections.ts` builds it
|
||||
from `ctx.paths.skillRoot`), not the planted fixture copy. So a run can satisfy
|
||||
the section-read assertion by reading the GLOBAL install's section instead of the
|
||||
hermetic fixture.
|
||||
|
||||
**Why:** A behavioral test that passes by reading the global install doesn't prove
|
||||
THIS branch's carved section loads. If the fixture's section were broken but the
|
||||
global install's weren't, the test would still pass.
|
||||
|
||||
**Context:** Codex outside-voice finding on the carve-guard ship (v1.57.0.0).
|
||||
Pre-existing in `auq-sdk-capture.ts` — affects `skill-e2e-ship-section-loading`,
|
||||
`skill-e2e-plan-ceo-review-section-loading`, and the new
|
||||
`carve-section-loading.test.ts`. Fix: match the fixture's ABSOLUTE sections path
|
||||
(the `planDir` copy), not a bare `sections/<file>.md` regex; or rewrite the STOP
|
||||
path to the fixture during the run.
|
||||
|
||||
**Effort:** S (human ~3h, CC ~30min). **Depends on:** None.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<!-- AUTO-GENERATED from audit-phases.md.tmpl — do not edit directly -->
|
||||
<!-- Regenerate: bun run gen:skill-docs -->
|
||||
**Scope gate (read first).** This section holds every scope-dependent phase (2-11), but you run ONLY the phases your resolved mode selected back in `## Mode Resolution` (always-loaded in the skeleton). Phases 0, 1, 12, 13, 14 always run; Phases 2-11 are scope-gated. "Execute in full" means work through this section applying that selection, NOT run a phase your mode did not select just because its prose lives here. Example: `--owasp` runs Phase 9 from this section, not Phases 2-8/10/11.
|
||||
|
||||
### Phase 2: Secrets Archaeology
|
||||
|
||||
Scan git history for leaked credentials, check tracked `.env` files, find CI configs with inline secrets.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
**Scope gate (read first).** This section holds every scope-dependent phase (2-11), but you run ONLY the phases your resolved mode selected back in `## Mode Resolution` (always-loaded in the skeleton). Phases 0, 1, 12, 13, 14 always run; Phases 2-11 are scope-gated. "Execute in full" means work through this section applying that selection, NOT run a phase your mode did not select just because its prose lives here. Example: `--owasp` runs Phase 9 from this section, not Phases 2-8/10/11.
|
||||
|
||||
### Phase 2: Secrets Archaeology
|
||||
|
||||
Scan git history for leaked credentials, check tracked `.env` files, find CI configs with inline secrets.
|
||||
|
||||
@@ -114,12 +114,14 @@ export function checkOrdering(root: string, guard: CarveGuard): string[] {
|
||||
// 5. The post-STOP gate fires after the last STOP (review skills).
|
||||
const gate = guard.staticInvariants.gateAfterStop;
|
||||
if (gate) {
|
||||
const firstStop = skeleton.indexOf(STOP);
|
||||
// Gate must fire after the LAST STOP (once all section work returns), not just
|
||||
// the first — for multi-STOP skeletons a gate between two STOPs is stranded.
|
||||
const lastStop = skeleton.lastIndexOf(STOP);
|
||||
const lastGate = skeleton.lastIndexOf(gate);
|
||||
if (lastGate < 0) {
|
||||
failures.push(`gateAfterStop marker missing from skeleton: "${gate}"`);
|
||||
} else if (firstStop >= 0 && lastGate < firstStop) {
|
||||
failures.push(`gateAfterStop "${gate}" appears before the STOP (stranded above it)`);
|
||||
} else if (lastStop >= 0 && lastGate < lastStop) {
|
||||
failures.push(`gateAfterStop "${gate}" appears before the last STOP (stranded above it)`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user