Skip to content

Latest commit

 

History

History
188 lines (136 loc) · 8.13 KB

File metadata and controls

188 lines (136 loc) · 8.13 KB

Route-Bound Execution Guard

The route-bound execution guard turns KnowledgeOS from an advisory checklist into a stricter execution harness.

The goal is simple: an agent should not mutate a project merely because a path is writable. The write must also belong to the selected task route.

Route is intentionally a policy guard, not a heavyweight workflow engine. Many real tasks are mixed: documentation plus code, research plus refactor, migration plus report. KnowledgeOS therefore uses route profiles to set boundaries, evaluation profiles, and human gates, while leaving fine-grained capability choice to dispatch-task.

In short:

route-task = what task policy applies, where writes may go, and what completion gate is required
dispatch-task = which orchestrator, subagent, MCP, skill, or script should be considered

Making route more complex is not automatically better. The safer default is a small number of policy profiles plus visible dispatch evidence.

What Was Added

check-route-write

check-route-write combines two gates:

  1. .agent-os/write-policy.yaml decides whether the path is generally safe.
  2. .agent-os/workflows/router.yaml decides whether the path is inside the task route's allowed_outputs.

Example:

./bin/knowledgeos check-route-write \
  --project-root /path/to/project \
  --task-id T001 \
  --path .agent-os/workspace.yaml

If the write is generally safe but outside the task route, the command returns route_output_denied.

Hardened run-task

run-task now requires:

  • task status is ready or in_progress;
  • task type resolves through route-task;
  • route status is routed.

This prevents agents from creating official run envelopes for backlog, completed, cancelled, or unknown-route tasks.

Evidence File Write Guard

