Commit Graph
523 Commits
Author SHA1 Message Date
marcopanandClaude Opus 4.6 87cb806dfc fix(harness): prevent Pi crash on unhandled throw in reviewer tool execute
The last live session crashed during reviewer_schema_linking: an uncaught
exception (likely from execFileSync in currentPhase/phaseMeta or from
cat.columns being undefined) rejected the async execute() Promise. Pi does
not catch rejected tool Promises — Node.js treats them as unhandled
rejections and kills the process.

Fix:
- Wrap all four reviewer tool execute bodies (select/decide/confirm/
  schema_linking) in a top-level try/catch → returns a textResult on any
  unexpected error instead of crashing Pi.
- reviewer_schema_linking: defensively re-parse `tables` if still a string
  (belt-and-suspenders over prepareArguments), guard cat.columns before .map().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 14:33:42 +02:00
marcopanandClaude Opus 4.6 6ee5bda7f0 feat: gate decision-type validation, force-advance, and frontend fixes
Gate (tht-gate.js):
- Pre-validate decision types against workflow.yaml before showing reviewer widget
- Reject decisions emitted by later phases (min-phase check)
- Copy top-level `kind` into artifact when model forgets it (prevents loop)
- Force-advance on reviewer_decide/schema_linking when advance:true — skip
  redundant reviewer_confirm gate

Backend:
- Emit agent_end on clean Pi exit (code 0 + bridge idle) instead of marking failed

Frontend:
- Strip <think> tags from transcript and activity panel
- Fix mermaid render with offscreen container + cleanup
- Graceful mermaid error: show source code instead of red error, fall back to table

