Commit Graph
184 Commits
Author SHA1 Message Date
marcopanandClaude Opus 4.8 cbb8e184f1 feat(harness): cross-model behavior matrix (G) — harness + results
Tier 1 (clean-room first-turn harness, harness/scripts/model-matrix.mjs):
kickoff + resume chain in-turn on ALL available models — zai/glm-5.2,
deepseek/deepseek-v4-{pro,flash}, aritmolab/qwen3.6-35b-a3b, zai/glm-4.5-air.
The resume cold-start stall recurs on none (closes A's cross-model robustness).
aritmolab/gemma4-26b-a4b is a 404 at the endpoint (listed but not served) — an
availability gap classified as MODEL_ERROR, not a workflow issue.

Tier 2 (live, baseline zai/glm-5.2): F single-select auto-confirm verified
end-to-end — answering the first reviewer_select persisted a concept_clarified
decision (review_decisions.jsonl 0->1) with no follow-up confirmation gate.
Closes F's deferred live check.

No prompt hardening needed. Results in the G plan doc + memory. Throwaway psd
sessions used and deleted; real sessions untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:46:55 +02:00
marcopanandClaude Opus 4.8 e8cdd0037c docs(plan): scope workstream G (cross-model behavior matrix)
Actionable scoping for the final workstream: a two-tier method (clean-room
first-turn harness generalised from the A2 repro-driver for cheap kickoff/resume
signals; sparing full Playwright F1 runs for the gate round-trip) over the
configured models (GLM 5.2 baseline, Deepseek V4, Qwen3.6, + breadth). Folds in
F's deferred single-select live check and A's resume-on-weaker-models check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:20:46 +02:00
marcopanandClaude Opus 4.8 0a13f71b4d feat(resume): Resume in the kebab menu (A1) + harden the resume kickoff (A2)
A1 — SessionMenu gains a Resume item, gated to status!=="finalized" && !archived
(matching the backend's 409 read-only guard), wired in AppShell to doResume ->
POST /sessions/:id/resume. SessionMenu.test.tsx (3 tests); frontend 96/96, tsc clean.

A2 — diagnosis-first clean-room repro driving `pi --mode rpc` with the backend's
exact resume handshake shows the cold-start stall NO LONGER reproduces on pi
0.79.4 (8/8 chained into `tht session show` + `read SKILL.md` in-turn, fresh and
partway sessions). The earlier narrate-and-stop predates the pi upgrade.
Defense-in-depth anyway: RIPRENDI_KICKOFF hardened to force the in-turn tool call
(gate_resume_kickoff.test.js + live regression 2/2). Gate JS 34/34.

PROJECT_STATE open-item #1 (resume stall) flipped to RESOLVED; cross-model resume
robustness folded into workstream G.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:19:10 +02:00
marcopanandClaude Opus 4.8 cef9ae4368 feat(harness): single-select answers auto-confirm (reviewer_select persists)
F — reviewer_select options may now carry a `decision` payload {type, subject,
detail?, rationale?} plus an optional `advance`. Picking such an option IS the
confirmation: the gate persists it directly (tht decision add) and optionally
advances, with no redundant reviewer_decide/reviewer_confirm follow-up gate.
Options without a payload stay ask-only; back/exit/Other never persist.

Pure logic extracted + exported for unit tests: resolveSelectOutcome (classifies
the response) and decisionAddArgs (shared with reviewer_decide, DRY). Gate JS
suite 33/33 (gate_select_decision.test.js, +5); harness pytest 269 unchanged.

Contract docs updated together: reviewer_select tool description, SKILL.md
(widget summary, disciplines 2-3, Phase-1 single-pick), and the CLAUDE.md gate
note. Live verification (model truly emits reviewer_select+decision, decision in
review_decisions.jsonl, no follow-up gate) deferred to workstream G — it is
model-behavior-dependent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:01:50 +02:00
marcopanandClaude Opus 4.8 b056ff334f feat(frontend): phase progress dots (B) + compact sidebar redesign (C)
B — WorkflowBar renders F1..F8 as colored ring-dots (no phase-name text):
green=done, amber=running (subtle pulse), red=error, gray=pending; green
connectors lead the active dot, each dot carries data-state. Lightweight
error signal: sessionStore gains `phaseError`, set when an info event has
level=error during the active phase, cleared on the next ui_request.

C — denser single-line session rows (inline status dot + name, py-1), a
3-level type hierarchy (L1 SESSIONS / L2 section+group headers / L3 names),
and the "No group" label removed (ungrouped render after the last group,
guarded so the empty-state still teaches when there are zero groups).

Live-verified with Playwright (all four dot states, sidebar hierarchy, and
E's deferred activity-panel check). Frontend 93/93, tsc -b clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:53:29 +02:00
marcopanandClaude Opus 4.8 2e09c88f78 docs(state): record UI-redesign progress (D+E done; B/C/F/A pending)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:46:50 +02:00
marcopanandClaude Opus 4.8 0eeb3f7522 feat(frontend): rotating activity icon + 5-line expandable activity panel
- CentralStatus: replace the red pulsing dot at the start of the "working" line
  with the rotating WorkingSpinner, now a button that opens the model-activity
  panel (onOpenActivity). WorkingSpinner is extracted to its own module (was
  local to AppShell).
- ModelActivityPanel: show the last 5 lines of the model-stream tail (refreshing
  as the stream grows) with an expand toggle to the full stream, replacing the
  unbounded full transcript.
- AppShell: drop the separate spinner button (the inline icon is now the single
  trigger) and the local WorkingSpinner def.
- Remove the now-orphaned Transcript.tsx (its only consumer was the panel).

TDD: CentralStatus + ModelActivityPanel tests RED->GREEN; frontend suite 87/87;
tsc clean. Live visual verification pending (to do with the B/C frontend pass).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 16:26:43 +02:00
marcopanandClaude Opus 4.8 c12bdcd257 feat(harness): derive a 3-5 keyword session name (YAKE, no LLM)
New sessions get a concise Italian-keyword `name` instead of the truncated
question. `tht session new` (when no --name is given) derives it via a new
`_extract_name` helper using YAKE (pure-Python, unsupervised, Italian, no LLM),
dropping generic query verbs and keeping the top keywords in reading order;
falls back to `_summarize` if YAKE is unavailable. `create_session` core keeps
its `name=None` default — the policy lives at the CLI layer.

TDD: tests/test_session_name.py (unit + CliRunner integration). Full harness
suite 269 passed; ruff clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 15:54:54 +02:00
marcopanandClaude Opus 4.8 d27afd0896 fix(gate): read reviewer_select/confirm choice from the choices[] array
The frontend's reviewer widgets uniformly send the picked option in a `choices`
array (SelectWidget/ArtifactGateWidget: `choices: [optionId]`), but the gate's
reviewer_select and reviewer_confirm(reject) handlers read `resp.choice`
(singular). Result: every single-select gate saw an undefined choice, answered
"Nessuna scelta ricevuta", and re-presented forever — the workflow could never
pass F1. (reviewer_decide/multiselect already read `resp.choices`, so it worked.)

Add a shared selectedChoice(resp) helper reading choices[0] (falling back to the
legacy singular choice); both handlers use it.

TDD: gate/__tests__/gate_choice.test.js RED->GREEN; full gate suite 28/28.
Verified LIVE (Playwright -> real Pi -> GLM 5.2): a single-select F1 answer is
now accepted and the workflow advances (clarification 2/4 -> 3/4). The same run
also live-verified the F1 hang fix (418187a).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 12:48:56 +02:00
marcopanandClaude Opus 4.8 418187a4ad fix(backend): echo Pi's RPC id so reviewer gates unblock after answer
ctx.ui.input in `pi --mode rpc` correlates extension_ui_response on its own
top-level RPC id (crypto.randomUUID), not the descriptor id the gate carries
in `title`. SessionBridge replied with the descriptor id, so Pi silently
dropped the response and the model never resumed — every reviewer widget hung
after the human answered.

SessionBridge now stores Pi's top-level m.id (pendingPiId) and replies
extension_ui_response{ id: pendingPiId, value: <uiResponse> }; value still
carries the descriptor id so the gate's internal resp.id === descriptor.id
check still holds.

The fake-pi double had masked the bug by forcing m.id == descriptor.id; it now
mirrors real Pi (distinct randomUUID, correlate on it, drop unknown ids), with
a negative regression test. SKILL.md Phase 1 also now steers multi-answer
disambiguation to reviewer_decide (multiselect).

Tests: backend 67/67, tsc clean, fake-pi contract 2/2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 10:43:49 +02:00
marcopanandClaude Opus 4.8 4f60b38ca2 feat(frontend): central 'working' indicator — elapsed time + model-stream tail
While the model works (active session, no pending widget), CentralStatus shows
a Claude-Code-style live status: a pulsing dot, elapsed seconds (ticking), and a
short tail of the model's current output — so the centre no longer looks stuck
during the long F1 loop. Verbose stream stays in the left panel. No tokens yet
(would need the SessionBridge to forward Pi usage).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 22:15:34 +02:00
marcopanandClaude Opus 4.8 9eae655453 style(frontend): move AppShell test imports to top (merge act, add useSessionStore)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:52:37 +02:00
marcopanandClaude Sonnet 4.6 feda972a08 feat(frontend): minimal central area; WIP icon above composer toggles model-activity panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 21:47:50 +02:00
marcopan b391101a5d feat(frontend): CentralStatus + ModelActivityPanel components 2026-06-29 21:42:46 +02:00
marcopan 068c6f197d feat(frontend): store lastUserEntry + stepMessages; record user input/choice 2026-06-29 21:39:02 +02:00
marcopanandClaude Opus 4.8 3a97ab3b2f fix(frontend): configurable RenameDialog title; 'Rename group' for group rename
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:36:14 +02:00
marcopanandClaude Sonnet 4.6 84db1e1085 feat(frontend): rename group (reassign members via setSessionGroup)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 21:32:32 +02:00
marcopan 5442a07ced feat(frontend): Active/Archive as independent accordions (replaces toggle) 2026-06-29 21:26:52 +02:00
marcopanandClaude Opus 4.8 a868fc0673 docs(plan): session UI refinements implementation plan (5 tasks, frontend, TDD)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:23:49 +02:00
marcopanandClaude Opus 4.8 3d06505819 docs(spec): session UI refinements design
Active/Archive accordions; rename group (client-side reassign); central
area shows only last user entry + gate notify/info + active widget; the
verbose model stream moves to a left on-demand panel toggled by the WIP
icon (moved above the composer). Frontend-only; fine thinking-separation
deferred.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:13:28 +02:00
marcopanandClaude Opus 4.8 37d40d6680 fix(backend): drop pi --approve flag (removed in pi 0.73 @mariozechner rebrand)
pi 0.73 rpc mode is headless and runs tools without an approval gate; the
removed --approve flag made pi exit with 'Unknown option: --approve', breaking
every session spawn. Spawn args are now just --mode rpc. +regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:03:48 +02:00
marcopan a791919925 fix(backend): check read-only 409 before the Ollama preflight on resume 2026-06-29 20:06:03 +02:00
marcopanandClaude Sonnet 4.6 90a26dafce feat(backend): Ollama embeddings preflight on session create/resume (503 hard-fail)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 19:37:39 +02:00
marcopan a0af089d00 feat(backend): ThtRunner.ollamaEnsure (parses tht ollama ensure --json) 2026-06-29 19:31:49 +02:00
marcopan deb8081bc2 test(harness): end-to-end tht ollama ensure via root app 2026-06-29 19:30:00 +02:00
marcopan 7e19f81173 feat(harness): tht ollama ensure CLI command (hard-fail preflight) 2026-06-29 19:25:23 +02:00
marcopan 9c39ea129e fix(harness): ensure_ollama never raises on start/probe failure (stage server) 2026-06-29 19:19:26 +02:00
marcopan 5f5cac05d5 feat(harness): EmbeddingsConfig bin/start_cmd + ensure_ollama preflight orchestration 2026-06-29 19:15:28 +02:00
marcopanandClaude Opus 4.8 f66e8e41d9 docs(plan): Ollama embeddings preflight implementation plan (4 tasks, TDD)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 19:00:04 +02:00
marcopanandClaude Opus 4.8 c2f8dd5af9 docs(spec): Ollama ensure (embeddings preflight) design
Hard-fail preflight at session create/restart: ensure Ollama up + warm the
configured embedding model, refuse the session if embeddings unavailable.
Parameterized ollama bin/start_cmd; tht ollama ensure command + backend 503.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 18:53:03 +02:00
marcopanandClaude Opus 4.8 1334c1d871 docs: add project CLAUDE.md (commands + architecture + gotchas)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 14:21:52 +02:00
marcopanandClaude Opus 4.8 d258a1ae4c docs: add PROJECT_STATE.md orientation snapshot
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 14:19:59 +02:00
marcopanandClaude Sonnet 4.6 2c21e4659f fix(frontend): surface session mutation failures via toast; doResume only activates on success
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 13:30:46 +02:00
marcopanandClaude Sonnet 4.6 aa378291f9 feat(frontend): collapsible group headers; resume/delete integration tests; English test name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 13:22:09 +02:00
marcopanandClaude Sonnet 4.6 f8be6613a5 feat(frontend): AppShell session management — grouping, archive view, docs panel, mutations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 13:13:22 +02:00
marcopan 910928471a fix(frontend): wrap schema-linking fallback pre; test archived hides Resume 2026-06-29 13:09:56 +02:00
marcopanandClaude Sonnet 4.6 964bfa39ea feat(shell): add SessionDocumentsPanel read-only left drawer (Task 11)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 13:05:40 +02:00
marcopan f8c246a1b6 fix(harness): English document section titles in build_documents 2026-06-29 13:02:51 +02:00
marcopanandClaude Opus 4.8 4f97ea9fc2 fix(frontend): English UI strings for session menu/dialogs; rename empty-guard + cancel test
- SessionMenu: anglicize all Italian labels (Vista divisa → Split view, etc.)
- RenameDialog: add empty-name guard + change title to "Rename session"
- DeleteConfirmDialog: translate title and description to English
- SessionActions.test: add 2 new tests (empty name guard, cancel on DeleteConfirmDialog)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 13:01:54 +02:00
marcopan 013a84ed4b feat(frontend): RenameDialog and DeleteConfirmDialog 2026-06-29 12:55:08 +02:00
marcopan 50025c809e fix(frontend): make NavSessions rows keyboard-accessible (role/tabIndex/Enter+Space) 2026-06-29 12:53:42 +02:00
marcopanandClaude Sonnet 4.6 d5f82b70a4 feat(frontend): SessionMenu kebab + NavSessions prop-driven; AppShell owns sessions query
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 12:50:24 +02:00
marcopanandClaude Opus 4.8 8243ce6446 feat(frontend): session mutation + documents API client and types
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 12:45:09 +02:00
marcopan 57580676a3 docs(harness): add Phase 0 Resume cold-start procedure to the orchestrator skill 2026-06-29 12:41:27 +02:00
marcopan 790ac71284 feat(backend): spawnFor new/resume prompt mode; resume sends /riprendi-sessione 2026-06-29 12:38:26 +02:00
marcopan 387ae56583 test(backend): make mgr injectable; assert teardown-before-delete ordering 2026-06-29 12:36:29 +02:00
marcopanandClaude Opus 4.8 bd29ac517c feat(backend): rename/group/archive/unarchive/delete/documents routes + resume read-only guard
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 12:32:52 +02:00
marcopan 4a63db51e8 feat(backend): ThtRunner session mutation + documents methods 2026-06-29 12:29:14 +02:00
marcopan 03053b0716 feat(harness): tht session documents --json read command 2026-06-29 12:25:40 +02:00
marcopan 38cd4889f4 style(harness): move test_session_mutations imports to top, drop unused json 2026-06-29 12:23:48 +02:00