docs(core): scope the archived three-encoding decision — it is not 52-or-nothing (#3147)
The `archived` family is the largest unclaimed cluster (52 sites) and its blocker is that **nobody has scoped it**. This scopes it. It converts nothing. ## The two options both read as enormous because 52 sites are counted as one lump They are not one lump. The sites answer **two different questions**: | question | renameable? | |---|---| | **LANE** — "is this row resting in the board's archive lane?" | yes — must resolve | | **STATE** — "did Fusion archive this row?" (the marker `archiveTask` writes) | **no** | `async-maintenance.ts` already draws that line and marks its own site DELIBERATE-LITERAL: > `'archived'` is the STATE marker here, not a lane. This sweep collects rows Fusion itself archived or soft-deleted; a card merely sitting in a workflow's archived-TRAIT lane is live work and must not be collected. Widening to the resolved archived set would pull real cards into a cleanup pass. **Converting that site would be a bug, not progress.** `async-archive-lineage.ts`'s soft-delete path is the same shape — `column = 'archived', deleted_at IS NOT NULL` is the storage state it has just written. So the first question is a **triage**, not a conversion: which of the 52 are lane questions? Nobody has answered it, which is exactly why the cost reads as unbounded. ## Measured: the SQL half, which the existing note calls the hard part 8 Drizzle sites across 7 files. **Four already have `store` in scope** — they could take a resolved set today with no signature change: - `branch-group-ops.ts` — `clearNearDuplicateReferencesToImpl(store, ...)` - `branch-and-pr-entities.ts` — `findRecentTasksByContentFingerprintImpl(store, ...)` (2 sites) - `task-mutation-ops.ts` — `cleanupArchivedTasksImpl(store)` **Four need one parameter each**, the same optional-lane-set shape used throughout this program: - `async-lifecycle.ts` — `liveLineageChildFilter(parentId, projectId?)` - `async-search.ts` — `liveSearchPredicate(includeArchived, projectId?)` - `async-self-healing.ts` — `listSoftDeletedColumnDriftCandidates(db, ...)` - `store.ts` — the revert-lookup conditions (already holds `this.asyncLayer`) That is not *"threading a resolver into the persistence layer"*. It is four call sites that already have what they need, plus four one-parameter widenings — **before** any triage removes the STATE sites from the count entirely. ## What I did not do, and why The triage itself: a per-site judgement about what each guard *means*. That belongs to whoever owns this gate, not to a passing fleet lane — and getting it wrong in the STATE direction pulls live cards into a cleanup sweep, which is the one failure mode here that destroys work rather than hiding an affordance. What was cheap and missing was the **shape** of the problem. ## Measured - Comment-only; parity test **2/2**. - `tsc --noEmit -p packages/core` clean; census `--strict` clean. - `check-fnxc-future-dates` is red from `main`'s own #3128 stamps — **#3139** fixes that; this branch inherits and does not add to it. ## Census No movement. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,6 +113,34 @@ NOT CONVERTED HERE, and deliberately: the gate requires all three encodings to m
|
||||
conversion is one coordinated change with its inventories updated in the same commit. This supplies
|
||||
the classification that change needs; it does not pre-empt it.
|
||||
|
||||
FNXC:WorkflowResolvedColumns 2026-07-31-23:55 (SCOPING — the choice is not 52-or-nothing):
|
||||
"Convert all three encodings" and "declare `archived` non-renameable" are the two options offered, and
|
||||
both sound enormous because 52 sites are counted as one lump. They are not one lump: the sites answer
|
||||
TWO DIFFERENT QUESTIONS, and only one of them is a lane question.
|
||||
|
||||
LANE: "is this row resting in the board's archive lane?" — renameable, must resolve.
|
||||
STATE: "did Fusion archive this row?" — the marker `archiveTask` writes, NOT renameable.
|
||||
|
||||
`async-maintenance.ts` already draws that line and marks its site DELIBERATE-LITERAL: "the STATE
|
||||
marker here, not a lane... a card merely sitting in a workflow's archived-TRAIT lane is live work and
|
||||
must not be collected." Converting that site would be a BUG, not progress.
|
||||
|
||||
MEASURED, on the SQL half this file calls the hard part — 8 Drizzle sites across 7 files:
|
||||
FOUR already have a `store` in scope and could take a resolved set with no signature change:
|
||||
branch-group-ops.ts clearNearDuplicateReferencesToImpl(store, ...)
|
||||
branch-and-pr-entities.ts findRecentTasksByContentFingerprintImpl(store, ...) [2 sites]
|
||||
task-mutation-ops.ts cleanupArchivedTasksImpl(store)
|
||||
FOUR need one parameter each, the optional-lane-set shape used throughout this program:
|
||||
async-lifecycle.ts liveLineageChildFilter(parentId, projectId?)
|
||||
async-search.ts liveSearchPredicate(includeArchived, projectId?)
|
||||
async-self-healing.ts listSoftDeletedColumnDriftCandidates(db, ...)
|
||||
store.ts the revert-lookup conditions (already holds `this.asyncLayer`)
|
||||
|
||||
That is not "threading a resolver into the persistence layer". It is four call sites that already have
|
||||
what they need plus four one-parameter widenings — before the triage above removes the STATE sites
|
||||
from the count. (Two of the four "already have a store" sites turned out to be STATE on inspection;
|
||||
the triage note above is the authority, this is the reachability survey that preceded it.)
|
||||
|
||||
FNXC:WorkflowResolvedColumns 2026-07-31-23:50 (one wrong reason for picking the cheap option, removed):
|
||||
The second option looks like it has already been taken — `trait-types.ts` annotates the flag
|
||||
"RESTRICTED (built-in only)", which reads as "a custom board cannot have its own archive lane". It does
|
||||
|
||||
Reference in New Issue
Block a user