requirements cannot be expressed; agent picking ignores rule hostnames #90
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Labels: bug, scheduling, priority/high
The plans store has a requirements field (os, commands, architecture, capabilities) with capabilities: ["workflow_v2"]. create_plan exposes no parameter for it. The agent cannot declare what a plan needs.
Consequence, observed: execution 643895b6 ran plan 0c52ac87 — a script hardcoded to adam-slave-0 paths (/etc/rsnapshot.conf, /home/eduardez/backups) — on adam-slave-1, where it found nothing, printed PLAN ABORTED, and was recorded remediated. Rule 3749b312 listed hostnames: ["adam-slave-0","adam-master"], so the hostname filter was not honoured on that dispatch path. Either the filter is not enforced, or a manual dispatch bypasses it silently.
Either way the execution record does not distinguish rule-triggered from manually-triggered runs.
Fix:
Acceptance criteria
Claimed — branch
issue/90-requirements-hostnames. Doing: expose requirements on create_plan/plan_update tools + hostAllowed gate on manual run + Execution.trigger.Issue #90 plan — create_plan requirements + dispatch honours rule hostnames
Branch:
issue/90-requirements-hostnames(base5b84430). Worktree:/home/eduardez/workspace/gotoi-wt/issue-90.Restated goal
Three gaps, all verified on base
5b84430:create_plan/plan_updatecontrol tools expose norequirementsparameter, so the AIcannot declare what a plan needs (
os/architecture/capabilities/commands).POST /plans/:id/run(manual dispatch) never consults the plan's referencing rules'hostnames/groupIds, so a rule-scoped plan can be hand-run on any host.ExecutionhasruleId?but notrigger, so the record cannot distinguish a rule-triggered runfrom a manual or retried one.
Deliver: tool params + end-to-end passthrough for
requirements; ahostAllowedguard on manualrun;
Execution.trigger?: 'rule' | 'manual' | 'retry'persisted, projected, and mirrored to thedashboard types; UCs UC-MW-176 / UC-MW-177; two new red-first tests.
Project fact that contradicts the task file
Task row "API create/patch accept
requirements" (MET) is false on base5b84430.planCreateBody(middleware/src/routes/plans.ts:56-82) andplanPatchBody(L84-108) carry norequirementskey;createPlanFromBody'sstampPlan({...})(L174-192) never copies it;applyPlanPatchhard-preservesrequirements: prev.requirements(middleware/src/plans.ts:262) andhas no
hasOwnPropertybranch for it.Plan.requirements(type + jsonb column +compatibility())does exist and is read by scoring/templates — only the write path is missing.
Consequence: a params-only change in
control-agent.tswould still drop the value, because the toolrun fns funnel through
planCreateBody/applyPlanPatch. The frozen design's "params + passthroughchange only" therefore expands to include the REST create/patch field, otherwise gap 1 is not fixed.
This is the smallest correct diff for the stated goal; recorded here rather than silently widening scope.
Scope
In:
middleware/src/routes/plans.ts—requirementsinplanCreateBody/planPatchBody/createPlanFromBody;hostAllowedgate +trigger: 'manual'inPOST /plans/:id/run.middleware/src/plans.ts—PlanDraft.requirements,planDraftSchema,applyPlanPatchbranch.middleware/src/control-agent.ts—create_plan/plan_updateparams,PLAN_PATCH_KEYS,planPatchToolSchema, descriptions.middleware/src/pipeline.ts,middleware/src/incidents.ts—trigger: 'rule'where a matchedrule created the execution.
middleware/src/routes/executions.ts—trigger: 'retry'.middleware/src/types.ts,middleware/src/db/schema.ts,middleware/drizzle/0034_execution_trigger.sql+.down.sql,middleware/src/db/persist.ts,middleware/src/views.ts,dashboard/src/lib/types.ts.Out (per task):
agent/**;middleware/src/match.ts;middleware/src/rules.tssemantics;capabilities.ts;plans/; typed steps (#89).UC decision
UC-MW-176-requirements-tool.md— "create_plan and plan_update carry requirements" (control toolaccepts + persists
requirements;related:UC-MW-68, UC-MW-136, UC-MW-137).UC-MW-177-dispatch-trigger-record.md— "manual dispatch honours rule host scoping and executionsrecord their trigger" (related: UC-MW-101, UC-MW-108).
related:+## Relatedheading too.Ordered tasks
Each task ends with its single verifying command; commit after each green step (
Refs #90).related:edits →python3 docs/use-cases/_check.pymiddleware/tests/uc-mw-176-requirements-tool.test.ts,uc-mw-177-dispatch-trigger-record.test.ts→cd middleware && bun test tests/uc-mw-176-requirements-tool.test.ts tests/uc-mw-177-dispatch-trigger-record.test.ts(expected red)requirementsend to end (plans.ts draft/patch/schema + routes/plans.ts bodies + control-agenttool params) →
cd middleware && bun test tests/uc-mw-176-requirements-tool.test.ts tests/uc-mw-136-ai-read-table.test.ts tests/uc-mw-137-ai-create-plan-rule.test.tshostAllowedgate +triggerfield plumbing (types, schema, migration, persist, views,dashboard mirror, stamping sites) →
cd middleware && bun test tests/uc-mw-177-dispatch-trigger-record.test.ts tests/uc-mw-100-rules.test.ts tests/uc-mw-05-match-plan.test.tsOpen questions and assumptions
requirements? No (verified above). Assumption: fixing itis in scope because the tool run fns delegate to
planCreateBody/applyPlanPatch.trigger: 'rule'? Those created from a matched rule:pipeline.ts:273-287and
incidents.ts:202-218(both stampruleId: m.ruleId).retry→routes/executions.ts:114-128;manual→routes/plans.ts:1096-1109. Other creation sites (agent-step.ts,control-agent.ts,executions.tsrollback/chain,routes/agents.ts,pipeline.ts:114diagnostic) have no matchedrule; assumption: leave
triggerundefined there — optional field, no behaviour change.its allowed hostnames/groups, mirroring the existing
status:draft409 style. No referencing rule =no restriction (seed disk-cleanup rule has none, so existing tests stay green).
requirementsonplan_updatefor a template/shared plan? Shared plans are not editable(403), unchanged.
Risk + boring fallback
executionSummary'sOmit<Execution, ...>return type forcesa TS edit there; handled in task 4.
decide()already gatescompatibility; the tool change only stores the value. If an end-to-end "incompatible agent refused"
assertion turns out to depend on capabilities the test agent cannot report, the boring path is to
assert the stored
plan.requirementsand thatcompatibility()rejects the target agent, and noteit — no new gate logic (two-attempt cap).
0033_plan_typed_steps.sqlis latest). Fallbackif it collides: use the next free integer following the same
ALTER TABLE ... ADD COLUMN IF NOT EXISTS/DROP COLUMN IF EXISTSpattern.hostAllowedgate cannot be made to work without touchingmatch.ts/rules.ts, stop, keep the diff torequirements+trigger, and report PARTIAL withthe reason.
REVIEW: FIXED 2 — findings: (1) five partner UCs got doubled '- -' Related bullets from the related: edit — fixed
c4de134; (2) issue requirement 'every execution records trigger' was missing on operator agent-test, control-chat machine-command, rollback, and chain runs (chain kept ruleId but dropped trigger) — fixed7d11488, alert diagnostics with no matched rule stay undefined and are documented in UC-MW-177 4a; static gates all green (UC check, AI headers, type mirror, no Showing lines in source). UNFIXED: implementer report file issue-90.report.md absent (anomaly, cannot retro-create); pre-existing flake tests/uc-mw-114-agents-bulk.test.ts 5s timeout reproduced on clean origin/agent-develop — not from this diff.Implementation landed — worktree pushed
PR opened: #102
5 commits, 24 files, +569/-36 lines. Two new UCs (MW-176 requirements tool,
MW-177 dispatch trigger). All static gates green; the 1-fail middleware result
is the pre-existing UC-MW-19 baseline red (also fails on clean).
Refs #90
issue/90-requirements-hostnamesto issue/90-requirements-hostnamesDONE (runner, 2026-10-09 12:5x) — PR: #103 (draft) against agent-develop.
Branch issue/90-requirements-hostnames, 5 commits (3 implementer 1f140de/5a9cda9/17d0e39 + 2 reviewer c4de134/7d11488). The implementer session was killed by the harness after its own gate run (ALL_GATES_DONE 11:38, before DONE); the runner harvested committed work, ran §4.6 review + §5 gates, and published.
review: FIXED 2 — (1) trigger stamping was missing on agent-test / machine-command / rollback / chain runs (
7d11488); (2) doubled Related bullets in partner UCs (c4de134). Reviewer report: meta/issue-90.review.md (run archive).Gates on final tree: static all green (UC check, headers 581, type-mirror, Showing-lines, gofmt); dashboard 254/254 + svelte-check 0 err; middleware 634/635 (only documented pre-existing UC-MW-19); go agent 6 fails all reproduced identically on clean origin/agent-develop (environmental /etc/gotoi/agent.json, no agent/ files in diff).
DRAFT reason — hidden UC-OP-02 set: times out at 5000 ms on branch (5083–5101 ms, 3 runs, 2 isolated); clean origin/agent-develop baseline passes 5055 ms (55 ms margin). Branch adds migration 0034 to every buildApp boot (~30–45 ms PGlite), pushing the frozen hidden set's budget over the line. Counters code untouched; visible UC-OP-02 twin passes. OPERATOR CALL: raise hidden-set budget (e.g. 8000 ms) or slim hidden boot — this will fire on every future migration otherwise.
Refs #90
CORRECTION (runner): PR #102 — opened by the original worker session after its gates and reviewed-fixed at c4de134/7d11488 — was merged into agent-develop by the integrator (merge commit
3122e89) before this runner published. Runner's duplicate draft #103 closed with explanation; #102 is the record. Hidden UC-OP-02 5000 ms budget finding still stands as an operator item: it will time out on every future PGlite migration (baseline 5055 ms, +1 migration ≈ 5083–5101 ms).