Commit Graph
249 Commits
Author SHA1 Message Date
marcopanandMarco Pancotti bd63e3194f docs(skill): Phase 4 uses reviewer_schema_linking; honor curated output columns 2026-07-06 23:25:00 +02:00
ad788278dd feat(gate): reviewer_schema_linking tool with per-column curation + deterministic sync
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 559f52e26e feat(gate): buildSchemaLinkingRequest descriptor builder 2026-07-06 23:25:00 +02:00
00365cc6e6 feat(tht): sync-schema-linking projects F4 ledger into schema_linking.json
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 1df5d40d05 feat(tht): column_promoted/column_excluded decision types (F4) 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 9339a8272b feat(tht): schema columns reader (name/description/type/pk) from catalog 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti bfb54922f7 feat(replay): F4 schema-linking fixture + augment script from real catalog 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 32b8e78032 feat(frontend): register schema-linking widget + response summary 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti b6397bd965 fix(frontend): English chrome labels in schema-linking gate (Promote/Exclude/Columns) 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 40a0395a70 feat(frontend): schema-linking gate widget with staged column curation 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 1d877d98ec feat(frontend): schema-linking types + columns modal 2026-07-06 23:25:00 +02:00
9de87d2d51 docs: Plan 2 (harness + persistence + live) for F4 column curation
TDD tasks: schema columns catalog reader, column_promoted/excluded ledger
types (+ F4 emits), deterministic sync-schema-linking projection, the
reviewer_schema_linking gate tool (+ stringified-tables handling), SKILL.md
Phase 4 guidance, backend passthrough test, promoted_columns_for helper, and
live end-to-end verification. Hard SQL enforcement documented as a non-goal
(fragile through CTEs); curated columns are persisted + honored softly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 23:25:00 +02:00
106a0de047 docs: Plan 1 (frontend + contract + replay) for F4 column curation
Bite-sized TDD tasks: schema-linking types + columns modal, gate widget with
staged per-table column selection, registry/summary wiring, and a replay
fixture generated from the real physical.yaml catalog. Offline-verifiable in
the replay server; harness wiring is Plan 2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 23:25:00 +02:00
94d171ddf1 docs: design for F4 schema-linking per-table column curation
Reviewer curates, per promoted table, which columns to use over the full
catalog list (suggested pre-selected + bold); selection persists into
schema_linking.json + the decision ledger and softly guides SQL generation
(Option 1). Dedicated structured schema-linking gate widget (Approach A),
staged commit, inline gate + single columns modal. Hard SQL enforcement is
an explicit follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 23:25:00 +02:00
marcopan e11ffecfc4 feat(frontend): richer gate bodies + replay-friendly session exit
Improves how reviewer gates render their content, and adds two small
hooks that make the frontend cooperate with the standalone replay server
(also useful as generic primitives).

Gate body rendering:
- IntroBody: gate intros now render paragraphs plus real bullet lists
  with a hanging indent and emphasised bullet lead term, filling the
  card width (no narrow measure cap). Backed by introFormat (parser) +
  IntroBody (renderer), with tests.
- GateArtifactBody: artifact-review gates whose artifact is a bare file
  reference (e.g. {kind:"phase", data:{file:"question.md"}}) now fetch
  the referenced session document and render its full content, instead
  of showing the file reference as text. Falls back to ArtifactView for
  inline-content artifacts and unmapped files. Backed by gateArtifact
  (resolver) with tests. ArtifactGateWidget passes sessionId through.
- SelectWidget renders intros via IntroBody.

Replay-friendly session exit:
- AppShell: a system_event {event:"session_exit"} now triggers
  stopSession(), returning to the landing view. Generic primitive (the
  real backend can emit it too); used by the replay server's "Esci".
- SessionMenu: the ⋮ trigger is now always visible (was opacity-0 /
  group-hover only), so Resume is reachable without hovering.

