You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shadow mode is the switch that lets Outpost run alongside an incumbent without machine-generated text reaching real reporters. The worker's gate covers the AI answer on every platform, and #233 is currently making the predicate itself fail closed rather than fail open on SHADOW_MODE=TRUE.
The Teams bot sits outside that gate. apps/teams-bot/src contains no reference to SHADOW_MODE or isShadowMode at all, and apps/teams-bot/src/handlers/message.ts:120 posts the acknowledgment card at ingest:
Teams is deliberately the only platform that still acknowledges — the comment above that block explains why, and the reasoning holds. But it means Teams is also the only platform whose ingest post the worker's gate structurally cannot cover, because it never goes through the worker.
So on a staging run with shadow mode on: the worker correctly withholds the AI answer, and the reporter has already been told in a real Teams channel that an AI answer is coming. A promise from staging, an answer from production, or a promise and nothing.
Two supporting bits worth fixing at the same time:
.env.example:41-42 says the flag "covers EVERY platform (GitHub, Slack, Teams)". Not true today.
docs/deployment.md:212 says "When adding any new outbound post path, check SHADOW_MODE before posting" — that's the instruction that produced the three duplicated comparisons Treat an unclear SHADOW_MODE as on, instead of posting for real #233 is consolidating. Once isShadowMode() lands in shared, that line should name the helper.
apps/teams-bot has no shadow-mode test today, so this wants one alongside — ideally using the importOriginal + spread mock so it exercises the real predicate rather than a copy of it.
Depends on #233 for the shared helper. Kept separate so that diff stays about the predicate.
Shadow mode is the switch that lets Outpost run alongside an incumbent without machine-generated text reaching real reporters. The worker's gate covers the AI answer on every platform, and #233 is currently making the predicate itself fail closed rather than fail open on
SHADOW_MODE=TRUE.The Teams bot sits outside that gate.
apps/teams-bot/srccontains no reference toSHADOW_MODEorisShadowModeat all, andapps/teams-bot/src/handlers/message.ts:120posts the acknowledgment card at ingest:Teams is deliberately the only platform that still acknowledges — the comment above that block explains why, and the reasoning holds. But it means Teams is also the only platform whose ingest post the worker's gate structurally cannot cover, because it never goes through the worker.
So on a staging run with shadow mode on: the worker correctly withholds the AI answer, and the reporter has already been told in a real Teams channel that an AI answer is coming. A promise from staging, an answer from production, or a promise and nothing.
Two supporting bits worth fixing at the same time:
.env.example:41-42says the flag "covers EVERY platform (GitHub, Slack, Teams)". Not true today.docs/deployment.md:212says "When adding any new outbound post path, checkSHADOW_MODEbefore posting" — that's the instruction that produced the three duplicated comparisons Treat an unclear SHADOW_MODE as on, instead of posting for real #233 is consolidating. OnceisShadowMode()lands inshared, that line should name the helper.Shape of the fix, once #233 merges:
apps/teams-bothas no shadow-mode test today, so this wants one alongside — ideally using theimportOriginal+ spread mock so it exercises the real predicate rather than a copy of it.Depends on #233 for the shared helper. Kept separate so that diff stays about the predicate.