Version: 0.1
Date: 2026-06-02
Repos: OL frontend DUNIN7/loomworks (/Users/dunin7/loomworks); engine DUNIN7/loomworks-engine.
Origin: Surfaced when an Operator clicked Confirm on the upload clarification card for a Monstera AVIF on Fenwick and the Companion displayed "Noted — skipped." Engine state showed the card resolution wrote nothing (by design — the card is v1 local-state only; engine re-dispatch is a future-phase capability per CR-2026-093 v0.3 §13.3). Two distinct defects came out of the trace.
Line refs re-verified against live code 2026-06-02 — both held, no drift.
resolutionLabel null-skill → "skipped" fallthrough (frontend, cosmetic)
File: /Users/dunin7/loomworks/src/components/chat/AskOperatorToClarifyCard.tsx
Line refs (verified 2026-06-02, no drift): Confirm button onClick at line 80; label fallback at line 42; resolutionLabel at lines 107–114 (the "skipped" fallthrough is line 113).
The code (lines 107–114, verbatim):
function resolutionLabel(
action: ClarifyAction,
skill: string | null,
): string {
if (action === "confirm" && skill) return `confirmed ${skill}`;
if (action === "pick") return "you'll pick a different skill";
return "skipped";
}
The Confirm button (line 80) calls resolve("confirm", classification.classified_label).
What input produces it. When the engine's classified_label is null (the no-confident-candidate case — see Finding B), Confirm dispatches resolve("confirm", null). In resolutionLabel, the only confirm branch is guarded by && skill; with skill === null that guard is false, so execution falls through past the pick branch to the default return "skipped".
What the user sees. They click Confirm, and the card renders "Noted — skipped." — i.e. a genuine confirm action is mislabeled as a skip. (The local state is correctly recorded as action: "confirm"; only the displayed string is wrong.)
What the correct behavior should be. resolutionLabel needs a branch for action === "confirm" with a null/empty skill — e.g. return "confirmed" (no skill name) rather than falling through to "skipped". The action recorded is "confirm", so the label must read as a confirm, not a skip.
Not a mis-wire, not intentional. This is not Confirm being wired to the skip path (the dispatched action is genuinely "confirm"), and not a deliberate "confirm-with-all-zero-scores → skip" semantic. It is purely a missing label branch.
Scope note. The card is used only at UploadResultCard.tsx:165, which passes no onResolved, so today all three actions (confirm/pick/skip) are engine no-ops regardless of label — engine re-dispatch is a future-phase capability (CR-2026-093 v0.3 §13.3). So Finding A is currently cosmetic-only, but it will mislead the moment re-dispatch is wired.
classified_label (engine; deviates from CR-2026-093 §13.1)
File: /Users/dunin7/loomworks-engine/src/loomworks/uploads/executor.py, function classify_purpose_for_chains.
Line refs (verified 2026-06-02, no drift):
def classify_purpose_for_chains — line 186framing_kind dataclass default = "accuracy" — line 109 (also on the UploadEventReceived model, upload_event.py:123)if not purpose_declaration ...): returns classified_chain=None (213), above_threshold=False (216), no framing_kind set → defaults to "accuracy"if max_score == 0): returns classified_chain=None (243), above_threshold=False (246), no framing_kind set → defaults to "accuracy"if len(top_chains) > 1): the only branch that explicitly sets framing_kind="purpose" (line 281), with classified_chain=Noneclassified_chain=top_chains[0], above_threshold=True
The defect. When there is no confident candidate — either no purpose declaration (line 211) or zero keyword matches (line 241) — the function returns classified_chain=None but leaves framing_kind at its "accuracy" default. The OL accuracy card (AskOperatorToClarifyCard.tsx, rendered when framing_kind === "accuracy") then shows "I want to make sure I read this right. I think this is —." (the em-dash because classified_label is null, AskOperatorToClarifyCard.tsx:42). An accuracy question with nothing to confirm. This is also the precise input that triggers Finding A.
What the user saw (this incident). The Monstera AVIF produced all-zero candidate scores → classified_label=None, framing_kind="accuracy" → the accuracy card rendered "I think this is —", and Confirm (with null skill) displayed "Noted — skipped" (Finding A).
Settled commitment (verbatim from loomworks-engine/docs/phase-crs/phase-60-cr-operator-layer-upload-pathway-v0_3.md):
Alignment result: CONSISTENT (no conflict). Finding B identifies code that deviates from the settled commitment, not a finding that contradicts it. §13.1 defines accuracy framing as presupposing a confident candidate ([candidate]); the engine emitting framing_kind="accuracy" with classified_label=None breaks that definition. So recording Finding B upholds §13.1 rather than contradicting it — no STOP condition.
The remedy is left open (deliberately). §13.1's two surfaces are accuracy (one confident candidate) and purpose-2f (multiple candidates above threshold). The zero-confident-candidate case (no purpose / no keyword match) fits neither as defined — routing it to framing_kind="purpose" would stretch 2f's "this could go a few ways / multiple valid" meaning to cover "no idea which." So this finding asserts only that accuracy-with-null-candidate is wrong (it violates §13.1); whether the fix is (a) route zero-candidate to the 2f purpose surface, or (b) introduce a distinct third framing for "couldn't classify," is an open design question for whoever owns the upload-clarification surface. Do not treat (a) as settled.
Both findings unrecorded until now. This file records them; it is uncommitted. Findings A and B are independent fixes (frontend label vs. engine framing-selection); B touches a settled commitment (§13.1) and should be resolved with the surface owner, not unilaterally.