Verified offline against the replay server (no VPN needed); tsc clean.
2026-07-05 18:25:02 +02:00
marcopan c3a3cb8da5 feat(replay): standalone reviewer-gate replay server on :5333
Reproduces the real reviewer UI for any recorded session, with no VPN/Pi/
Python/DWH. The server (node:http, zero deps) serves the built SPA and a
tiny SSE/REST shim that re-emits the reviewer gates captured in a Pi
transcript, in their original order, with the reviewer's real 3-Jul
choices shown as comparison badges.

- tools/replay/extract.mjs: extracts gates from one or many transcripts
  (session-id, file, or directory). Handles sessions split across resume
  re-entries by sorting on message timestamp and dropping unanswered
  gates. Reads the question from session_manifest.yaml, resolving the
  sessions dir from any workspace yaml (no hardcoded paths).
- tools/replay/server.mjs: same-origin :5333. SSE streams gates; POST
  /response advances the cursor and pushes info badges (scelta reale).
  POST /resume and the final "Ripeti/Esci" widget close the SSE so the
  browser EventSource reconnects (cursor resets, gate 1 re-emitted) — the
  replay is re-runnable any number of times. GET /sessions/:id/documents
  reads the real session files so GateArtifactBody resolves file-reference
  artifacts. Exit emits system_event {event:"session_exit"} to return to
  the landing.
- scripts/replay.sh: launcher (extract / build / run / all).
- tools/replay/README.md: data flow, commands, fidelity notes.
- .gitignore: ignore tools/replay/web/ (built artifact, like dist/).
2026-07-05 18:24:26 +02:00
marcopanandClaude Fable 5 2f68b0d109 fix(frontend): contain viewer/widget crashes with error boundaries
A render error in one viewer or gate widget unmounted the whole React root
(white screen). Add a reusable ErrorBoundary (class component, no new dep) with
resetKeys + an on-brand fallback, and wire it at two surfaces:
- WidgetHost: isolates the gate widget (reset on descriptor id) so a malformed
  gate payload no longer blanks the conversation
- SessionDocumentsPanel: wraps each document (reset on doc key/content) so one
  crashing viewer degrades only its section; siblings and the panel survive

