Skip to content

docs(design): forge self-delegate write path record (Record A) (RIG-3299) - #900

Open
rigel-mintaka wants to merge 3 commits into
mainfrom
compass-forge/rig-3299-self-delegate-design
Open

docs(design): forge self-delegate write path record (Record A) (RIG-3299)#900
rigel-mintaka wants to merge 3 commits into
mainfrom
compass-forge/rig-3299-self-delegate-design

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

This PR is part of a stack containing 2 PRs:

  1. main
  2. "docs(design): forge self-delegate write path record (Record A) (RIG-3299)" (this PR)
  3. docs(server): forge self-origin notification suppression record (RIG-3326) #997

Record 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: IssueCreateInput carries assigneeId (human) and delegateId (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=app token self-set delegateId — was a pre-freeze gate. It has been measured against the live testbed, so this PR is at review, not holding.

  • OQ-1 self-delegate — ALLOWED. An actor=app client-credentials token scoped read,write,app:assignable set delegateId to its own app-user id ("Compass Live Tests") on issueCreate; the create returned success: true with the delegate slot populated. Probe issues TEST-816 (delegate-only) and TEST-817 (assignee+delegate), both archived.
  • OQ-2 assignee slot — independent. Delegate-only left assignee: null (no actor=app auto-assign). A human assigneeId and an app delegateId coexist in one issueCreate. The two slots never contend.
  • OQ-3 outbound shape — always assign a human AND delegate the app (Matt's ruling). Supersedes the prior draft's "leave Assignee empty" recommendation.
  • OQ-4 — deferred to Record B by design. Whether an app-set delegateId fires a created AgentSessionEvent needs a public webhook ingress, which only Record B builds.

Consequences: the agentSessionCreateOnIssue fallback is not taken, and app:assignable is adopted as the confirmed oracle mint scope, making T0 unconditional. Prerequisite RIG-3302 is done — Matt enabled app:assignable on the testbed app; the mint now returns scope: "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=self plus a caller-supplied human assigneeId on forge.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:line citation in Record A now cites its enclosing symbol plus the
file 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.go grew 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 to
go/internal/linearagent/, not go/internal/compute/ — a basename-only
rewrite would have fabricated seven citations into an unrelated package, which
is the failure mode this convention exists to prevent.

moon ci green — 18 actions, 0 failed. design-ledger-gate OK; markdownlint 0
errors. Record-only change: no Go, proto, or SQL touched.

@linear-code

linear-code Bot commented Sep 5, 2026

Copy link
Copy Markdown

RIG-3299

@trunk-io

trunk-io Bot commented Sep 5, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-forge-rig-3299-self.compass-eng-docs.pages.dev

Deployed from compass-forge/rig-3299-self-delegate-design at 8b28ed1.

Changed pages:

@rigel-mintaka
rigel-mintaka force-pushed the compass-forge/rig-3299-self-delegate-design branch from 16e3f8f to 90fcb06 Compare September 5, 2026 21:47
@rigel-mintaka rigel-mintaka changed the title docs(server): forge self-delegate write path design record (RIG-3299) docs(design): forge self-delegate write path record (Record A) (RIG-3299) Sep 5, 2026
@rigel-mintaka
rigel-mintaka force-pushed the compass-forge/rig-3299-self-delegate-design branch 3 times, most recently from cc64134 to 050dc12 Compare September 6, 2026 01:52
@rigel-mintaka
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
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
rigel-mintaka and others added 3 commits September 7, 2026 17:37
…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
rigel-mintaka force-pushed the compass-forge/rig-3299-self-delegate-design branch from f32510d to 8b28ed1 Compare September 7, 2026 21:42
@trunk-io

trunk-io Bot commented Sep 8, 2026

Copy link
Copy Markdown

Stacked PR 997 failed testing in the merge queue. Please investigate the failure and re-submit the stack.

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.

2 participants