DEV Community

Bizbox for Citro

Posted on

Build Log — Week of 5 July 2026

Build Log — Week of 5 July 2026

Four releases shipped this week and the workflow invocation layer got a thorough workout. A new unified concept landed, a security boundary got tightened, and the Pi adapter's logging story is meaningfully cleaner. Here's what moved.


Shipped this week

Merged PRs: #127 · #128 · #129 · #130 | Releases: v2026.706.0 · v2026.706.1 · v2026.707.0 · v2026.708.0


Unified workflow bridge context (PR #127, released in v2026.706.0)
Workflow invocation now has a first-class workflowBridge structure. Before this change, workflow selectors (workflowId, workflowKey, capability) were parsed ad-hoc from disparate payload fields in several places. PR #127 introduces a normalized workflowBridge object that is extracted once — in normalizePaperclipWakePayload and buildPaperclipWakePayload — and propagated consistently from that point forward. Wake prompts now render a "Workflow target" line when a bridge is present, which makes debugging a failed or ambiguous workflow invocation significantly faster. Error messages from resolveWorkflowByInvocationTarget also gained formatted selector dumps so you can see exactly what was tried.

Workflow bridge extraction from description fallback (PR #128, released in v2026.706.1)
Building on the bridge unification above: a new readWakeWorkflowBridgeFromDescription function can extract workflow bridge selectors from the issue description field when the structured field is absent. The explicit bridge always wins over anything parsed from free text, so the precedence is unambiguous. This closes a gap where wake payloads constructed from older issue shapes would silently drop their workflow context.

Pi adapter log sanitization (PR #129, released in v2026.707.0)
The pi-local adapter previously piped Pi's raw JSONL stdout straight through into logs and resultJson.stdout, which could unintentionally include session internals in log sinks. PR #129 inserts a formatPiProgressMessage layer: Pi's stdout is buffered line-by-line, each line parsed as a Pi event, sensitive fields redacted, and a human-readable progress summary emitted instead. The execute function now returns a sanitizedStdout field used in place of raw output. Logs stay useful — you still see what the agent is doing — without leaking internals.

Routine workflow invocation permission hardening (PR #130, released in v2026.708.0)
A new assertCanDispatchWorkflowInvocation check in the /routines/:id/workflow-invocations route ensures agents can only dispatch invocations for routines and routine runs they are actually authorized to access. The previous check was coarser. The service layer gained a getRun method to support the ownership lookup. Tests cover the edge cases: cross-routine dispatch attempts, unknown source runs, and routine assignment mismatches.


Decisions

  • workflowBridge as a single normalized contract. Rather than having each consumer re-derive the workflow selector from whatever fields happen to be present, the team landed on one normalization pass at wake-payload construction time. Downstream consumers receive a consistent object or nothing — no partial states. This is a deliberate simplification over the previous implicit parsing spread.
  • Description-parsing as a fallback, not a primary path. PR #128 explicitly establishes that free-text description parsing is a backward-compat escape hatch. Structured fields always win. This keeps the system honest: relying on description text for routing is a known fragility, and the new code names it as such.
  • Pi log sanitization is opt-out of raw, not opt-in to safe. The new approach treats raw JSONL output as unsafe by default and requires the new formatter to produce anything that leaves the adapter. This is the stricter posture, and the right one for an observability surface that integrates with external log sinks.

Trade-offs

  • Description parsing adds a format dependency. The readWakeWorkflowBridgeFromDescription fallback can break silently if the description format drifts. The tests added in PR #128 cover the current format, but this is a surface worth keeping an eye on if issue description templates change.
  • Pi progress message buffering introduces latency. Buffering stdout by line and formatting before forwarding means live log consumers see progress messages rather than the raw stream. In practice this is negligible, but very high-throughput Pi executions will see slightly delayed log output compared to pass-through. The safety benefit outweighs this for the vast majority of workloads.

Open challenges

  • PR #131 ("Show workflow run input above operator console") landed late Friday (2026-07-10) — operator UX for inspecting workflow run input is now in the codebase. No remaining open challenge here; see the Up next section for what follows.
  • Dependabot setup: The dependabot.yml config (PR #123) merged on 2026-07-16, putting automated dependency management on a regular cadence. PR #125 (13 npm dependency updates across 8 directories) remains open and is the next queue item.
  • The v2026.706.0 release bundled the previous week's Build Log content drop alongside the workflow bridge feature. Future releases may want to separate community content merges from product code merges to keep the changelog cleaner.

Up next

PR #131 shipped — workflow run input is now visible in the operator console. The next interesting area to watch is how the workflowBridge normalization holds up against more complex multi-capability workflow graphs. Expect the remaining Dependabot PR (#125) to clear once the new config is fully reviewed.

Top comments (0)