mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-09 01:46:46 +08:00
* fix(subscribers): stop an armed autopilot from subscribing its trigger's creator An autopilot fires on its schedule, its agent files issues, and the member who armed the trigger is auto-subscribed to every one of them. The delegated-subscriber rule (MUL-5483) subscribes the human an agent-created issue exists on behalf of, and it tested that by asking whether the origin run carries an originator. That was sound when it was written: direct_human was the only attribution root that left an originator behind, so "this run carries a human" and "a human asked for this work" were the same statement. MUL-6951 separated them. An armed schedule/webhook trigger now runs with its creator's authorization (trigger_owner), and attribution COPIES that human down every agent hop, so the rule started reading an automation's authorization as a request. attribution.DelegatedSubscriber already documents this exact outcome as one it must not produce — the origin_type='autopilot' exclusion says the autopilot's own subscriber template, not whoever armed the trigger, is the audience for its issues. The regression arrives one hop below that exclusion, where the issue's origin is an ordinary agent_create. The rule now asks what it means: did this chain BEGIN with a member acting. The originator alone cannot answer that below the first hop, because a hop relabels its own originator_source to 'delegation' — so GetDelegatedSubscriptionFacts walks delegated_from_task_id back to the run that actually resolved the human and returns that root's label alongside the originator, in one workspace-scoped read that replaces the previous single-task load. Accepting only direct_human makes it a whitelist: the next root that resolves a human some other way stays silent here until someone decides otherwise, instead of switching this rule on for a population nobody chose. No schema change and no change to attribution itself: originator, accountable and every authorization decision are untouched. Only who gets subscribed moves. Verification (real PostgreSQL 17): internal/attribution, cmd/server pass; the four new tests fail against the unfixed rule, and the tenant-guard test fails when the workspace predicate is removed from the new query. internal/handler and internal/service each keep one pre-existing failure that reproduces identically on a clean tree (source-context object-store cleanup), as do cmd/multica, internal/cli, internal/daemon and internal/daemon/execenv. Co-authored-by: multica-agent <[email protected]> * test(subscribers): close the review gaps in the lineage walk's coverage Addresses Elon's review on #8031. The 32-hop stop is accepted as a product limit (Bohan's call), so it is now written down as behaviour instead of contradicted by it. DelegatedSubscriber claimed "No depth cap", which was true of WHO the human is — the originator is copied onto every run — but not of proving the chain began with them, which is the part that walks. The query comment called the cap cycle protection only. Both now say what actually happens: past 32 hops the root is unproven and nobody is subscribed. TestDelegatedSubscribe_LineageWalkStopsAt32Hops pins both sides, so the limit cannot drift silently; moving it to 3 reddens the 32-hop case. The tenant test claimed to cover every hop and covered one. An issue pointing straight at a foreign run only exercises the anchor's predicate, so deleting the recursive branch's workspace_id left it green. It is now two cases, and the added one — a local run naming a foreign parent — fails with that predicate removed while the original case still passes, which is exactly the blind spot. The chain fixture builds through internal/testutil instead of hand-writing an INSERT with a matching cleanup, per the repository's test convention. No production behaviour changes: the rule, the walk and every existing assertion are untouched. Verification (real PostgreSQL 17): cmd/server, internal/attribution, internal/service pass; both new tests were run against a deliberately broken query and fail there. gofmt, go vet, git diff --check clean. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: J <[email protected]>