Skip to content

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, and loadEvalRemarkTracks (the read the EVAL surfaces consume) keeps only them. Splitting at the source — inside mergedIssues — frees every issue surface at once, by construction: the [[issues-view]] Issues page list, the [[dashboard-issues]] board issue badge, and the spex issues drain 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: evalTimeline attaches the eval thread as EvalEntry.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 from entry.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.