feat(content): wire the classifier, so deny actually denies #390
No reviewers
Labels
No labels
move-to-repo
coilyco-bridge-deploy
move-to-repo
coilyco-flight-deck-agent-compose
move-to-repo
coilyco-gaming-eco-app
move-to-repo
coilysiren-inbox
move-to-repo
unknown
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/sirens-echo!390
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/deny-actually-denies"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
closes #388
The wiring for #227, and the enforcement half #228 rides on.
The taxonomy declared
deny: trueon six classes and nothing read it at runtime. Asking where the bus is got whatever the model decided. Lucia landed the taxonomy and prompt; I landed the bounded block response; Quail confirmed nothing gates content. The invocation between them was declined by all of us in turn.Inert until a deployment says otherwise
SIRENS_ECHO_CONTENT_CLASSESnames the taxonomy. Unset loads none, runs no classifier, and costs nothing — not a model call, not a decision, not a tag beyondcontent.classified: false.That is deliberate. A gate that refuses member requests should arrive by a decision someone made, and the cost is real: one extra model call per turn, landing hardest on the cheapest turns. The full costing is on 227 and the enabling decision is Kai's.
The property that matters more than the feature
A broken gate is not a denial. A classifier that errors, times out, or answers with a class outside the closed set leaves the turn unclassified and the turn proceeds.
Treating a classifier failure as a refusal turns one broken dependency into a service that refuses everything — and does it while looking like policy working correctly. That is the failure mode worth engineering against here.
Kai's four tags
The first earns its place by being false much of the time; a tag that is always true says nothing, and asking for a boolean is what suggested the gate should be able to not run. A turn that was never classified carries only that tag — reporting a class for a decision that never happened would make the other three lies.
sensitivestays separate fromapprovedbecause it changes the refusal's shape and not its verdict: a sensitive block names no category, since naming it tells a member what to avoid saying next time.Ordering
Classification runs on the member's own message — what was asked for is the thing being classified — and before the answering call, so a blocked turn spends no completion budget on an answer nobody will read.
Not in scope
The deterministic prefilter I costed on 227, which would cut the per-turn cost. It is a change on top of this seam, not a replacement for it.
ward exec gategreen: build, policy-check, vet, test, test-skips, pre-commit.content classifier#227