Imported from instagrim-dev/roir (
AGENTS.md). Install upstream withnpx skills add instagrim-dev/roir. Copyright stays with the author.
ROI Command Vocabulary
ROI is a skill-driven lifecycle. There is no MCP server, no tool
registry to query, no daemon to keep alive. Each roi:* command opens a
SKILL.md under skills/ and follows its procedure. Skills shell to
node scripts/lifecycle.mjs <verb> to persist state in SQLite
(.data/roi.sqlite by default).
This file teaches Codex (and any other AGENTS.md-aware host) the ROI
ergonomic command surface and the underlying helper contract. Canonical
dispatch lives in skills/roi-drive/SKILL.md and skills/roi-go/SKILL.md.
Keep this file in sync when commands change.
Developing ROI itself
When editing this repository's code, skills, or docs (not just operating
roi:* commands): start with CONTRIBUTING.md. Verify with pnpm test;
run pnpm run release:check before release-facing changes and
node scripts/integration-smoke.mjs for helper/schema health. Release
checks pin required text in this file and in skills/roi-go/SKILL.md —
run them after editing either. Failure handling: fix forward per the host
workspace rules.
Command Aliases → Skills
| Alias | Stage | Canonical skill |
|---|---|---|
roi:start [goal] |
Open / initialize a mission | skills/roi-start/SKILL.md |
roi:work [goal] |
Alias for roi:start |
skills/roi-work/SKILL.md |
roi:clarify |
Refine brief | skills/roi-clarify/SKILL.md |
roi:brief |
Alias for roi:clarify |
skills/roi-brief/SKILL.md |
roi:source |
Record research findings | skills/roi-source/SKILL.md |
roi:research |
Alias for roi:source |
skills/roi-research/SKILL.md |
roi:outline |
Generate plans | skills/roi-outline/SKILL.md |
roi:plan |
Alias for roi:outline |
skills/roi-plan/SKILL.md |
roi:go [goal] |
Implement plans in product repo | skills/roi-go/SKILL.md |
roi:draft |
Open a run | skills/roi-draft/SKILL.md |
roi:run |
Run lifecycle (create / resume) | skills/roi-run/SKILL.md |
roi:drive [goal] |
Thin lifecycle orchestrator | skills/roi-drive/SKILL.md |
roi:verify |
Record verdict at verify_gate | skills/roi-verify/SKILL.md |
roi:review |
Alias for roi:verify |
skills/roi-review/SKILL.md |
roi:edit |
Respond to non-pass verdict | skills/roi-edit/SKILL.md |
roi:publish |
Record publication / handoff marker | skills/roi-publish/SKILL.md |
roi:learn |
Pattern detection / capability proposal | skills/roi-learn/SKILL.md |
roi:enlighten |
Alias for roi:learn |
skills/roi-enlighten/SKILL.md |
roi:inspect |
Read mission state | skills/roi-inspect/SKILL.md |
roi:status |
Alias for roi:inspect |
skills/roi-status/SKILL.md |
roi:cancel |
Cancel a run | skills/roi-cancel/SKILL.md |
How a skill runs
Every skill closes with a standard Reporting block:
mission_id: <id>
<stage-specific fields>
next_actions: <quoted from helper output>
→ <one sentence interpreting that next step>
Skills do not invent next actions. They quote next_actions from the
helper response verbatim and add one bridge sentence. If next_actions
is empty, the skill says so and stops.
Lifecycle Positions
mission created
→ brief revised (roi:clarify)
→ research recorded (roi:source — optional)
→ plans generated (roi:outline)
→ run created (roi:draft / roi:run)
→ orientation admitted (roi:go / roi:verify as task stage requires)
→ implementation done (roi:go)
→ paused at verify_gate (roi:verify — operator-owned)
→ paused at publish_gate (roi:publish — operator-owned)
→ terminal (optional roi:learn)
roi:drive advances through non-gate stages and stops at the verify
and publish gates. The operator runs roi:verify and roi:publish
explicitly because both stages produce durable judgments.
A full roi:verify pass reconciles the run ledger after roi:go evidence is
substantive for every run plan: queued run-scope workflow tasks are completed,
the run becomes completed, superseded stale blockers are hidden from
status_get.blocking_issues, and next_actions moves to roi:publish plus
roi:learn. Partial checkpoint passes deliberately do not publish and are valid
only for the semantic scope bound to a current orientation checkpoint.
Orientation And Checkpoints
Planning orientation is required before execution. It is complete only when the
current workspace/instructions, durable source artifacts, live-state identity,
semantic-owner and first-proof seams, material uncertainties, and execution
preconditions are recorded. Its completion basis is
owner_seam_coverage_and_material_uncertainty, never a read count, plan count,
percentage, score, or other numeric sufficiency proxy.
Execution and verification consume a durable orientation checkpoint. Refresh it immediately before every host mutation and immediately before each verifier, including helper-run oracles and manual review. A current checkpoint binds the plan id and revision, live-state identity, current unit, exact next action, proof obligation, observed owner-seam ids, checked preconditions, and persisted refresh event. Approval or prior evidence does not make a stale checkpoint current.
Canonical invalidators are exactly:
plan_identity_changecompactionhandoffmaterial_live_tree_changefailed_mutationverifier_command_invalidationowner_seam_disappearanceexecution_capability_unavailable
Use the lifecycle helper to persist and inspect orientation:
node scripts/lifecycle.mjs orientation_refresh '{"mission_id":"<id>","plan_id":"<plan-id>","plan_revision":3,"run_id":"<run-id>","plan_identity":"<plan-id>@3","live_state_identity":"git:<sha-or-tree-id>","current_unit":"<declared action>","next_action":"<declared action>","action_class":"implementation","proof_obligation_ids":["PO1"],"proof_targets":["<persisted verification target>"],"checked_preconditions":["<precondition>"],"observed_owner_seam_ids":["OS1"],"reason":"pre_mutation"}'
node scripts/lifecycle.mjs orientation_invalidate '{"checkpoint_id":"<checkpoint-id>","trigger":"plan_identity_change","reason":"plan revised from 2 to 3"}'
node scripts/lifecycle.mjs orientation_get '{"checkpoint_id":"<checkpoint-id>"}'
node scripts/lifecycle.mjs orientation_list '{"mission_id":"<id>"}'
plan_revise invalidates checkpoints bound to the prior revision. Material
revisions require fresh planning_orientation; status/wave-only revisions may
retain the current planning orientation. A
quality_review reopen invalidates every current checkpoint binding for the
affected plan using verifier_command_invalidation; also record material_live_tree_change or
owner_seam_disappearance when that is the observed cause. Reorientation must
finish before remediation mutation or another verifier runs.
Progress counts and ContextPack.freshness_ttl are telemetry only. They may
prompt an operator to inspect or refresh state, but they cannot establish
orientation sufficiency, authorize mutation, select checkpoint scope, or prove
verification completeness.
Passing roi:go evidence for a plan with actions requires admitted
mutation-class history plus verifier coverage since the latest invalidation.
Every verify_evaluate verdict requires a current checkpoint bound to the
matching verify-gate task. Public task_transition may manage nonterminal
state but cannot complete service-owned workflow stages.
All executor modes (local, agent, and a2a) require a current task-bound
implementation checkpoint before dispatch. Automatic spec and quality review
stages require their own task-bound verifier checkpoints. When roi:go
evidence names a run, its implementation and verifier checkpoints must bind
that run's concrete implement task; run-level checkpoints cannot substitute.
Two loops
| Loop | Command | What moves |
|---|---|---|
| Work | roi:go |
Product repo, tests, evidence_record (verification) |
| ROI | roi:drive |
Status read → delegate to next stage skill; pauses at gates |
roi:drive is a thin orchestrator. It does not edit code, record
evidence, or record verdicts. Those belong to the named stage skills.
evidence_record accepts run_oracles: true to have the helper run plan
verification_targets directly and stamp verified_by: mcp (legacy stamp
name; means helper-verified). Without it,
implementation_proof_trust stays agent_claimed. Strict mode
(operator says "strict" or ROI_STRICT_VERIFY=1) chains roi:go with
run_oracles: true and roi:verify with require_verified_proof: true.
Recommended pairing: roi:outline → roi:go → roi:drive (or just
roi:drive, which will invoke roi:go when implementation is owed).
Lifecycle helper contract
node scripts/lifecycle.mjs <verb> '<json-args>'
node scripts/lifecycle.mjs <verb> - # JSON via stdin (long bodies)
node scripts/lifecycle.mjs --list-verbs # canonical verb registry
Output is pretty-printed JSON of the service method's return value on
stdout. Exit 0 on success, exit 1 with a lifecycle: <verb> failed: …
message on stderr otherwise.
Verbs are snake_case (mission_create, plan_generate,
evidence_record). The helper's --list-verbs output is the canonical
surface — do not memorize the list.
Storage: .data/roi.sqlite by default; override with ROI_SQLITE_PATH.
SQLite WAL handles concurrent invocations safely.
Inline Plan Intake
ROI natively accepts inline Plan output from Codex, Copilot, Claude Code, Cursor, CE, and plain Markdown. Stage skills normalize that text before execution instead of making the operator copy steps into ROI fields by hand.
Use the non-persistent helper first:
node scripts/lifecycle.mjs plan_normalize '{"stage":"outline","text":"<inline plan text>"}'
plan_normalize returns normalized.plans in plan_generate shape plus a
brief_patch. The invoked stage decides the durable write:
roi:clarify/roi:briefrecords scope, constraints, assumptions, and success criteria throughbrief_revise.roi:outline/roi:planpassesnormalized.planstoplan_generateafter applying normal plan-quality checks.roi:go/roi:drivemust first ensure normalized plans are persisted withplan_generate; implementation still runs only from stored ROI plans and recordsroi:goevidence per plan.
Normalization preserves intent and removes host-specific UI/prose wrappers;
it does not make external Plan text authoritative over ROI gates, helper
next_actions, verification policy, or plan-quality rules.
If no explicit validation lines are detected, normalized plans carry empty
verification_targets plus requires_verification_targets: true; roi:outline
must add runnable targets before persistence.
Input dispatch (roi:go and roi:drive)
Priority order:
- Mission ID — if a mission ID is known in context, use it directly.
- Outline JSON (
roi:go) — artifact fromplan_generate; confirm viaplan_list. - Inline Plan text — run
plan_normalizewith the invoked stage, then persist via the stage-owned helper verb before continuing. - File path —
.md/.txtbrief or requirements; extract goal,mission_create+brief_revisewhen needed. - Goal string — search
mission_listfor a match first.
Agentic plan strength
Plans and briefs for multi-turn agent execution should optimize
outcome strength (invariants, property-style acceptance, falsifiable
verification_targets), not downstream prescription (line numbers, test
scripts, long file checklists).
Canonical guidance: skills/references/agentic-plan-strength.md —
applies to roi:clarify, roi:outline, roi:plan, roi:draft,
roi:verify, and CE plan bundle materialization
(fixtures/ce-plan-bundle.example.json).
Pairing: CE plan / requirements own what must remain true; ROI owns waves, verify gate, and evidence.
Source Contract Preservation
When a mission is derived from a roadmap, CE plan, doctrine, requirements
brief, or other source artifact whose acceptance bullets must survive
execution, roi:outline must preserve that source explicitly:
- Set
source_contract_refson each affected plan to the source artifact path(s). - Set
requires_source_contract_check: true. - Convert every load-bearing source requirement into either a runnable
verification_targetsentry or an explicit manual-review obligation.
For those marked plans, roi:go evidence with result: pass must include
content.implementation_proof.source_contract:
{
"source_refs": ["docs/plans/source-roadmap.md"],
"coverage": [
{
"requirement": "Inventory includes public_url and task_path fields",
"disposition": "verification_target",
"verification_target": "node scripts/check-inventory-contract.mjs"
},
{
"requirement": "Ledger names the approval artifact for scenario-deepening rows",
"disposition": "manual_review",
"evidence": "docs/audits/selector-decision-ledger.md"
}
]
}
The helper rejects a passing roi:go evidence row for marked plans when this
coverage is missing or malformed. The evidence source_refs must include every
path in the plan's source_contract_refs, and each verification_target
coverage row must exactly match one entry in the plan's verification_targets.
If a requirement cannot be covered by a plan target, use manual_review or
not_applicable with evidence or reason instead. manual_review evidence must
cite an inspectable proof artifact; local repo-relative evidence paths must
exist when the helper can resolve them. For high-stakes source-derived
missions, record independent-review metadata in source_contract.review and
pass require_independent_source_contract_review: true to verify_evaluate.
status_get.summary.source_contract_proof_confidence reports none,
structural, or independent_reviewed. The mission_go_progress status field
(not a helper verb) and roi:verify
keep the plan open until source-contract coverage exists.
Notes
- The lifecycle helper is the only persistence path. There is no MCP server.
- Verb names use underscore form:
mission_create,status_get,evidence_record, etc. - Implementation dispatch:
skills/roi-go/SKILL.md. - Lifecycle dispatch (status read → delegate; mandatory gates):
skills/roi-drive/SKILL.md. - After
roi:drivereaches terminal state, suggestroi:learn— do not callenlighten_runautomatically. - Trust honesty: lifecycle completion is not external-ship proof.
Cite git/CI/human review outside ROI when reporting product readiness.
See
docs/limitations.md.