The observed crash: a schema-linking doc that parses but lacks `candidates`
makes SchemaLinkingViewer throw. Verified live via Playwright against the mock
backend. TDD throughout; tsc clean, 123/123 vitest (+8 new tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 13:18:51 +02:00
marcopanandClaude Fable 5 864b7ee29c docs: add AGENTS.md — Codex-facing mirror of the repo guidance
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 13:04:52 +02:00
marcopanandClaude Fable 5 4cd1cbc493 style(frontend): look&feel v2 — layered shadows, sharper radii, mono data register
Colors (GSD palette) untouched. New visual vocabulary across the whole GUI:
- warm-tinted layered shadow tokens (--shadow-xs/sm/md) replacing flat rings;
  cards/dialogs framed with hairline border + real elevation
- strict radii scale: xl cards / lg inputs / md controls / 2xl dialogs;
  buttons move from pills to rounded-md
- third type register: --font-mono + tabular-nums on SQL, timers, dates, ids;
  standardized .thot-label micro-label tier
- prose: framed tables with uppercase headers, elevated code blocks
- SqlViewer badges moved from hardcoded Tailwind greens/reds to success/
  destructive token tints; ResultsPanel inline styles replaced with classes
- artifact gate: first option rendered as filled primary action

Verified offline via Playwright against a mock backend replaying a real psd
session (no VPN needed). tsc clean, 115/115 vitest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 13:04:46 +02:00
marcopanandClaude Opus 4.8 cc1ffb59fa docs(pi): revise dual-mode gate eval per review (P1/P2)
- present() = presentBlockingWidget: transport + no-limbo loop + response
  validation; both branches share validateUiResponse; the id invariant must be
  validated explicitly in the TUI branch (emitAndWait no longer runs there)
- TUI renderer uses numbered options + index parsing, never label mapping
  (frontend already answers with ids); artifact-gate editor is viewer-only,
  returned content ignored
- guards resolved: both TUI-only notices now ctx.mode === "tui"
- interactive-render.js as two layers (renderTuiDescriptor +
  validateSyntheticResponse); add negative test cases + a real TUI smoke

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 12:41:39 +02:00
marcopanandClaude Opus 4.8 a166d9bc4e fix(gate): guard the steering-during-lock hint on ctx.mode, not ctx.hasUI
The "respond with gate widgets; use '!' for free text" notice is terminal-
flavored. Like the reLoop Esc guard, it used ctx.hasUI, which on pi >=0.80 is
true in RPC too, so it leaked to the browser. Now guarded on ctx.mode === "tui".
The plain text is still swallowed by the `handled` return in all modes; only the
warning is dropped in RPC. No functional ctx.hasUI guard remains in the gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 12:41:39 +02:00
marcopanandClaude Opus 4.8 d6b4729ddf feat(shell): yellow active session, growing composer, phase title, refined activity log, arrow panel toggle
Fix six GUI defects, verified live against the real stack:

- NavSessions: mark the in-progress (active) session in yellow (warning
  token) — both its status dot and its row background.
- SteerInput: the composer is now an auto-growing textarea that wraps and
  grows vertically (caps at 160px, then scrolls); Enter sends, Shift+Enter
  inserts a newline.
- WorkflowBar: show a synthetic title of the current phase under the 8 dots
  from static EN/IT strings (no LLM); English is displayed to match the chrome.
- CentralStatus: reformat the 5-line system-message tail as a structured,
  monospace list with per-line markers and an emphasized last line.
- AppShell + CentralStatus: move the left Model-activity panel toggle off the
  working spinner (now a pure status indicator) onto a dedicated arrow button
  (→ opens, ← closes).
- gate: rename the phase-confirm button "Conferma e prosegui" → "Salva e
  procedi" (builders.js + its L1 test).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 14:32:01 +02:00
marcopanandClaude Opus 4.8 1f9818c50f fix(gate): guard the TUI-only "Esc" notice on ctx.mode, not ctx.hasUI
reLoop's "Esc non chiude il gate..." warning is terminal-specific. On pi 0.73
ctx.hasUI was false in RPC, so `if (ctx.hasUI)` effectively meant "TUI only". On
pi >=0.80 hasUI is true in RPC too (dialog-capable UI via the bridge), so the
notice leaked to the browser on any invalid gate response. Guard on
ctx.mode === "tui" to restore the original intent. The fake pi runtime gains
mode:"tui" so the roundtrip test still exercises the notice.

Audit of the other 5 ctx.ui.notify: left as-is. They are valid in both live
modes (TUI and RPC, both hasUI=true) and the gate cannot run headless
(emitAndWait needs a UI), so a guard would be dead code. Their dual-mode
rationalization belongs with the future present() work (tracked in the eval doc).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 14:21:57 +02:00
marcopanandClaude Opus 4.8 0afa9a2f80 docs(pi): correct dual-mode gate eval — hasUI polarity, info/freetext wiring, citations
- #1 hasUI: real 0.80.3 comment is "true in TUI and RPC modes" (doc had the old
  0.73.1 "false in print/RPC"). hasUI no longer distinguishes TUI from RPC, so it
  is NOT a fallback for the interactive branch — only ctx.mode === "tui" is.
- #2 info/freetext: buildInfoRequest exists in builders.js but is NOT wired into
  tht-gate.js (imports only select/multiselect/artifact-gate). info notices are
  hand-written ctx.ui.notify; freetext is a control, not a descriptor. Table now
  lists only the 3 real present() descriptors.
- #3 cite the REWRITE banner (tht-gate.js:8-10), not :227; id-match quoted verbatim.
- #4 new "Note implementative": 227 comment, 4/6 unguarded notify, and the
  ctx.hasUI guard migration side-effect (now fires in RPC on 0.80.3).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 14:13:26 +02:00