Workflow:
- F2 now emits table_promoted and table_excluded (early schema linking decisions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 14:14:44 +02:00
marcopanandClaude Opus 4.8 9fbca06f7c feat(harness): make tht schema columns glob/pattern-aware
At F4 (schema_linking) a model asking for a whole table family, e.g.
`fact_sost_impianto_*`, used to hit a bare "tabella non nel catalogo" and stall
without recovering. Now a pattern (containing * ? [) resolves to every matching
catalog table and returns their columns (JSON becomes an array of per-table
objects); exact names keep the original single-object contract. A non-glob miss
also suggests sibling tables sharing the leading segment, to aid recovery.

Verified live: `fact_sost_impianto_*` resolves the 20-table family on the psd
catalog. Harness suite green (811 passed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 13:24:20 +02:00
marcopanandClaude Opus 4.8 ccfa3a18bf feat(frontend): pulse the stop dot while the harness is working
Give live feedback that something is happening the moment a session starts
processing: the red stop dot in the composer beats with a soft heartbeat + halo
while the harness is actively working (running — not waiting at a gate or
finalized), and settles the instant the model hands control back to the reviewer
or the session ends. Ring/scale only (no layout properties animated); honors
prefers-reduced-motion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 12:33:25 +02:00
marcopanandClaude Opus 4.8 3453f3ae23 feat: pre-check DWH reachability before creating a session (local dev only)
New session now refuses to spawn a Pi runtime that would only die in bootstrap
retrieval when the DWH/vector host is unreachable (e.g. a dropped VPN). Before
`session new`, POST /sessions probes the DWH via `tht db ping`; if it is down it
returns 503 {code:"dwh_unreachable"} with a clear message and creates nothing.

- Gated behind the THT_DWH_PRECHECK flag (default off), enabled only by the local
  dev launcher (run-stack.sh) — containers/CI never pay the probe, and existing
  tests that don't set it are unaffected.
- ThtRunner.dbPing() runs `tht db ping` with a 10s timeout (run() gains an optional
  timeout that SIGKILLs a hung child).
- Frontend: apiFetch throws a typed ApiError (status + parsed payload); the new-
  session composer shows the specific alert on `dwh_unreachable` instead of the
  generic retry hint, keeping the question for retry.

Verified live on an isolated backend (precheck on + broken DWH host → 503
dwh_unreachable, no session created) and via unit tests (backend 228, frontend 308).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 12:08:47 +02:00
marcopanandClaude Opus 4.8 84da3b149b fix(backend): log the real bootstrap failure cause server-side
Session bootstrap swallowed configure/retrieval errors and surfaced only the
generic BOOTSTRAP_FAILURE_MESSAGE, so an operator could not tell why a session
"didn't start" — e.g. `tht search pack` failing because the DWH/vector host is
unresolvable behind a dropped VPN. Log the underlying error to the backend
console; the client-facing message stays generic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 11:48:05 +02:00
marcopanandClaude Opus 4.8 f979ada5e7 feat(frontend): open a live session straight to its pending gate
Opening an in-progress session that has a live Pi runtime now reconnects to
its pending gate instead of the empty landing screen that read as "stopped".
Cold/completed sessions keep the read-only documents panel with its explicit
Resume, so a mere click never spawns a runtime. Backend GET /sessions now
reports a per-session `active` flag (live runtime bound) to drive this.

Also:
- "New session" now closes any open session detail panel (left box).
- The model-activity separator can be dragged to a full 50/50 split
  (was capped at 576px); central-min still guards narrow viewports.

Test fixes uncovered along the way:
- Node 25 ships an experimental global localStorage that shadows jsdom's and
  lacks clear(), failing every jsdom test at setup; install a spec-compliant
  in-memory Storage (feature-detected, inert on CI/LTS).
- Fix 4 pre-existing session-mgmt tests that used an ambiguous getByText for a
  session shown in both nav and header; target the nav item by test id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 22:56:12 +02:00
marcopan 6274bf2da0 Merge branch 'feat/per-provider-model-credentials' 2026-07-17 19:31:06 +02:00
marcopanandClaude Opus 4.8 c5fd03ed84 feat(backend): let pi self-authenticate providers from its own auth store
The backend injects a single managed model key (THT_MODEL_API_KEY[_FILE]) as
the selected provider's env var, but that key belongs to one provider — so
selecting a second cloud provider (e.g. DeepSeek while the managed key is zai's)
forced the wrong key onto it and failed auth. This is why the model could not be
switched to DeepSeek.

When the selected provider is present in pi's own auth store
(~/.pi/agent/auth.json), skip injection and let pi resolve that provider's key
itself. Deployments without an auth store (containers) yield an empty set, so the
managed-key injection stays authoritative and fail-fast there. authProviders is
injectable into PiProcessManager for deterministic tests.

Verified live: GLM 5.2, DeepSeek V4 Flash, and aritmolab Qwen3.6 all operate through the ThothII model selector.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:26:18 +02:00
marcopanandClaude Opus 4.8 c252c95c5f fix(frontend): pin the question as a stable first line during processing
The central column was top-anchored with no fixed header, so the user's
question was never shown while the model worked and the activity/gate
content drifted upward. Render the active session's question as a sticky,
always-present first row of the central area so it stays evident and
anchored at the top of the form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:30:18 +02:00
User bd7fa6d2c1 Merge branch feat/user-owned-sessions 2026-07-16 20:40:51 +02:00
User 3abe69badc docs: record session storage deployment gotchas 2026-07-16 20:40:51 +02:00
User 5cacf70a0d fix: bootstrap user preferences without invalidating DWH cache 2026-07-16 20:32:20 +02:00
User ccb3cf4aa9 test: cover user-owned session security boundaries 2026-07-16 19:16:58 +02:00
User 7a65fc80a2 fix(deploy): validate session migrator TLS mode 2026-07-16 19:07:53 +02:00
User cadc4c6947 docs(deploy): document user-owned session cutover 2026-07-16 19:02:58 +02:00
User c6a74c9ccb fix(frontend): harden owner action confirmation 2026-07-16 18:51:02 +02:00
User 58e0884df1 feat(frontend): expose owned session scopes 2026-07-16 18:46:18 +02:00
User b454fb478b fix(backend): harden principal child isolation 2026-07-16 18:38:40 +02:00
User 458eb13c89 feat(backend): enforce user-owned sessions 2026-07-16 18:32:52 +02:00
User 72db6b823d fix(harness): record postgres decision phases 2026-07-16 18:08:17 +02:00
User c1cddaa667 refactor(harness): route workflow persistence through repositories 2026-07-16 18:01:29 +02:00
User 259f021313 fix(harness): preserve session migration JSON errors 2026-07-16 17:35:54 +02:00
User 5dbb91390f feat(harness): persist server sessions in postgres 2026-07-16 17:31:04 +02:00
User 8f0154eb9e fix(harness): persist evidence artifact 2026-07-16 17:14:47 +02:00
User 8f364ec564 feat(harness): add local session repository 2026-07-16 17:11:22 +02:00
User 8296937bc0 docs: add user-owned session storage plan 2026-07-16 17:01:39 +02:00
User 671bd20329 chore: ignore Vitest cache 2026-07-16 13:03:38 +02:00
User c587f9dc4a merge: resizable activity timeline and CTE density 2026-07-15 16:06:19 +02:00
User 7fc58287a7 docs: clarify activity split fallback 2026-07-15 15:59:21 +02:00
User 6a5ca7e8cb docs: record final activity split deployment 2026-07-15 15:57:33 +02:00
User 1f540fcb78 fix(frontend): harden activity split responsiveness 2026-07-15 15:52:22 +02:00
User f0ef2654df docs: record activity split deployment 2026-07-15 15:32:29 +02:00
User f1af1f909b style(frontend): tighten CTE plan vertical rhythm 2026-07-15 15:15:56 +02:00
User d177e1c0af feat(frontend): add resizable activity split 2026-07-15 15:04:15 +02:00
User 30e76a968d fix(frontend): restore readable model activity timeline 2026-07-15 14:55:57 +02:00
User 9274f07987 docs: plan resizable activity timeline 2026-07-15 14:44:36 +02:00
User 7ad06cde81 docs: design resizable activity timeline 2026-07-15 14:29:50 +02:00
User bef21f9e43 test(frontend): harden live log contract 2026-07-15 12:45:26 +02:00
User 4356a1243c docs: record central live log deployment 2026-07-15 12:31:57 +02:00
User 09f9bdffe5 fix(frontend): restore live log text contrast 2026-07-15 12:27:19 +02:00
User 6b0da84a3d style(frontend): compact CTE plan spacing 2026-07-15 12:09:04 +02:00
User 00c1af5a5a fix(frontend): reset live log follow state on resume 2026-07-15 12:04:05 +02:00
User 279b79516c fix(frontend): deduplicate live workflow activity 2026-07-15 11:55:14 +02:00
User e7a8bc29b0 docs: harden central log implementation plan 2026-07-15 11:48:30 +02:00
User b9e4a747f0 docs: plan central live log and compact CTE plan 2026-07-15 11:44:45 +02:00
User d5ec7686a0 docs: design central live log and compact CTE plan 2026-07-15 11:27:39 +02:00
User 9554379916 docs: record filtered model activity deployment 2026-07-15 03:49:09 +02:00
User 72085990ef fix(frontend): hide model activity execution noise 2026-07-15 03:24:22 +02:00
User e9cbc2b701 docs: plan model activity signal filter 2026-07-15 03:15:53 +02:00