Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/soul_protocol/spec/decisions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# decisions.py — Decision trace payload types and helpers for the Org Journal.
# Updated: feat/rfc07-decision-outcome-attached — extend the
# ``trace_decision_chain`` decision-action filter to include
# ``decision.outcome_attached`` so post-close outcome mutations
# (introduced by RFC 07) surface in the trace alongside the chain
# proper.
# Created: feat/decision-traces — Workstream D of the Org Architecture RFC (PR #164).
#
# Every agent proposal a human edits or rejects becomes a structured, auditable
Expand Down Expand Up @@ -211,7 +216,15 @@ def trace_decision_chain(journal, correlation_id: UUID) -> list[EventEntry]:
the same correlation_id are filtered out.
"""
events = journal.query(correlation_id=correlation_id, limit=10_000)
decision_actions = {"agent.proposed", "human.corrected", "decision.graduated"}
decision_actions = {
"agent.proposed",
"human.corrected",
"decision.graduated",
# RFC 07: outcome-attachment events update an already-emitted
# Decision's outcome and belong in the chain so traces surface
# the full lifecycle, including post-close mutations.
"decision.outcome_attached",
}
chain = [e for e in events if e.action in decision_actions]
chain.sort(key=lambda e: e.ts)
return chain
Expand Down
12 changes: 12 additions & 0 deletions src/soul_protocol/spec/journal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# journal.py — Org Journal primitives (Actor, DataRef, EventEntry).
# Updated: feat/rfc07-decision-outcome-attached — register
# ``decision.outcome_attached`` in ACTION_NAMESPACES. RFC 07 introduces
# this action as a projection-update event that mutates a Decision's
# outcome after first emit. The hash chain excludes ``outcome``, which
# is what makes the mutation safe; this is the only spec action that
# mutates a prior projection record.
# Updated: feat/0.3.2-spike — add EventEntry.seq (backend-assigned, None until
# committed). Journal.append now returns the committed EventEntry so callers
# can thread seq through idempotency/pagination without racing MAX(seq) or
Expand Down Expand Up @@ -100,6 +106,12 @@ def _encode_bytes(v: bytes | None) -> str | None:
"agent.proposed",
"human.corrected",
"decision.graduated",
# RFC 07 (Decision Graph Query Layer): projection-update event that
# mutates an already-emitted Decision's ``outcome`` field after the
# chain has closed. The hash chain excludes ``outcome``, so this
# post-hoc update is safe — it is the only event in the spec that
# mutates a prior projection record.
"decision.outcome_attached",
# Credentials & Zero-Copy
"credential.acquired",
"credential.used",
Expand Down
4 changes: 4 additions & 0 deletions tests/test_spec/test_decisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ def test_namespaces_include_decision_actions():
assert "agent.proposed" in ACTION_NAMESPACES
assert "human.corrected" in ACTION_NAMESPACES
assert "decision.graduated" in ACTION_NAMESPACES
# RFC 07 — projection-update event that mutates an already-emitted
# Decision's outcome field. Registered additively in the journal's
# action catalog so the chain projection can recognize it.
assert "decision.outcome_attached" in ACTION_NAMESPACES


def test_build_proposal_event_shape(drafter: Actor):
Expand Down
Loading