Skip to content

feat(workflow): H1->SpecDD auto-advance — sentinel hook + dispatch script + M3 imperatives (Phase 1)#103

Merged
sgwannabe merged 5 commits into
mainfrom
feat/h1-specdd-auto-advance
Apr 25, 2026
Merged

feat(workflow): H1->SpecDD auto-advance — sentinel hook + dispatch script + M3 imperatives (Phase 1)#103
sgwannabe merged 5 commits into
mainfrom
feat/h1-specdd-auto-advance

Conversation

@sgwannabe

Copy link
Copy Markdown
Contributor

Summary

Phase 1 of 2 — addresses user-reported gap: /pf:new did not auto-advance into SpecDD after H1 freeze (design-approved.json lock written but no Task dispatch). Phase 2 (preview server after H2) follows in a separate PR.

Three-layer fix:

  • NEW scripts/dispatch-spec-cycle.sh — machine-verifiable lock validator. Mirrors scripts/h1-modal-helper.sh style (single-line JSON via python3 for fail-closed encoding).
  • NEW plugins/preview-forge/hooks/post-h1-signal.py — PostToolUse hook on Write. When runs/<id>/design-approved.json is written and chosen_preview.json.lock is already present, drops runs/<id>/.h1-frozen-signal + appends a Blackboard h1.frozen row. Bounded stdin (4 MiB cap, MemoryError catch — W1.3 hardening). Always exits 0.
  • MODIFIED hooks.json (added new PostToolUse Write matcher; existing entries preserved), chief-engineer-pm.md §3.9 (imperative Task block), run-supervisor.md §1 (sentinel polling rule), commands/new.md L11 (zero-input dispatch contract).

Side-effect / breaking-change table