Agents should not hand-edit lifecycle evidence files. The default write policy now human-gates direct writes to:

  • .agent-os/runs/**/run.yaml
  • .agent-os/runs/**/context-pack.md
  • .agent-os/runs/**/spec-snapshot.md
  • .agent-os/runs/**/plan.md
  • .agent-os/runs/**/eval.md
  • .agent-os/runs/**/phases.ndjson
  • .agent-os/runs/**/command-events.ndjson
  • .agent-os/runs/**/step-events.ndjson
  • .agent-os/runs/**/capability-events.ndjson
  • .agent-os/runs/**/effect-assertions.ndjson
  • .agent-os/runs/**/postflight.md
  • .agent-os/tasks.yaml
  • .agent-os/specs.yaml
  • .agent-os/specs/**
  • .agent-os/evals.yaml
  • .agent-os/read-policy.yaml
  • .agent-os/write-policy.yaml
  • .agent-os/dispatch-policy.yaml
  • .agent-os/tool-registry.yaml
  • .agent-os/workflows/router.yaml
  • .agent-os/phase-policy.yaml
  • .agent-os/fabric-link.yaml

The CLI commands can still write their own task/evidence state. Manual writes to those files are treated as a governance change or possible spoofing attempt.

complete-task

complete-task closes a task only after the run has evidence of evaluation success, spec/context/plan evidence, lifecycle phase evidence, declared outputs, effect verification, and required postflight.

By default, the run must first pass knowledgeos eval-task. The generated eval.md must include both Generated By: knowledgeos eval-task and Status: passed.

The run must also pass verify-lifecycle, which checks .agent-os/runs/<RUN_ID>/phases.ndjson against .agent-os/phase-policy.yaml.

verify-lifecycle also checks command evidence from .agent-os/runs/<RUN_ID>/command-events.ndjson, so a hand-written phases.ndjson is not enough.

verify-lifecycle also checks capability visibility. A run must contain dispatch-task --run-id evidence, and required dispatch stages must either have a matching capability-event record or an explicit public skip reason in the dispatch phase evidence.

The run must also pass verify-context, which checks context-pack.md, spec-snapshot.md, plan.md, and the matching command evidence. If the active spec changes after the run snapshot, completion fails with spec_drift.

The run must also pass verify-effects, which checks .agent-os/runs/<RUN_ID>/effect-assertions.ndjson and matching artifact-assert command evidence. A hand-written effect ledger is not enough. If an effect assertion claims a capability_event_id, that id must exist in the same run's capability-events.ndjson; bogus links are rejected. Agents must relay the returned EFFECT_VERIFY_OK marker before claiming effect verification success.

Effect strictness is project-level:

  • observe: record the state without blocking.
  • warn: allow completion but write warnings into the receipt.
  • enforce: block completion when declared output effects are missing or forged.
  • off: allow only with a receipt-visible downgrade reason.

If .agent-os/fabric-link.yaml sets postflight_required: true, complete-task runs the shared-fabric after-task.sh hook and requires [SYNC_OK] in stdout. If the hook cannot run, the task cannot complete unless the agent uses --allow-pending-postflight "<reason>", and that pending reason is written into the receipt.

Then complete-task writes:

  • run receipt;
  • run handoff;
  • .agent-os/receipts/latest.md;
  • .agent-os/handoffs/current.md;
  • completed run status;
  • completed task status.
  • postflight evidence when postflight is required.

Safer Run IDs

complete-task rejects run ids containing path separators. This prevents a malicious or mistaken ../ style value from escaping .agent-os/runs/.

Doctor Router Consistency

doctor now checks that every router profile has:

  • an eval_profile that exists in .agent-os/evals.yaml;
  • non-empty allowed_outputs.
  • a complete run-task -> context-pack -> plan-task -> phase-task -> eval-task -> verify-context -> verify-lifecycle -> verify-effects -> complete-task lifecycle order.

This catches incomplete routes before agents rely on them.

Execution Contract

For substantial work, the recommended local flow is now:

doctor
-> route-task
-> check-route-write for each planned path
-> run-task
-> dispatch-task --run-id records dispatch evidence for this run
-> context-pack writes/refreshes spec-snapshot.md and context-pack.md
-> plan-task writes the public execution plan
-> trace-step records public operational progress when useful
-> phase-task records route/plan/review/dispatch/execute/report public evidence
-> capability-event records MCP / skill / subagent / orchestrator / important script use
-> execute
-> eval-task writes deterministic eval evidence after checks pass
-> verify-context
-> verify-lifecycle
-> artifact-assert records real side-effect proof as EFFECT_OK
-> verify-effects emits EFFECT_VERIFY_OK with status and counts
-> complete-task
-> complete-task runs required postflight

Shared Fabric still owns global boot, memory lanes, and optional external postflight persistence. KnowledgeOS owns project-local route, write, run, phase ledger, eval, receipt, handoff state, and the completion-time postflight gate.

Security Boundary

This is not a sandbox. It is a harness-level execution guard.

It helps prevent:

  • accidental writes to raw materials;
  • writes outside the selected task's output scope;
  • official run evidence for unrouted tasks;
  • task completion without a command-generated spec snapshot, context pack, and plan;
  • silent spec drift after a run starts;
  • task completion without a passing eval;
  • task completion without required public phase evidence;
  • task completion without required real artifact effect evidence;
  • silent completion when required postflight is missing;
  • run-id path traversal into unrelated files.

It does not replace OS-level file permissions, runtime sandboxing, code review, or human approval for high-risk actions.

Verification

The route-bound execution guard tests cover:

  • allowed route writes;
  • out-of-route write denial;
  • immutable path denial;
  • non-ready task rejection;
  • unknown route rejection;
  • missing eval rejection;
  • missing plan/context rejection;
  • spec drift rejection;
  • missing lifecycle rejection;
  • postflight-required rejection when the hook is missing;
  • safe task completion after eval-task records Status: passed;
  • safe task completion after verify-lifecycle and verify-effects pass and postflight returns [SYNC_OK];
  • run-id path traversal rejection.