@open-agent-toolkit/cli 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: oat-project-implement
3
- version: 2.1.3
3
+ version: 2.1.4
4
4
  description: Use when plan.md is ready for execution. Dispatches one phase implementer per phase, owns independent phase review and bounded fix routing, and supports plan-declared worktree-isolated parallel phases.
5
5
  oat_gateable: true
6
6
  argument-hint: '[--retry-limit <N>] [--dry-run]'
7
7
  disable-model-invocation: true
8
8
  user-invocable: true
9
- allowed-tools: Read, Write, Bash(git:*), Bash(oat project log:*), Glob, Grep, AskUserQuestion, Task
9
+ allowed-tools: Read, Write, Bash(git:*), Bash(oat:*), Bash(oat project log:*), Glob, Grep, AskUserQuestion, Task
10
10
  ---
11
11
 
12
12
  # Implementation Phase
@@ -204,4 +204,6 @@ Rules:
204
204
  - Implementation.md tracks all progress
205
205
  - Final verification passes
206
206
  - Final review passes (no Critical/Important findings)
207
+ - The configured implementation exit gate has an allowed and fresh disposition
208
+ before approval-aware sequencing, completion state, or success output
207
209
  - No unresolved blockers
@@ -35,7 +35,7 @@ Options:
35
35
  3. Modify plan to address blocker
36
36
  ```
37
37
 
38
- ### Step 11: Mark Implementation Complete
38
+ ### Step 11: Prepare Final Closeout Baseline
39
39
 
40
40
  When all plan tasks are complete (i.e., there is no next incomplete `pNN-tNN` task):
41
41
 
@@ -48,11 +48,11 @@ When all plan tasks are complete (i.e., there is no next incomplete `pNN-tNN` ta
48
48
  - Design deltas (if any)
49
49
  - This should reflect **what was actually implemented**, including any deviations from design and any review-fix work.
50
50
 
51
- Update frontmatter:
51
+ Keep implementation in progress while clearing the completed task pointer:
52
52
 
53
53
  ```yaml
54
54
  ---
55
- oat_status: complete
55
+ oat_status: in_progress
56
56
  oat_ready_for: null
57
57
  oat_blockers: []
58
58
  oat_last_updated: { today }
@@ -60,11 +60,13 @@ oat_current_task_id: null
60
60
  ---
61
61
  ```
62
62
 
63
- **Important:** `oat_current_task_id` should never point at an already-completed task. If all tasks are done, set it to `null` and proceed to the final review gate.
64
-
65
- ### Step 12: Update Project State
63
+ **Important:** `oat_current_task_id` should never point at an already-completed
64
+ task. If all tasks are done, set it to `null`, but do not mark implementation
65
+ complete before final verification, final review, the configured implementation
66
+ exit gate, and the approval-aware closeout sequence finish.
66
67
 
67
- Update `"$PROJECT_PATH/state.md"` so other skills reflect task completion and review gating:
68
+ Update `"$PROJECT_PATH/state.md"` so other skills reflect task completion while
69
+ closeout remains in progress:
68
70
 
69
71
  **Frontmatter updates:**
70
72
 
@@ -72,11 +74,9 @@ Update `"$PROJECT_PATH/state.md"` so other skills reflect task completion and re
72
74
  - `oat_last_commit: {final_commit_sha}`
73
75
  - `oat_blockers: []`
74
76
  - `oat_phase: implement`
75
- - `oat_phase_status: in_progress` (until final review passes)
77
+ - `oat_phase_status: in_progress` (until all closeout boundaries pass)
76
78
  - `oat_project_state_updated: "{ISO 8601 UTC timestamp}"`
77
- - **If** `"implement"` is in `oat_hill_checkpoints`: append `"implement"` to `oat_hill_completed` array
78
-
79
- **Note:** Only append to `oat_hill_completed` when the phase is configured as a HiLL gate.
79
+ - Do not append `"implement"` to `oat_hill_completed` yet.
80
80
 
81
81
  Update content:
82
82
 
@@ -95,21 +95,23 @@ Implementation - Tasks complete; awaiting final review.
95
95
  - ⧗ Awaiting final review
96
96
  ```
97
97
 
98
- **Bookkeeping commit (required):**
98
+ **Baseline bookkeeping commit (required):**
99
99
 
100
100
  **DO NOT SKIP.** This commit prevents state drift across sessions.
101
101
 
102
- After updating state.md to reflect implementation completion, refresh the repo dashboard when available and commit all modified project tracking files:
102
+ After updating state.md to reflect task completion and pending closeout, refresh
103
+ the repo dashboard when available and commit all modified project tracking
104
+ files:
103
105
 
104
106
  ```bash
105
107
  oat state refresh
106
108
  git add "$PROJECT_PATH/implementation.md" "$PROJECT_PATH/state.md" "$PROJECT_PATH/plan.md"
107
- git diff --cached --quiet || git commit -m "chore(oat): update tracking artifacts for implementation complete"
109
+ git diff --cached --quiet || git commit -m "chore(oat): prepare final implementation closeout"
108
110
  ```
109
111
 
110
112
  Do not use `git add -A` or glob patterns. Only commit the three project artifacts listed above; `.oat/state.md` is a generated, gitignored dashboard.
111
113
 
112
- ### Step 13: Final Verification
114
+ ### Step 12: Final Verification
113
115
 
114
116
  Run project-wide verification:
115
117
 
@@ -129,7 +131,7 @@ pnpm build
129
131
 
130
132
  All must pass before proceeding.
131
133
 
132
- ### Step 14: Trigger Final Review
134
+ ### Step 13: Trigger Final Review
133
135
 
134
136
  **At the final plan phase boundary, a code review is required before PR.**
135
137
 
@@ -167,7 +169,7 @@ filename and never move its status backward.
167
169
  echo "$FINAL_ROW" | grep -qE "^\\|\\s*final\\s*\\|.*\\|\\s*passed\\s*\\|" && echo "passed"
