marcopan 60b6e38096 feat(harness): rewrite nsp-gate.js glue wired to widget-descriptor builders (D2/D4)
Rewrite of ChironeWp3's gate extension. The pure widget-descriptor CONSTRUCTION
is in ./gate/builders.js (L1-tested, C1); this file is the GLUE -- it depends on
the Pi runtime (pi.on, pi.registerTool, ctx.sendRaw) and is verified end-to-end at
L2 (Task D4), NOT unit-tested here. A fake-Pi runtime mock (cross-cutting
follow-up) would let it run in CI.

PRESERVED VERBATIM (load-bearing runtime glue, spec D4):
- anti-bypass tool_call hook: FORBIDDEN (nsp phase advance|reopen, decision add,
  cte plan) + PROTECTED_FILES (review_decisions.jsonl, session_manifest.yaml,
  cte_plan.json)
- input lock + the input hook: /nuova-domanda|/riprendi-sessione entry detection,
  free-input block, the `!`-prefixed steer channel
- before_agent_start kickoff injection + the two kickoff payloads (model prose)
- agent_end prose safety net (nudges the model back to reviewer_* tools)
- session_start state reset
- exit-code contracts with the CLI (5 = gate refusal, 6 = needs human,
  7 = not-ready silent no-op)
- textResult / nsp() / relayIfNspFails / advanceIfReady helpers

TWO CORRECTIVE CHANGES vs source:
1. F2 single source: workflow facts (max_phase, phase names, schema-linking phase)
   come from `nsp phase meta --json`, NOT from JS-mirrored constants. The source's
   PHASE_NAMES array (truncated to 7) is gone; F8/datamart can no longer drift.
2. D2/D4 widget-descriptor: reviewer interaction is emitted as a widget-descriptor
   (built by ./gate/builders.js) and awaited by id via emitAndWait + the
   extension_ui_response dispatcher. This replaces the source's blocking native TUI
   primitives (ctx.ui.select/custom) and introduces the correlation-by-id layer
   ChironeWp3 never had.

Four tools wired: reviewer_select, reviewer_decide (persists via nsp decision add),
reviewer_confirm (gate; privileged action on approve), rewrite_question. Plus the
/torna slash command for rollback. No-limbo invariant preserved: cancel/undefined
re-presents the widget; real escapes are always in the descriptor's reserved field.
2026-06-26 23:12:51 +02:00
S
Description
ThothII
35 MiB
Languages
TypeScript 46.1%
Python 18%
Go 15.1%
JavaScript 12.6%
Shell 4.9%
Other 3.3%