Commit Graph
136 Commits
Author SHA1 Message Date
marcopan a0daa319ca fix(storage): contain logical corpus root 2026-07-11 21:26:47 +02:00
marcopan 7f3f6f7ce7 fix(storage): harden portable path diagnostics 2026-07-11 21:25:03 +02:00
marcopan eacb139e22 feat(storage): resolve portable workspace roots 2026-07-11 21:21:06 +02:00
marcopan 3e2ad7955c fix(adapter): close final foundation review 2026-07-11 21:14:32 +02:00
marcopan 45d57756aa fix(core): restore adapter command behavior 2026-07-11 21:04:53 +02:00
marcopan a35efa16de fix(core): preserve adapter command contracts 2026-07-11 21:00:50 +02:00
marcopan dbbab6d005 refactor(core): route integrations through adapter factory 2026-07-11 20:52:41 +02:00
marcopan 1e0911bb6a feat(config): add typed resource schema 2026-07-11 20:43:08 +02:00
marcopan fe8d70da47 fix(vector): separate write transport fields 2026-07-11 20:35:57 +02:00
marcopan ff4d662aba refactor(vector): define store contract 2026-07-11 20:24:14 +02:00
marcopan f6302b31dd fix(dwh): validate adapter limits strictly 2026-07-11 20:19:05 +02:00
marcopan 216984aac8 fix(dwh): align adapter sampling contract 2026-07-11 20:14:23 +02:00
marcopan 717e5ecced refactor(dwh): adapt direct and REST transports 2026-07-11 20:03:31 +02:00
marcopan a4eb6cc9e5 refactor(dwh): define adapter contract 2026-07-11 19:57:39 +02:00
marcopanandClaude Opus 4.6 1e4bc11418 fix(embed): fast-fail + auto-restart Ollama on solved-search hang
Embeddings timeout was 120s, causing multi-minute hangs when Ollama was
down during F4/F6/F7 solved-search. Now: connect_timeout=5s across all
HTTP clients (REST + Ollama), read_timeout reduced to 30s for embeddings,
and OllamaEmbeddings auto-restarts the server on ConnectionError before
degrading gracefully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-07 19:49:55 +02:00
marcopanandClaude Opus 4.6 893ad99594 fix(gate): auto-finalize session after last phase approval
The model sometimes stops after receiving 'Fase approvata' without calling
`tht session finalize`, leaving the session open. Now the gate itself calls
finalize after advancing the max phase (F8), making session closure
deterministic regardless of model behavior.

- reviewer_confirm kind:phase: after phase advance at max_phase, gate calls
  `tht session finalize <session>` (best-effort with recovery message)
- SKILL.md updated: model no longer needs to call finalize itself
- Tests: 2 new JS tests (auto-finalize at max phase; no-finalize at non-max)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-07 18:47:19 +02:00
marcopanandClaude Fable 5 ade6838182 docs: add efficiency-levers setup and current-run instructions
- PROJECT_STATE.md: section on three deployed levers (FK annotations, context-pack, recap v2)
  with setup instructions for new workspaces; psd pre-configured
- README.md: one-time setup for workspace (tht schema suggest-fks); note that levers 2+3 auto-activate
- Updated 'How to run' with explicit command and prereq checklist
- Last-updated timestamp: 2026-07-08

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 17:43:51 +02:00
marcopanandClaude Fable 5 e24b41b156 feat(opt): three efficiency levers for NL→SQL workflow
Lever 1: Join-graph via FK logics in annotations + suggest-fks command
  - TableAnnotation.foreign_keys field stores curated logical FKs (DWH has no FK constraints)
  - tht schema suggest-fks: mine from approved SQL, heuristics (time_key → dim_time),
    same-name discovery + explicit --assume flag for multi-owner PKs
  - mschema renders 【Foreign keys】 section populated; validation in merge.py
  - SKILL.md F4 now reads FKs from mschema-text, no custom data_time_key logic

