Files
ThothII/harness/docs/workflow-editing.md
T
marcopan 50d5f9c9cf docs(harness): README + workflow editing + testing guide (D6)
README: install, configure (.env + workspaces/), the workflow, run inside Pi, the
three-level test commands, layout, references.

docs/workflow-editing.md: how to edit workflow.yaml (add/reorder/merge/skip phases,
advance kinds, prerequisite predicates, decision_min_phase derivation, artifacts_out
+ teardown) -- referencing spec §5.3. Emphasizes no mirrored constants (the F2 point).

docs/testing.md: the honest L0/L1/L2 split in plain language -- what each covers and
does NOT. States the headline plainly: the skill->LLM->gate loop has NO automated
regression coverage (L2 only, pre-release). Documents the fake-Pi follow-up as the
gap-closer. Security note on keys (.env gitignored, never logged, rotate leaked keys).
2026-06-26 23:20:06 +02:00

76 lines
3.3 KiB
Markdown

# Editing the workflow
`harness/workflow.yaml` is the **single source of workflow truth** (spec F2, §5.3).
`phase.py`, the gate (`nsp-gate.js`), and the skill all read from it. There are **no
mirrored constants** in JS or Python — that was the ChironeWp3 drift bug
(`PHASE_NAMES` truncated to 7 entries in JS, F8/datamart silently dropped). Editing
this one file is the only place the workflow changes.
## Structure
```yaml
schema_version: 1
phases:
- id: F3 # stable id (referenced by the gate)
name: riscrittura # human label (nsp phase show / gate UI)
advance: kind:phase # how the phase advances (see below)
prerequisites: # what must hold before advancing (gate checks these)
- decision_exists: question_rewritten
artifacts_out: [question.md] # files produced; used by teardown on rollback (D15)
```
`decision_min_phase: auto` and `max_phase: auto` mean these are derived from the
phase list (don't hard-code them).
## `advance` kinds
| kind | meaning |
|----------------------------|----------------------------------------------------------------|
| `kind:phase` | advances on any phase-approved decision for this phase |
| `auto_if_empty` | auto-advances if no decisions were made (F2 memoria) |
| `auto_if_empty_or_skipped` | auto-advances if empty OR a `phase_skipped` decision exists |
| `reviewer_decide` | requires an explicit reviewer decision (F4, F8) |
## `prerequisites` predicates
A phase is "ready to advance" when ALL its prerequisites hold. Predicates:
- `decision_exists: <type>` — a decision of that type exists (effective view).
- `decision_subject_exists: [<type>, <subject>]` — e.g. a `phase_skipped` for `phase:6`.
- `file_validates: [<artifact>, <model>]` — e.g. `schema_linking.json` parses as a
`SchemaLinking`.
- `all_ctes_approved: true` — all CTE blocks approved (F6).
- `any: [...]` / `all: [...]` — combine predicates.
A decision type's **min phase** is derived: the earliest phase whose prerequisites
reference it. So adding a prerequisite like `decision_exists: my_new_decision` to F5
automatically makes `my_new_decision` valid from phase 5.
## Common edits
### Add a phase
Append a phase to `phases:`. `max_phase` becomes the new count automatically. Give it
an `id`, `name`, `advance`, and (optionally) `prerequisites` / `artifacts_out`.
### Reorder / merge / skip phases
Reorder the list; `max_phase` and `decision_min_phase` recompute. To make a phase
skippable, set `advance: auto_if_empty_or_skipped` and let the gate emit a
`phase_skipped` decision (predicate `decision_subject_exists: [phase_skipped, "phase:N"]`).
### Add an artifact
Add it to a phase's `artifacts_out`. On rollback (`teardown_to_phase`), artifacts
produced by phases **after** the target are deleted; the target phase's artifacts are
preserved. This is the D15 fix for the orphaned-CTE-blocks-finalize bug.
## After editing
```bash
nsp phase meta --json # confirm the new shape (max_phase, phases, artifacts_out)
pytest # L1 coherence smoke re-derives from the new workflow.yaml
```
No JS or Python constants to update — that's the point.