| name | oat-project-import-plan |
| version | 1.3.3 |
| description | Use when you have an external markdown plan to execute with OAT. Preserves the source plan and normalizes it into canonical plan.md format. |
| argument-hint | <path-to-plan.md> [--provider codex|cursor|claude] [--project <name>] |
| disable-model-invocation | true |
| user-invocable | true |
| allowed-tools | Read, Write, Bash, Glob, Grep, AskUserQuestion |
Import External Plan
Import a markdown plan from an external coding provider and normalize it into OAT project artifacts.
Prerequisites
- External plan exists as a local markdown file.
- OAT repository scaffolding is available.
Mode Assertion
OAT MODE: Plan Import
Purpose: Preserve the original plan and generate a runnable canonical plan.md for OAT execution.
BLOCKED Activities:
- No destructive edits to the imported source file.
- No implementation code changes.
ALLOWED Activities:
- Creating/updating project artifacts.
- Plan normalization into OAT task structure.
- Updating project state metadata for import mode.
Self-Correction Protocol:
If you catch yourself:
- Mutating source plan content in-place → STOP; copy source first.
- Producing prose-only plan without runnable tasks → STOP and normalize to
pNN-tNN tasks.
Recovery:
- Preserve source in
references/imported-plan.md.
- Regenerate canonical
plan.md in OAT structure.
Progress Indicators (User-Facing)
When executing this skill, provide lightweight progress feedback so the user can tell what’s happening after they confirm.
-
Print a phase banner once at start using horizontal separators, e.g.:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OAT ▸ IMPORT PLAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
Before multi-step work, print step indicators, e.g.:
[0/7] Checking inherited git state...
[1/7] Resolving project + source plan…
[2/7] Preserving imported source…
[3/7] Normalizing plan to OAT task structure…
[4/7] Updating plan metadata…
[5/7] Running import-aware plan review…
[6/7] Updating project state + dashboard…
[7/7] Ensuring implementation tracker…
Process
Step 0 (Preflight): Inherited Git State
Before scaffolding, surface the working tree state so unrelated changes don't get carried into the project workflow's bookkeeping commits.
- Run
git status --porcelain. If empty, continue silently to the next step.
- If non-empty, present the dirty list to the user.
- If
.oat/sync/manifest.json or paths under .claude/, .cursor/, .codex/ appear in the list, note: "These are generated by oat sync (often by pnpm run worktree:init or oat-worktree-bootstrap-auto) and are typically safe to commit as chore: run sync."
- Offer three choices via
AskUserQuestion:
- Commit now (recommended when only sync output is dirty) — stage and commit. For sync-only diffs, default the message to
chore: run sync; otherwise ask the user for the commit message.
- Proceed anyway — start the project workflow with the dirty state acknowledged.
- Abort — exit the skill so the user can clean up manually.
Tool availability is not the same as interactivity. If AskUserQuestion is unavailable but chat is available, present the three choices as a plain chat message and wait for the user's reply. Only fall back to "Proceed anyway" when OAT_NON_INTERACTIVE=1 is set or there is no user-response channel at all.
Do not advance past this gate without an explicit choice.
Step 0.5: Resolve Active Project
PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo ".oat/projects/shared")}"
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
If no valid active project exists:
Step 1: Resolve and Validate Source Plan Path
Inputs:
- source path from
$ARGUMENTS
- optional provider hint from
--provider
If source path is not provided, discover likely recent plans first. The discovery script checks both provider plan directories and this repository's external plan directory by default:
.oat/repo/reference/external-plans/
bash .agents/skills/oat-project-import-plan/scripts/find-recent-provider-plans.sh --hours 24
Optional: extend discovery roots via OAT_PROVIDER_PLAN_DIRS (colon-separated):
export OAT_PROVIDER_PLAN_DIRS="$HOME/custom-plans:$HOME/tmp/provider-plans"
Then ask user to either:
- choose one of the listed files (by number), or
- provide a manual file path.
Validation rules:
- File must exist.
- File extension must be
.md (or user explicitly confirms nonstandard markdown extension).
- File must contain non-empty content.
Step 2: Preserve Imported Source
Create references directory if missing:
mkdir -p "$PROJECT_PATH/references"
cp "{source-path}" "$PROJECT_PATH/references/imported-plan.md"
Never overwrite an existing source snapshot without user confirmation.
If already present, write timestamped copy:
references/imported-plan-YYYY-MM-DD-HHMM.md
Step 3: Normalize Into Canonical OAT plan.md
Create/update "$PROJECT_PATH/plan.md" using .oat/templates/plan.md and map imported content into the canonical structure. Apply oat-project-plan-writing invariants after mapping:
## Phase N
### Task pNN-tNN (stable task IDs)
- Step structure (RED/GREEN/Refactor/Verify/Commit)
- Required sections:
## Reviews, ## Implementation Complete, ## References
- Review table preservation rules (never delete existing rows)
Normalization rules:
- Preserve original intent and ordering from source.
- Generate stable task IDs per
oat-project-plan-writing format (pNN-tNN).
- Where source lacks test/verify details, add explicit TODO-style placeholders with clear expected output.
- Keep tasks executable and atomic.
Dispatch Profile import handling:
- Preserve recognizable OAT-format
## Dispatch Profile rows as user-authored constraints or preferences.
- Treat foreign model or effort hints as dispatch constraints only when the source clearly presents them as explicit requirements or preferences.
- Otherwise preserve model or effort hints as rationale/context in the relevant task or phase text and let runtime selection decide.
- Do not generate Dispatch Profile recommendation rows during import.
Step 4: Update Plan Metadata
Set frontmatter in "$PROJECT_PATH/plan.md":
oat_status: complete
oat_ready_for: null (Step 4.5 sets this after the import-aware plan review)
oat_phase: plan
oat_phase_status: complete
oat_plan_source: imported
oat_import_reference: references/imported-plan.md
oat_import_source_path: {source-path}
oat_import_provider: {codex|cursor|claude|null}
Step 4.5: Run Import-Aware Plan Artifact Review Loop
Invoke the shared Auto Artifact-Review Loop from oat-project-plan-writing with target plan before advancing project state or handing off to implementation.
Required payload:
target: plan
type: artifact
scope: plan
artifact_path: "$PROJECT_PATH/plan.md"
oat_output_mode: structured
import_aware: true
review_note: "Review for canonical OAT plan conformance, executable completeness, stable task IDs, required sections, review-row preservation, and verification clarity. Preserve the imported source's intent and ordering; do not rewrite the author's plan goals or product decisions unless required for OAT conformance or completeness."
Apply the shared loop exactly:
- Resolve
workflow.autoArtifactReview.plan; only an explicit false skips the loop.
- Resolve
oat_orchestration_retry_limit from project state, defaulting to 2.
- Dispatch
oat-reviewer in structured mode using Tier 1 subagent when available and Tier 2 inline fallback otherwise.
- Apply Critical and Important artifact-local fixes when unambiguous and limited to canonical conformance/completeness; offer Medium and Minor fixes instead of silently applying them.
- Re-dispatch after rewrites until clean or the retry bound is exhausted.
- Update the
plan artifact row in the ## Reviews table to passed when clean. If residual findings remain, preserve the row and surface the residual findings before downstream handoff.
After the loop completes or is explicitly skipped, set "$PROJECT_PATH/plan.md" frontmatter:
oat_ready_for: oat-project-implement
Step 5: Update Project State
Set "$PROJECT_PATH/state.md" frontmatter:
oat_workflow_mode: import
oat_workflow_origin: imported
oat_phase: plan
oat_phase_status: complete
oat_current_task: null
oat_project_state_updated: "{ISO 8601 UTC timestamp, e.g. 2026-03-10T14:30:00Z}"
Step 5.5: Ensure Active Project Pointer
Import mode must leave the imported project as active for immediate execution.
Validate target project before writing pointer:
if [[ ! -f "$PROJECT_PATH/state.md" ]]; then
echo "Error: Project missing state.md: $PROJECT_PATH/state.md" >&2
exit 1
fi
oat config set activeProject "$PROJECT_PATH"
oat state refresh
If activeProject in local config already exists with a different path, treat this as a project switch and note it in output.
Step 6: Ensure Implementation Artifact Exists
If missing, scaffold from template:
.oat/templates/implementation.md → "$PROJECT_PATH/implementation.md"
Initialize pointer to first plan task ID.
Step 7: Output Next Action
Report:
- source imported path
- normalized phases/tasks count
- Dispatch Profile handling: preserved/mapped/omitted; foreign hints kept as rationale when not explicit constraints
- first task ID
- active project pointer path
- dashboard refresh status
- next options:
oat-project-implement (sequential by default; parallel when oat_plan_parallel_groups is declared)
Success Criteria
- ✅ Imported markdown preserved at
references/imported-plan.md.
- ✅ Canonical
plan.md generated with OAT task structure.
- ✅
plan.md metadata marks oat_plan_source: imported.
- ✅
plan.md records the import-aware plan artifact review row unless workflow.autoArtifactReview.plan was explicitly disabled.
- ✅
state.md marks oat_workflow_mode: import.
- ✅
implementation.md is present and resumable.
- ✅
oat_plan_hill_phases left unset in frontmatter (deferred to oat-project-implement Step 2.5).
- ✅
## Planning Checklist items left unchecked (HiLL configuration deferred to implementation).
- ✅
activeProject in .oat/config.local.json points to the imported project.
- ✅
.oat/state.md has been refreshed locally after pointer update; it is not staged or committed.