GV-10: Visibility-gated events, webhooks, notifications, queues, reviews, work items, and artifacts
Parent epic: #638
Plan ID: IMP-10
Depends on: #645
Branch Contract
- Top-level integration branch:
epic/638-visibility-owned-branches.
- Start only after accepted-private PromotionSet workflow is available on the epic branch.
Objective
Gate public-facing event and workflow projections so private branch/reference/promotion activity does not leak through webhooks, SignalR/watch, notifications, queues, review reports, work items, artifacts, or search/activity surfaces.
Why This Matters
Visibility bugs often hide in projections outside the main read route. Accepted-private work must not leak through event names, delivery ids, review queues, or linked artifacts.
Minimum Detail Gate
- Invariant tuple: Internal persisted actor events may remain complete, but every external projection/delivery is computed for a caller or subscription audience and suppresses private resources until reveal.
- Forbidden implementation shapes: Do not send
promotion-set.applied for private apply to public webhook owners. Do not expose private ids in webhook delivery records, user-facing logs, queue candidates, review artifacts, or work-item links. Do not rely only on internal event persistence suppression; projections need audience filters.
- Positive tests: Authorized audience receives private signals according to explicit audience rules.
- Negative tests: Public webhook delivery count is unchanged for private create/apply; public notification/watch observes no private activity.
- Regression tests: Existing public webhook/event flows continue for public resources.
- Boundary/property tests: Reveal emits exactly one public event/projection and does not replay private history. For public subscribers, projected event stream equals filtering internal stream to visible resources plus reveal events.
Candidate Owned Paths
src/Grace.Server/WebhookDispatch.Server.fs
src/Grace.Types/Webhooks.Types.fs if event names/versioning change.
- Notification/SignalR/watch server modules.
- Queue/review/work-item/artifact route modules.
src/Grace.Server.Tests/* webhook/projection/review tests.
src/Grace.CLI.Tests/* watch tests if watch is affected.
Implementation Seams
- Add audience-aware event projection and dispatch filters.
- Define reveal-time public event semantics and event name/version if product needs webhooks.
- Filter queue/review/work-item/artifact links pointing to private refs/promotion sets.
- Gate notifications/watch/SignalR groups by visible branch/reference audience.
Contract Propagation
- Events, webhooks, SignalR, watch, search, and projections: update with projection tests.
- Review/queue/work-item/artifact route outputs: update if present/touched; otherwise provide source-search waiver.
- Docs/event reference: defer to GV-15 unless event names change.
Stale-Authority Preflight
- Authoritative state: persisted actor event plus current resource visibility/audience at projection time.
- Revalidate before dispatch/delivery/public projection, not only when the event was originally emitted.
- If reveal projection fails after reveal event, retry must be idempotent and must not duplicate public webhooks.
Validation
Server-api plus async/runtime plus event projection profile. Run focused webhook/notification/work-item tests, targeted Fantomas, and Fast or Full if Service Bus/SignalR/Aspire participates.
Product Decisions Covered
PD-01, PD-02, PD-03, PD-08.
Acceptance Criteria
- Public event/webhook/notification projections are silent before reveal.
- Authorized private audience receives intended signals.
- Reveal-time public event semantics are proven.
Approved Carry-Forward Decisions And Proof Obligations
These decisions are already approved through the #645 unblock and review-stabilization work. Treat them as part of this issue's contract, not as optional implementation notes.
- Reveal is the first public publication point for private accepted PromotionSet work. A terminal reveal must create the public
promotion_set.applied webhook delivery and the public PromotionSetApplied automation/Eventing projection exactly once.
- Private review events and review projections created from a private PromotionSet must inherit private visibility metadata before publication. Public automation must suppress those private review events until the source becomes public through reveal.
- Queue state exposed through review candidate and review report snapshots must use the same caller-visible queue projection as the queue routes. A public candidate must not reveal hidden private running or queued work in the same branch queue.
- Queue mutations for private PromotionSets, including retry, cancel, enqueue, dequeue, and gate-rerun style operations, must stamp private visibility metadata so public automation does not receive hidden PromotionSet ids through queue events.
- Routes that load or act on a PromotionSet id must prove the caller can observe that PromotionSet before returning projections or mutating retry, cancel, recompute, enqueue, dequeue, or gate-rerun state. Hidden private PromotionSets are missing-equivalent or no-op to non-observers.
- Public-facing projection, dispatch, and delivery code must re-check the current visibility of the source at projection time. Do not rely on the visibility that was true when an internal actor event was first persisted.
Stabilization Preflight For The Worker
Before editing code, identify the exact external surfaces that currently exist for webhooks, Eventing/automation, SignalR/watch, notifications, queues, review reports, work items, artifacts, activity/search, and logs. For each surface, record one of these outcomes in the handoff:
The proof set must include negative evidence that a public observer cannot learn private branch, reference, PromotionSet, queue, review, work-item, artifact, or delivery ids from a projection side channel. If a new durable projection concept, retry policy, stale-source rule, or public contract is needed and it is not already named above, stop and ask for maintainer approval before implementing it.
GV-10: Visibility-gated events, webhooks, notifications, queues, reviews, work items, and artifacts
Parent epic: #638
Plan ID: IMP-10
Depends on: #645
Branch Contract
epic/638-visibility-owned-branches.Objective
Gate public-facing event and workflow projections so private branch/reference/promotion activity does not leak through webhooks, SignalR/watch, notifications, queues, review reports, work items, artifacts, or search/activity surfaces.
Why This Matters
Visibility bugs often hide in projections outside the main read route. Accepted-private work must not leak through event names, delivery ids, review queues, or linked artifacts.
Minimum Detail Gate
promotion-set.appliedfor private apply to public webhook owners. Do not expose private ids in webhook delivery records, user-facing logs, queue candidates, review artifacts, or work-item links. Do not rely only on internal event persistence suppression; projections need audience filters.Candidate Owned Paths
src/Grace.Server/WebhookDispatch.Server.fssrc/Grace.Types/Webhooks.Types.fsif event names/versioning change.src/Grace.Server.Tests/*webhook/projection/review tests.src/Grace.CLI.Tests/*watch tests if watch is affected.Implementation Seams
Contract Propagation
Stale-Authority Preflight
Validation
Server-api plus async/runtime plus event projection profile. Run focused webhook/notification/work-item tests, targeted Fantomas, and Fast or Full if Service Bus/SignalR/Aspire participates.
Product Decisions Covered
PD-01, PD-02, PD-03, PD-08.
Acceptance Criteria
Approved Carry-Forward Decisions And Proof Obligations
These decisions are already approved through the #645 unblock and review-stabilization work. Treat them as part of this issue's contract, not as optional implementation notes.
promotion_set.appliedwebhook delivery and the publicPromotionSetAppliedautomation/Eventing projection exactly once.Stabilization Preflight For The Worker
Before editing code, identify the exact external surfaces that currently exist for webhooks, Eventing/automation, SignalR/watch, notifications, queues, review reports, work items, artifacts, activity/search, and logs. For each surface, record one of these outcomes in the handoff:
The proof set must include negative evidence that a public observer cannot learn private branch, reference, PromotionSet, queue, review, work-item, artifact, or delivery ids from a projection side channel. If a new durable projection concept, retry policy, stale-source rule, or public contract is needed and it is not already named above, stop and ask for maintainer approval before implementing it.