Skip to content

feat(doctor): per-trigger flow-tier resolution lines - #191

Merged
edgehero merged 1 commit into
mainfrom
feat/doctor-flow-tiers
Aug 13, 2026
Merged

feat(doctor): per-trigger flow-tier resolution lines#191
edgehero merged 1 commit into
mainfrom
feat/doctor-flow-tiers

Conversation

@edgehero

Copy link
Copy Markdown
Owner

The doctor half of #189 Gap 1 (the runner half merged as #190). Doctor now answers, per trigger, whether run.flow resolves in any host-visible skill tier, before the trigger fires.

What

  • One line per distinct (flow, folder, skillsDir, packages) question, probed in the loader's precedence order: repo .pi/skills at HEAD (cron folders), injected run.skillsDir, overlay skills/, staged packages.
  • The repo probe reuses the flow gate's ls-tree mechanics (100644-blob rule, hardened git flags) but deliberately not readFlowGate itself: the gate's fail-closed catch would turn a broken folder into a confident wrong ✓, and its no-ref rule guards against an agent a host preflight does not have. Doctor resolves HEAD itself and degrades to unknown.
  • New shared reader readStagedSkills in worker/src/packages.mjs (never-throws; importable by admin for Topology: flows resolved from injected, overlay or staged-package skills render as missing #188's topology): mirrors pi's manifest-vs-convention rule at the pin, including that a pi manifest without a skills key contributes nothing, and declares pattern-carrying manifests not-enumerable rather than guessing (patterns can also disable files; a wrong ✓ is the one inadmissible direction).
  • No hit prints ⚠, never ✗ and never a fixAction, naming tiers checked vs not checkable here (a forge trigger's repo, a pattern-manifest package). Staged-package-only resolution is a plain ✓ naming the package, per the issue's acceptance. Charset-failing flows get their own ⚠. Zero triggers add zero lines.
  • The fix line names the in-container half (flow_not_loaded, feat(runner): report a run.flow that resolves in no loaded skill tier #190) so the two advisory layers reference each other.

Specs

REQ-PER-TRIGGER-SKILLS AMENDED (doctor acceptance clause), REQ-GLOBAL-PI-OVERLAY AMENDED (overlay + staged tiers join doctor's obligations), DES-FLOW-RESOLUTION-TWO-ADVISORY-LAYERS AMENDED (doctor layer specified in full, readFlowGate rejection recorded). UNCHANGED, checked: REQ-DEPLOYMENT-BOOTSTRAP (warn-tier, no fixAction), INT-TRIGGERS-FILE-CONTRACT, INT-CONTAINER-JOB-INPUTS, INT-PI-PACKAGES-FILE-CONTRACT, DES-AI-TRIGGER-FLOW-GATE, DES-CLI-SURFACE.

Suite: 2219 tests, 0 failed, 0 skipped, in the CI posture (loader/worker/receiver gates on, live Valkey).

The doctor half of issue #189 Gap 1 (the runner half merged as #190): one
line per distinct (flow, folder, skillsDir, packages) question, naming the
skill tier that resolves the trigger's run.flow, probed in the loader's own
precedence order.

The repo tier reuses the flow gate's ls-tree mechanics (100644-blob rule,
hardened git flags) but deliberately NOT readFlowGate itself: the gate's
fail-closed catch turns a broken folder into deny, and deny-implies-exists
would print a confident wrong answer on an advisory line; its no-ref rule
guards against an agent self-authorizing, which a host-side preflight does
not face, so doctor resolves HEAD itself and degrades to unknown. The
staged tier gets the genuinely new reader, readStagedSkills in
worker/src/packages.mjs (never-throws, reachable by admin for issue #188's
topology): it mirrors pi's manifest-vs-convention rule at the 0.80.7 pin,
including that a pi manifest WITHOUT a skills key contributes nothing, and
declares a pattern-carrying manifest not-enumerable rather than guessing,
because patterns can also disable files and a wrong checkmark is the one
direction an advisory line may not err in.

When nothing resolves the line is a warn, never a fail and never a
fixAction (triggers content is the never tier), naming the tiers checked
and the ones not checkable on this host: a forge trigger's repo is not
here, and mid-setup is legal. Staged-package-only resolution is a plain
checkmark naming the package, per the issue's acceptance. A flow failing
the skill charset is its own warn. Zero triggers add zero lines; the two
package-feature no-op pins keep their broad needle by stripping the flow
lines, which name staged packages as a tier.

Specs: REQ-PER-TRIGGER-SKILLS AMENDED (the doctor acceptance clause),
REQ-GLOBAL-PI-OVERLAY AMENDED (overlay + staged tiers join doctor's
obligations), DES-FLOW-RESOLUTION-TWO-ADVISORY-LAYERS AMENDED (the doctor
layer specified in full, readFlowGate rejection recorded). UNCHANGED,
checked: REQ-DEPLOYMENT-BOOTSTRAP (warn-tier, no fixAction),
INT-TRIGGERS-FILE-CONTRACT, INT-CONTAINER-JOB-INPUTS,
INT-PI-PACKAGES-FILE-CONTRACT, DES-AI-TRIGGER-FLOW-GATE, DES-CLI-SURFACE.

Signed-off-by: Rob Boerman <robboerman@live.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant