Skip to content

(MOT-4365) feat(harness,console): show the payload a trigger fire delivered - #718

Merged
andersonleal merged 5 commits into
mainfrom
feat/trigger-fire-payload
Aug 5, 2026
Merged

(MOT-4365) feat(harness,console): show the payload a trigger fire delivered#718
andersonleal merged 5 commits into
mainfrom
feat/trigger-fire-payload

Conversation

@andersonleal

@andersonleal andersonleal commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Problem

The console's trigger-fired card showed registration and fire bookkeeping but never what was delivered. For a ƒ-call binding the dispatched payload existed only at fire time inside harness::trigger::deliver and was never persisted — so "what was sent to the target function?" was unanswerable from the timeline. Wakes were only marginally better: the event was embedded in the notification text, truncated at 600 chars.

The delivered value can differ from the raw fired event three ways: a condition's Allow { payload: Some(next) } rewrites the event, projection injects it into the target's payload template at event_into, and filesystem_scope::inject stamps the payload just before dispatch.

What changed

TriggerFired gains an optional payload field carrying the final dispatched payload — post-conditions, post-projection, post-stamping. dispatch/call_target now return (Value, Result<(), String>) so the record gets what actually went out, including on a failed dispatch (the attempted payload lands next to the dispatch failed: … note). Wakes record the post-conditions event, recovering what the 600-char truncation loses. Skip/gc/expiry records carry no payload — nothing was delivered.

The console types the field, renders it as a payload pane in the card's terminal tab, and picks it up in the RAW JSON tab for free.

Decisions worth knowing

  • No size cap. Full fidelity was chosen over a 16KB whole-or-nothing alternative. The payload persists in the owner session's transcript jsonl (model-invisible custom entry, but on disk).
  • Because of that, fired::emit now retries the append once with payload: None if the first attempt fails. Previously a size-driven append failure would have dropped the entire record — losing the timeline notice and the panel's retired flag for a fired once-trigger. Bookkeeping survives even when the payload cannot be persisted; still strictly best-effort, never blocks a fire.
  • No Deps mock fixture. The dispatch glue is covered by the compile-driven signature change; the pure project() half gets a unit test, and the e2e mechanical_reaction scenario now asserts a delivered fire's record carries a payload (that gate fails if payload: Some(&delivered) is ever reverted).

Compatibility

Additive and optional (skip_serializing_if). Records written before this field deserialize unchanged and render with no pane — the console gates on t.payload !== undefined, so a legitimately falsy delivered payload (null, 0, false, "") still renders.

Testing

  • cargo test -p harness --lib — 303 passed (baseline 302 + 1)
  • cargo fmt --check, cargo clippy --all-features -- -D warnings — clean
  • console/web: 87 files / 1121 tests passed; tsc --noEmit clean; biome clean on touched files
  • e2e mechanical_reaction compiles and passes its offline suite; the live scenario needs III_BIN and runs in CI

Known / deferred

  • The console renders payload JSON with an uncapped JSON.stringify + Prism tokenize per card, no memoization or virtualization. This is the existing console-wide pattern (same as RegistrationPane, SpawnView, the scrapling views) — widened here, not invented. Deferred.
    Fixes MOT-4365.

Summary by CodeRabbit

  • New Features
    • Trigger-fired events now include delivered payload details when available.
    • Terminal views display trigger payloads in a collapsible JSON panel with copy support.
  • Bug Fixes
    • Preserved payload information across trigger delivery, authorization, approvals, and execution.
    • Added graceful fallback handling when payload recording fails.
  • Tests
    • Added coverage for payload mapping, serialization, omitted payloads, and event delivery scenarios.

The trigger_fired payload is deliberately uncapped, so an oversized one
(e.g. a bulk UPDATE...RETURNING event) is the likeliest way the append
ever fails. Losing the whole record then drops the fire notice from the
timeline and the `retired` flag the panel needs for a fired once-trigger's
ghost row. `emit` now retries once with `payload: None` on append failure
when the record carried a payload, reusing the same entry id so a
partially-succeeded first attempt is harmless.

Also pin, in the mechanical_reaction e2e scenario, that a delivered call
binding's fired record actually carries a `payload` key - nothing
previously asserted this, so flipping it away silently would have left
the suite green.
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview Aug 5, 2026 7:52pm
workers-tech-spec Ready Ready Preview Aug 5, 2026 7:52pm

Request Review

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 54 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Trigger-fired payload flow

Layer / File(s) Summary
Delivery payload contract and projection
harness/src/functions/trigger_deliver.rs, console/web/src/types/chat.ts
Trigger delivery returns wake and function payloads, including attempted payloads on failures. The chat type accepts optional payload data.
Fired-record persistence and fallback
harness/src/subscriptions/fired.rs, harness/src/bindings/{expiry,gc}.rs
Fired records store optional payloads and retry serialization without payload data when needed. Expiry and garbage-collection records explicitly omit payloads.
Console payload mapping and display
console/web/src/components/chat/*, console/web/src/lib/sessions/entry-mapper.test.ts
The console maps trigger payloads, displays formatted JSON with copy support, and adds a Storybook fixture.
End-to-end payload validation
harness/tests/e2e/src/scenarios/mechanical_reaction.rs
The mechanical reaction scenario requires a delivered trigger record with a recorded payload.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TriggerDelivery
  participant FiredRecord
  participant SessionMapper
  participant ChatTerminal
  TriggerDelivery->>FiredRecord: store delivered payload
  FiredRecord-->>SessionMapper: provide trigger-fired payload
  SessionMapper->>ChatTerminal: render mapped payload
  ChatTerminal-->>ChatTerminal: format JSON and copy payload
Loading

Possibly related PRs

  • iii-hq/workers#468: Extends related trigger-fired payload flow across chat types, mapping, and fired records.
  • iii-hq/workers#469: Shares trigger-fired payload propagation and mapping changes.
  • iii-hq/workers#681: Adds related trigger payload propagation through delivery and fired-event paths.

Poem

A rabbit watched the trigger fly,
With payload tucked beneath the sky.
The record kept its fields in line,
The console showed the JSON shine.
“Copy,” said Bun, “the flow is fine!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: displaying the payload delivered by a trigger fire across the harness and console.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/trigger-fire-payload

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@andersonleal andersonleal changed the title feat(harness,console): show the payload a trigger fire delivered (MOT-4365) feat(harness,console): show the payload a trigger fire delivered Aug 5, 2026
@andersonleal
andersonleal merged commit 671a67a into main Aug 5, 2026
33 of 35 checks passed
@andersonleal
andersonleal deleted the feat/trigger-fire-payload branch August 5, 2026 20:20
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