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.
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
// Etichette riservate del gate HITL e helper di deduplica. Modulo PURO (nessuna
|
||||
// dipendenza da pi-tui): condiviso da nsp-gate.js e testabile in isolamento con
|
||||
// node --test .pi/extensions/test_reserved_labels.mjs
|
||||
// `Altro — specifica…` e le due vie di fuga (torna indietro / esci) vengono
|
||||
// SEMPRE aggiunte dal gate alle opzioni in arrivo: se il modello ri-propone uno
|
||||
// step con queste etichette gia' presenti, stripReserved evita il duplicato.
|
||||
|
||||
export const ALTRO = "Altro — specifica…";
|
||||
export const QUIT_LABEL = "Esci da Pi (/quit)";
|
||||
export const BACK_LABEL = "Torna indietro (fase precedente)";
|
||||
export const CONTROL_LABELS = new Set([QUIT_LABEL, BACK_LABEL]);
|
||||
|
||||
const RESERVED = new Set([ALTRO, QUIT_LABEL, BACK_LABEL]);
|
||||
|
||||
// true se l'etichetta e' una di quelle che il gate aggiunge da se'.
|
||||
export function isReserved(label) {
|
||||
return RESERVED.has(label);
|
||||
}
|
||||
|
||||
// rimuove da una lista di etichette ogni voce riservata (Altro + controlli),
|
||||
// preservando ordine e voci normali. Idempotente.
|
||||
export function stripReserved(labels) {
|
||||
return labels.filter((label) => !isReserved(label));
|
||||
}
|
||||
Reference in New Issue
Block a user