marcopanandClaude Opus 4.8 be02e96f9e chore(pi): consolidate 0.80.3 migration — align extension + docs to @earendil-works
- aritmolab-provider.js: import pi-ai from @earendil-works (was @mariozechner).
  Verified live that the aritmolab/qwen provider still registers under pi 0.80.3
  (get_available_models -> aritmolab, deepseek, zai). Removes the dual-package
  reliance on the frozen @mariozechner install still on disk for rollback.
- docs/general/pi-configuration.md: built-in models package is @earendil-works/pi-ai

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 13:23:46 +02:00
marcopanandClaude Opus 4.8 b35c4b5692 docs(pi): migrate runtime to @earendil-works@0.80.3; update dual-mode gate eval
- live pi repointed 0.73.1 (@mariozechner, frozen) -> 0.80.3 (@earendil-works);
  validated via API/RPC surface diff (stable+additive) + model-matrix smoke
  (GLM 5.2 new+resume CHAINED)
- PROJECT_STATE: item 6 migration note (supersedes the 0.79.4 references)
- dual-mode gate eval: integrate review points (#3,#5,#7,#8,#9,#10) and flip #1
  to ctx.mode === "tui" (0.80.3 exposes ctx.mode: tui|rpc|json|print)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 12:51:56 +02:00
marcopanandClaude Opus 4.8 a0a503b721 fix(gate): coerce stringified object params; block model edits to gate code
Some models (GLM 5.2) send object params (reviewer_confirm's artifact,
write_schema_linking's schema_linking) as JSON-encoded strings. These failed
TypeBox validation before execute(), making the model retry in an unbounded loop
(observed ~2100s hang). jsonObjectOrSelf() coerces them back to objects in
prepareReviewerArguments and write_schema_linking.

Also close an anti-bypass gap: pi's write/edit tools were unrestricted on the gate
code, so a looping model actually patched tht-gate.js. GATE_CODE_FILES now blocks
any write under .pi/extensions. Requires a pi restart to take effect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:28:45 +02:00
marcopanandClaude Opus 4.8 f1b071d165 feat(shell): 30/55/15 layout, formatted activity log, instant resume, stop confirmation
Left panels 30vw / central 55% / right rail 15vw, minimal padding. Model-activity
log and documents render via .thot-prose; decisions become hairline rows with
semantic type chips. Resume switches the view optimistically (instant feedback).
The Stop button now asks for confirmation before interrupting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:15:48 +02:00
marcopanandClaude Opus 4.8 a719ad5990 feat(viewer): artifact modal renders structured text, never raw JSON
ArtifactView's fallback (StructuredValue) turns any object/array into labelled
sections, bullet lists and paragraphs (strings as markdown). Verified against the
real F1 gate (kind:"text", {recap, chiarimenti_risolti[], ...}). MarkdownView
uses the real .thot-prose class (Tailwind Typography is not installed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:15:48 +02:00
marcopanandClaude Opus 4.8 cec6620c00 feat(widgets): redesign gate widgets — readable hierarchy, prominent select-all, styled controls
Titles + intro read as a clear prompt (comfortable line length), options as
spaced choice rows, Other/Back/Exit as discreet secondary controls under a
divider. Multiselect gets a prominent Select all/Deselect all at the head of the
list with a live count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 18:15:48 +02:00
marcopanandClaude Opus 4.8 56ed8b29bd feat(workflow-bar): processing-only elapsed timer + optimistic phase paint on resume
Timer now accumulates only while the harness works, pausing while a gate awaits
the reviewer and freezing when finalized (keyed per session, in-memory). Resume
now colours the re-entry phase immediately from the manifest's phase (1..8),
mirroring the F1 paint for new questions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 14:13:02 +02:00
marcopanandClaude Opus 4.8 e4ada07dab feat(viewer): erDiagram shows real column types when present; ArtifactView accepts a {content} sql wrapper
erDiagram reads data_type/type from the candidate (top-level or signals),
falling back to the generic 'col' token Mermaid needs — real types render as
soon as schema_linking.json carries them. ArtifactView gains a defensive
{content} fallback for sql-kind artifacts, verified against real session shapes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 14:13:02 +02:00
marcopanandClaude Opus 4.8 c3e8f14ad9 test(gate): clarify the 'altrove' first-token guard comment
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 14:13:02 +02:00
marcopan 3f852fd817 feat(workflow-bar): total elapsed timer after the phase circles 2026-07-03 13:26:25 +02:00
marcopan e630ac98f9 feat(workflow-bar): optimistic F1 at start; all-green when session finalized 2026-07-03 13:22:09 +02:00
marcopan 37b3eb45e9 feat(gate): render reviewer artifacts in a 90% modal (fix empty artifact.data gate) 2026-07-03 13:17:54 +02:00
marcopan 0975a8a72b feat(viewer): ArtifactView routes artifact.data by kind (schema/sql/cte/question) 2026-07-03 13:13:51 +02:00
marcopan 893e9e4059 feat(viewer): schema linking renders a Mermaid erDiagram (tables + relations) 2026-07-03 13:09:09 +02:00
marcopan 168a72372b fix(gate): robust isReserved strips model Altro/other variants (no duplicate free-text option) 2026-07-03 13:05:21 +02:00
marcopanandClaude Opus 4.8 3de1a784ce docs(plan): implementation plan for workflow UI fixes (6 tasks, TDD)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 13:01:31 +02:00
marcopanandClaude Opus 4.8 3c198ec775 docs(spec): design for workflow UI fixes (phase circles, timer, artifact modal, Altro dedup)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 12:45:05 +02:00
marcopanandClaude Opus 4.8 b043293baf fix(gate): stop injecting the redundant Altro option on select gates
buildSelectRequest injected an `altroOption` ({id:"other", opens:freetext}) into the
select descriptor, but SelectWidget/MultiselectWidget never route option.opens — so it
rendered as an inert "Altro — specifica…" button next to the working reserved
"Other — specify" control (which now owns free-text since the reviewer-gate-ux fix).
Remove the injection, the now-unused altroOption()/ALTRO_LABEL, and the unused
allow_other flag from both builders (no frontend consumer). Free-text stays offered on
every gate via the reserved "Other" control. The ArtifactGateWidget opens/LinkageHost
linkage (reject-with-reason capability) is intentionally kept — it is a separate,
tested feature, not the injected duplicate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 19:10:01 +02:00
marcopanandClaude Opus 4.8 25ab37d0fe fix(frontend): disable 'Altro' Send until non-whitespace text (no empty freetext)
Backlog T2 from the reviewer-gate-ux review: the Send button on the reserved
"Other — specify" textarea emitted control:freetext with an empty payload when
clicked on an empty/whitespace field. Guard with disabled={!text.trim()}.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 18:52:12 +02:00
marcopan 78518210a0 docs(skill): document empty-memory auto-advance (no empty checklist) in Phase 2 2026-07-02 18:39:12 +02:00
marcopan 0a76103c35 fix(gate): empty memory phase shows a notice and auto-advances instead of an empty checklist 2026-07-02 18:34:17 +02:00
marcopan 644634d492 fix(gate): reviewer_confirm requires explicit approve; free-text is actionable, not accidental approve 2026-07-02 18:30:14 +02:00
marcopan 2633b46199 fix(gate): buildArtifactGate emits approve/reject options so the gate renders a forward button 2026-07-02 18:27:11 +02:00
marcopan 541df01684 fix(frontend): 'Other — specify' opens a text field and emits control:freetext 2026-07-02 18:24:02 +02:00
marcopan eacc441a4f fix(frontend): render Back/Exit/Other controls on the multiselect widget 2026-07-02 18:20:25 +02:00
marcopanandClaude Opus 4.8 daceda3555 docs(plan): reviewer gate UX fixes implementation plan; align spec Part 4 to ctx.ui.notify
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 17:16:57 +02:00