Skip to content

Add structured ReACT event sink for protocol adapters (#156) - #178

Merged
jamiesun merged 2 commits into
mainfrom
copilot/event-sink-156
Jun 30, 2026
Merged

Add structured ReACT event sink for protocol adapters (#156)#178
jamiesun merged 2 commits into
mainfrom
copilot/event-sink-156

Conversation

@jamiesun

Copy link
Copy Markdown
Collaborator

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 — new pub const Event union (thinking, step, policy_deny, running, observation, final, malformed, compacted) and a lightweight pub const EventSink vtable. Added Agent.events and an inline fn emitEvent. Events fire at the top of each trace* method, so they are independent of the text trace writer (fire even with no writer attached) and leave trace output byte-identical. tracePolicyDeny/traceObservation now take the current action.
  • src/api.zigRunOptions.event_sink is forwarded into the agent in runDetailedWithOptions.
  • src/root.zig — unchanged; the public-API whitelist stays narrow (RunOptions is internal-only).

Lifetime contract: event slices are turn-arena lifetime, valid only during the synchronous emit call. Sinks must consume immediately and must not retain references (documented on Event).

ci: secret hygiene guard

  • .github/workflows/ci.yml — fails CI if config.toml stops being gitignored or if an inline sk-… / api_key="…" literal lands in src/ or config.example.toml. Locks in the current audit-clean state.

Acceptance criteria (#156)

  • agent.Event / agent.EventSink exist; Agent.events field present
  • All existing trace tests pass unchanged (byte-identical text output)
  • Capturing test sink receives the expected ordered events for a scripted run (thinking → step → running → observation → … → final), including a policy-deny path
  • api.RunOptions.event_sink forwards into the agent; covered by an api.zig test using TestBrain
  • src/root.zig unchanged; public-API whitelist test green
  • zig build + zig build test green

Verification

  • zig fmt --check clean
  • zig build ✅ · zig build test 704/704 passed ✅ · zig build -Doptimize=ReleaseSafe ✅ · --versionscoot 0.5.0

Blast radius

Additive in-process channel; no new execution surface, no behavior change when events == null. Touches src/agent.zig and src/api.zig only (plus the CI workflow).

jamiesun and others added 2 commits June 30, 2026 11:16
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
jamiesun force-pushed the copilot/event-sink-156 branch from 7081376 to 54059bc Compare June 30, 2026 03:17
@jamiesun
jamiesun merged commit 960c764 into main Jun 30, 2026
5 checks passed
@jamiesun
jamiesun deleted the copilot/event-sink-156 branch June 30, 2026 03:21
@jamiesun jamiesun mentioned this pull request Jun 30, 2026
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>
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.

[agent] Structured ReACT event sink for protocol adapters (streaming source)

1 participant