Model any long task as anordered contract chain, letting the AI execute small contracts within a small window and immediately write back to external state upon completion, thereby working stably and continuously for 5+ hours and resuming losslessly after context compression or session switching.
Reference full methodology:ai-long-running-workflow-methodology.md
When to Use
Applicable:
- Medium-to-large new products from 0 to 1 (5+ independently deliverable phases)
- Framework/SDK migration, major version upgrades (Vue2→3, Java8→21, etc.)
- Architecture replacement / large-scale refactoring / module-level rewrite
- Long-form document engineering (technical books, series reports, course lecture notes)
- Compliance remediation / security hardening (SOC2, MLPS, ISO 27001)
- Data governance / schema rebuild / long-chain ETL rewrite
Do not use:
- Single bug fix or one-off small task (too heavy)
- Exploratory research (no predefinable phase)
- Phases where requirements are highly unstable and phases will be frequently rewritten (wait for requirements to stabilize first)
Prerequisites (must be satisfied)
The following prerequisitesif not satisfied, this Skill generates no files, and must first be handled by the user:
- The target project root directory must be a git workspace. That is, in that directory
git rev-parse --is-inside-work-treemust returntrue(worktree / submodule / a non-ignored subdirectory under a parent repository are all considered valid git workspaces).- Phase-Contract relies on git for phase-level path whitelist comparison, rollback, and handoff verification. In a non-git directory,
execution/*'s "allowed changes/forbidden changes" cannot be objectively verified, the Quality Gate will be left dangling,completeand the state written back cannot correspond to any auditable diff. - Fix:
cd <target> && git init && git add -A && git commit -m 'baseline', or move the project into an existing git repository and retry.
- Phase-Contract relies on git for phase-level path whitelist comparison, rollback, and handoff verification. In a non-git directory,
- Locally available
rubyis available, version ≥ 2.6 (ruby -vverification). planctl is a single-file Ruby script and does not depend on gems. macOS 14+ / mainstream Linux distributions satisfy this by default; Windows users are recommended to use it within WSL. If Ruby is missing, the user must install it first; this Skill is not responsible for installing it on their behalf. - Explicit opt-out (not recommended): only when the project has a genuine reason not to use git (e.g., a temporary sandbox, fully managed by another VCS) may the environment variable be set before invoking this Skill
PHASE_CONTRACT_ALLOW_NON_GIT=1, and in the subsequently generatedplan/common.md, clearly record this deviation and compensating measures in a risk section (how to perform phase-level rollback, how to audit the scope of changes). The default path must not use opt-out.
What It Produces
Running this skill will create a complete Phase-Contract artifact set in the target project:
<project>/
├── plan/
│ ├── manifest.yaml # 流程清单(phase 顺序 + depends_on + required_context)
│ ├── common.md # 全局硬约束(所有 phase 必带)
│ ├── workflow.md # 流程说明
│ ├── state.yaml # 执行账本(脚本写入)
│ ├── handoff.md # 压缩恢复锚点(脚本写入)
│ ├── phases/
│ │ └── phase-0-<name>.md # 定位合同模板
│ └── execution/
│ └── phase-0-<name>.md # 执行合同模板
├── scripts/
│ └── planctl # 调度脚本(Ruby,可直接执行)
├── AGENTS.md # Agent 强制层(唯一真源)
└── CLAUDE.md -> AGENTS.md # Claude Code 强制层(符号链接)
Core Principles (must not be violated)
| # | Principle | Concrete action |
|---|---|---|
| P1 | State externalization | Write progress to state.yaml, not to AI memory |
| P2 | Separation of scheduling and execution | The script decides what to do, the AI decides how to do it |
| P3 | Three-file context law | The working window only loads common + phase + execution three documents |
| P4 | Two-layer contract | phases/* says "what it is",execution/* says "what can be touched" |
| P5 | Mandatory dependency verification | depends_on + --strict Blocking skip |
| P6 | Write upon completion | complete Atomic write-back state.yaml and handoff.md, without either one, do not proceed to the next round |
| P7 | Fixed recovery protocol | After compression, always three steps: manifest → handoff → next |
| P8 | Milestone externalization | complete Automatic git add/commit/push; when a remote exists, form a remote record; when no remote exists, retain a local rollback-capable milestone |
| P9 | Explicit overall wrap-up | After all phases are complete, you must run planctl finalize; the first successful execution writes finalized_at, refreshes handoff, automatically wraps up git, and then returns the final dashboard and decision-making authority to the human |
| P10 | Integrity before progress | complete Run contract lint, required checks, and path gate first; if any required gate fails,state.yaml does not advance |
Procedure
Step 0: Environment prerequisite check (blocking gate)
Before collecting any input or generating any file, first verify Prerequisites:
-
Execute in the target project root directory:
git -C <target> rev-parse --is-inside-work-tree。 -
If it returns
true→ continue to Step 1. -
If it returns non-zero or
false:-
immediately stop the scaffolding process,do notcreate
plan/、scripts/planctl, or any agent enforcement layer files. -
Output standard guidance to the user (output verbatim, do not soften):
Detected that
<target>is not a git workspace. Phase-Contract Workflow relies on git for phase-level whitelist comparison, rollback, and handoff verification; lacking git will make everycompleteafter phase-0 impossible to objectively verify.Please first execute:
cd <target> git init git add -A git commit -m 'baseline'Then call this Skill again. If the project truly needs to not use git, please export
PHASE_CONTRACT_ALLOW_NON_GIT=1before calling and be prepared to record risks and compensating measures inplan/common.md. -
Wait for the user's decision before re-entering Step 1; do not offer compromises such as "then let me skip this step first".
-
-
If
PHASE_CONTRACT_ALLOW_NON_GIT=1is explicitly set, skipping this gate is allowed, but when generatingplan/common.mdin the subsequent Step 2, you must forcibly write a "non-git workspace deviation" risk section (a numbered standalone section), explicitly listing: the reason for deviation, the manual rollback plan, and the change audit method.
Step 1: Collect input
If the user has not specified, use the ask-questions tool to collect item by item:
- Project root directory path(absolute path)
- One-sentence project positioning(written into common.md and manifest)
- Primary splitting dimension: by module / by layer / by chapter / by control item / by migration wave (must choose one, cannot mix)
- Initial phase list: phase id + one-sentence title + depends_on (5–12 is appropriate)
- Global hard constraints: tech stack versions, dependency no-go zones, quality baseline, non-goals (5–10 items, sharp enough is sufficient)
A phase for which you cannot write an objective completion determination, Runtime Evidence, or Failure Modes is split incorrectly; require the user to change the split on the spot.
Step 2: Generate skeleton files
According to the template in templates/ , simultaneously produce:
plan/manifest.yaml:withcompression_control、execution_rule、required_context、allowed_pathsandchecks.required/optional;new projects default toexecution_rule.require_phase_checks: trueandexecution_rule.enforce_allowed_paths: trueplan/common.md:write the hard constraints of Step 1 item 5 into the contractplan/workflow.md:directly copy references/workflow-template.mdplan/state.yaml:initial empty state (version: 1 / completed_phases: [] / completion_log: [])plan/handoff.md:initial state, marked "no phase has started yet"AGENTS.md:directly copy references/agent-instructions-template.md, replace<PROJECT>with the project name. It is the agent instructions'single source of truth, automatically injected at the start of a session by Codex and other agents compatible with theAGENTS.mdprotocol (including GitHub Copilot).CLAUDE.md:symlinktoAGENTS.md(ln -s AGENTS.md CLAUDE.md) for Claude Code to inject. Do not copy it as a physical file—any one-sided drift will break the enforcement layer, andplanctl doctorwill report an error on drift.
Step 3: Install planctl
Copy scripts/planctl.rb to the target project's scripts/planctl, and add the executable bit:chmod +x scripts/planctl。planctl does not have a built-in fixed list of intermediate artifacts; this part is left to the AI to reason about during phase implementation by combining untracked files, build/compile/run/test command output, path semantics, and "whether it can be regenerated from source". For any path judged to be temporary output, the AI should, before complete , write the exact rules into the root directory's .gitignore, to avoid git add -A bringing them into milestone commits; anything that is a real deliverable, fixture, snapshot baseline, lockfile, or generated code/documentation that must be committed must not be mistakenly ignored. Run ruby scripts/planctl status once as a self-check, then run ruby scripts/planctl lint-contracts --phase <phase-0-id> to check the current formal contract, and finally run ruby scripts/planctl doctor for a full checkup (Ruby version, git working tree, manifest references, current phase contract lint, state/handoff consistency, AGENTS.md existence and CLAUDE.md symlink check).
Step 4: Generate the first batch of phase contracts
- For
phase-0(and any phase the user explicitly wants to start immediately), generateformalofphases/*andexecution/* - For the remaining future phases, generatepaired placeholder contracts, using the references/phase-templates.md in
PHASE_CONTRACT_PLACEHOLDERtemplate
Do not write all future phases as formal contracts at once—that would break the "only 3 documents installed" invariant and would also be overturned by subsequent cognitive updates; but do not leave empty files either, because planctl doctor needs to verify that manifest references exist, and advance --strict needs to recognize, when that phase becomes current, that it is still a placeholder contract and return ACTION: promote_placeholder。
See references/phase-templates.md。
Writing iron rules:
- Completion criteria must not contain subjective words such as "good", "reasonable", or "basically complete"
- execution's "allowed changes" must be a path-level whitelist
- execution is afencerather thanscaffolding, do not write "first step A, second step B"
- All formal contracts must contain four stable markers:
PHASE_CONTRACT:FACT_AUDIT、PHASE_CONTRACT:PRODUCTION_WIRING、PHASE_CONTRACT:RUNTIME_EVIDENCE、PHASE_CONTRACT:FAILURE_MODES PHASE_CONTRACT:PRODUCTION_WIRINGbelow must haveComponent Adoption Table, covering all newly added classes / targets / configs / keys / logs / metrics; if this phase has no production wiring, it must explicitly writeN/A: <原因>- Components referenced only in tests must be marked
test_only; if a component is planned to be wired in a future phase, the current phase must default it to off and mark it in the tablefuture_phase:<phase-id>
Step 5: Start and verify
Run in the target project root:
ruby scripts/planctl advance --strict
Three acceptance criteria:
- The command returns with exit code 0
ACTION: implement, the phase that should currently be executed and itsrequired_context required_contextare exactly three:common.md+phases/phase-0-*.md+execution/phase-0-*.mdruby scripts/planctl lint-contracts --phase <phase-0-id>returns 0, proving that the current formal contract meets the minimum requirements for marker / allowed_paths / required checksplan/handoff.mdalready contains the three compression-recovery steps and the next phase guidance
Step 6: Output usage guide
Tell the user the loop command for each subsequent round (Golden Loop):
# 查看下一步(连续执行状态机)
ruby scripts/planctl advance --strict
# 在实施前或改完合同后做当前 phase 的合同 lint
ruby scripts/planctl lint-contracts --phase <phase-id>
# 实施该 phase 后标记完成(自动刷新 handoff、并 git add -A / commit / push 本 phase 的里程碑)
ruby scripts/planctl complete <phase-id> --summary "<做了什么>" --next-focus "<下一个 phase 要关注什么>" --continue
# complete --continue 会立刻运行 advance;若 ACTION: promote_placeholder,先补正式合同,再重跑 advance
# 当 advance 返回 ACTION: finalize 时,跑一次 finalize 收尾,不要直接收工
ruby scripts/planctl finalize
Note:
completehas automaticallywrite_state→write_handoff_file(both are atomic writes via tmp+rename).ruby scripts/planctl handoff --writeonly serves asmanual remediation: for example, you manually editedstate.yamlbut forgot other linked refreshes, orcompleteafterhandoff.mdwas accidentally edited and needs to be replayed. The normal loop does not need this extra step.
If
advance --strictreturnsACTION: promote_placeholder, this is not a user confirmation point, but an internal to-do of the Golden Loop: first upgrade the two files into a formal contract, then rerun the same strict command.
Compression recovery / cold start: a new session only needs one command to start, replacing manually reading three files:
ruby scripts/planctl resume --strict
The output includes the project overview, handoff snapshot, and next step ACTION, enough for any agent to recover all context in a single read and continue the Golden Loop.
Repository health check: when you suspect agent instructions are out of sync, manifest references are broken, or state and handoff are inconsistent, run:
ruby scripts/planctl doctor
The script checks whether AGENTS.md exists,CLAUDE.md whether it is a symlink pointing to AGENTS.md (a physical copy drift will report an error), verifies whether the plan_file/execution_file of each phase in the manifest exists, and checks whether state.yaml the phase ids in are all in the manifest; problems exit with exit 2.
and reminds of three things:
- Compression or new session recoveryalways and onlythree steps: read manifest → read handoff → run
advance --strict(or one stepresume --strict) completeis the atomic entry point for writing back state + handoff + git milestone;do notadd anotherhandoff --writeto it; a phase that has not runcompleteis directly not considered completecompleteenforces before writing back: dependency check →lint-contracts→ required checks →allowed_pathsgate; if any required gate fails, it exits with exit 2 and does not writestate.yaml/handoff.md- optional checks failures only warn, but will be appended to
completion_log[*].checks, for subsequent handoff / finalize / review complete --continueafter must immediately obeyadvance's nextACTION; if it returnspromote_placeholder, first upgrade the two contracts of that phase, do not stop to ask the user whether to continue- A phase not written to
state.yamlis not considered complete, no matter how well the AI says it did - When
advance/complete --continueoutputsACTION: finalizeor "All phases are completed", the next action is not to directly announce to the human that the project is over, but to runruby scripts/planctl finalize, returning the dashboard and decision-making power to the human according to Step 8
Step 7: Milestone commit and push (complete automatically executed)
complete will, after a phase is judged complete,state.yaml / handoff.md After writing back, automatically complete the following git operations, used to leave each phase atraceable, revertible, auditablemilestone record.During phase implementation, AI should not itself git commit / git push, and should uniformly leave it to complete for one-time finalization, avoiding half-finished commits and message style drift.
Automatic flow:
- Before
git add -A, AI first infers on its own, based on untracked/newly generated files produced by the current phase, which belong to build / compile / run / test temporary output, and updates the root directory.gitignorewhen needed. Then planctl executesgit add -A, staging the code/docs produced by the phase,plan/state.yaml、plan/handoff.md(and, when necessary, the newly updated.gitignore) together. - If the staging area is empty (for example, repeated
complete) → skip the commit and give aNothing to commitprompt. - Otherwise commit in idiomatic English, format:
- Subject:
chore(plan): complete <phase-id> — <phase title>(automatically truncated to within 100 characters) - Body: the user-provided
--summary(when omitted, a generic prompt) - Trailers:
Phase-Id: <id>、Next-Focus: <...>(from--next-focus)、Automated-By: scripts/planctl complete - written via
git commit -F -(stdin), fully respecting the repository's pre-commit / commit-msg hooks, without using--no-verify。
- Subject:
git push: if the repository already has a remote configured, prefer the current branch's upstream; if there is no upstream, fall back togit push -u origin HEAD(when there is noorigin, use the first available remote). If the repository has not configured any remote, thenskip push and continue execution, only printing a warning; the phase is still considered complete.- Failure does not roll back:
state.yamlhas already been recorded as complete. No remote, push failure, or other commit/push exceptions only output a warning, leaving it for the user to handle manually; it will not mark a completed phase back as incomplete, nor should it abort subsequent phase planning and execution because of this.
Environment variables (only for special scenarios, by defaultdo notset):
PHASE_CONTRACT_SKIP_PUSH=1: only do a local commit, do not push (offline or confidential branches).PHASE_CONTRACT_SKIP_COMMIT=1: skip both commit and push (for troubleshooting in extreme cases).PHASE_CONTRACT_ALLOW_NON_GIT=1: non-git workspace mode,complete's git finalization is not executed at all.
Typical output:
Marked complete: phase-0-scaffold
Updated state file: plan/state.yaml
Updated handoff file: plan/handoff.md
[main 33b5258] chore(plan): complete phase-0-scaffold — bootstrap plan artifacts
[planctl] Committed milestone: phase-0-scaffold
To git@github.com:acme/widget.git
c6a54d1..33b5258 main -> main
Step 8: Overall finalization (planctl finalize)
For each plan, after "the last phase has also finished running complete",there is still one step leftbefore it is truly finished: run ruby scripts/planctl finalizeonce, aggregate all states into the final execution dashboard, and hand decision-making back to the human. This step is the Skill's last mile, not an optional optimization.
Trigger conditions (entering finalization if any is satisfied):
complete's output containsAll phases are completed. No remaining work.advanceorcomplete --continue's output containsACTION: finalize
Actions AI must immediately execute (executed consecutively, no user confirmation needed):
ruby scripts/planctl finalize
finalize only runs when state.yaml already contains all phases in the manifest, and each phase is in completion_log has completed_at and successful evidence for all required checks; if any phase is missing, failed, or the ledger is inconsistent, it will reject with exit 2, and will not write the ledger or output the dashboard. On the first successful execution, it will first write plan/state.yaml.finalized_at, refresh plan/handoff.md, execute git add -A → git commit -F - → git push, and then output the final execution dashboard. If commit or push fails, only print a warning and do not roll back the ledger. If finalized_at already exists, subsequent repeated finalize remains read-only: do not rewrite the ledger, do not commit/push again, and only regenerate the dashboard.
The final execution dashboard aggregates in one pass:
- Project overview: total number of phases / number completed, first and last completion timestamps, cumulative elapsed.
- Finalized at: final ledger write timestamp.
- Phase ledger: each phase's id, title, completed_at, summary, next_focus, and the milestone commit SHA found by
git log --grep "Phase-Id: <id>". Phases that cannot be found will be explicitly marked, prompting manual reconciliation. - Repository status: current branch, upstream, ahead/behind, whether the working tree is clean, list of uncommitted files (truncated to the first 10 items), configured remotes, most recent commit.
- Health check: whether the manifest → plan_file/execution_file references still exist, whether the phase ids in
state.yamlare all present in the manifest, whetherAGENTS.mdexists and whetherCLAUDE.mdis a symlink pointing to it. List issues and notes separately. - Recommended human next steps: automatically derived based on the five sections above, for example if there are unpushed commits, prompt
git push, if there is no remote, prompt to firstgit remote add origin, if a phase is missing a summary, prompt to add the narrative, and append a set ofgeneral wrap-up actions(end-to-end acceptance, human code review, decide whether to create a release tag, archiveplan/, write external delivery notes, return release/maintenance decisions to humans).
After receiving the finalize output, the AI must conduct another in-depth review, and must not forward it as-is:
- Read through
manifest.yaml/state.yaml/handoff.mdand the most recent N milestone commits, and verify that the phase ledger, git status, and health in the dashboard match the actual repository state. - Translate general recommendations into concrete actions for this project (with commands, target branch, potential reviewers, and deadlines), distinguishing "must do immediately", "advance in the short term", and "optional optimization".
- Identify risks that finalize did not explicitly state but objectively exist: for example, a summary that is inconsistent with the diff, a recommendation that does not apply in this project's context, or whether a mild warning in the health notes needs to be escalated to an issue.
Finally, must report to humans in the form of afinal execution dashboard, and explicitly return the following decision points to humans (the AI must not execute them on its own):
- whether to go live / release / announce externally
- whether to create a release tag for the results (
git tag -a vX.Y.Z, whether togit push --tags) - whether to archive
plan/(git mv plan plan-archive-<date>) before starting the next planning item, or keep it as a long-term archive - whether to arrange long-term maintenance, rotation, or regression testing
- whether security / compliance / legal review is needed
Even if the first finalize automatically commits/pushes the finalization ledger, before humans give explicit instructions, the AI still must not git tag / push tags / delete or move plan/ / rerun this Skill scaffolding / continue modifying state.yaml. If finalize's health reports an issue, first report it according to the "abort conditions" logic in Step 7 and let humans decide whether to fix the problem first and then wrap up, or accept the current state and wrap up. Repeat finalize No side effects, but it should be avoided for use as status.
Decision Points
phase count > 12: demand an immediate re-split, or introduce epic a grouping layer (see references/methodology.md §7.1)。
dependency cycle: directly determine that the split is wrong and refactor the phase boundaries. Any circular dependency is invalid.
common.md reaches item 15 and still cannot be stopped: distinguish "constraints" (eternally unchanging) from "policies" (may change), and push the latter down to the specific phase.
the user says "just have the AI write all the phase documents for me": write only phase-0 (and the phase that is about to start immediately) as a formal contract; keep future phases as placeholder contracts for now. The manifest and common must be led by the user, otherwise AI fitting will steer the whole thing off course.
advance --strict the new phase pointed to is still a placeholder contract: this is not a blocker, nor is it a user confirmation point.advance will return ACTION: promote_placeholder; first upgrade that phase's phases/*.md and execution/*.md synchronously into formal contracts, then rerun the same strict command; before it returns ACTION: implement implementation must not begin.
the user already has a phase structure but no planctl system: skip Step 1.3–1.4, generate only the infrastructure (manifest, common, workflow, planctl, agent instructions), and bring the existing phase documents into the manifest.
a phase was done badly and needs to be rolled back: run ruby scripts/planctl revert <phase-id>. By default --mode revert uses git revert to preserve history (safe, can be pushed);--mode reset uses git reset --hard to rewrite history (private branches only; the script does not push automatically). The script will automatically remove that phase from state.yaml , append a reverted_at entry to completion_log, and commit the ledger with chore(plan): revert <phase-id> . If that phase still hascompleted downstream dependencies, the script will refuse the rollback, and the downstream must first be rolled back in reverse order.
AI crosses boundaries and modifies files between phases: in manifest.yaml 's execution_rule , add enforce_allowed_paths: true, and fill in allowed_paths: glob allowlist for each phase (see references/templates.md). Once enabled, complete will, before writing back state, compare git diff --cached against the allowlist; out-of-bounds paths abort directly anddo not update state.yaml, and the phase remains incomplete. To temporarily turn it off, use enforce_allowed_paths: false(warning only) or PHASE_CONTRACT_ENFORCE_PATHS=1 override.
cold start of a new session / continuing after context compression: run ruby scripts/planctl resume --strict or ruby scripts/planctl advance --strict. It prints the project overview, handoff snapshot, and the complete result of the next phase in one go, equivalent to manually reading manifest + handoff + running the state machine.
suspect state/agent instructions are out of sync: run ruby scripts/planctl doctor. Check whether AGENTS.md exists, whetherCLAUDE.md is a symlink pointing to AGENTS.md (a physical copy drift will error), and validate the consistency of manifest references, state, and handoff; if a problem is found, exit with exit 2.
the last phase has also finished running complete done: do not directly declare to the user that "the project is complete." Immediately run ruby scripts/planctl finalizeaccording to Step 8, report the dashboard to the human, and explicitly hand back decision points such as release / tagging / archiving plan/ / scheduling maintenance.finalize will exit 2 and refuse to run when not all phases are complete, so it is itself the gate for "whether it is truly possible to wrap up".
Quality Gates
After generation is complete, verify item by item:
- the target project root is a git worktree (
git rev-parse --is-inside-work-treeistrue), orPHASE_CONTRACT_ALLOW_NON_GIT=1has been explicitly set andplan/common.mdcontains a deviation risk section -
manifest.yamlofphases[].required_contextexactly three items (common + plan + execution) -
manifest.yamlofcompression_control.rulesexplicitly prohibits loading all phase documents at once -
common.mdcontains only constraints that never change, with no implementation steps -
phases/phase-0-*.md"completion criteria" are all objective checkable items -
execution/phase-0-*.md"allowed changes" is a path whitelist rather than a capability description -
phase-0(and any phase preparing to start immediately) use the formal contract; future phases not yet entered use paired placeholder contracts withPHASE_CONTRACT_PLACEHOLDERand the sentinel is located within the first 40 lines of the file -
execution/phase-0-*.mdcontains an "execution adjudication rules" veto clause -
AGENTS.mdis generated from the template and contains 10 hard constraints (see references/methodology.md §9);CLAUDE.mdis a symbolic link pointing toAGENTS.md.github/copilot-instructions.md was not generated.github/copilot-instructions.md - agent instructionsmust not introduce agent-specific sections(
AGENTS.mdis the single source of truth; any differences such as "only Claude sees" or "only Copilot sees" will cause hidden drift); if differences are truly needed, instead carry them inplan/common.mdusing a subsection "differentiated by agent" -
scripts/planctlis executable,ruby scripts/planctl statusruns successfully -
planctl advance --strictreturnsACTION: implement, phase-0, and required_context is three items - When a future phase is still a placeholder contract and it becomes the current phase,
planctl advance --strictwill returnACTION: promote_placeholder, until the two contracts are upgraded - the first
completeBefore this, if untracked intermediate artifacts have already appeared in the repository, AI has judged based on reproducibility, delivery boundaries, and project conventions and updated the root.gitignore, and will not bring these artifacts into milestone commits - If the target project has already configured
git remote, its current branch can be pushed; if there is temporarily no remote, it has been clearly stated in the delivery notes to the user: subsequentcompletewill only commit locally and skip push, butdoes not blockcontinuing to execute subsequent tasks -
scripts/planctl finalizerefuses to run with exit 2 when not all phases are complete; the first successful execution will writefinalized_at, refreshhandoff.md, attempt automatic commit/push, and repeated execution remains read-only while still being able to print the dashboard -
AGENTS.mdcontains §12 "Overall Finalization Protocol (Finalization)", and the prohibited actions explicitly state thatfinalizemust not be skipped to declare the project finished on one's own