Files
gbrain/test/fixtures/hook-transcript.jsonl
Garry TanandClaude Fable 5 c2cc8b0207 v0.45.1.0 feat(context): hook-lane feedback loop + cross-turn dedupe for the harness hooks (#4025)
* refactor(context): extract pure gateVolunteeredPointers (no behavior change)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(context): volunteer-shaped resolve IPC — channel/cwd/volunteer fields, handler-result widening, server-side gate + validated source + delivery-point logging; listener on both engines

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(cli): gbrain volunteer-hook — one-shot harness hook entry (IPC-first; Postgres-only fallback; startup-hook-exempt)

T0 evidence: a UserPromptSubmit hook's additionalContext is recorded in the
session transcript as a structured hook_additional_context attachment and
transcript_path is stable across turns — cross-turn dedupe reads ONLY those
attachments (never raw tail substrings). Live smoke: seeded brain + running
serve → pointer injected via IPC at 0.43s wall, turn 2 suppressed, one event
banked channel=claude-code.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(recipes): claude-code-reflex + codex-reflex (experimental) hook adapters

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(doctor): volunteer_channels per-adapter visibility

Engine-aware sibling of retrieval_reflex_health: groups
context_volunteer_events by channel (7d) so operators can see which push
adapters fire; message separates installed-but-unregistered from
registered-but-quiet; pre-v117 tolerant; info-only status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(context): hook-lane feedback loop + cross-turn dedupe — converge cathedral-3 onto the #3975 harness hooks

The #3975 hook lane volunteered pages invisibly (nothing logged to
context_volunteer_events) and re-volunteered the same page every turn an
entity was mentioned (no priorContextText). This convergence ports the
cathedral-3 branch's two gap-fills into the blessed lane and retires its
parallel surface:

- transcripts: parseTranscript extracts injectedContextBlocks (structured
  hook_additional_context attachments — the T0-verified recorded shape of
  our own injections; never raw-turn substring matching)
- hook user-prompt: feeds those blocks as priorContextText (volunteer once
  per session, not once per mention) + sends a feedback-loop channel
  (--harness <claude-code|codex>, default claude-code); hook joins
  STARTUP_HOOK_SKIP_COMMANDS (per-prompt check-update spawn class, grep-pinned)
- turn-context: result exposes post-trim volunteered survivors
- resolve-ipc: additive TurnContextRequest.channel + onTurnContextDelivered
  seam (fires post-write only — abandoned blocks are never counted)
- serve: delivery callback logs volunteered pages + pointers per channel
- doctor: volunteer_channels check (per-channel 7d visibility; separates
  installed-but-unregistered from registered-but-quiet; pre-v117 tolerant)

Retired (never released): gbrain volunteer-hook, hook-adapters.ts,
claude-code-reflex + codex-reflex recipes, the volunteer-shaped resolve wire
extension. Kept: gateVolunteeredPointers extraction, VolunteerChannel
claude-code/codex values, the real hook-transcript fixture.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: regenerate llms bundles for the hook-lane doc updates

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: coverage for the hook-lane delivery wiring

Extract logTurnContextDeliveryFireAndForget into volunteer-events.ts so the
shipped serve callback is unit-testable (channel fallback, sessionId clamp,
pointer+page rows in ONE synchronous registration — the double dynamic import
could register the pending write too late to survive process exit). Direct
units for isVolunteerChannel, explicit-channel logDeliveredReflexPointers,
and the pure gate (idempotency pin; stale parity claim in its doc corrected).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: pre-landing review fixes — 7-reviewer batch