Lever 2: Context-pack consolidation at kickoff (tht search pack)
  - Single embedding of question, reused for schema + evidence + solved searches
  - One command: tht search pack <question> --session <id> → retrieval_pack.md
  - Graceful degradation when Ollama/vector store unreachable (exit 0, empty sections)
  - SKILL.md F1 prescribes as first call; reduces model thinking turns via pre-retrieval

Lever 3: Phase-summary recap v2 auto-construction from session ledger
  - tht session show --json includes full decisions ledger
  - tht phase meta --json exports 'emits' (substantive decision types per phase)
  - Gate appends deterministic 【Decisioni registrate in questa fase】 section (appendLedgerSection)
  - Model authors only summary + checks; recap table comes from persisted state (exact by construction)
  - SKILL.md Disciplina 6: brief model output, gate fills the rest

Tests: 358 Python (including 10 FK + 3 pack + 1 session-ledger tests) + 111 JS gate tests, all pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 17:43:08 +02:00
marcopanandClaude Fable 5 34aeda006e perf(f1): cache-guard schema introspect + F1 toolbox in skill (~-5 min per session)
Transcript analysis (session 2026-07-06-175012, GLM 5.2) showed F1 at 567s:
182s wasted on a useless `tht schema introspect` (re-introspecting the remote
DWH although physical.yaml was already materialized) plus ~220s of model
thinking inflated by ~7 exploratory turns (--help/find/cat). The actual
searches cost ~15s; reviewer gates (~145s, untouched) are the quality contract.

- schema_cmd.py: introspect now exits 0 with "OK (cache)" in ~1s when
  physical.yaml exists; --refresh forces the real re-introspection.
  Deterministic cross-model guarantee, verified live on psd (163 tables, 1.2s).
- SKILL.md: F1 toolbox (only `tht search find` + `tht schema render`; no
  introspect/--help/filesystem browsing; batch all searches in one turn);
  F4 step 1 is render-only with a one-shot introspect fallback.
- tht-gate.js: `tht schema introspect ... --refresh` added to FORBIDDEN
  (maintenance stays shell-only, never in-session).
- tests: 4 new pytest cases (cache hit placement proven with fake credentials,
  refresh bypass, corrupt-catalog fall-through, render fallback message) and
  2 gate anti-bypass JS cases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:02:45 +02:00
