A web project's Governance page offers the Ambient policy panel, accepts a
standing order, and reports it saved. The setting is then never read.
ambientPolicyApplies gates the panel on the scope prefix:
// plugins/web-ui/src/ambient-policy.ts
return scopeId.startsWith("channel:") || scopeId.startsWith("group:");
and channelContainer in src/api/routes/context-policy.ts accepts the same
two kinds (the admin registry's identical copy in
src/api/routes/admin-resources.ts does too), so the policy is written to
channel_policy keyed by the project's container. But the only thing that ever
runs an ambient judgement is judgeAmbientContainer, and its only production
caller is ingestSurfaceEvents (app-messaging.ts), which in turn is only
reached from src/slack/mirror.ts with surface: "slack" — the
reason: "scheduled" branch has no production caller either. A project's
messages go straight to a turn request, so nothing ever consults the policy.
The prefix collision looks accidental rather than deliberate: Slack group DMs
are also group:, but projects carry their own marker —
PROJECT_GROUP_PREFIX = "web-project-" in src/projects/project-store.ts,
already used for LIKE 'group:web-project-%' queries in the session store. So
the two are separable.
Either hiding the panel for project scopes or saying it doesn't apply there
would help. A standing order that saves successfully and silently does nothing
is worse than one you can't set.
(Verified against 0f0e0ad.)
A web project's Governance page offers the Ambient policy panel, accepts a
standing order, and reports it saved. The setting is then never read.
ambientPolicyAppliesgates the panel on the scope prefix:and
channelContainerinsrc/api/routes/context-policy.tsaccepts the sametwo kinds (the admin registry's identical copy in
src/api/routes/admin-resources.tsdoes too), so the policy is written tochannel_policykeyed by the project's container. But the only thing that everruns an ambient judgement is
judgeAmbientContainer, and its only productioncaller is
ingestSurfaceEvents(app-messaging.ts), which in turn is onlyreached from
src/slack/mirror.tswithsurface: "slack"— thereason: "scheduled"branch has no production caller either. A project'smessages go straight to a turn request, so nothing ever consults the policy.
The prefix collision looks accidental rather than deliberate: Slack group DMs
are also
group:, but projects carry their own marker —PROJECT_GROUP_PREFIX = "web-project-"insrc/projects/project-store.ts,already used for
LIKE 'group:web-project-%'queries in the session store. Sothe two are separable.
Either hiding the panel for project scopes or saying it doesn't apply there
would help. A standing order that saves successfully and silently does nothing
is worse than one you can't set.
(Verified against 0f0e0ad.)