From 32054fc9452aab9a23735c609cfac213a61cf133 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 3 Jul 2026 20:26:52 +0000 Subject: [PATCH 1/2] Scope the frontend audit walk to screens as well as components The extraction convention already binds src/screens (its CLAUDE.md mirrors the components one), but frontend-organization.md's audit checklist only walked src/components - so the periodic sweeps never looked at the biggest files in the frontend, which is where the tech-debt audit found ~22k lines of unextracted decision logic. --- docs/dev/frontend-organization.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev/frontend-organization.md b/docs/dev/frontend-organization.md index aca24364..7ec2e74e 100644 --- a/docs/dev/frontend-organization.md +++ b/docs/dev/frontend-organization.md @@ -191,7 +191,10 @@ component "to consolidate." Each is locally reasonable. The aggregate is a layer rebuilt one inch at a time. Periodically (and after any non-trivial UI work), walk -`src/components/*.svelte` and ask, per file: +`src/components/*.svelte` AND `src/screens/*.svelte` and ask, per +file (the screens are where the convention drifts hardest - they +are the biggest files, and "it's only used by this screen" is the +exact rationalization the convention exists to refuse): 1. **What's in the ` @@ -571,37 +369,19 @@ {/if}

Observations from this conversation

- {#if currentThreadObs === null || currentThreadProcessedAt === null} - -

- Not yet analyzed. Conversations become eligible - once their last activity falls on a previous day; - the hourly sweep picks this one up then. -

- {:else if currentThreadObs.length === 0} -

- Already analyzed - no clear bias evidence was - found in this conversation. Reporting nothing - is the correct answer most of the time. -

+ {#if obsEmptyCopy !== null} + +

{obsEmptyCopy}

{:else}
- {#each currentThreadObs as o (o.id)} + {#each currentThreadObs ?? [] as o (o.id)}
{biasLabel(o.bias)} - confidence {(o.confidence * 100).toFixed(0)}% + confidence {formatConfidence(o.confidence)}

{o.reasoning}

@@ -611,36 +391,18 @@ {/if}

Reactions to compensation on this conversation

- {#if currentThreadReactions === null || currentThreadProcessedAt === null || currentThreadReactions.length === 0} -

- {#if currentThreadReactions === null || currentThreadProcessedAt === null} - - Not yet analyzed. Reactions are recorded for the - biases that were active in the system prompt while - the conversation happened; the sweep classifies - them once the conversation settles. - {:else if renderedRows.length === 0} - No biases were active in the system prompt during - this conversation, so there was nothing for you - to react to. - {:else} - Already analyzed - the agent did not see a clear - affirmation or pushback signal for the active - biases on this conversation. - {/if} -

+ {#if reactionsEmptyCopy !== null} + +

{reactionsEmptyCopy}

{:else}
- {#each currentThreadReactions as r (r.id)} + {#each currentThreadReactions ?? [] as r (r.id)}
{biasLabel(r.bias)} - + {reactionVerdict(r.wasConfirmed)}
@@ -689,32 +451,18 @@ title={biasDefinition(row.bias)} >{biasLabel(row.bias)} - + - {#if !hasEvidence(row.bias)} + {#if !hasEvidence(observationCounts, row.bias)} no evidence {:else} {formatProbability(row.ciLower)} @@ -752,7 +500,7 @@
CI lower (90%)
- {#if !hasEvidence(row.bias)} + {#if !hasEvidence(observationCounts, row.bias)} no evidence {:else} {formatProbability(row.ciLower)} @@ -768,9 +516,9 @@ trailing feedback sentence when the EMA is meaningful enough to shift the gates. -->

- {interpretBias(row, rendered.has(row.bias))} + {interpretBias(row, rendered.has(row.bias), hasEvidence(observationCounts, row.bias))}

- {#if hasEvidence(row.bias)} + {#if hasEvidence(observationCounts, row.bias)}