168
170
  ```
169
171
 
170
- - Continue to Step 15 (final closeout)
172
+ - Continue to Step 14 (configured implementation exit gate)
171
173
 
172
174
  **If final review is not marked `passed`:**
173
175
 
@@ -183,7 +185,7 @@ highest target-preserving route before launch, and run
183
185
 
184
186
  - If receive creates fix tasks, return through the normal bounded implement and
185
187
  re-review loop.
186
- - Continue to Step 15 only when the final Reviews row is `passed`.
188
+ - Continue to Step 14 only when the final Reviews row is `passed`.
187
189
  - A failed blocking review, unresolved Critical finding, exhausted route, or
188
190
  missing credential with no adequate fallback is an autonomy boundary. Persist
189
191
  the review state and report the exact resume action instead of falling
@@ -282,7 +284,318 @@ To run in a separate session use: oat-project-review-provide code final
282
284
  - Record the passed final review and keep the project in implementation closeout.
283
285
  - Do not append `"implement"` to `oat_hill_completed`, set
284
286
  `oat_phase_status: complete`, or offer the normal next-step prompt yet.
285
- - Continue to **Final HiLL Closeout Sequence**.
287
+ - Continue to **Gate Execution**.
288
+
289
+ ### Step 14: Gate Execution
290
+
291
+ The configured implementation exit gate is independent from the optional
292
+ `oat_phase_review_gate`, the root-owned phase reviews, and the mandatory final
293
+ lifecycle review. A missing, disabled, or unconfigured phase gate never disables
294
+ or satisfies this configured exit gate.
295
+
296
+ **Persisted transition contract:**
297
+
298
+ `"$PROJECT_PATH/state.md"` is the routing source of truth. Store one closeout
299
+ generation as a sibling of `oat_post_implement_sequence`:
300
+
301
+ ```yaml
302
+ oat_implement_exit_gate:
303
+ status: pending # pending | allowed | blocked | stale
304
+ resolution: configured # configured | no_gate
305
+ disposition: null # null | passed | warned | prompt_approved | no_gate
306
+ config_fingerprint: '<stable hash of the resolved declaration>'
307
+ resolved_command: null
308
+ resolved_description: null
309
+ on_failure: block # block | prompt | warn | null
310
+ max_attempts: 2
311
+ attempts_completed: 0
312
+ reviewed_head: null
313
+ implementation_fingerprint: null
314
+ launch_state: not_started # not_started | intent_persisted | accepted | result_persisted | not_accepted
315
+ launch_attempt_id: null
316
+ launch_started_at: null
317
+ launch_result_receipt: null
318
+ gate_run_marker: null
319
+ gate_run_id: null
320
+ envelope_status: null
321
+ artifact: null
322
+ handoff: null
323
+ receive_state: not_started # not_started | intent_persisted | completed | reconciliation_required
324
+ receive_correlation: null
325
+ receive_source_artifact: null
326
+ receive_archived_artifact: null
327
+ receive_event_identity: null
328
+ receive_pre_head: null
329
+ receive_commit: null
330
+ receive_eligible: false
331
+ receive_completed: false
332
+ failure: null
333
+ updated_at: '2026-07-18T00:00:00Z'
334
+ ```
335
+
336
+ At the start of a new closeout generation, require a current passed final
337
+ lifecycle review, capture `reviewed_head`, and compute a deterministic
338
+ `implementation_fingerprint` from the gate-reviewed basis. Resolve
339
+ `workflow.gates.skills.oat-project-implement` once. Canonically serialize the
340
+ resolved command, description, `onFailure`, and `maxAttempts` to derive
341
+ `config_fingerprint`; persist the complete resolved inputs with `status:
342
+ pending` before any gate launch. Missing state means unresolved, never no gate.
343
+ A `null` resolution persists `allowed/no_gate` with `disposition: no_gate`,
344
+ null run/artifact/receive provenance, and the current implementation basis.
345
+
346
+ An in-flight `pending` or `blocked` generation reuses its persisted resolved
347
+ configuration and never re-resolves it. Recompute the fingerprint from those
348
+ persisted inputs before resume. If the persisted resolved configuration does
349
+ not reproduce `config_fingerprint`, mark the generation `stale` and fail
350
+ closed. External configuration changes are considered only when a new
351
+ generation starts; they never rewrite an in-flight snapshot.
352
+
353
+ **Launch acceptance and reconciliation:**
354
+
355
+ The launch state advances only as `not_started` → `intent_persisted` →
356
+ `accepted` → `result_persisted`; an explicit pre-start rejection instead
357
+ records `not_accepted`. Before invoking the configured command, generate and
358
+ persist `launch_attempt_id`, `launch_started_at`, and
359
+ `launch_result_receipt` before invoking the command. The receipt is a
360
+ closeout-owned path selected before launch; capture the command's stdout there
361
+ without changing its configured argv.
362
+
363
+ For `oat --json gate review`, the gate CLI run marker is acceptance evidence
364
+ established before its reviewer child launch. Observe the marker that uniquely
365
+ matches the normalized project and starts no earlier than
366
+ `launch_started_at`; persist its path as `gate_run_marker`, its run ID as
367
+ `gate_run_id`, and `launch_state: accepted`. More than one matching marker is
368
+ ambiguous and blocks reconciliation.
369
+
370
+ On resume from `intent_persisted` or `accepted`, reconcile the exact
371
+ `gate_run_marker`, durable result receipt, and run-correlated active or archived
372
+ artifact before deciding the next transition:
373
+
374
+ - A still-present matching marker proves an accepted run may be active. Preserve
375
+ `accepted`, wait for that run, and never launch a replacement.
376
+ - A complete result receipt must parse as exactly one structured envelope whose
377
+ run ID matches the marker and artifact. Persist its envelope fields and
378
+ `launch_state: result_persisted` before receive or policy handling.
379
+ - A matching artifact without its result receipt proves acceptance but not the
380
+ terminal outcome. Persist
381
+ `blocked/launch_result_reconciliation_required`; do not infer `ok` or
382
+ `blocked` from findings or exit status.
383
+ - Relaunch only after durable `not_accepted` evidence proves that no gate
384
+ process or reviewer child was accepted. This requires an explicit pre-start
385
+ launcher rejection plus absence of a matching marker, result receipt, and
386
+ active or archived artifact.
387
+ - Absent or ambiguous evidence persists
388
+ `blocked/launch_reconciliation_required` and never relaunches automatically.
389
+ Surface the persisted attempt ID, marker/receipt paths, and exact recovery
390
+ action so a human can reconcile or explicitly retire that attempt.
391
+
392
+ Persist and commit every state transition before crossing its launch, receive,
393
+ stop, approval-aware sequence, completion, or output boundary. Append a concise
394
+ audit event to `implementation.md`; that prose and review ledger rows are
395
+ evidence, not routing state.
396
+
397
+ **Structured outcomes, receive, and policy:**
398
+
399
+ - Accept only a complete structured envelope whose status and correlation
400
+ fields are internally consistent. Receive is eligible only for `ok` or
401
+ `blocked` with `receiveEligible: true` and a corroborated non-null `handoff`.
402
+ Ineligible, null, or contradictory handoffs, unknown statuses,
403
+ `review_failed`, `artifact_validation_failed`, and
404
+ `targeting_correlation_failed` persist `blocked`, remain outside receive, and
405
+ cannot produce an allowed disposition. They ignore `on_failure`, including
406
+ `warn`; policy handling is unavailable without a validated, receive-eligible
407
+ `blocked` envelope whose eligible receive completed durably.
408
+ - Manual review provenance is rejected: only `oat_review_invocation: gate` with
409
+ the matching `oat_gate_run_id` may satisfy the configured gate. A normal
410
+ final review, phase review, or manually produced independent-review artifact
411
+ cannot populate configured-gate provenance.
412
+
413
+ **Receive intent and reconciliation:**
414
+
415
+ The receive state advances only as `not_started` → `intent_persisted` →
416
+ `completed` or `reconciliation_required`. For a receive-eligible `ok` or
417
+ `blocked` envelope, first resolve the receiver's collision-safe archive
418
+ destination. Then persist the receive correlation, source and expected archived
419
+ artifact paths, exact Reviews event identity, and `receive_pre_head` before
420
+ invoking receive. `receive_correlation` binds the gate run ID, handoff, source
421
+ artifact, scope, type, and source filename; set `receive_state:
422
+ intent_persisted` and commit it before calling `oat-project-review-receive`.
423
+
424
+ On normal return or resume from `intent_persisted`, reconcile all three durable
425
+ receipt components:
426
+
427
+ 1. the exact archived artifact at `receive_archived_artifact`, carrying the
428
+ matching `oat_gate_run_id`;
429
+ 2. the bound Reviews event identified by Scope + Type + original source
430
+ filename, with its artifact set to that archived path and a monotonic
431
+ received/fix/passed status; and
432
+ 3. the receive bookkeeping commit after `receive_pre_head`, whose bounded diff
433
+ contains that archive move and the matching project tracking updates.
434
+
435
+ When the exact archived artifact, the bound Reviews event, and the receive
436
+ bookkeeping commit all corroborate the persisted correlation, store that commit
437
+ as `receive_commit`, set `receive_state: completed`, and set
438
+ `receive_completed: true` from that corroborated durable receipt without
439
+ invoking receive again. An already-completed receive is idempotent and must not
440
+ run again.
441
+
442
+ If any component is missing, contradictory, or cannot be uniquely correlated,
443
+ persist `blocked/receive_reconciliation_required` and stop with the recovery
444
+ command `oat-project-review-receive`; do not invoke it automatically. Surface
445
+ the expected source/archive paths, event identity, pre-receive HEAD, and
446
+ candidate commit so a human can repair or confirm the durable receipt before
447
+ resume. A receive failure persists `blocked` and cannot become an allowed
448
+ disposition.
449
+
450
+ - After successful receive, `ok` persists `allowed/passed`. Apply the persisted
451
+ `on_failure` policy only to a validated, receive-eligible `blocked` envelope
452
+ after its eligible receive is durably completed.
453
+ - `block` outcomes consume remediation attempts only after a valid configured
454
+ gate result and its eligible receive disposition are durably processed.
455
+ Increment `attempts_completed` before remediation/rerun. Below
456
+ `maxAttempts`, remediate, mark the changed implementation basis `stale`, rerun
457
+ Steps 12-13 for that basis, and return to `pending` with updated
458
+ `reviewed_head` and `implementation_fingerprint` while preserving the
459
+ persisted configuration and consumed attempt count. At `maxAttempts`,
460
+ persist `blocked` and stop without another gate launch.
461
+ - Launch failures, missing CLIs, unavailable runtimes, and transport failures
462
+ do not increment `attempts_completed`. Persist failure context and
463
+ `status: blocked`, then stop or escalate without treating infrastructure
464
+ recovery as a remediation attempt or applying `on_failure`.
465
+ - Envelope validation/correlation failures and receive failures likewise remain
466
+ `blocked` regardless of `on_failure`; they cannot persist `allowed/warned`,
467
+ `allowed/prompt_approved`, or any other allowed disposition.
468
+ - An explicit prompt continuation persists `allowed/prompt_approved`; defer or
469
+ no response persists `blocked` and stops. A warn continuation persists
470
+ `allowed/warned` before closeout proceeds.
471
+
472
+ **Interruption, resume, and freshness:**
473
+
474
+ - Resume `pending` or `blocked` from the persisted transition without replacing
475
+ its generation. Continue from the first incomplete launch, envelope, receive,
476
+ policy, or persistence boundary.
477
+ - A fresh `allowed` result resumes after the gate without executing the gate or
478
+ receive a second time. Reuse requires a valid disposition, complete
479
+ configured-gate provenance when configured, an unchanged implementation
480
+ fingerprint, and any eligible receive marked complete.
481
+ - Closeout-only descendants include configured gate artifacts and receipts,
482
+ project tracking, `project-log.md` appends, summary/documentation/PR sequence
483
+ outputs, final HiLL bookkeeping, and completion bookkeeping. Classify
484
+ gate-owned `oat project log append` mutations introduced with PR #156 as
485
+ closeout-only; they do not invalidate the reviewed implementation basis.
486
+ - Determine freshness from every path changed after `reviewed_head`, and require
487
+ each descendant commit to contain only recognized closeout work. An unknown
488
+ changed path fails closed as substantive implementation change.
489
+ Implementation, test, skill, template, or workflow configuration changes
490
+ make the prior result `stale`. Preserve its provenance for audit, require a
491
+ current final lifecycle review for the new basis, and start a new generation.
492
+
493
+ Before approval-aware sequencing, final HiLL approval, implementation
494
+ completion, or success output, run the configured gate:
495
+
496
+ 1. Classify persisted state. A fresh allowed generation proceeds to Step 15
497
+ without duplicate gate or receive execution. A valid `pending` or `blocked`
498
+ generation resumes its first incomplete boundary with its persisted
499
+ configuration. For absent or stale state, start a new generation and resolve
500
+ the gate for this skill:
501
+
502
+ ```bash
503
+ oat gate resolve oat-project-implement --json
504
+ ```
505
+
506
+ Persist the resolution and configuration fingerprint before launch. If the
507
+ command returns JSON `null`, persist the allowed no-gate transition; no gate
508
+ is configured; proceed directly to the completion steps in Step 15 below.
509
+
510
+ 2. Export the resolved project path into the command shell:
511
+
512
+ ```bash
513
+ export PROJECT_PATH
514
+ ```
515
+
516
+ If the resolved command invokes review, parse its argv before launch and
517
+ require the canonical global-JSON shape
518
+ `oat --json gate review --project "$PROJECT_PATH" ...`. The configured review
519
+ command must place the global `--json` before `gate review`, must already
520
+ include `--project "$PROJECT_PATH"`, and must not include `--target <id>`. Reject
521
+ `oat gate review ...` without the global `--json` flag before launch because
522
+ it emits human-oriented output rather than the structured envelope. For any
523
+ invalid shape, stop and require the user to migrate the stored declaration
524
+ before execution; never rewrite user or local configuration during closeout,
525
+ and never inject, reorder, or append arguments at execution time.
526
+
527
+ 3. If launch reconciliation does not already prove an accepted or completed
528
+ attempt, persist the launch intent and preselected result receipt, then
529
+ execute the resolved command exactly as configured. Capture stdout directly
530
+ into that durable receipt while separately retaining stderr and the exit
531
+ code; the capture wrapper must not alter the configured command argv.
532
+ Observe and persist the gate run marker before treating the reviewer child as
533
+ accepted. A zero exit code means the review passed its threshold, but it does
534
+ not by itself authorize artifact receipt or complete the handoff. Validate
535
+ the receipt as one structured envelope, then persist the run ID, envelope
536
+ status, artifact, eligibility, handoff correlation, failure details, and
537
+ `launch_state: result_persisted` before receive or policy handling.
538
+
539
+ 4. Review-artifact handoff:
540
+ - Parse the structured gate result. An exit code or artifact path alone never
541
+ authorizes `oat-project-review-receive`.
542
+ - Invoke receive only when all three conditions hold: `status` is `ok` or
543
+ `blocked`, the envelope explicitly sets `receiveEligible: true`, and a
544
+ non-null `handoff` confirms the artifact was corroborated.
545
+ - `receiveEligible: false` is a hard stop even when `artifactPath` is present.
546
+ Never receive `targeting_correlation_failed`; correct the project/run
547
+ routing and run a new gate.
548
+ - Keep `artifact_validation_failed` outside receive until the artifact is
549
+ corrected and the gate successfully revalidates it. Treat `review_failed`,
550
+ unknown statuses, null handoffs, and contradictory eligibility fields as
551
+ operational failures.
552
+ - `blocked` exits nonzero but is receive-eligible; `ok` exits zero and still
553
+ requires durable receive disposition. Route by structured status and
554
+ eligibility, not by exit code.
555
+ - After eligible receive succeeds, persist `receive_completed: true` before
556
+ applying the terminal disposition. Never invoke receive again for that
557
+ persisted run.
558
+
559
+ 5. Do not route policy from a generic nonzero exit. Apply persisted
560
+ `on_failure` and `max_attempts` only after Step 4 validates a
561
+ receive-eligible `blocked` envelope and its eligible receive is durably
562
+ completed. Use `description` to orient these validated blocking-finding
563
+ outcomes:
564
+ - `block`: read gate feedback, remediate, and re-run the gate up to
565
+ `maxAttempts` attempts (default `2`). Persist each consumed remediation
566
+ attempt. If the gate ends in `block` after attempts are exhausted,
567
+ escalate to the human with accumulated feedback and append that feedback
568
+ to `implementation.md`.
569
+ - `prompt`: persist the blocked boundary, surface the gate failure, and ask
570
+ the human how to proceed. Continue only after an explicit persisted
571
+ approval.
572
+ - `warn`: persist the warned allowance and failure details before continuing.
573
+
574
+ Any nonzero result without that validated and durably received `blocked`
575
+ envelope remains blocked and skips all three policies. In particular,
576
+ `warn` plus `review_failed` remains `blocked`, and `warn` plus an invalid,
577
+ malformed, or contradictory envelope remains `blocked`. Launch failures,
578
+ missing CLIs, unavailable runtimes, transport failures, validation or
579
+ correlation failures, and receive failures cannot continue to sequencing,
580
+ final HiLL, completion, or success output regardless of `on_failure`.
581
+
582
+ When the gate ends in `block` after attempts are exhausted or remains at an
583
+ unresolved `prompt` boundary, the completion steps below MUST NOT run. The
584
+ project stays `in_progress` and resumable through `oat-project-implement`.
585
+
586
+ 6. Runtime selection note: the step runs the gate `command` as-is and reads no
587
+ OAT runtime env var. By default, `oat gate review` avoids the resolved
588
+ producer family. Exact review scopes use a claimable producer identity from
589
+ the matching dispatch stamp. Final/range reviews aggregate in-scope
590
+ implementer/fix stamps; when a stamp's producer is not claimable or has an
591
+ unknown family, its launcher-owned configured target may contribute a
592
+ lower-confidence family exclusion without becoming runtime identity. If no
593
+ claimable family remains, selection degrades to same-runtime avoidance.
594
+ Reusable lifecycle skill-gate commands must not include `--target <id>` so
595
+ independent review stays provider-neutral. Use explicit targets only for
596
+ manual/debug commands or deliberate local/user-specific overrides; do not
597
+ hardcode provider/model targets in bundled skill guidance or shared
598
+ lifecycle gate examples.
286
599
 
287
600
  ### Step 15: Final HiLL Closeout Sequence
288
601
 
@@ -291,12 +604,19 @@ and root-owned phase review have finished. Do not move lifecycle sequencing
291
604
  into phase or optional nested workers or weaken exact target selection for
292
605
  child dispatches.
293
606
 
607
+ Before creating or resuming `oat_post_implement_sequence`, and again before
608
+ every dispatch, final HiLL transition, completion mutation, and success output,
609
+ require `oat_implement_exit_gate` to remain allowed and fresh. If it becomes
610
+ stale, malformed, pending, or blocked, persist/retain that state, stop the
611
+ sequence, and resume through `oat-project-implement`.
612
+
294
613
  Identify the final implementation phase from the plan. A final HiLL checkpoint
295
614
  exists when `oat_plan_hill_phases` is `[]` (every phase) or when it explicitly
296
615
  contains that final phase ID. Defer only a checkpoint on the final implementation
297
616
  phase; non-final checkpoint behavior remains unchanged.
298
617
 
299
- Run final verification (Step 13). Final review must be `passed` before any
618
+ Run final verification (Step 12). Final review must be `passed` and the
619
+ configured implementation exit gate in Step 14 must be allowed before any
300
620
  pre-approval dispatch. If final checkpoint auto-review is enabled, Step 8 has
301
621
  already run `oat-project-review-provide code final`; do not run a duplicate
302
622
  final review here.
@@ -407,7 +727,52 @@ snapshot. Retain the existing next-step prompt only after final approval when a
407
727
  final checkpoint is configured. Under autonomy, the default snapshot above
408
728
  always resolves the unset case.
409
729
 
410
- ### Step 16: Prompt for Next Steps
730
+ ### Step 16: Mark Implementation Complete
731
+
732
+ Run this step only after the configured gate passes or resolves to a
733
+ policy-allowed disposition, including an allowed no-gate outcome, and the Step
734
+ 15 closeout sequence has reached its terminal allowed state. A configured gate
735
+ that is blocked, unresolved, malformed, or stale leaves implementation in
736
+ progress.
737
+
738
+ Update `"$PROJECT_PATH/implementation.md"` frontmatter:
739
+
740
+ ```yaml
741
+ ---
742
+ oat_status: complete
743
+ oat_ready_for: null
744
+ oat_blockers: []
745
+ oat_last_updated: { today }
746
+ oat_current_task_id: null
747
+ ---
748
+ ```
749
+
750
+ Update `"$PROJECT_PATH/state.md"`:
751
+
752
+ - `oat_current_task: null`
753
+ - `oat_last_commit: {final_commit_sha}`
754
+ - `oat_blockers: []`
755
+ - `oat_phase: implement`
756
+ - `oat_phase_status: complete`
757
+ - `oat_project_state_updated: "{ISO 8601 UTC timestamp}"`
758
+ - If `"implement"` is in `oat_hill_checkpoints`, append `"implement"` to
759
+ `oat_hill_completed`; otherwise leave it unchanged.
760
+
761
+ Update the current phase and progress content to record that implementation,
762
+ final review, the configured exit gate, and closeout sequencing are complete.
763
+ Then refresh the dashboard and create the required completion bookkeeping
764
+ commit:
765
+
766
+ ```bash
767
+ oat state refresh
768
+ git add "$PROJECT_PATH/implementation.md" "$PROJECT_PATH/state.md" "$PROJECT_PATH/plan.md"
769
+ git diff --cached --quiet || git commit -m "chore(oat): mark implementation complete"
770
+ ```
771
+
772
+ Do not use `git add -A` or glob patterns. Only commit the three project
773
+ artifacts listed above; `.oat/state.md` is a generated, gitignored dashboard.
774
+
775
+ ### Step 17: Prompt for Next Steps
411
776
 
412
777
  Run the standard next-step prompt only when `OAT_AUTONOMOUS` is not `1`,
413
778
  `workflow.postImplementSequence` was unset, and no sequence snapshot was
@@ -449,7 +814,7 @@ Do not route directly to `oat-project-complete`. The `pr_open` status set by pr-
449
814
 
450
815
  Tell user: "Run the skills individually when ready: oat-project-summary → oat-project-document → oat-project-pr-final"
451
816
 
452
- ### Step 17: Output Summary
817
+ ### Step 18: Output Summary
453
818
 
454
819
  ```