Risk Status
Existing valid /pf:new runs that auto-advanced via M3 markdown No regression — markdown is additive (§3.9 sits after existing §3 H1 / A-5 sections; old text untouched).
hooks.json existing PostToolUse entries (askuser-enforcement, auto-retro-trigger) Unchanged. New matcher appended as a sibling object; JSON validates.
PostToolUse hook fires on EVERY Write — perf impact? Negligible. Hook short-circuits at the regex match in <1 ms; only does fs work if path matches runs/*/design-approved.json AND chosen_preview.json.lock exists.
Markdown imperatives affecting tests/test-advocate-boilerplate.sh No — boilerplate hash test scopes to advocate files only; M3 / run-supervisor / new.md are out of scope. Verified green post-edit.
run-supervisor.md polling rule executable in M1's mental model? Yes — same find polling pattern already used elsewhere in this file (Blackboard polling §3). The runs/.last-spec-dispatch watermark is now seeded with an epoch-0 touch on first poll (codex P1 fix below).
All 13+ regression suites green Yes (verified).

Verification

Unit:

  • bash scripts/dispatch-spec-cycle.sh <empty_dir> → exit 2 + stderr (correct).
  • bash scripts/dispatch-spec-cycle.sh <dir_with_3_files> → exit 0 + JSON byte-shape {"action":"dispatch","agent":"SPEC_LEAD","input_dir":"...","run_id":"..."} (correct).
  • python3 -c 'import json; json.load(open("plugins/preview-forge/hooks/hooks.json"))' — passes.
  • post-h1-signal.py integration: with both lock files present + CLAUDE_PLUGIN_ROOT pointed at the plugin, sentinel + Blackboard row both written. Without chosen_preview.json.lock, no sentinel written (correctly silent).

Regression (all green):

  • scripts/verify-plugin.sh — Pass 57 / Fail 0
  • tests/fixtures/security/verify-security.sh
  • tests/test-advocate-boilerplate.sh
  • for p in standard pro max; do tests/e2e/mock-bootstrap.sh "$p"; done — all PASS
  • tests/fixtures/lesson07-regression/verify-lesson07.sh
  • tests/fixtures/cache-concurrency/test-{race-window,self-heal,5way}.sh
  • tests/fixtures/filled-ratio-gating/verify.sh
  • tests/fixtures/h1-modal-swap/verify.sh
  • tests/fixtures/spec-anchor-convergence/verify.sh

Codex review

One pass. P1: 1 (applied), P2: 2 (deferred), P3: 0.

P1 (applied)

  • Initialize .last-spec-dispatch before polling H1 signals (run-supervisor.md). Fresh install had no watermark → find -newer returned 0 + exit 1, making the first H1 signal invisible. Fix: documented [ -f runs/.last-spec-dispatch ] || touch -t 197001010000 runs/.last-spec-dispatch guard before the polling find so the baseline is always discoverable.

P2 (deferred to follow-up PR)

  • Per-run dispatch tracking instead of one shared watermark. Single runs/.last-spec-dispatch can lose events if multiple runs reach H1 between polls. Mitigation suggestion: switch idempotency marker to runs/<id>/.spec-dispatched per-run flag. Defer because (a) Preview Forge's standard usage is one run at a time and (b) Phase 2 will revisit the standup loop anyway.
  • Require mitigations.json in dispatch-spec-cycle.sh. spec-lead.md treats it as required input and /pf:design can regenerate it after override; current validator passes without it. Defer because (a) the current 3-file gate matches what the plan explicitly enumerated and (b) tightening to 4 files is a separable spec/policy change worth its own review.

Refs

  • User-reported gap (Phase 1 of plan noble-enchanting-floyd): /pf:new did not auto-advance into SpecDD after H1 freeze.
  • Phase 2 (preview server after H2) — separate PR.

🤖 Generated with Claude Code

Validates chosen_preview.json.lock + design-approved.json + idea.spec.json
in <run_dir>; emits dispatch JSON for SPEC_LEAD on success (exit 0),
exit 2 + stderr on missing/empty artifact, exit 1 on bad arg. Mirrors
scripts/h1-modal-helper.sh contract style (single-line JSON via python3
for fail-closed encoding). Phase 1 of 2 — addresses user-reported gap
where /pf:new did not auto-advance into SpecDD after H1 freeze.
…son (Phase 1)

PostToolUse hook on Write tool: when runs/<id>/design-approved.json is
written and chosen_preview.json.lock already exists, drops a
.h1-frozen-signal sentinel and appends a Blackboard h1.frozen row so
M1 run-supervisor's standup loop can dispatch SpecDD without user
re-prompting. Bounded stdin read (4MiB cap, MemoryError catch — W1.3
hardening). Always exits 0 (advisory). Registered in hooks.json
PostToolUse with matcher Write; existing hook entries preserved.
…Phase 1)

- chief-engineer-pm.md §3.9: imperative Task block for auto-dispatching
  SPEC_LEAD immediately after design-approved.json lock; references
  scripts/dispatch-spec-cycle.sh for verification.
- run-supervisor.md §1: standup-tick polling rule for
  runs/*/.h1-frozen-signal sentinel with idempotent
  runs/.last-spec-dispatch marker.
- commands/new.md L11: replaces vague 'after design approval' phrasing
  with explicit immediate-dispatch contract (zero-input, verifiable).

LLM trust hardening — three places that previously implied auto-advance
now state it imperatively, matching the README 'human clicks twice'
promise.
…poll (codex P1)

Without an initial 'runs/.last-spec-dispatch' file, 'find -newer' returns
no matches (and exits 1) on fresh installs, making the first H1 signal
invisible to the standup polling loop. Document an epoch-0 touch guard
so the find always starts with a discoverable baseline. Addresses codex
P1 from Phase 1 review.
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@sgwannabe has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 14 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 21 minutes and 14 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db240dbc-2bb9-4e9d-b474-1b5311b38941

📥 Commits

Reviewing files that changed from the base of the PR and between 86053b0 and 3d2c75b.

