Context
The agent-orchestrator (initializ/agent-orchestrator) is wiring up its own audit-event emit path onto the same NATS JetStream stream (AUDIT_EVENTS / subject auditEvent) that Forge agents publish to:
- ORCH-2 (initializ/agent-orchestrator#22) ships the orchestrator's
AuditEvent envelope + NATS publisher, modeled on runtime.AuditEvent.
- ORCH-3 (initializ/agent-orchestrator#24) hooks the six workflow lifecycle events (
workflow_started, workflow_step_*, workflow_complete, workflow_cancelled).
- ORCH-7 (initializ/agent-orchestrator#26) propagates
X-Workflow-Id / X-Workflow-Execution-Id / X-Workflow-Step-Id so a downstream agent's audit events share the workflow's identity.
For a single workflow run, the audit stream then contains events from N producers: the orchestrator (1) and each agent invoked as a step (1 per step).
Question
What scope does Forge's seq field use?
The orchestrator scopes its seq per workflow_execution_id (counter starts at 1 for the first event of the run, advances by 1 per subsequent event). If Forge does the same — keying its sequencer on workflow_execution_id once the FWS-2 headers are present — then the seqs collide on the wire: both producers emit events with seq=1, 2, 3... for the same workflow_execution_id.
Looking for confirmation of one of:
- Per-invocation — Forge's seq is monotonic for the lifetime of one A2A call (one orchestrator dispatch). New invocation → seq restarts at 1. Doesn't collide with orchestrator across invocations, but two parallel agent calls for the same execution still collide with each other.
- Per-execution — Forge's seq is monotonic per
workflow_execution_id. Collides directly with orchestrator's seq for the same execution.
- Per-agent-process — Forge's seq counts events emitted by this agent process since startup, regardless of which workflow they belong to. Never collides with orchestrator within a single execution, but seq isn't useful for in-run gap detection.
Why it matters
The orchestrator's docstring on its Sequencer says "monotonic per WorkflowExecutionID — starts at 1 for the first event of a run." If Forge uses the same scope (option 2), a naive consumer that orders or dedupes by (workflow_execution_id, seq) will see duplicates / gaps for every multi-producer workflow.
Both sides need to agree on:
- The seq scope (so the docstrings are consistent across producers).
- The partition key for consumers — almost certainly
(workflow_execution_id, entity_type, entity_id, seq) rather than (workflow_execution_id, seq). Worth nailing down which fields disambiguate.
- Whether to add an explicit
producer / source field to the envelope so consumers don't have to infer the entity-vs-producer mapping. Could land in either codebase or both.
Cross-refs
- initializ/agent-orchestrator#22 — orchestrator audit publisher (ORCH-2)
- initializ/agent-orchestrator#24 — workflow lifecycle audit events (ORCH-3)
- initializ/agent-orchestrator — paired orchestrator-side follow-up to tighten the docstring and (optionally) add a
producer field; link added in a follow-up comment.
- forge#185 —
X-Workflow-Id header contract split
Asks
- Confirm the seq scope Forge uses today (or plans to use once the FWS-2 contract is fully wired).
- Confirm the consumer-side partition key — what does the security service partition on before checking seq?
- Opinion on adding a
producer field to the envelope so the contract is explicit on both sides.
Context
The agent-orchestrator (initializ/agent-orchestrator) is wiring up its own audit-event emit path onto the same NATS JetStream stream (
AUDIT_EVENTS/ subjectauditEvent) that Forge agents publish to:AuditEventenvelope + NATS publisher, modeled onruntime.AuditEvent.workflow_started,workflow_step_*,workflow_complete,workflow_cancelled).X-Workflow-Id/X-Workflow-Execution-Id/X-Workflow-Step-Idso a downstream agent's audit events share the workflow's identity.For a single workflow run, the audit stream then contains events from N producers: the orchestrator (1) and each agent invoked as a step (1 per step).
Question
What scope does Forge's
seqfield use?The orchestrator scopes its
seqperworkflow_execution_id(counter starts at 1 for the first event of the run, advances by 1 per subsequent event). If Forge does the same — keying its sequencer onworkflow_execution_idonce the FWS-2 headers are present — then the seqs collide on the wire: both producers emit events withseq=1, 2, 3...for the sameworkflow_execution_id.Looking for confirmation of one of:
workflow_execution_id. Collides directly with orchestrator's seq for the same execution.Why it matters
The orchestrator's docstring on its
Sequencersays "monotonic per WorkflowExecutionID — starts at 1 for the first event of a run." If Forge uses the same scope (option 2), a naive consumer that orders or dedupes by(workflow_execution_id, seq)will see duplicates / gaps for every multi-producer workflow.Both sides need to agree on:
(workflow_execution_id, entity_type, entity_id, seq)rather than(workflow_execution_id, seq). Worth nailing down which fields disambiguate.producer/sourcefield to the envelope so consumers don't have to infer the entity-vs-producer mapping. Could land in either codebase or both.Cross-refs
producerfield; link added in a follow-up comment.X-Workflow-Idheader contract splitAsks
producerfield to the envelope so the contract is explicit on both sides.