455
820
  Implementation complete for {project-name}.
@@ -471,39 +836,3 @@ Final review:
471
836
 
472
837
  Next: Create PR or run the oat-project-pr-final skill (when available)
473
838
  ```
474
-
475
- ### Gate Execution
476
-
477
- Before reporting this skill as complete, run the configured gate as the final step:
478
-
479
- 1. Resolve the gate for this skill:
480
-
481
- ```bash
482
- oat gate resolve <this-skill> --json
483
- ```
484
-
485
- If the command returns JSON `null`, no gate is configured; the skill is complete.
486
-
487
- 2. Export the resolved project path into the command shell:
488
-
489
- ```bash
490
- export PROJECT_PATH
491
- ```
492
-
493
- If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"` and must not include `--target <id>`. A valid reusable shape is `oat gate review --project "$PROJECT_PATH" ...`. If the declaration is missing, stop and migrate the stored gate command; do not inject or append arguments at execution time.
494
-
495
- 3. Execute the resolved command exactly as configured. Capture stdout, stderr, the exit code, and the structured JSON result. A zero exit code means the review passed its threshold, but it does not by itself authorize artifact receipt or complete the handoff.
496
-
497
- 4. Review-artifact handoff:
498
- - Parse the structured gate result. An exit code or artifact path alone never authorizes `oat-project-review-receive`.
499
- - Invoke receive only when all three conditions hold: `status` is `ok` or `blocked`, the envelope explicitly sets `receiveEligible: true`, and a non-null `handoff` confirms the artifact was corroborated.
500
- - `receiveEligible: false` is a hard stop even when `artifactPath` is present. Never receive `targeting_correlation_failed`; correct the project/run routing and run a new gate.
501
- - Keep `artifact_validation_failed` outside receive until the artifact is corrected and the gate successfully revalidates it. Treat `review_failed`, unknown statuses, null handoffs, and contradictory eligibility fields as operational failures.
502
- - `blocked` exits nonzero but is receive-eligible; `ok` exits zero and still requires durable receive disposition. Route by structured status and eligibility, not by exit code.
503
-
504
- 5. If the command exits nonzero, use `description` to orient the next steps and handle `onFailure`:
505
- - `block`: read gate feedback, remediate, and re-run the gate up to `maxAttempts` attempts (default `2`). If attempts are exhausted, escalate to the human with accumulated feedback and append that feedback to `implementation.md`. Treat a launch failure, missing CLI, or no eligible runtime as escalation-biased and do not spend it as a remediation attempt.
506
- - `prompt`: surface the gate failure and ask the human how to proceed.
507
- - `warn`: record the gate failure and continue.
508
-
509
- 6. Runtime selection note: the step runs the gate `command` as-is and reads no OAT runtime env var. By default, `oat gate review` avoids the resolved producer family. Exact review scopes use a claimable producer identity from the matching dispatch stamp. Final/range reviews aggregate in-scope implementer/fix stamps; when a stamp's producer is not claimable or has an unknown family, its launcher-owned configured target may contribute a lower-confidence family exclusion without becoming runtime identity. If no claimable family remains, selection degrades to same-runtime avoidance. Reusable lifecycle skill-gate commands must not include `--target <id>` so independent review stays provider-neutral. Use explicit targets only for manual/debug commands or deliberate local/user-specific overrides; do not hardcode provider/model targets in bundled skill guidance or shared lifecycle gate examples.