📒 Files selected for processing (6)
  • plugins/preview-forge/agents/meta/chief-engineer-pm.md
  • plugins/preview-forge/agents/meta/run-supervisor.md
  • plugins/preview-forge/commands/new.md
  • plugins/preview-forge/hooks/hooks.json
  • plugins/preview-forge/hooks/post-h1-signal.py
  • scripts/dispatch-spec-cycle.sh
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/h1-specdd-auto-advance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06eedbdfff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


검증 스크립트:
```bash
bash scripts/dispatch-spec-cycle.sh runs/<id>/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Call dispatch validator via plugin-root absolute path

The new imperative uses bash scripts/dispatch-spec-cycle.sh runs/<id>/, but Preview Forge sessions run from user workspaces (created by pf init) where scripts/ is not present, and M1 pre-flight explicitly avoids operating inside the plugin repo. In that normal runtime context this command becomes No such file or directory, so H1→SpecDD auto-advance cannot produce the dispatch JSON. Use the same ${CLAUDE_PLUGIN_ROOT}/../../scripts/... form already used in this file for other scripts.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지적 정확합니다. 사용자 workspace(pf init로 생성된 환경)에는 plugin repo의 scripts/ 디렉터리가 없으므로 bare scripts/dispatch-spec-cycle.sh 호출은 No such file or directory로 실패합니다.

§3.9 검증 스크립트 호출을 같은 파일의 다른 §3 helper들(generate-gallery.sh, open-browser.sh, h1-modal-helper.sh, generate-spec-anchor-audit.py)과 동일한 ${CLAUDE_PLUGIN_ROOT}/../../scripts/... 절대 경로 형태로 통일했습니다 (commit 3d2c75b).

전체 회귀 suite (verify-plugin / security / e2e standard·pro·max / advocate-boilerplate / lesson07 / cache-concurrency 3종 / filled-ratio-gating / h1-modal-swap / spec-anchor-convergence) 모두 그린 확인했습니다.

- chief-engineer-pm.md §3.9: replace bare `scripts/dispatch-spec-cycle.sh`
  with `${CLAUDE_PLUGIN_ROOT}/../../scripts/dispatch-spec-cycle.sh` so the
  H1->SpecDD auto-advance validator works in user workspaces (where the
  plugin repo's `scripts/` directory is not present), matching the form
  already used by generate-gallery.sh / open-browser.sh / h1-modal-helper.sh
  / generate-spec-anchor-audit.py in this same file.

Refs PR #103 review comments

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sgwannabe sgwannabe merged commit 17f354a into main Apr 25, 2026
7 checks passed
@sgwannabe sgwannabe deleted the feat/h1-specdd-auto-advance branch April 25, 2026 16:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d2c75bfe1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


검증 스크립트 (다른 §3 helper와 동일한 plugin-root 절대 경로 형태 — 사용자 workspace에서 `scripts/`가 없을 때도 동작):
```bash
bash "${CLAUDE_PLUGIN_ROOT}/../../scripts/dispatch-spec-cycle.sh" runs/<id>/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Whitelist dispatch validator in M3 Bash scope

§3.9 now requires M3 to run dispatch-spec-cycle.sh, but this agent’s own allowed_scope still limits Bash to generate-gallery.sh and open-browser.sh; that contradiction means the model can legitimately refuse the new command and stall H1→SpecDD auto-advance even when the hook signal exists. Please add this script to the Bash allowlist (or move execution to an agent that already allows it) so the new imperative is actually executable.

Useful? React with 👍 / 👎.

Comment on lines +117 to +119
tool = payload.get("tool_name") or payload.get("tool") or ""
if tool != "Write":
return 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect H1 completion on Edit writes too

The new hook only handles Write, so if design-approved.json is updated through Edit (e.g., rerunning or correcting Gate H1 on an existing run file), no .h1-frozen-signal is emitted and the SpecDD auto-dispatch path is skipped. This should mirror the existing post-write hooks that handle multiple edit tools to avoid missing valid freeze events.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant