docs(design): forge self-delegate write path record (Record A) (RIG-3299) - #900
Merged
Merged
Conversation
|
😎 This pull request was merged. |
|
Compass engineering docs preview: https://compass-forge-rig-3299-self.compass-eng-docs.pages.dev Deployed from Changed pages: |
rigel-mintaka
force-pushed
the
compass-forge/rig-3299-self-delegate-design
branch
from
September 5, 2026 21:47
16e3f8f to
90fcb06
Compare
rigel-mintaka
force-pushed
the
compass-forge/rig-3299-self-delegate-design
branch
3 times, most recently
from
September 6, 2026 01:52
cc64134 to
050dc12
Compare
rigel-mintaka
marked this pull request as ready for review
September 6, 2026 01:52
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 6, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
resolve
This was referenced Sep 6, 2026
Draft
rigel-mintaka
added a commit
that referenced
this pull request
Sep 7, 2026
Both load-bearing Open Questions are ruled, so the record flips Draft -> Active and its ledger rows land in this push. - OQ-1: the actor carrier is the consumable `forge_state_transitions` memo, not a synthetic STATE event. RIG-3326 is the side whose text bends -- its STATE arm resolves the actor through a memo lookup rather than off the event body. T5 keeps its subject and T4's memo half is in scope. - OQ-2: Linear default-state resolution defaults only where the target is unambiguous and fails `invalid_argument` naming the candidates otherwise, replacing the positional tie-break. A mandatory `workflow_state` was also rejected: it forces a provider-aware state fetch into every callsite and splits GitHub/Linear ergonomics. Measured at freeze, the Rigel team has exactly one `completed`, one `unstarted` and one `backlog` state, so the original "silently picks a board column" premise had no choice to make -- the rejection arm is a guard against future drift, covered by fixture because no current board reproduces it. All nine task slices are now unconditional; T3 gains the multi-candidate rejection fixture. DL-342/DL-343 appended with the real ruling date, ids re-verified next-free against main (highest DL-337) and every open design PR (#913 338/339, #900 340, #932 341). Refs RIG-3331 Co-authored-by: Matt Wilkinson <matt@rigel.build>
trunk-io Bot
pushed a commit
that referenced
this pull request
Sep 7, 2026
* docs(design): forge state-transition write op record (RIG-3331)
Design record for the forge state-transition write op: an agent sets an
issue/PR state on both GitHub and Linear through the same attribution
chokepoint every other forge write rides.
Portable {open, closed} core plus per-provider refinements (close_reason on
GitHub, workflow_state on Linear), fail-loud invalid_argument on a
refinement/provider mismatch, ErrUnsupported on the Linear PR half.
Transitions mutate an existing coordinate, so they are neither F3-deduped nor
DL-055-recorded, following the comment-arm precedent.
The load-bearing contract is actor attribution: the emitted STATE event must
carry the acting agent so RIG-3326's suppression arm can key on the real
transition actor rather than the DL-055 author-row proxy, which would wrongly
eat a human-close notification to the author.
Two load-bearing Open Questions are held for Matt: the actor-carrier mechanism
(OQ-1, a cross-record contract with RIG-3326) and the Linear default
workflow-state rule (OQ-2, a product-behavior call).
Refs RIG-3331
Co-authored-by: Matt Wilkinson <matt@rigel.build>
* docs(design): close the review findings on the state-transition record (RIG-3331)
Adversarial review returned 4 high, 5 medium, 3 low. Fixes, each verified
against the cited source:
Two fabricated citations removed (rule://planning-evidence). The record named
translateAttribution as an existing symbol - it does not exist anywhere in the
tree; the real path is stripBodyToRef plus the detect-path attribution
assignment. It also quoted 'deliberately never imports the store' as if from
the ingest package; the actual term of art is the no-store rule. Both
underlying claims were true, only the citations invented.
The F3/DL-055 argument reached the right conclusion from the wrong premise.
The comment arm is excluded because a comment is unrepresentable in the store
index; a transition targets a coordinate that IS representable and often
already occupied. The record inverted the risk as 'no row exists at the
coordinate at all'. The real hazard is a row that DOES exist:
RecordAuthoredArtifact's ON CONFLICT DO UPDATE overwrites client_request_id,
which backs the F3 memo through a unique partial index, so routing a
transition through record would destroy the original create's idempotency
memo. Conclusion kept, reasoning replaced, hazard named.
T1 was red by construction: it widened Provider while extending only the fake,
but four compile-time satisfaction assertions live in that package, so the
GitHub and Linear ones break immediately and T2/T3 (the repair) come after.
T1 now lands the interface with all four implementors.
The transition memo omitted tenant_id. Its sibling forge_authored_artifacts is
tenant-keyed and defended by a two-tenants-same-coordinate test, so without it
one tenant's memo could attribute another's STATE event. The RLS catalog test
audits tables that carry the column, so an omission is invisible to it - the
column now ships with three explicit obligations instead of a reliance on the
guard.
Three tasks silently depended on unruled Open Questions while the checklist
presented nine unconditional slices. T3 is OQ-2-contingent, T4's memo half and
all of T5 are OQ-1-contingent, each now tagged with what changes under the
alternative ruling.
Also: ruled the ambiguous-workflow-state-name case (Linear does not enforce
name uniqueness within a team) rather than leaving an implementer to invent a
rule on the write path; specified the workflow-state cache separately from the
invalidation-free teamIDs cache, since humans rename and reorder states;
named the webhook/sweep double-emission and cursor-advance races; stated the
memo read's tenant context; pinned the table to 0001_init.sql per the
collapsed-migration convention; corrected the DL enumeration to include PR
#932's DL-341; resolved the T8 contradiction (the rows ship in the freeze
push, because DL-343's substance is what OQ-1 asks Matt to rule, and stamping
'Active (Matt)' now would attribute a decision he has not made); and flipped
Status to Draft.
Refs RIG-3331
Co-authored-by: Matt Wilkinson <matt@rigel.build>
* docs(design): freeze forge state-transition record (RIG-3331)
Both load-bearing Open Questions are ruled, so the record flips Draft ->
Active and its ledger rows land in this push.
- OQ-1: the actor carrier is the consumable `forge_state_transitions` memo,
not a synthetic STATE event. RIG-3326 is the side whose text bends -- its
STATE arm resolves the actor through a memo lookup rather than off the
event body. T5 keeps its subject and T4's memo half is in scope.
- OQ-2: Linear default-state resolution defaults only where the target is
unambiguous and fails `invalid_argument` naming the candidates otherwise,
replacing the positional tie-break. A mandatory `workflow_state` was also
rejected: it forces a provider-aware state fetch into every callsite and
splits GitHub/Linear ergonomics. Measured at freeze, the Rigel team has
exactly one `completed`, one `unstarted` and one `backlog` state, so the
original "silently picks a board column" premise had no choice to make --
the rejection arm is a guard against future drift, covered by fixture
because no current board reproduces it.
All nine task slices are now unconditional; T3 gains the multi-candidate
rejection fixture. DL-342/DL-343 appended with the real ruling date, ids
re-verified next-free against main (highest DL-337) and every open design
PR (#913 338/339, #900 340, #932 341).
Refs RIG-3331
Co-authored-by: Matt Wilkinson <matt@rigel.build>
---------
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 7, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
resolve
…299) Record A of the forge delegation split: the outbound self-delegate write path (delegateId self + optional human assigneeId on the Linear issueCreate), Linear-only, degrade-on-probe-failure. Ships Status: Active with the RIG-3302 probe results folded in — OQ-1 self-delegate ALLOWED, OQ-2 assignee slot independent, OQ-3 always-assign shape (both slots, never delegate-only) — T0 oracle mint-scope bump made unconditional, and a hermetic end-to-end routing e2e task (T4: real stamped Server create -> self-delegate -> synthetic created SessionEvent -> assert routes to owning Manager). Inbound DL-309 round-trip stays Record B behind RIG-3271; self-origin notification suppression is its own record (RIG-3326). Appends DL-327 to the decision ledger (satisfies design-ledger-gate DL-Q1). Co-authored-by: Matt Wilkinson <matt@rigel.build>
DL-330 was claimed by the merged apple-container macOS-runner record, so Record A's row was a duplicate and would have red the fail-closed design-ledger-gate on merge. DL-340 sits above every in-flight mint (#927/#916 hold DL-333..337), not merely above main's tail — a tail check cannot see a concurrently-open claim, which is how this class of collision keeps recurring. Co-authored-by: Matt Wilkinson <matt@rigel.build>
Replace every path:line citation in the self-delegate record with the symbol-plus-path form the convention requires: a line number is stale the moment the file it points into moves, and a stale citation in a frozen record sends its reader to the wrong code with no signal that it drifted. The drift is observable on main, not hypothetical: PR #916 (RIG-3320) had to chase six prose citations in a MERGED record when the resolver grew a few lines (resolver.go:33-36 -> :40-43). Nothing failed; the record was simply wrong until a human noticed. Each of the 47 citations was resolved to its real enclosing symbol against the source tree and verified present in the cited file. Two bare basenames (routing.go, routing_test.go) resolved by content to internal/linearagent, NOT internal/compute -- a basename-only rewrite would have fabricated seven citations into an unrelated package. Refs RIG-3299 Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added a commit
that referenced
this pull request
Sep 7, 2026
…3326)
Design record for suppressing self-origin forge notifications at the
notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW /
OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass
handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed
notification advances delivered_revision only when the subscriber was already
caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither
resurrects it nor masks a prior undelivered real notification.
The owner half of that identity is not on the wire today: AgentAttribution is
{agent_handle} only, so the parse discards the owner it already produces and the
COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and
adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it).
Sibling of Record A (forge self-delegate write path, PR #900); depends on
RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress
on the real transition actor rather than an author-row proxy.
Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335
(owner_handle carriage, amending the DL-094 clause DL-186 carried forward;
DL-186 stays Active).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
resolve
rigel-mintaka
force-pushed
the
compass-forge/rig-3299-self-delegate-design
branch
from
September 7, 2026 21:42
f32510d to
8b28ed1
Compare
mattwilkinsonn
approved these changes
Sep 8, 2026
|
Stacked PR 997 failed testing in the merge queue. Please investigate the failure and re-submit the stack. |
mattwilkinsonn
approved these changes
Sep 9, 2026
|
Stacked PR 997 failed testing in the merge queue. Please investigate the failure and re-submit the stack. |
mattwilkinsonn
approved these changes
Sep 12, 2026
|
Stacked PR 997 was cancelled: the stacked PR was pushed to. |
trunk-io
Bot
deleted the
compass-forge/rig-3299-self-delegate-design
branch
September 12, 2026 20:15
trunk-io Bot
pushed a commit
that referenced
this pull request
Sep 12, 2026
…3326) (#997) * docs(server): forge self-origin notification suppression record (RIG-3326) Design record for suppressing self-origin forge notifications at the notify-router fan-out: an agent no longer wakes on its own COMMENT / REVIEW / OPENED / STATE on a subscribed artifact, matched on owner-qualified Compass handles, failing open on any ambiguity. CHECKS is never suppressed. A suppressed notification advances delivered_revision only when the subscriber was already caught up (CAS-guarded, artifact-scope only), so the reconcile sweep neither resurrects it nor masks a prior undelivered real notification. The owner half of that identity is not on the wire today: AgentAttribution is {agent_handle} only, so the parse discards the owner it already produces and the COMMENT/REVIEW arm would be structurally inert. T0 restores owner_handle and adds an internal ForgeEvent.Actor carrier for STATE (RIG-3331 populates it). Sibling of Record A (forge self-delegate write path, PR #900); depends on RIG-3331 (agent-driven state-transition write op) for the STATE arm to suppress on the real transition actor rather than an author-row proxy. Ledger-impact: adds DL-334 (self-origin notification suppression) and DL-335 (owner_handle carriage, amending the DL-094 clause DL-186 carried forward; DL-186 stays Active). Co-authored-by: Matt Wilkinson <matt@rigel.build> resolve * docs(server): resolve the STATE actor from RIG-3331's memo, and cite symbols not lines (RIG-3326) Two changes to the self-origin suppression record, both consequences of rulings that landed after it was frozen. 1. The STATE actor carrier is RIG-3331's memo, not a field on the event. This record froze the carrier as a new ForgeEvent.Actor field added by T0, on the reasoning that ForgeEvent has no actor slot and COMMENT/REVIEW are symmetric only because CommentRef holds theirs. Matt ruled the opposite on 2026-09-07 (RIG-3331 OQ-1): the actor travels in a durable, tenant-scoped forge_state_transitions memo written at the write-path chokepoint and consumed on match at the notify lane. A provider webhook is the forge's own statement of what happened, and stamping a Compass field onto the struct parsed from it invents an event the forge never sent. So T0 adds no ForgeEvent field. The field would have shipped inert: COMMENT/REVIEW resolve through CommentRef.Agent, OPENED through the DL-055 row, and STATE -- its only remaining client -- now resolves through the memo, leaving no populator and no consumer (rule://no-inert-gating). The fail-open interim is unchanged: a memo miss resolves no actor exactly as a nil field did, so STATE delivers until RIG-3331's op is writing memos. Amends the STATE row of the actor-source matrix, the carrier section, the T0 interface block, the T0 checklist entry, and DL-338's actor-source clause. Also states the dependency direction explicitly: RIG-3331 is the PREREQUISITE, this record is the consumer. 2. Symbol-plus-path citations. Replaces every path:line citation in the record and in DL-338/DL-339 with the symbol form. A line number is stale as soon as the file moves, and the drift is observable on main: PR #916 had to chase six prose citations in a merged record when resolver.go grew a few lines. All 104 were resolved to their enclosing symbol against the source tree and verified present in the cited file; the scrub was scoped to my own rows, leaving DL-064's citation into the vendored fork tree alone rather than resolving it by basename into an unrelated file. Refs RIG-3326 Co-authored-by: Matt Wilkinson <matt@rigel.build> * fix(docs): renumber the suppression record's ledger rows to DL-351/352 (RIG-3326) main gained DL-338 from RIG-3490 after this branch claimed 338/339, so design-ledger-gate:check failed on the merge-queue trial branch with a duplicate ledger id. Move both rows to the free range above main's max. Co-authored-by: Matt Wilkinson <matt@rigel.build> * fix(docs): renumber the suppression record's ledger rows to DL-358/359 (RIG-3326) Another lane claimed DL-351/352 on main (#1092, RIG-3655) while this record sat in review, so the post-merge ledger carried two rows for each id. Main's max is now DL-357; move to DL-358/359. Co-authored-by: Matt Wilkinson <matt@rigel.build> * fix(ui): ignore the e2e visual-run output dir (RIG-3326) `apps/ui/e2e/.gitignore` ignored `/.output/` but not its sibling `/.output-visual/`, so a local visual run's `.last-run.json` was snapshotted into a commit and failed `root:lint` on formatting. Co-authored-by: Matt Wilkinson <matt@rigel.build> * docs(design): renumber suppression ledger rows to DL-364/DL-365 (RIG-3326) DL-358 was claimed on main by #1129 (RIG-3336, Compass Runner containerization) while this record sat in review, and open #1164 claims 358 as well. Main's ledger max is DL-363, so 358/359 were both stale reservations sized against an older main. Renumbered to DL-364/DL-365, above main's max and free across every open PR that touches DECISIONS.md. Co-authored-by: Matt Wilkinson <matt@rigel.build> --------- Co-authored-by: Matt Wilkinson <matt@rigel.build>
|
This pull request was merged into |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is part of a stack containing 2 PRs:
mainRecord A of the forge delegation split: the OUTBOUND self-delegate write path — an agent-filed Linear issue is delegated to the acting app itself (
delegateId=self) alongside a human assignee. Grounded in the Linear GraphQL schema:IssueCreateInputcarriesassigneeId(human) anddelegateId(agent user) as independent optionals.The inbound DL-309 delegation round-trip is Record B, split out and sequenced behind the RIG-3271 gating-posture ruling (a new live-Linear leg on the required gate is the flake class RIG-3271 is escalating).
Pre-freeze gate: SATISFIED (T1 live probe, 2026-09-05)
The load-bearing unknown — can an
actor=apptoken self-setdelegateId— was a pre-freeze gate. It has been measured against the live testbed, so this PR is at review, not holding.actor=appclient-credentials token scopedread,write,app:assignablesetdelegateIdto its own app-user id ("Compass Live Tests") onissueCreate; the create returnedsuccess: truewith the delegate slot populated. Probe issues TEST-816 (delegate-only) and TEST-817 (assignee+delegate), both archived.assignee: null(noactor=appauto-assign). A humanassigneeIdand an appdelegateIdcoexist in oneissueCreate. The two slots never contend.delegateIdfires acreatedAgentSessionEvent needs a public webhook ingress, which only Record B builds.Consequences: the
agentSessionCreateOnIssuefallback is not taken, andapp:assignableis adopted as the confirmed oracle mint scope, making T0 unconditional. Prerequisite RIG-3302 is done — Matt enabledapp:assignableon the testbed app; the mint now returnsscope: "app:assignable read write".Ordering constraint: T0 (the mint-scope bump in
tools/forge-linear-token/index.ts) must land ahead of T1/T2/T3 — changing a client-credentials mint scope revokes in-flight oracle tokens.Ledger-impact: DL-340 (delegation write path) ratifies the direct self-delegate path — the outbound provider sends
delegateId=selfplus a caller-supplied humanassigneeIdonforge.CreateIssue, degrade-on-probe-failure. The row is resolved by the T1 probe outcome above, not proposed pending it. No DL-324 reversal: the outbound path uses the existing app token, no Linear user credential.Spec-impact: none
Refs RIG-3299
Co-authored-by: Matt Wilkinson matt@rigel.build
Amendment in this push: symbol-plus-path citations
Every
path:linecitation in Record A now cites its enclosing symbol plus thefile path. A line number goes stale the moment the file it points into moves,
and a stale citation in a frozen record sends its reader to the wrong code with
no signal that it drifted.
The drift is observable on main, not hypothetical: PR #916 (RIG-3320) had to
chase six prose citations in an already-merged record when
go/internal/secrets/resolver.gogrew a few lines (:33-36→:40-43).Nothing failed and no gate caught it; the record was simply wrong until a human
noticed.
All 47 citations were resolved to their real enclosing symbol against the
source tree and verified present in the cited file. Two bare basenames
(
routing.go,routing_test.go) were resolved by content togo/internal/linearagent/, notgo/internal/compute/— a basename-onlyrewrite would have fabricated seven citations into an unrelated package, which
is the failure mode this convention exists to prevent.
moon cigreen — 18 actions, 0 failed.design-ledger-gateOK; markdownlint 0errors. Record-only change: no Go, proto, or SQL touched.