gate(census): say WHY role and status are not backlog, where the numbers print (#3275)
## The hazard
The column backlog is **0**. The two largest numbers the census prints
are now `ROLE (12)` and `STATUS (185)`, sitting directly beneath it,
labelled only `(not guards)`.
That is a verdict with no reason. For a worker under a directive to
drive a census down — finding the backlog line already at zero and two
bigger numbers underneath — "(not guards)" is thin protection. This PR
puts the reason where the numbers are.
## Why they are genuinely not backlog
Both classify by **receiver**, not by the literal
(`ROLE_RECEIVER_TOKENS` = `role, agentType, agent, lane, capability,
sessionPurpose, surface, purpose, agentRole`; status matches
`/status/i`). A legacy column id next to one of those is a different
domain that happens to share vocabulary with the old board. Sampled from
the current tree, not reasoned:
| site | receiver | what it actually is |
| --- | --- | --- |
| `packages/cli/src/commands/task.ts:529` | `outcome === "archived"` | a
task **outcome** |
| `.../routes/register-chat-routes.ts:894` | `type === "done"` | a chat
**message type** |
| `.../cli-agent/telemetry-hub.ts:304` | `kind === "done"` | a telemetry
**kind** |
| `packages/cli/src/commands/goals.ts:178` | `status === "archived"` | a
**goal's** status |
| `packages/cli/src/commands/mission.ts:145` | `status ===
"in-progress"` | a **mission's** status |
None is a task column, so none has a workflow lane to resolve against.
Converting a goal's `status === "archived"` to a column trait would not
remove a legacy id — **it asks the wrong object for a lane it does not
have**, and the resulting bug would be invisible on the default board
for precisely the reason every inert conversion is. That is 185
opportunities to inject a real defect while a number goes down.
## Output-only, verified
Counts, JSON, baseline comparison and exit codes are untouched:
```
--strict exit=0
json totals: {"column": 0, "role": 12, "status": 185, "deliberate": 150} # byte-identical
```
60 census tests pass (`lifecycle-column-census.test.ts`,
`census-reclassification-message.test.ts`). `lifecycle-columns`,
`move-target-literals`, `inert-sync-lanes`, `quarantine-ledger` all exit
0.
## Provenance
I raised "role/status have no inertness proof behind them" several times
as a reason not to touch them, which was too weak — it implied the work
might be valid pending proof. Rather than leave that hanging I went and
looked. They are not unproven conversions; they are **not conversions at
all**. Correcting my own earlier framing, and putting the finding where
the next person will hit it instead of in a report they will not read.
No changeset — internal tooling.
This commit is contained in:
@@ -277,8 +277,31 @@ if (json) {
|
||||
} else {
|
||||
console.log(`lifecycle-column-census: scanned ${files.length} source files\n`);
|
||||
console.log(` COLUMN guards (the backlog): ${summary.totals.column}`);
|
||||
console.log(` ROLE comparisons (not guards): ${summary.totals.role}`);
|
||||
console.log(` STATUS comparisons (not guards): ${summary.totals.status}`);
|
||||
/*
|
||||
FNXC:LifecycleColumnCensus 2026-07-31-23:57 (these two are NOT a second backlog — do not convert them):
|
||||
Both classify by RECEIVER, not by the literal. A legacy column id appearing next to a role- or
|
||||
status-named receiver is a DIFFERENT DOMAIN that happens to share vocabulary with the old board.
|
||||
Measured samples from the current tree:
|
||||
|
||||
outcome === "archived" packages/cli/src/commands/task.ts a task OUTCOME
|
||||
type === "done" .../routes/register-chat-routes.ts a chat MESSAGE TYPE
|
||||
kind === "done" .../cli-agent/telemetry-hub.ts a telemetry KIND
|
||||
status === "archived" packages/cli/src/commands/goals.ts a GOAL's status
|
||||
status === "in-progress" packages/cli/src/commands/mission.ts a MISSION's status
|
||||
|
||||
None is a task column, so none has a workflow lane to resolve against. "Converting" a goal's
|
||||
`status === "archived"` to a column trait does not remove a legacy id — it asks the wrong object for
|
||||
a lane it does not have, and the resulting bug is invisible on the default board for the same reason
|
||||
every inert conversion is.
|
||||
|
||||
Why this needs saying where the numbers PRINT rather than only in the classifier: the two counts sit
|
||||
directly under the backlog with larger values (12 and 185 against a backlog of 0). A worker told to
|
||||
drive a census down, finding the column line at zero, has two bigger numbers in front of them and
|
||||
"(not guards)" alone does not explain why they are off-limits. The label states the verdict; this
|
||||
states the reason.
|
||||
*/
|
||||
console.log(` ROLE comparisons (NOT backlog — agent/chat/telemetry receivers, not columns): ${summary.totals.role}`);
|
||||
console.log(` STATUS comparisons (NOT backlog — goal/mission/step status, not columns): ${summary.totals.status}`);
|
||||
console.log(` DELIBERATE-LITERAL (reviewed): ${summary.totals.deliberate}`);
|
||||
/*
|
||||
FNXC:LifecycleColumnCensus 2026-08-01-01:40:
|
||||
|
||||
Reference in New Issue
Block a user