eval-issue-split¶
Provenance¶
- Source:
.spec/spexcode/spec-cli/issues/eval-issue-split/spec.md - Source SHA-256:
9004a9cbf23fe093d651c73318dab4166ca8ddb4c5bce430d51fd04ad7bfbfcf
raw source¶
An eval-remark thread and a taste issue were living in ONE list and reading as the same kind of thing — both "issues" on the board badge, both in the drain, both in the Issues page's list. But a scenario-scoped concern is a remark, not an issue (I1): it ages a scenario's loss and clears only by the teeth ([[remark-teeth]]); it must never be a drainable issue, or the loss signal could be bypassed by resolving it as an issue. So the two must split, read-time, over the one file store — and the word "forum", which still named the local store everywhere in the code, had to go with them: the local store is just where a local Issue lives, not a second concept.
expanded spec¶
Three moves, one milestone — a read-time split. This node killed "forum" from every code identifier; the
on-disk store dir itself was renamed next, in the follow-on [[issues-store-rename]] (.spec/.forum →
.spec/.issues, with a one-shot self-migration so no deployment breaks) — so the substrate now carries the
issues name top to bottom, and the old data-dir name is no longer residue but retired.
-
Kill "forum" at the substrate. The local issue store's code no longer speaks "forum": its data-level identifiers are the issues model —
postLocalIssue/replyLocalIssue(the programmatic write entrypoints),localStoreDir/LOCAL_STORE_REL(the venue),withStoreLock/commitStore/writeStoreFile(the write mechanism). The dashboard route is#/issues(not#/forum), the side-nav entry reads Issues, and the user-facing prose says "issues page", never "Forum". [[local-issues]] still OWNS the local store's whole mechanism; it is simply named as what it is — the local store of [[issues]]. -
Read-time split by concern key. An eval-remark thread's tell is its concern,
eval: <node> · <scenario>(isEvalConcern). Two complementary reads run over the ONE store:mergedIssues(the read every ISSUE surface consumes) excludes eval concerns, andloadEvalRemarkTracks(the read the EVAL surfaces consume) keeps only them. Splitting at the source — insidemergedIssues— frees every issue surface at once, by construction: the [[issues-view]] Issues page list, the [[dashboard-issues]] board issue badge, and thespex issuesdrain all stop counting eval remarks as issues, with no per-surface filter. The eval-remark tracks instead ride the EVAL side ([[evals-view]]): the [[evals-feed]] rows and the [[event-detail]] pane, through the M2 server overlay. -
One overlay feeds both eval homes. The (node, scenario)↔thread join is lifted server-side onto the reading itself:
evalTimelineattaches the eval thread asEvalEntry.thread, so it is present on every eval home — the issues-page feed folds it in through the board, the session tab through the proof model. [[event-detail]] therefore reads its remark track fromentry.thread, never from a resident issues list (which no longer holds eval threads anyway) — the counterpart to splitting them out.
Together these reach U1: ONE EventDetail component ([[event-detail]]), store-agnostic, reused in every
home — the issues eval tab AND the session eval tab (whose "no resident issues list" degradation is gone, since
the composer authors remarks through the CLI-parity /api/remarks and needs no list). U2 holds
throughout: scenario and issue stay DISTINCT peer types on DISTINCT surfaces (Evals | Issues) — the split is
exactly what keeps them from collapsing into one super-type.