Multi-confirmed: volunteer_channels now runs on the LOCAL doctor path too
(buildChecks; docs pointed there); transient DB errors no longer misreported
as pre-v117; priorContextText deduped + 32KB-capped hook-side. Red team:
delivery counts reconciled against the hook heartbeat (CAUTION when mostly
degraded — write-accept isn't injection); IPC clamp drops advisory
priorContextText BEFORE any window turn; foreign hook_additional_context
blocks (no gbrain marker) excluded from dedupe input; engine-aware quiet
guidance (Postgres brains aren't told to chase hook registration); 2MB dedupe
horizon documented. Security: wire channel claims restricted to harness
channels. DRY: VOLUNTEER_CHANNELS single source, shared reflexPointerRationale,
SESSION_ID_MAX_LEN shared with the op clamp; dead channel param dropped from
logDeliveredReflexPointers. Tests: budget-trim volunteered invariant under
real trim pressure, poll/ordering-based delivery-seam tests (no fixed sleeps),
doctor branch + engine-parity-row tests, wiring source pins, cap pins;
fixture pruned to load-bearing lines (environment inventory removed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: adversarial-review fixes — cross-model P1 + Claude adversarial batch

P1 (codex structured review + Claude adversarial, cross-model): the remote
run_doctor path now threads the caller's source scope into
volunteer_channels — a source-bound token can no longer see other sources'
activity counts/timestamps (must-never-violate source-isolation rule);
local trusted doctor stays brain-wide. Claude adversarial: IPC connection
handler gains a one-request re-entrancy guard (trailing bytes mid-await
double-processed the same line → duplicate handler work + duplicate
delivery logging); partial client-side trims now heartbeat as reason
'trimmed' (delivery-count drift visibility); heartbeat reconciliation uses
the same 7-day window as the counts + a 5-sample floor; one oversized
dedupe block no longer evicts all smaller ones (continue, not break);
quiet-channel guidance no longer claims old serves attribute hook traffic
to reflex (they log nothing); 'transient' claim softened to evidence;
marker-filter + unknown-channel-default comments state their honest limits.
Pins: scoped-query SQL/params, re-entrancy single-fire, updated wiring grep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: bump version and changelog (v0.45.1.0)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: restamp bootstrap runbook + regenerate vendored template repo for v0.45.1.0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: update project documentation for v0.45.1.0

Post-ship /document-release pass: fold the post-doc review fixes into the
reference docs (KEY_FILES: source-scoped remote volunteer_channels + heartbeat
reconciliation, 32KB-capped dedupe input, marker filter, IPC one-request
guard + clamp order), fix BRAINBENCH's now-stale memoryless-hook rationale,
and mark the doctor-check half of the push-context TODO shipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: cross-model doc-review fixes for v0.45.1.0

Codex doc review against the shipped diff: push-context channel table gains
the harness-hook row (three-channels claim was stale), the guide states the
PGLite-socket topology limit and the bounded dedupe horizon, delivery-point
claims are hedged to match the code (write-accept isn't proof of injection;
the doctor reconciles against the hook heartbeat, which can't inspect
registration), BRAINBENCH's future-tense hooks-PR sentence updated now the
hook has landed, and the adapter-flip + resolver-channel TODOS reflect the
current lane count. llms-full.txt regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(hook): document --harness in the user-prompt usage text

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 22:45:44 -07:00

10 lines
8.4 KiB
JSON

{"parentUuid":null,"isSidechain":false,"promptId":"78f45f0e-2c39-4b1e-9d8f-95398888a476","type":"user","message":{"role":"user","content":"Reply with exactly: OK"},"uuid":"c5412863-c32f-4238-befe-211fd8e9e40a","timestamp":"2026-08-07T22:57:11.762Z","permissionMode":"default","promptSource":"sdk","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"c5412863-c32f-4238-befe-211fd8e9e40a","isSidechain":false,"attachment":{"type":"deferred_tools_delta","content":["non-hook attachment payload (pruned)"]},"type":"attachment","uuid":"0914b2ae-9fa3-4835-8c47-1340372590f9","timestamp":"2026-08-07T22:57:11.761Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"506a2299-320a-4849-ae4f-06b2ddf9f5c2","isSidechain":false,"attachment":{"type":"hook_additional_context","content":["## Brain pages mentioned this turn\n- **Acme Example** → `companies/acme-example` — T0MARKER synopsis text (use get_page before relying on details)"],"hookName":"UserPromptSubmit","toolUseID":"hook-dfcc4b2e-6420-4ce0-aefc-5adf5f327471","hookEvent":"UserPromptSubmit"},"type":"attachment","uuid":"4aab3af5-fbc5-4bf0-8e8c-dcebd96f9f9e","timestamp":"2026-08-07T22:57:11.997Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"4aab3af5-fbc5-4bf0-8e8c-dcebd96f9f9e","isSidechain":false,"message":{"model":"claude-haiku-4-5-20251001","id":"msg_011CdpDQwaJ4BRvcyTt8oapt","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"","signature":"Ev8CCpMBCBAYAipA+CQZdUNK9xbPsi5AAWMR+eOlEO7dW62oifzjyKspp2s4+A5EE+DZx6l6/osd8+uxk5F8N/Coo4OT6rpKB7A95DIZY2xhdWRlLWhhaWt1LTQtNS0yMDI1MTAwMTgAQgh0aGlua2luZ1okZjUwZTdmOGYtNDRiZS00ZDNiLTkxODctMWVjODVkOTcxMTdhEgxozpFIaIr6nwJjQqUaDD6b6wbVHgiQq3/4OiIw0coI5rHvLPv/+qUn3LbnCPrFnuAET5hDjFL+r2euwW829zXy525WJRP/E3ur3W+GKpgBg+H5fYUgUehfoAiUdTb9bNNerh4+bOoUBypRP1fieWJMQJb9ukNTLwhKtVlz0jghlK3XJviYKRGvOaH4Xtz6B2ZJ+mqfDLQvD4qAfv3UrFSFEMt3dJkt+eKLdTnoU28j+RN1W06ub5ZT3ZbCDU6nfDDnBLKkHJZAs+hxQ+nKxKEPlH1BW0i7CwG5zTtzGG/9Jn+ebmG3ct0YAQ=="}],"stop_reason":"end_turn","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":10,"cache_creation_input_tokens":8505,"cache_read_input_tokens":17923,"output_tokens":42,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":8505},"inference_geo":"not_available","iterations":[{"input_tokens":10,"output_tokens":42,"cache_read_input_tokens":17923,"cache_creation_input_tokens":8505,"cache_creation":{"ephemeral_5m_input_tokens":8505,"ephemeral_1h_input_tokens":0},"type":"message"}],"speed":"standard"},"diagnostics":null},"requestId":"req_011CdpDQvxLyfQCWv2P8khkD","type":"assistant","uuid":"1baf6f33-ee55-4201-a213-30cc5ec4330e","timestamp":"2026-08-07T22:57:12.996Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"1baf6f33-ee55-4201-a213-30cc5ec4330e","isSidechain":false,"message":{"model":"claude-haiku-4-5-20251001","id":"msg_011CdpDQwaJ4BRvcyTt8oapt","type":"message","role":"assistant","content":[{"type":"text","text":"OK"}],"stop_reason":"end_turn","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":10,"cache_creation_input_tokens":8505,"cache_read_input_tokens":17923,"output_tokens":42,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":8505},"inference_geo":"not_available","iterations":[{"input_tokens":10,"output_tokens":42,"cache_read_input_tokens":17923,"cache_creation_input_tokens":8505,"cache_creation":{"ephemeral_5m_input_tokens":8505,"ephemeral_1h_input_tokens":0},"type":"message"}],"speed":"standard"},"diagnostics":null},"requestId":"req_011CdpDQvxLyfQCWv2P8khkD","type":"assistant","uuid":"6157afae-2c5f-49ba-8c92-f45c784ad20c","timestamp":"2026-08-07T22:57:12.998Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"6157afae-2c5f-49ba-8c92-f45c784ad20c","isSidechain":false,"promptId":"5abf932e-bcd0-4f5e-ab08-b70bcc9430ff","type":"user","message":{"role":"user","content":"Reply with exactly: OK2"},"uuid":"c2547569-6ab3-45f8-86f3-b6dd21d457c6","timestamp":"2026-08-07T22:57:38.070Z","permissionMode":"default","promptSource":"sdk","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"c2547569-6ab3-45f8-86f3-b6dd21d457c6","isSidechain":false,"attachment":{"type":"hook_additional_context","content":["## Brain pages mentioned this turn\n- **Acme Example** → `companies/acme-example` — T0MARKER synopsis text (use get_page before relying on details)"],"hookName":"UserPromptSubmit","toolUseID":"hook-ac0a75fb-4416-4776-8a3b-8f26074a7e92","hookEvent":"UserPromptSubmit"},"type":"attachment","uuid":"7ed2565b-cd29-4c68-8a49-6120be7a565c","timestamp":"2026-08-07T22:57:38.081Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"7ed2565b-cd29-4c68-8a49-6120be7a565c","isSidechain":false,"message":{"model":"claude-haiku-4-5-20251001","id":"msg_011CdpDSsqNWmeG6GyEPqti9","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"","signature":"EssCCpMBCBAYAipAoIHdw7UeVQFGVggtXZWJo+MzYkcxbdDKhzUeYIZlYhbMIJ9K89udijGxf9wsx1Mlz95+tbcUve2wfhViilEJzjIZY2xhdWRlLWhhaWt1LTQtNS0yMDI1MTAwMTgAQgh0aGlua2luZ1okZjUwZTdmOGYtNDRiZS00ZDNiLTkxODctMWVjODVkOTcxMTdhEgzabyBggUAlP8Q0na8aDCiuK4NGCa/6eHl6BiIw6szGDxbpIvQkLYbqTKRJlCA6n64XIx6hnyoUBs3FAEbak0GdBL7twTiF4lHSOxv0KmU6b5udn/54+g/96TjFQo0arUzfDj+g3RVuopeFQE4ylawKLkaEZfnBL4q6URiV1aiBO0ksa3bL9JbczvdY+brnQ4AX+Xkn55XGz6jpX59B3dSREcTdIOLP9e9KiuV1Tjv3V3iBwxgB"}],"stop_reason":"end_turn","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":10,"cache_creation_input_tokens":121,"cache_read_input_tokens":26428,"output_tokens":33,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":121},"inference_geo":"not_available","iterations":[{"input_tokens":10,"output_tokens":33,"cache_read_input_tokens":26428,"cache_creation_input_tokens":121,"cache_creation":{"ephemeral_5m_input_tokens":121,"ephemeral_1h_input_tokens":0},"type":"message"}],"speed":"standard"},"diagnostics":null},"requestId":"req_011CdpDSrW1XHHRdozGtBYFD","type":"assistant","uuid":"07076359-b0d0-4fe4-a9df-a27d72f828d8","timestamp":"2026-08-07T22:57:39.029Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}
{"parentUuid":"07076359-b0d0-4fe4-a9df-a27d72f828d8","isSidechain":false,"message":{"model":"claude-haiku-4-5-20251001","id":"msg_011CdpDSsqNWmeG6GyEPqti9","type":"message","role":"assistant","content":[{"type":"text","text":"OK2"}],"stop_reason":"end_turn","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":10,"cache_creation_input_tokens":121,"cache_read_input_tokens":26428,"output_tokens":33,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":121},"inference_geo":"not_available","iterations":[{"input_tokens":10,"output_tokens":33,"cache_read_input_tokens":26428,"cache_creation_input_tokens":121,"cache_creation":{"ephemeral_5m_input_tokens":121,"ephemeral_1h_input_tokens":0},"type":"message"}],"speed":"standard"},"diagnostics":null},"requestId":"req_011CdpDSrW1XHHRdozGtBYFD","type":"assistant","uuid":"1aaf0c13-c744-4b1d-a678-6c7bd64af48a","timestamp":"2026-08-07T22:57:39.031Z","userType":"external","entrypoint":"sdk-ts","cwd":"/private/tmp/gbrain-t0-hook-test","sessionId":"6be46ff6-277c-47f9-95ac-9168ef494450","version":"2.1.224","gitBranch":"HEAD"}