Integracja listy zadań (planfile) i runtime procesów (urirun)

Relcom może opcjonalnie oprzeć listę zadań o standard ticketów planfile, a **uruchamianie i monitorowanie procesów** o runtime URI urirun, zamiast traktować takie operacje jako czyste zdarzenia audytowe.

Integracja jest best-effort i wyłączona domyślnie. Bez zainstalowanych narzędzi Python cały system działa jak dotychczas — operacje degradują się przezroczyście do wyniku mode: "lab-audit". Nie wprowadza to twardej zależności.

Model

Operacja planu (OQL)Backend gdy TASK_RUNTIME_ENABLED=trueFallback
task.create, manual.taskplanfile ticket create → ticket PLF-NNNlab-audit
process.run, workflow.requesturirun run <uri> <registry> --executelab-audit

Most żyje w @subactor/runtime/task-runtime (klasa TaskRuntime) i jest instancjonowany w services/bridge. Zwraca ustrukturyzowane koperty i nigdy nie rzuca przy braku binarki lub martwym node — zwraca {ok:false, available:false, source:"lab-audit-fallback", reason:...}, a bridge kontynuuje plan z wynikiem lab-audit. Realne błędy CLI (np. zła nazwa ticketu przy dostępnym planfile) są zgłaszane jako błąd kroku, nie ukrywane.

Uwaga implementacyjna: CLI planfile jest zakresowane katalogiem roboczym (.planfile/ w cwd) i nie ma flagi --project; projekt wybiera się przez cwd procesu. ticket create nie wspiera --format json, więc identyfikator ticketu jest parsowany z linii ✓ Created PLF-NNN: ..., a pełne dane odczytuje ticket list --format json.

Konfiguracja

Zmienne (zadeklarowane w config/env-contract.json, propagowane do .env):

TASK_RUNTIME_ENABLED=false      # główny przełącznik
PLANFILE_BIN=planfile           # binarka planfile w PATH
PLANFILE_PROJECT_DIR=           # katalog projektu (.planfile/); puste = cwd bridge
URIRUN_BIN=urirun               # binarka urirun w PATH
URIRUN_REGISTRY_PATH=           # skompilowany rejestr URI dla `urirun run`
URIRUN_ALLOW=proc://**          # polityka allow deny-by-default dla wykonania

Weryfikacja

Test jednostkowy: npm run test uruchamia components/testkit/tests/task-runtime.test.mjs (fallback przy wyłączeniu, budowa komend, degradacja przy braku binarki, parsowanie JSON/loose i ID ticketu).

Sprawdzenie na żywo wobec prawdziwego CLI planfile:

node --input-type=module -e '
import {TaskRuntime} from "@subactor/runtime/task-runtime";
const rt = new TaskRuntime({enabled:true, planfileProject:"/tmp/pf"});
console.log(await rt.createTicket({name:"Relcom onboarding", priority:"high", labels:["subactor"]}));
console.log(await rt.listTickets());
'
# → CREATE ok=true source=planfile id=PLF-001
# → LIST   ok=true tickets=[["PLF-001","Relcom onboarding","high"]]

Granica

To integracja warstwy developerskiej/laboratoryjnej. Produkcyjnie należy uruchamiać urirun jako node HTTP (urirun node serve --execute) i wołać POST /run oraz GET /events zamiast CLI, a planfile wystawić przez planfile serve (REST), z kolejką, tenancy i audytem zgodnie z docs/PRODUCTION_READINESS.md.