Add structured ReACT event sink for protocol adapters (#156) - #178
Merged
Conversation
Lock in the audit-clean state: fail CI if config.toml stops being gitignored or if an inline sk-/api_key="..." literal lands in src/ or config.example.toml. Secrets must stay env/file/cmd only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce an opt-in, in-process structured event channel that fires synchronously at the existing trace points, so protocol adapters and observability sinks no longer have to parse formatted trace lines or poll the audit JSONL. - agent.zig: add pub Event union and lightweight EventSink vtable; add Agent.events plus an inline emitEvent helper. Events fire at the top of each trace* method, independent of the text trace writer and with byte-identical trace output. tracePolicyDeny/traceObservation now take the current action. - api.zig: forward RunOptions.event_sink into the agent in runDetailedWithOptions. - root.zig unchanged; the public-API whitelist stays narrow. Event slices are turn-arena lifetime, valid only during emit; sinks must consume immediately and never retain references. Foundation for the ACP adapter epic (#155) and the observability hook sink (#137); follow-up to the agent event callback requested in #134. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jamiesun
force-pushed
the
copilot/event-sink-156
branch
from
June 30, 2026 03:17
7081376 to
54059bc
Compare
Merged
jamiesun
added a commit
that referenced
this pull request
Jun 30, 2026
- Opt-in PreToolUse policy hook at the guard() chokepoint (#136, #177) - Opt-in PostToolUse audit/observability hook (#137, #179) - Structured ReACT event sink for protocol adapters (#156, #178) - WebAssembly spec conformance test suite for scoot-wasm (#163, #180) - project-audit agent skill scoring ten dimensions of repo health (#168) - scoot-edge E1 status heartbeat + E0 boundary doc (#172, #173) - Harden scoot-wasm against hostile bytecode: explicit traps/errors, no OOM panic (#174, #181) - Tighten agent boundary guardrails (#176) - Wasm compute-unit build guidance and docs (#170) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in, in-process structured ReACT event channel so protocol adapters and observability sinks no longer have to parse formatted trace lines or poll the audit JSONL. Closes #156. Also lands a small audit-driven CI hardening step.
Foundation for the ACP adapter epic (#155) and the observability hook sink (#137); follow-up to the agent event callback requested in #134.
Changes
feat: structured event sink (#156)src/agent.zig— newpub const Eventunion (thinking,step,policy_deny,running,observation,final,malformed,compacted) and a lightweightpub const EventSinkvtable. AddedAgent.eventsand aninline fn emitEvent. Events fire at the top of eachtrace*method, so they are independent of the texttracewriter (fire even with no writer attached) and leave trace output byte-identical.tracePolicyDeny/traceObservationnow take the currentaction.src/api.zig—RunOptions.event_sinkis forwarded into the agent inrunDetailedWithOptions.src/root.zig— unchanged; the public-API whitelist stays narrow (RunOptionsis internal-only).Lifetime contract: event slices are turn-arena lifetime, valid only during the synchronous
emitcall. Sinks must consume immediately and must not retain references (documented onEvent).ci: secret hygiene guard.github/workflows/ci.yml— fails CI ifconfig.tomlstops being gitignored or if an inlinesk-…/api_key="…"literal lands insrc/orconfig.example.toml. Locks in the current audit-clean state.Acceptance criteria (#156)
agent.Event/agent.EventSinkexist;Agent.eventsfield presenttracetests pass unchanged (byte-identical text output)api.RunOptions.event_sinkforwards into the agent; covered by anapi.zigtest usingTestBrainsrc/root.zigunchanged; public-API whitelist test greenzig build+zig build testgreenVerification
zig fmt --checkcleanzig build✅ ·zig build test704/704 passed ✅ ·zig build -Doptimize=ReleaseSafe✅ ·--version→scoot 0.5.0Blast radius
Additive in-process channel; no new execution surface, no behavior change when
events == null. Touchessrc/agent.zigandsrc/api.zigonly (plus the CI workflow).