* test(#3606): pin hook-kind coverage in the wired guard * fix(#3606): validate hook-kind coverage at call sites and dispatch generically * fix(#3606): address review - segment-granular narrowing, zero-coverage diagnosis, quick.md, fragment extraction * fix(#3606): drop stale shrink-ack, export HOOK_GROUP_KINDS, dedupe scanner regex * chore(#3606): regenerate install-tree fixtures for new wave-post fragment * chore(#3606): sync canonical launcher preamble into new fragment * fix(#3606): keep fragment preamble ahead of first gsd_run mention * fix(#3606): revert sync script's preamble move in explore.md * chore(#3606): regenerate derived manifests post-rebase * chore(#3606): allowlist peer test files - base was red on the count lane * chore(#3606): regenerate inventory for peer's verify-command-grounding doc * chore(#3606): grounding test maps to its own module by longest prefix * chore(#3606): backfill changeset pr number --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -644,7 +644,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
||||
WAVE_PRE_HOOKS_JSON=$(gsd_run loop render-hooks execute:wave:pre --raw)
|
||||
```
|
||||
|
||||
If a contribution's `activeHooks` entry provides an alternate wave dispatch, follow it instead of step 3's inline loop; otherwise proceed to step 3.
|
||||
**Contribution dispatch:** inject every `kind == "contribution"` fragment per @gsd-core/references/loop-hook-dispatch.md (skip when none); one naming an alternate wave dispatch replaces step 3's inline loop. Then proceed to step 3.
|
||||
|
||||
3. **Spawn executor agents:**
|
||||
|
||||
@@ -1014,40 +1014,9 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
||||
|
||||
**If `activeHooks` is empty or absent:** Skip silently to step 5.8.
|
||||
|
||||
⚠ **Validate `check` before shell use** (third-party manifest input) — `loop-hook-dispatch.md` § `gate`.
|
||||
**Contribution dispatch:** inject every `kind == "contribution"` fragment per @gsd-core/references/loop-hook-dispatch.md (skip when none), before the gates below.
|
||||
|
||||
**For each active entry where `kind == "gate"`** (process in array order), run the gate check — a `predicate` gate (ADR-2008 / #2008) substitutes `gsd_run check predicate --predicate '<predicate JSON>' --phase-number "${PHASE_NUMBER}" --raw`:
|
||||
|
||||
```bash
|
||||
GATE_RESULT=$(gsd_run check ${hook.check.query} "${PHASE_NUMBER}" --raw)
|
||||
CHECK_EXIT=$?
|
||||
```
|
||||
|
||||
**Step 1 — did the CHECK COMMAND itself succeed?**
|
||||
|
||||
If the check command failed (non-zero `CHECK_EXIT`, empty output, or unparseable JSON):
|
||||
- `onError == "halt"` → treat as a fatal error: stop wave completion, do NOT proceed to step 5.8, and surface: `⚠ Gate check command failed ({hook.capId}): command error. Resolve before continuing.`
|
||||
- `onError == "skip"` → log a warning and continue to the next hook. Do NOT read `GATE_RESULT.block`.
|
||||
|
||||
**Step 2 — read `GATE_RESULT.block` (boolean).** This step is only reached when the command succeeded.
|
||||
|
||||
- **Blocking gate (`hook.blocking == true`) AND `GATE_RESULT.block == true`:** HALT — stop wave completion, do NOT proceed to step 5.8, and present:
|
||||
|
||||
```
|
||||
⚠ Wave {N} blocked by capability gate ({hook.capId}): {GATE_RESULT.message}
|
||||
Resolve before continuing to next wave.
|
||||
```
|
||||
|
||||
This halt is **not** bypassed by `onError` — `onError` only covers command errors (step 1 above), not the gate's block decision.
|
||||
|
||||
- **Non-blocking gate (`hook.blocking == false`):** never halts. If `GATE_RESULT.block` is `true` (or non-empty `message`), print `⚠ {hook.capId} advisory (wave {N}): {GATE_RESULT.message}`, then:
|
||||
- If `GATE_RESULT.spawn_mapper == true` OR `GATE_RESULT.directive == "auto-remap"`: spawn `gsd-codebase-mapper` per `execute-phase/steps/codebase-drift-gate.md`; pass `--paths {GATE_RESULT.affected_paths}`. Continue regardless (wave NOT failed by remap failure).
|
||||
- Otherwise: continue after advisory.
|
||||
- If block `false` and no `message`: continue silently.
|
||||
|
||||
- **Blocking gate (`hook.blocking == true`) AND `GATE_RESULT.block == false`:** continue silently.
|
||||
|
||||
**When all active gates are processed without a blocking halt:** continue to step 5.8.
|
||||
**For each active entry where `kind == "gate"`** (process in array order): read and execute `gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md` for the full evaluation contract (check validation, `onError`, blocking semantics, mapper spawn). When all active gates are processed without a blocking halt, continue to step 5.8.
|
||||
|
||||
5.8. **Handle test gate failures (when `WAVE_FAILURE_COUNT > 0`):**
|
||||
|
||||
@@ -1202,7 +1171,7 @@ VERIFY_POST_HOOKS_JSON=$(gsd_run loop render-hooks verify:post --raw)
|
||||
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
||||
```
|
||||
|
||||
Resolve active step hooks from `VERIFY_POST_HOOKS_JSON` where `kind == "step"` and `ref.skill == "secure-phase"`.
|
||||
Dispatch every `kind == "step"` hook per @gsd-core/references/loop-hook-dispatch.md (skip when none). The secure-phase routing below applies when that specific hook is active.
|
||||
|
||||
If no active secure-phase step hook exists: skip.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user