GEODE v1.0.9
Public extension control is now a small, versioned hook ABI backed by
trusted tool/LLM middleware and a separate internal runtime-event plane.
Changed
- Extension authority is split into three explicit surfaces: 13 versioned,
bounded public hooks (HookName/HookRegistry), four trusted request and
execution middleware join points (MiddlewareRegistry), and the
observation-onlyRuntimeEventBus. Tool and LLM execution now have real
async onion boundaries; compaction, approval, sub-agent, durable session,
and verification checkpoints are wired to their owning state transitions.
PostVerifysupports monotone bounded continuation without replaying tool
side effects. Escalation now withholds the candidate, parks the session under
external_verification_required, and exposesAgenticResult.pending_text
only to the owning outer loop. The existing 56 stored runtime-event values
and SQLite rows are unchanged; compatibility aliases retainHookEvent/
HookSystem. - Extension invocation audit metadata is canonical in
sessions.db:hook_eventsand conditionally mirrored to an active run
transcript.jsonl. Request/response bodies and handler reasons are omitted.
The single newEXTENSION_INVOKEDruntime event uses audit retention. - Hook
actionnamespaces fold from 27 first-segments to 13 families. 16 of the 27 held a single
event each, so the namespace classified nothing for more than half the vocabulary; the singletons
now sit in the domain they belong to (adapter/prompt/model/reasoning→llm,
user/execution/result/post→turn,shutdown/handoff→session, plus newpolicy
andimprove). No event is added or removed — all 56 stay live — andACTION_FAMILY_ALIASES
keeps rows already on disk resolving — verified against everyactionin the live
hook_eventstable, pre-fold segments included. For scale, read from source rather than docs:
Hermes declares 23 hooks (hermes_cli/plugins.pyVALID_HOOKS), Codex 50 metric constants plus
14 event names (codex-rs/otel/src/metrics/names.rs,events/session_telemetry.rs). - Dispatch stamps
schema_versionon every payload (OBSERVER_SCHEMA_VERSION,geode.observer.v1).
A subscriber that only receives the payload — a plugin, an exporter — could not otherwise tell
which contract it was reading, sincehook_events.schema_versionis visible to SQL readers only.
setdefault, so a replayer feeding an archived payload keeps that payload's version.
Fixed
- Runtime
session_idandturn_idcorrelation now survives the shared typed
activity projection into both canonical SQLite and active JSONL hook-event
storage. The subscription-backed behavior E2E covers all 13 public hooks and
four middleware join points; its reviewed decision/tool trajectory is
published separately from withheld runtime checkpoints and provider
reasoning. - Trusted/public tool rewrites now propagate the effective tool name,
arguments, and cumulative personal-data classification into approval,
transcript, tool-log, and offload policy. Batch cost approval is scoped only
to the original expensive-operation cost gate and cannot authorize a
rewritten MCP/write/dangerous tool. Headless hook-requested permission fails
closed rather than opening a console prompt. Tool lifecycle runtime events
retain session/turn correlation after the middleware boundary moved into the
executor. - Public hook dispatch keeps required schema fields when bounding payloads,
isolates handler payload copies, rejects in-place mutation, and permits
payload updates only forREWRITE. Tool-execution short circuits now close
approval records asskipped, and IPC/scheduler terminal owners call the
asyncSessionEndpath. - The emit-side payload validator now reads both contract registries instead of one.
REQUIRED_PAYLOAD_KEYScovers 4 events by hand while the declarative_TYPED_ROW_SPECStable
carries pydanticdetails_clsmodels whose required fields are a contract for 14 more — a
disjoint set the validator never consulted. Deriving rather than transcribing raises emit-time
coverage from 4/56 to 18/56 without adding a hand-written contract.