marcopanandClaude Opus 4.6 0cad04a8d8 docs(vector): add write-RPC migration instructions (existing_vector_hashes + upsert_vector_records)
The original doc only covered search_similar; the write functions also need
solved_question in their kind whitelist for the memory table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-07 15:15:55 +02:00
marcopanandClaude Fable 5 a26f16ad79 feat(vector): server-side kinds filter for search_similar (legacy fallback) + graceful solved-search degrade
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:23:28 +02:00
marcopanandClaude Fable 5 8d427a2ccb fix(gate): actionable recovery for mid-promotion failures; truthful solved-index copy; fast-follow notes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:07:00 +02:00
marcopanandClaude Fable 5 8af0552dcc docs(skill): prescribe solved-question recall in F4/F6/F7; refresh PROJECT_STATE
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:54:42 +02:00
marcopanandClaude Fable 5 4c4099df09 fix(finalize): report the unchanged (no-upsert) solved-question case instead of staying silent
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:50:53 +02:00
marcopanandClaude Fable 5 2742a1fc42 feat(finalize): auto-index the question->SQL pair (best-effort, never blocks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:48:02 +02:00
marcopanandClaude Fable 5 1f429b6b35 feat(cli): tht memory solved-index / solved-search (question->SQL exemplars)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:43:52 +02:00
marcopanandClaude Fable 5 c0324c127a feat(solved): solved_question vector kind + one-row upsert (D11 pattern)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:38:10 +02:00
marcopanandClaude Fable 5 ae89957175 docs(skill): prescribe the F8 memory-promotion gate; drop optional D11 notes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:34:04 +02:00
marcopanandClaude Fable 5 e25ba5126b feat(gate): reviewer_memory_promote — deterministic F8 memory-promotion gate
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:30:35 +02:00
marcopanandClaude Fable 5 bf7e850e6b feat(memory): filter gate-declined candidates from promotion preview
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:26:59 +02:00
marcopanandClaude Fable 5 cadbdf177a feat(memory): memory_promoted/memory_promotion_declined decision types (F8 emits)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:22:07 +02:00
marcopanandClaude Fable 5 b59b57c4e6 fix(review-gates): green success badges, null-safe preview rows, optional section items
- Extract shared statusBadgeClass() helper (src/viewers/statusBadge.ts) so
  SqlViewer, CteResultViewer and PhaseSummaryViewer can't drift: ok/success/
  passed/promoted render green (--success), warn renders amber (--warning),
  error/failed stay destructive red, everything else stays neutral outline.
  Previously CteResultViewer/PhaseSummaryViewer mapped "ok"/"promoted" to the
  default badge variant, which is bg-primary (GSD red) — success states
  rendered red.
- enrich.js: buildCteResultV2 now falls back preview.rows to [] instead of
  null when last_test.preview_rows is missing (pre-upgrade ok records), and
  CteResultViewer reads result.preview?.rows?.length with a null-safe
  fallback so it degrades to the "No preview rows" empty state instead of
  crashing.
- PhaseSummaryViewer: section.items is optional (model-authored sections can
  be prose-only); render (section.items ?? []) instead of crashing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 01:37:35 +02:00
marcopanandClaude Fable 5 3ad93cd02f feat(gate): deterministic v2 review-gate payloads (cte_plan/cte_result/phase)
The tht-gate.js reviewer_confirm now builds structured v2 artifacts before the
widget so the reviewer approves gate-derived data, not raw model text:

- new pure modules gate/artifact-contracts.js (soft validators, {ok,errors},
  legacy-passthrough) and gate/enrich.js (index/description enrichment,
  buildCteResultV2 fusing thin model data with `tht cte info`, phase enrichment)
- cte_plan v2: validate + enrich + persist via `tht cte plan --name … --doc -`
  (names derived from data.ctes[]); legacy `names` param kept as fallback
- cte_result v2: rebuild from `tht cte next`/`tht cte info` (sql + preview from
  the persisted test record); null/error last_test -> actionable textResult
- phase v2: soft-validate + fill phase from meta + catalog descriptions
- prepareReviewerArguments coerces artifact.data too (GLM double-stringify);
  legacy markdown strings pass through unchanged
- SKILL.md: Phase 6 cte_plan payload A + thin cte_result guidance; Discipline 6
  payload C example; Discipline 7 reworded for gate-rebuilt cte_result

Legacy (non-v2) paths unchanged. TypeBox stays Type.Any() for artifact.data;
validation is soft (textResult) so models self-correct instead of looping.
All 102 gate JS tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 00:42:48 +02:00
marcopan 9b4f6b9804 feat(harness): persist CTE preview rows, add tht cte info, --doc for cte plan
WS1 of review-gates-v2: gives the JS gate (WS2) deterministic data to build the
cte_result v2 payload.

- CteTestRecord gains optional preview_rows (JSON-coerced, truncated cells);
  test_cmd populates it from the bounded result rows.
- New read-only `tht cte info <name> --session <id> [--json]`: plan
  index/total, persisted .sql, cte_plan_doc.json entry (if any), last
  CteTestRecord. Exits 1 with a clean stderr message on missing
  session/plan/name/sql.
- `tht cte plan --doc -` validates a chain-doc JSON (ctes[].name must match
  --name, same order) and writes it to cte_plan_doc.json; cte_plan.json stays
  a plain list[str] (load-bearing for tht.phase.next_cte). --doc is optional.
2026-07-07 00:23:50 +02:00
marcopanandMarco Pancotti d942635085 fix(f4): harden schema-columns enrichment + ValidationError guard + staged-helper note 2026-07-06 23:25:00 +02:00
marcopanandMarco Pancotti 3ed570ee60 feat(tht): promoted_columns_for helper (curated column set) 2026-07-06 23:25:00 +02:00
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
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 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 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 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 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 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