Parse nested JSONB job-status RPC result before completion gate checks - #156
Merged
Conversation
Copilot
AI
changed the title
[WIP] Parse the JSON status RPC result before checking ok
Parse nested JSONB job-status RPC result before completion gate checks
Jul 2, 2026
BigSimmo
marked this pull request as ready for review
July 2, 2026 10:29
BigSimmo
enabled auto-merge
July 2, 2026 10:29
This was referenced Jul 30, 2026
BigSimmo
added a commit
that referenced
this pull request
Jul 31, 2026
#141 closed on the production defect, but --primary-hover and --success-hover are still undefined on main (referenced at favourites-library-redesign-page.tsx :203 and :217, zero definitions in the stylesheet). Impact is low — mockups are gate-exempt design scratch — but with #141 archived nothing in the ledger owned them, and .design-sync/NOTES.md is prose in a tooling file, not a tracked item. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
BigSimmo
pushed a commit
that referenced
this pull request
Jul 31, 2026
… rows CodeRabbit found row #165 claiming its follow-ups "were renumbered again to #156/#157/#158" — ids that now belong to unrelated rows on main. A reference that resolves to the wrong row is worse than none in a ledger whose whole job is to be followable later. Two fixes: - Dropped the renumbering trail entirely rather than updating it. It listed superseded ids that main has since reissued, and it went stale again on the very next sync; the row now states that renumbering happened and why, without naming numbers that no longer mean anything. - Corrected a second stale reference the earlier renumber missed: row #165 pointed at #157 for the privacy sign-off that variant F would need. That is the answer-mode caveat row, now #166. The earlier pass only rewrote three known cross-reference phrasings and did not catch this one. Verified by extracting every backtick id reference from the three rows: #165 and #166 now point at each other and #167 at #120, all live. check:outstanding-issues: 165 rows (50 open, 115 archived), unique ids, next-id=168 above the highest, no ids deleted from base 3b4872f. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NPyFcMfn1jMmphr6AqiWBg
BigSimmo
pushed a commit
that referenced
this pull request
Aug 5, 2026
…sign Four conflicts, resolved as the trial merge recorded in the PR body predicted. `search-screen.tsx` reduced to the handler alone, exactly as forecast: both sides had independently arrived at `--text-muted`, so the only disagreement left was `clearSearchFilters` (here) versus `clearSearch` (main). Kept this branch's — #1616 branched before defect #1611's sibling was fixed, and `clearSearch` on a control labelled `Clear` inside a filter row deletes the query the reader is looking at. `search-results-header-band.tsx` (2 hunks) took this branch: main's side is the pre-restructure shelf carrying only the token migration this branch had already applied. `document-search-results.tsx` (3 hunks): the two empty-state hunks took this branch's shared `SearchResultsEmptyState`. The import hunk is a genuine merge — v2 renamed `metadataPill` to `metadataPillDensity`, and the auto-merged body now calls `metadataPillDensity.roomyCompact`, so the import must follow. `EmptyState` is dropped from it because both of v2's call sites are the ones this branch replaced. `docs/outstanding-issues.md`: #1616 minted its own #237 and #238 from the same `next-id`, so both sides landed rows under both numbers. Renumbered *this* branch's to #246 and #247 and bumped the marker to 248, rather than taking one side wholesale — main's rows are already landed and referenced. This is the collision `#156` and `#168` predict; the guard caught it. Two v2 gates then failed on the merged tree and are now satisfied: - `check:design-system-contract` ratchets `textSoftConsumers` per file, and v2 had driven both of these to zero. The four remaining usages here are icons and glyphs, which this branch had deliberately left on `--text-soft` because v1 defined no decoration token. v2 defines `--decoration-soft`, so that constraint is gone and they move there — the tier v2 itself uses for the same nodes. - The generated adoption manifest and COMPONENTS.md maturity section went stale as a result; regenerated with `design-system:adoption:update`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qm3i3eLCDcwytzge1sKM4a
BigSimmo
added a commit
that referenced
this pull request
Aug 9, 2026
…1786) * feat(design-system): build ErrorState, the gate with nothing behind it GATES.md §3 lists the prohibition "Render '0 matches' after a failed request" with the gate "ErrorState adoption + check", status planned. Measured at origin/main 199b303, ErrorState existed nowhere in src or tests — only in COMPONENTS.md, GATES.md and SPEC.md. This builds it. The invariant is clinical, not cosmetic. A search that failed has no count to report, so reporting zero is a false statement about the corpus: on the services page "0 matches" asserts there are no crisis services when the search never ran, and on favourites it reads as "you have saved nothing" rather than "we could not load them". COMPONENTS.md:322 draws the same line from the other side — "no result count is available" is not a MissingValue. The component therefore takes no count and no children. There is no prop through which a number can arrive, and the generated dtsPropsFor entry now records that as the published API. The one remaining route, a caller writing a count into title or body, is covered by a development-time tripwire that matches a figure against a counted noun ("0 matches", "no results") so an error code or a duration does not trip it. It warns and never throws: on the one screen already reporting a failure, a thrown error is a blank page. Requirements came from the surfaces that hand-roll this guard today. Three do, and their comments state the rule outright: search-results-header-band.tsx:210 ("no number may reach the DOM"), services-navigator-page.tsx:634 ("a blocked registry must not reach the band as '0 matches'") and favourites-command-library-page.tsx:1182. They are correct, just not shared; converting them is a live-look change and deliberately not here. Three further sites carried into this task as hand-rolled guards are not that, measured at this HEAD, and are recorded so the next reader does not convert them: differentials-home.tsx:716,729 renders "0 matches"/"No matches" when sourcesChecked is true, i.e. a legitimate zero after a search that SUCCEEDED; specifiers-home-page.tsx:211 is a comment about not showing a stale zero above real catalogue results, and lives in src/components/specifiers/, not clinical-dashboard/; document-search-results gates on recordStatus for loading, not for a failed count. Registered per gates 11 and 12: source, design-sync export, preview, prop contract, publication test entry, behavioural DOM tests, adoption-contract family, and both generators regenerated (54 components, 59 roots). Uses the shared floatingControl recipe rather than a hand-rolled control, so the tap floor, focus ring and forced-colors border come from one owner. Adds zero arbitrary padding/gap/radius/line-height, so the ratchet landed in the previous commit is unaffected and the two stay separately revertible. Scope: ErrorState only. OfflineState, PermissionDeniedState, NotFoundState and UnavailableState share the pattern but have no gate pointing at them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat(design-system): ratchet raw gap literals, the family #1780 left uncovered #1780 landed rawPaddingLiterals, rawRadiusLiterals and rawLineHeightLiterals for #262 part 3. Gap was the one remaining spacing surface a hand-picked value could hide in: gap-[9px] and `gap: 18px` were counted by no ratchet at all. This adds rawGapLiterals on that commit's own predicate and wiring. Measured against origin/main ef9bb51: 34 sites across 9 files — 21 Tailwind utilities, every one under src/components/therapy-compass/, plus 13 CSS declarations in globals.css that a utility-only scan misses. Covering both spellings is the same reason #1780 counts both: otherwise a literal escapes by moving from a class into globals.css. Kept as its own metric rather than folded into rawPaddingLiterals so the therapy-compass cleanup can be paid down and re-pinned independently of the padding debt, which is spread across fifteen unrelated files. Reuses RAW_LITERAL_VALUE unchanged, so a value containing a CSS function (env(, clamp(, max(, calc() stays a sanctioned computed form and is exempt. Also corrects the §3 prohibition row, which #1780 left reading "implemented-partial (colour/shadow/tap literals only)" and which named none of the metrics it had just shipped. A row that understates shipped work is what sends the next session to rebuild it — this change was itself started as a duplicate of #262 part 3 for exactly that reason. Mutation-verified in both halves, each naming the metric and the path: a gap-[3px] utility gives "rawGapLiterals increased from 34 to 35" plus "at src/components/ui/missing-value.tsx increased from 0 to 1"; a `gap: 19px` declaration gives the same total plus "at src/app/globals.css increased from 13 to 14". Baseline diff is additive only. legacyShadowAliases measures 218 against its pinned 220 on main; that slack is left exactly as found. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(issues): capture the ErrorState and duplicate-work follow-ups Four rows (#298-#301), added with npm run issues:add. Ids 295-297 were claimed by main while this branch was open, which is ledger #156's read-modify-write race behaving exactly as recorded. - #298 (P2 task) the ErrorState enforcement check. GATES.md still reads "planned" for the 0-matches prohibition and nothing in scripts/ or eslint-rules/ references ErrorState, so the component exists but is not required. Deliberately not flipped to implemented. - #299 (P3 task) adopting ErrorState at the three surfaces that genuinely hand-roll the guard. Live-look change, downstream of the redesign. - #300 (P2 issue) three sites miscarried into M4 as guards that are not, so the next reader does not convert them. differentials-home renders its zero after a search that SUCCEEDED. - #301 (P3 issue) two sessions built #262 part 3 in parallel because the §3 row understated what had shipped. Proposes asserting that every baseline metric key appears in GATES.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(design-system): restrict the ErrorState copy tripwire to development Codex review on #1786 (P2). The doc comment described the tripwire as development-only, but the emitter only silenced NODE_ENV === "test", so a production caller supplying count-bearing title/body copy had the full caller-provided string written to console.warn. On a clinical surface that copy can quote the query — "0 results for <query>" — which turns a copy defect into a disclosure risk. Nobody reads a production browser console for design-system warnings, so the emit is now development-only and an unset NODE_ENV is treated as production: fail quiet. The gate is an exported predicate rather than an inline comparison because an inline comparison is untestable here. Vite statically replaces process.env.NODE_ENV inside src/ modules, so under Vitest the check compiles to `"test" === "development"` and no stubEnv can move it. The review asked for a production console-spy check; written that way it would have passed while proving nothing, staying silent for the wrong reason and continuing to pass even if the guard were deleted. shouldEmitErrorStateDiagnostic is asserted directly instead — development true; production, test and unset false — with the console spy kept alongside as the weaker check that catches an emitter which warns unconditionally. Verified: typecheck 0 errors, lint 0, format:check 0, check:design-system-contract 0, Tests 70 passed (70) across error-state.dom and design-sync-visual-exports. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
11 tasks
Copilot AI
added a commit
that referenced
this pull request
Aug 12, 2026
fix #186 archive - Restore #156 (read-modify-write race + Update-branch corruption) from archive back to the open issues section with its original full text; the underlying allocation race is not resolved by the conservative architecture decision described in the previous commit. - Re-add #156 to the recommendations priority table as row 51 (between #101 and #172, consistent with its original ordering). - Correct #101 to credit only metadata and memory parallelisation (hydrateCandidatesWithMetadataAndMemory) from PR #1474; visual hydration (attachPageVisualEvidence) is still called serially after hydration on all six call sites and is explicitly listed as a remaining candidate. - Update #186 archive text to reflect that only metadata+memory were updated in #101, not visual hydration. Co-authored-by: BigSimmo <87357024+BigSimmo@users.noreply.github.com>
BigSimmo
pushed a commit
that referenced
this pull request
Aug 12, 2026
docs/outstanding-issues.md has no merge driver by design, so this conflicted in seven hunks. Resolved by taking main's file as the base — it carries main's own archives (#207, #226, #230, #261, #284, #296) — then re-applying all 23 of this branch's changes through scripts/outstanding-issues.mjs: 15 archives and 8 detail rewrites. Verified afterwards that every one landed and that the guard reports no ids deleted from base. Two rows are deliberately NOT resurrected. This branch's #302 (style-contract line-break artifacts) and #303 (issues:next-id sync) no longer exist anywhere on main under any id — main has since reused both numbers for entirely different live rows. Both of this branch's rows were verified-delivered trivia, so nothing actionable is lost, but the disappearance is itself evidence for #156/#168: a main-side merge dropped rows, which is the hazard those rows describe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017paT42ZVMf8jaLtkjFxdy5
BigSimmo
added a commit
that referenced
this pull request
Aug 13, 2026
… queue text (#1890) * docs(issues): retire 22 non-actionable ledger rows and correct the #231 queue text A yield review of all 114 open rows against current main. The queue had become roughly 60 tasks and 50 notes; this removes the notes and fixes two places where the ledger was actively misdirecting. The correction that matters most: the recommended-queue entry for #231, the top clinical P1, told every session to "measure and fix the fast-route budget / generation timeout" — an approach #231's own detail records as tested and rejected, because the decisive 40-second probe completed generation in 25.272s with route_deadline_exceeded=false and still failed quality. The session-start hook prints the queue, not the row, so the refuted text was the text agents read. Closed 22 rows: - #304 was already done on main (commit d182844 refreshed the ranking snapshot; generatedAt is 0 days old, not 2026-07-20), yet sat in the queue advertising a freshness fuse that is not armed. - #241 #244 #272 #294 #300 #257 were standing cautions whose own text says "no action". Each one's knowledge now lives in the code it protects, so closing the row loses nothing. - #196-#200 are five steps of the disaster-recovery checklist that is canonical in docs/operator-backlog.md, with no trigger until a restore. - #86 #188 were index rows over children that are individually findable. - #250 #253 #254 were superseded; #250 and #253 say so themselves. - #156 #301 #152 #236 #260 merged into #168, #292 and #169 respectively — each pair or group was one problem recorded two to four times. Demoted 20 rows with a stated reason (premature ops for a single-user prototype, upstream-blocked, measurement-gated, or design-system adoption competing with an open clinical P1). The Pri cell is unchanged because the writer has no --pri flag — which is now #313. Added three rows for mechanism gaps this sweep exposed: rows outliving their own completion (#312), the missing --pri flag (#313), and the queue being able to contradict the row it cites with no guard (#314). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuYJz8hauCsCdx8r4fXiZU * docs(ledger): record the ledger yield review handoff Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuYJz8hauCsCdx8r4fXiZU * Keep recovery work visible and pin forced colors --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
completeJobassumedselect * from ...returned top-levelok/gate_passed, but for JSONB-returning RPC shapes the payload can be nested under the function-name column, makingrows[0]?.okundefined and falsely routing successful jobs into failure handling.Status RPC parsing hardening
parseJobStatusRpcResult(row, rpcName)insupabase/functions/indexing-v3-agent/behavior.ts.{ ok, gate_passed, ... }){ complete_strict_enrichment_job: { ok, gate_passed, ... } })missing: nullto[].Completion path update
supabase/functions/indexing-v3-agent/index.tsnow parses the first RPC row before evaluatingokandgate_passed.Focused regression coverage
tests/indexing-v3-agent.test.tswith parser tests for direct row, nested JSONB row, andmissing: null.Verification
npm run verify:cheapnpm run verify:uiwhen UI, routing, styling, browser behavior, reduced-motion, or forced-colors behavior changednpm run verify:releasebefore release or handoff confidence claimsnpm run format:checknpm run check:production-readinesswhen clinical workflow, privacy, environment, Supabase, source governance, or deployment behavior changednpm run check:deployment-readinesswhen deployment startup, hosting, or rollout behavior changedClinical Governance Preflight
Complete this section when the change touches ingestion, answer generation, search/ranking, source rendering, document access, privacy, production env, or clinical output.
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes