Skip to content

fix(hooks): merge end-of-turn hook — recap via reason (supersede #81), 3 branches + visible marker - #89

Merged
artyhoo merged 1 commit into
mainfrom
feat/eot-hook-merged
May 21, 2026
Merged

fix(hooks): merge end-of-turn hook — recap via reason (supersede #81), 3 branches + visible marker#89
artyhoo merged 1 commit into
mainfrom
feat/eot-hook-merged

Conversation

@artyhoo

@artyhoo artyhoo commented May 21, 2026

Copy link
Copy Markdown
Owner

What & why

The end-of-turn hook diverged into three versions; #81 (cfa28a3, currently on main) and d695ac5 made opposite assumptions about which Stop-hook field reaches the model. This PR settles it by evidence and merges the best of all three.

Load-bearing finding (verified dual-channel, [[no-paid-llm-in-ci]]-compatible — docs + WebSearch, no API):

  • On a Stop hook decision:"block", reason reaches the model — CC hooks docs (Stop decision-control): «reason must be provided for Claude to know how to proceed»; «the agent gets one more turn with the reason injected». Corroborated by independent WebSearch.
  • systemMessage is user-UI only — does NOT reach the model.

Therefore #81 is functionally broken: it delivers the entire recap instruction via systemMessage (user-only), so the model never receives the prompt to write the recap block. Its reason is a static placeholder. d695ac5/redesign correctly use reason (and d695ac5's in-code "systemMessage НЕ доходит" comment is verified-accurate — it was the 1.5h-later fix for #81's delivery bug). This PR supersedes #81's delivery bug.

A second-channel catch worth noting: a claude-code-guide sub-agent first answered "reason is user-only" by generalizing the UserPromptSubmit doc row to the Stop event (T16 pattern-matching-on-name). The independent WebSearch channel corrected it. Stop ≠ UserPromptSubmit on reason semantics.

Best-of-both merged (maintainer-confirmed forks 2026-05-21)

Axis Resolution Source
Delivery reason (model) + short systemMessage human note supersede #81 bug
Visible block restore forced «## 🟢 Простыми словами» header #81 — human scannability
Branches 3 (work / question / combined) #81's combined-case + redesign content
Anchor + drift verdict + recommendation-first kept redesign (cf650d4, D1–D3)
Statelessness preserved (no /tmp, no aggregation) all three

Branch C (long answer AND trailing fork-question) carries both the work recap (+ drift verdict) AND recommendation-first/fork-challenge — the 2-branch "long-wins" version dropped the recommendation nudge exactly when a fork is on the table.

Tests (2026-05-21, synthetic JSONL fixtures)

bash -n clean · Branch A (long→work recap, no question section) · Branch B (question→fork-challenge + recommendation-first) · Branch C (long+question→both) · silent on bare tool_use (exit 0) · AskUserQuestion→Branch B · anchor aiTitle-primary + first-user-msg fallback + graceful default · §1.8 skip smoke-test exit 0, no stderr.

Not a capability commit

Modifies existing <50-LOC-logic CC hook; no new dep; not under packages/. @cc-only-rationale retained. No new SSOT entry (existing #8/#9/#20 cover the anchoring/hook family). Escape-hatch Prior-art: trailer present.

§1.7 Self-reflection

Forward-check (what future work must honor)

Backward-check (existing rules/claims this PR leans on, verified)

Post-merge note

chore/ssot-karpathy-skills-ref (cf650d4) still carries the older 2-branch redesign hook. When that branch merges, its hook change will conflict with this one — resolve toward this (newer, 3-branch, reason-delivery) version; do not silently revert.

…ede #81), 3 branches + visible marker

#81 (cfa28a3, on main) delivered the recap INSTRUCTION via systemMessage, which
is user-only and never reaches the model — verified dual-channel (CC hooks docs
Stop decision-control: "reason must be provided for Claude to know how to proceed"
+ WebSearch). So #81's recap prompt was never seen by the model. d695ac5/redesign
correctly use `reason` (injected; agent gets one more turn). This merges best-of-all-three:

- reason-delivery (model receives) + short systemMessage human note   [supersede #81 delivery bug]
- forced visible «## 🟢 Простыми словами» header                      [from #81 — human scannability]
- session-goal anchor (aiTitle→first-msg fallback) + 3-way drift verdict + recommendation-first  [from redesign]
- 3 branches incl. combined long+question (keeps recommendation-first when a fork is on the table)
- stateless-fire preserved (no /tmp, no aggregation/isMeta)

Tested 2026-05-21: bash -n; branches A/B/C; silent on bare tool_use; AskUserQuestion→B;
anchor aiTitle-primary + first-user-msg fallback + graceful default; §1.8 skip smoke-test exit 0.

Prior-art: skipped — modifies existing <50-LOC-logic CC hook (delivery-channel merge), no new capability per dual-implementation-discipline §2(iv); SSOT #8/#9/#20 cover the anchoring/hook family.
@artyhoo
artyhoo merged commit 156b8a9 into main May 21, 2026
17 checks passed
artyhoo added a commit that referenced this pull request May 21, 2026
…#91)

Provenance for the hook redesign whose IMPL already shipped (#89 — session-anchored
dual-audience recap with aiTitle goal anchor). The design research-patch (D1-D6
locked, Rounds 1-4 + decisions) was committed on feat/eot-hook-anchor +
chore/ssot-karpathy-skills-ref but never reached main. Brought as the single file
only (verified identical across both branches; no branch legacy) onto a fresh
branch off origin/main.

Prior-art: skipped — landing an already-authored, approved design research-patch; impl already on main via #89, no new capability introduced.
artyhoo added a commit that referenced this pull request May 21, 2026
Lands the maintainer's settings.json safety-hardening that was stranded
uncommitted on the superseded chore/ssot-karpathy-skills-ref branch (the only
non-superseded residue there — every other file already on main via #89/#92/#93/
#94/#96/#97/#98). Committed verbatim.

On-thesis: this is edit-time (earliest-channel) enforcement of project safety
rules that previously lived only as memory/prose — "no git reset hard ever",
no force-push, no skip-verify. The harness now blocks them before they run:
  - destructive git: force/mirror push, push to main/master, skip-verify commit,
    hard reset, checkout discard, branch force-delete, filter-branch, update-ref
  - destructive fs: recursive delete, shred, dd, mkfs, sudo
  - pipe-to-shell: curl-to-shell, wget-to-shell; raw netcat/socat
  - secret exfil: gh secret set/delete, gh auth logout, reads of credential dirs
    (ssh / aws / gnupg / gh config) and dotenv files
  - self-protection: .git/hooks, .husky, settings.json (Edit/Write deny)
Also: portable $CLAUDE_PROJECT_DIR hook paths + ask-question-reminder.sh permission.

Prior-art: skipped — harness config hardening (permission deny-list), no new capability code or dependency
artyhoo added a commit that referenced this pull request May 21, 2026
…#106)

Append + in-place refinement of the living history book (v1 technical
+86 lines, v2 literary +78). Narrates post-#93 events: the end-of-turn
hook saga (#81 broken via systemMessage → #89 reason-channel fix),
#94 AskUserQuestion hook, principles 11/12/13 landing, the #96/#97
claim-scan experiment (H0 not rejected), #90 recommendation-gate, and
the niche-among-companions chapter. Colophon extended (chapters III–XII,
patches to 2026-05-21, PR #85#99). Preserves continuation work that was
stranded uncommitted on the superseded chore/ssot-karpathy branch.

Prior-art: skipped — narrative doc continuation, no new capability or dependency.
@artyhoo
artyhoo deleted the feat/eot-hook-merged branch May 22, 2026 18:10
artyhoo added a commit that referenced this pull request May 31, 2026
…brella done.md (#307)

Closes the companion-reuse-deep-dive umbrella tail (PRs #248-251 already merged):

- SSOT: 3 new append-only rows #88 (aif-handoff autoQueueMode LOGIC, ADOPT
  VOCABULARY + REFERENCE), #89 (omo session-plan-affinity, ADOPT VOCABULARY),
  #90 (Superpowers brainstorming scope-assessment, ADOPT VOCABULARY) — content
  copied from the merged R-phase patches; bare-ID column per principle-08 loader.
  #88 verdict-column normalized to clean `ADOPT VOCABULARY` with the faceted
  `+ REFERENCE` detail moved into the rationale column (principle-11 F2 convention,
  matches faceted rows #86/#87).
- SSOT #67: additive note appended to «Trigger to revisit» only; REJECT verdict
  for the full Kanban runtime unchanged.
- Resolved [next-available-slot] placeholders in the 3 source patches → #88/#89/#90.
  Devin (Sub-wave C) creates no row — its 2 descriptive placeholder mentions left as-is.
- done.md written per CLAUDE.md umbrella-closure schema (Final PR #251).

Verified: principle suite 153 pass / 4 skip; markdownlint clean.

Prior-art: skipped — doc-only edit (SSOT register rows + umbrella done.md + research-patch placeholder resolution); no new capability, dependency, or code.
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