Tp design complete
Skill CurtisThe/three-pillars-plugin/skills/tp-design-complete
Mark a TDD design as complete — stamp completion, archive handoff.md, archive to three-pillars-docs/completed-tp-designs/, and optionally commit + open a PR merging the design branch back to the base branch.From its SKILL.md
npx -y skills add CurtisThe/three-pillars-plugin --skill tp-design-completeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
31.0 KB, as published. Nobody here has run it
Design Complete
Mark a finished design as complete, archive it out of the active designs directory, and clean up session state.
Argument: {design-name} (required) — must match an existing directory under three-pillars-docs/tp-designs/.
Steps
- Run first-run preflight per skills/_shared/first-run.md.
0a. Run cwd preflight per skills/_shared/cwd-preflight.md: python3 "$TP_ROOT"/skills/_shared/cwd_preflight.py {design-name}. Exit 3 → stop and show the cd fix. Exit 0 → continue.
-
Validate the design name per
skills/_shared/validate-name.md. -
Resolve the design directory:
three-pillars-docs/tp-designs/{design-name}/. If it doesn't exist, tell the user and stop. -
Check if
-learnhas been run (hard-blocks unless--skip-learnwas passed): Determine whether this is a spike (hasspike-results.md) or a full design (hasimplementation-audit.md).- For spikes: Check if the
product_roadmap.mdDesign Inventory table has been updated with the spike's verdict (GO/PARTIAL/NO-GO). If not, refuse to proceed:Refusing to complete:
/tp-spike-learnhasn't been run yet — the Design Inventory doesn't carry a GO/PARTIAL/NO-GO verdict. That step propagates findings into project docs and scans for affected downstream designs; skipping it leaves the roadmap silently stale. Run/tp-spike-learn {design-name}first, then re-invoke this skill. If you have a specific reason to skip (e.g., the spike was a one-off scratchpad with no roadmap presence), re-invoke with--skip-learn. - For full designs: Check if the
product_roadmap.mdDesign Inventory status reflects completion. If it still says "Designed" or "Pending", refuse to proceed:Refusing to complete:
/tp-design-learnhasn't been run yet — the Design Inventory status is still "Designed" / "Pending" / "Implementing". That step propagates implementation results intoproduct_roadmap.md,architecture.md, andknown_issues.md, updates the Design Inventory status, and scans for affected sibling designs. Skipping it causes the roadmap to drift silently across the completion boundary. Run/tp-design-learn {design-name}first, then re-invoke this skill. If you have a specific reason to skip — legacy designs that pre-date this rule, or designs where learn was run out-of-band and the roadmap status is intentionally stale — re-invoke with--skip-learn. --skip-learnescape hatch: If the user passed--skip-learn, log a one-line notice (Proceeding without learn per --skip-learn flag) and continue. The flag exists for legacy designs and well-understood out-of-band cases; it must not become the default workflow. Do not silently treat absence-of-flag as override.
- For spikes: Check if the
-
Show a summary of what will happen:
- The completion date that will be stamped (today's date,
YYYY-MM-DD) - Whether
handoff.mdexists and will be archived (banner added) - The destination:
three-pillars-docs/completed-tp-designs/{design-name}/ - The current branch and the base branch — after archival, a commit will be made on the current branch and (if the current branch is not the base) a PR back to base will be offered
- The completion date that will be stamped (today's date,
-
Ask for confirmation before proceeding. A simple "Complete this design?" is enough.
-
On confirmation, execute these steps in order:
a. Preserve
handoff.md— do not delete it. It is the last live session state. It is bannered as an archive marker at its new location (step 6d1) and carried intocompleted-tp-designs/by thegit mvin step 6c, so the local archive retains the real session prose for/tp-session-restoreon this machine.handoff.mdis gitignored by design (skills/tp-session-save/SKILL.md— session state may reference sensitive configuration, so it is deliberately kept out of version control): it therefore stays a local-only file and is not committed to the completion PR. "Archive" here means preserve-and-banner in place, not commit to VCS — the point is to stop deleting it, so the local operator can still restore the session, without moving session context into version control.b. Create
three-pillars-docs/completed-tp-designs/directory if it doesn't exist.b1. Merge any spec delta before archiving: If
three-pillars-docs/tp-designs/{design-name}/spec-delta.mdexists, run/tp-spec merge {design-name}to merge it into the domain base spec atthree-pillars-docs/specs/<domain>/spec.md. This step is a no-op skip when the design has nospec-delta.md(e.g., designs not scaffolded via/tp-spec add, likeliving-spec-layeritself) — ifthree-pillars-docs/tp-designs/{design-name}/spec-delta.mddoes not exist, skip the merge sub-step (no-op) and proceed to thegit mv. If the merge is blocked (conflict or parse error), surface the error and stop — do not proceed with archival until the delta is clean or deliberately removed.c. Move the design directory using
git mv three-pillars-docs/tp-designs/{design-name} three-pillars-docs/completed-tp-designs/{design-name}to preserve git history.d. Stamp the completion date on
design.mdat its new location. Editthree-pillars-docs/completed-tp-designs/{design-name}/design.md. If it already has YAML frontmatter (starts with---), add acompleted: YYYY-MM-DDfield to the existing frontmatter. If it has no frontmatter, prepend a new frontmatter block:--- completed: YYYY-MM-DD ---followed by the existing content (preserve a blank line between the closing
---and the document body).Why edit after the move, not before:
git mvtransfers the index entry, not the working-tree content. If you editdesign.mdbefore the move, that edit becomes an unstaged modification at the old path;git mvthen stages a pure rename with the pre-edit content, and your frontmatter quietly fails to make it into the archival commit. Editing at the new location avoids the trap — step 6f'sgit addof the new design.md path catches the rename and the modification in one shot.d1. Banner the archived
handoff.mdat its new location (step 6d1). Ifthree-pillars-docs/completed-tp-designs/{design-name}/handoff.mddoes not exist (a pre-rule design, or a design that never wrote one), skip this sub-step cleanly — there is nothing to banner. Otherwise, prepend the dual archive marker to it: a machine frontmatter flag and a human blockquote.- If it already has YAML frontmatter, add
archived: trueandcompleted: YYYY-MM-DDfields to it. If it has none, prepend a new frontmatter block:--- archived: true completed: YYYY-MM-DD --- - Immediately after the frontmatter, insert the human-readable blockquote:
followed by the existing handoff content.> **📦 Archived handoff** — `{design-name}` was completed YYYY-MM-DD and archived to `completed-tp-designs/`. This is the last live session state, preserved for reference; it is not an active handoff.
This is a local-only edit — do NOT
git addit.handoff.mdis gitignored (.gitignoreignorestp-designs/*/handoff.mdandcompleted-tp-designs/*/handoff.md; session state stays out of VCS perskills/tp-session-save/SKILL.md). The banner is applied to the moved file in the working tree and is not staged or committed —git addwould refuse the ignored path anyway (and forcing it with-fwould defeat the security policy). The bannered handoff is the local operator's record, read by/tp-session-restoreon this machine; it never enters the completion PR. Edit at the NEW path (completed-tp-designs/{design-name}/handoff.md) so the local file that/tp-session-restorewill resolve carries the banner.e. Update Current Focus in
product_roadmap.md: If the roadmap has a## Current Focustable containing this design, remove its row and shift remaining priorities up (Priority 2 → 1, etc.). If removing this row unblocks another row (was listed in its "Blocked By"), clear the blocker and update its "Next Action" to the now-available step. Show the proposed changes and get user confirmation before writing.f. Commit the archival changes on the current branch:
- First, set
phase = "cleanup-pending"onlock.jsonat its archived location (three-pillars-docs/completed-tp-designs/{design-name}/lock.json— thegit mvin step 6c moved it). This marker MUST land in the archival commit below, not in a later staging step, or it never reaches the PR and/tp-post-merge's discovery gate can't find the design. (Step 6g references this as already-committed.) - Run archive-time cite rewrite (before staging), capturing the JSON:
RECONCILE_JSON="$(python3 "$TP_ROOT"/skills/_shared/reconcile_docs.py --archive-cites --slug {design-name} --apply --json)". This rewrites anytp-designs/{design-name}path cites in code and living docs tocompleted-tp-designs/{design-name}so cites on{base}are never dead between archive and post-merge. The--jsonoutput lists the rewritten file paths as anedits[]array (each entry carries apath). Stage exactly the--jsonfile list alongside the archival paths — by looping over it (the staging block below), never a fixed hardcoded set, so a rewrite outside the fixed archival paths is never left unstaged.--autoruns this sub-step identically (mechanical, no prompt). - Run
git status --shortand verify the only changes are the archival paths + the reconcile--jsonfile list: the oldthree-pillars-docs/tp-designs/{design-name}/(as deletions from the rename), the newthree-pillars-docs/completed-tp-designs/{design-name}/(additions, including any previously-untracked files like demos and decisions.md from a pre-rule-change design), optionallythree-pillars-docs/product_roadmap.md(modified), and the rewritten files from the--jsonlist. If unrelated changes appear in the working tree, stop and tell the user to commit or stash them first — the skill won't sweep unrelated WIP into the completion commit. - Stage the archival paths explicitly (do NOT use
git add -Aorgit add .). Thegit mvfrom step 6c only stages tracked files; any untracked siblings in the design directory (e.g.,decisions.mdordemos/content from a pre-2026-05 design before those became tracked-from-creation) need explicit re-add at the new path. Thegit addof the newdesign.mdpath is also what captures the frontmatter stamp from step 6d —git mvstaged a pure rename, thisaddrewrites the index entry with the post-edit content:
After this,# Tracked files that git mv already staged, plus the frontmatter modification at the new design.md path git add three-pillars-docs/tp-designs/{design-name} three-pillars-docs/completed-tp-designs/{design-name}/design.md # Catch any previously-untracked siblings that came along at filesystem level git add three-pillars-docs/completed-tp-designs/{design-name}/decisions.md 2>/dev/null git add three-pillars-docs/completed-tp-designs/{design-name}/demos/ 2>/dev/null # Roadmap update from step 6e git add three-pillars-docs/product_roadmap.md # cleanup-pending lock phase from the start of step 6f — MUST be in this commit git add three-pillars-docs/completed-tp-designs/{design-name}/lock.json # NOTE: handoff.md is NOT staged — it is gitignored by design (step 6a/6d1); the # banner from step 6d1 stays a local-only edit and never enters the completion PR. # Merged base spec from step b1 — the base spec lives OUTSIDE the design dir, so git mv # does NOT pick it up; it must be staged explicitly or it silently misses the commit. # If no spec-delta.md existed (the merge sub-step was a no-op), this line is a harmless no-op. git add three-pillars-docs/specs/<domain>/spec.md 2>/dev/null || true # Reconcile --archive-cites --json rewritten-file list: LOOP over it and git add EACH # rewritten path (closing the "a rewrite outside the fixed set above stays unstaged" hole). # RECONCILE_JSON was captured from the --json run at the top of step 6f. for f in $(printf '%s' "$RECONCILE_JSON" | python3 -c 'import sys,json; [print(e["path"]) for e in json.load(sys.stdin).get("edits", [])]'); do git add "$f" done # Sanity check before commit — design.md should appear as a rename WITH insertions (the frontmatter), # NOT a pure rename (0 insertions). If you see a pure rename, step 6d's edit didn't land in the # working tree at the new path; redo the frontmatter edit at the new path and re-add before committing. git status --shortgit statusshould show no remaining untracked entries underthree-pillars-docs/completed-tp-designs/{design-name}/. If any do, stage them too — the archive must be complete. - Staged-blob guard — run AFTER staging, strictly BEFORE the commit. The archived
design.md/lock.jsonstaged index blobs (not the working-tree files) must carry the completion stamp /cleanup-pendingphase, and no livetp-designs/{design-name}cite may survive — inspecting the blob after the commit would be inert. Run the read-only helper:python3 "$TP_ROOT"/skills/tp-design-complete/scripts/verify_archive_staged.py \ --repo "$(git rev-parse --show-toplevel)" --slug {design-name}- Exit
0→ all staged-blob assertions pass; proceed to the commit. - Exit
1(an assertion failed — a stamp/phase/cite that reached only the working tree, not the index): re-git addthe specific offending path named on the helper's stderr repair line (the double-add — the fix for a stampful working tree whose index blob is stale), then re-run the helper. If it still exits1, abort loudly with the repair message and a non-zero exit — never commit a stampless / lock-phaseless archive. - Exit
2(a precondition error — an archived path absent from the index, a bad slug): abort IMMEDIATELY with a distinct precondition message and a non-zero exit. Do not run the double-add retry — re-adding a path that is not there cannot fix a precondition error. - Under
--auto: on any abort (exit1still-failing, or exit2), log the abort tothree-pillars-docs/tp-designs/{design-name}/decisions.md(the sanctioned--autoaudit-trail write, same class as the BLOCKED-learn logged exception) and exit non-zero so the orchestrator escalates.
- Exit
- Commit with a focused message. The commit runs UNPIPED (no
| tail, no| head, no subshell that would swallow a hook's non-zero exit); capture the pre-commit HEAD first and, after the commit, assert HEAD advanced — a hook-blocked commit leaves HEAD unchanged and is a failure, not a success:
Do not add any Co-Authored-By trailer — respect the user's commit-style preferences.PRE=$(git rev-parse HEAD) git commit -m "Complete design: {design-name}" if [ "$(git rev-parse HEAD)" = "$PRE" ]; then echo "archival commit did not advance HEAD (hook-blocked?) — aborting, not reporting success" >&2 exit 1 fi - If the commit fails (e.g., a pre-commit hook blocks it → HEAD unchanged per the check above), stop and surface the hook output to the user. Do not retry with
--no-verify, and do not proceed to the PR step.
g. Offer to open a PR back to the base branch:
- The
phase = "cleanup-pending"marker was set and committed as part of the archival commit in step 6f (do not re-stage it here). If you somehow reach this step with the lock still showing an earlier phase (e.g., 6f was hand-run without it), set it now and amend the archival commit (git add .../lock.json && git commit --amend --no-edit) before opening the PR — the marker must be on the branch the PR ships, or/tp-post-merge's discovery gate can't find the design. This phase marker is the discovery signal that tells/tp-post-merge(and/tp-merge-from-mainstep 8) the design is awaiting teardown — it is not the safety gate. The actual gate is/tp-post-merge's own merge verification (verify_merged.py);/tp-post-mergeis the sole skill that runs post-merge cleanup, and it tears down only on a verified merge regardless of this marker. - Resolve the default branch: try
git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/nulland striporigin/; if that returns nothing, fall back tomain(thenmaster) if the remote has that ref (git ls-remote --heads origin main/master). Call this{default}. - Parent-aware base resolution — the current branch may have been cut from another in-flight design's branch rather than from
{default}. The PR should target the parent in that case so the design's lineage is preserved through to merge.- Compute the repo root:
ROOT="$(git rev-parse --show-toplevel)". - Run
python3 "$TP_ROOT"/skills/tp-design-complete/scripts/detect_parent.py --repo "$ROOT" --design {design-name} --default-branch {default}. The script inspects sibling designs'lock.jsonfiles (no namespace pattern matching — any branch name declared inlock.jsonis honored) to find branches that are ancestors of HEAD and have not been merged into{default}. Capture its stdout as JSON. - On exit 0, parse the JSON and branch on the
verdictfield:- none → set
{base} = {default}. No prompt. - single → tell the user:
Detected parent design '{design}' on branch '{branch}'. Target this for the merge instead of '{default}'? (parent / default / other). Onparent, set{base} = {branch}. Ondefault, set{base} = {default}. Onother, prompt for an explicit branch name and use that. - multiple → list each candidate numbered with design / branch /
last_touched, plusdefaultandotheras keywords. Prompt for a number or keyword and set{base}accordingly.
- none → set
- On non-zero exit or JSON parse failure, log a one-line warning (
parent-detection unavailable; defaulting to {default}) and set{base} = {default}. The default-branch path must always remain reachable — a buggy detector must never block a completion. - Failure modes the heuristic can't catch (worth knowing for when to override): rebased branches lose their original creation point so the merge-base ancestry breaks; force-pushed parents shift the merge-base under the script's feet; and if the user fast-forward-merged the parent into a different sibling, both will look like ancestors of HEAD until the parent gets deleted. The interactive prompt gives the user the last word — fall back to
defaultorotherwhen the detected target looks wrong.
- Compute the repo root:
- Get the current branch:
git branch --show-current. - Skip the PR offer and tell the user how to push manually if any of these are true:
- No
originremote (git remote get-url originfails). - Current branch equals the resolved base branch — there is nothing to PR; the archival commit is already on base and the user can push directly when ready.
- No
- Otherwise, ask:
Push
{current-branch}and open a PR into{base}? (yes / no) - On yes:
git push -u origin {current-branch}. If push fails, stop and surface the error.- If
ghis installed and authenticated (gh auth statusreturns 0), open the PR through the shared PR-author chokepoint —skills/_shared/github_pr_author.pyresolves an optional bot account from.three-pillars/config.json'sgithubblock before thegh pr createunderneath ever runs:
Repos with no# Resolve the FREE chokepoint git-toplevel-first (see first-run.md §Resolve a FREE _shared script) TOP="$(git rev-parse --show-toplevel 2>/dev/null || true)" if [ -n "$TOP" ] && [ -f "$TOP"/skills/_shared/resolve_script.py ]; then RS="$TOP"/skills/_shared/resolve_script.py; else RS="$TP_ROOT"/skills/_shared/resolve_script.py; fi GHPA="$(python3 "$RS" github_pr_author.py)" python3 "$GHPA" create --context manual -- \ --base {base} --head {current-branch} \ --title "Complete design: {design-name}" \ --body "$(cat <<'EOF' Archives `three-pillars-docs/tp-designs/{design-name}/` to `three-pillars-docs/completed-tp-designs/{design-name}/` and stamps the completion date on `design.md`. Closes the TDD pipeline for this design. Review and merge to land the archival on `{base}`. EOF )"github.pr_author_accountconfigured run plaingh pr createunderneath — byte-identical to today's behavior (ambientghauth; the helper's resolve step returnedNone). A helper exit code of 3 means the configured bot account is unavailable (BotAuthUnavailable); surface the helper's actionable stderr to the user and do not retry with ambient auth — a silent fallback would re-create the self-approval trap the config exists to prevent.- Light/just-do-it fidelity checklist: before invoking the helper, read the design's weight class —
python3 "$TP_ROOT"/skills/_shared/weight_class.py read three-pillars-docs/completed-tp-designs/{design-name}(the dir was archived in step 6c;read_classreads design.md's frontmatter). When it returnslightorjust-do-it, append the fidelity checklist fromskills/_shared/weight-class.md§Light fidelity checklist to the PR body — paste the checklist block verbatim between the body template's last line and theEOF. That checklist (every in-scope item traced to the diff, drift flagged) is the light class's impl-level instrument; the PR body is where the reviewer consumes it. Forfull/spike(or the legacy("full", "default")read), the body template is unchanged. Report the PR URL back to the user. - Request Copilot review on the new PR (default-on; suppress with
--no-review) — a completion PR with no reviewer requested is a review loop with nothing to classify (F2). Resolve{n}from the created PR URL and request the Copilot bot via the RESTrequested_reviewersendpoint — the known-good path; do not usegh pr edit --add-reviewer(it fails on classic-Projects repos with a GraphQL deprecation error before the reviewer is added):
Fail-open (load-bearing): a non-zero exit must not fail the completion — the PR already exists; report the failure and continue. Mirrorsgh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers \ -f 'reviewers[]=copilot-pull-request-reviewer[bot]'tp-run-full-designTier 6; pairs withcopilot-review-custom-instructions(the.github/instructions that make the requested review produce convention-aware comments instead of no-ops). After the review is requested,/tp-pr-iterate {design-name}can drive the review loop.
- Light/just-do-it fidelity checklist: before invoking the helper, read the design's weight class —
- If
ghis not available or auth fails, tell the user the branch is pushed and print a GitHub compare URL they can open in a browser:https://github.com/{owner}/{repo}/compare/{base}...{current-branch}?expand=1(derive{owner}/{repo}fromgit remote get-url origin).
- On no: leave the commit in place and remind the user how to push + open a PR when ready.
- Never merge the PR from within the skill — review happens on the PR, not inside the skill.
- This skill ends at PR-open — teardown is
/tp-post-merge's sole responsibility. After reporting the PR URL, tell the user:After the PR is merged, run
/tp-post-merge {design-name}to delete the branch and worktree. If you use/tp-merge-from-mainto sync the base in, its step 8 will auto-chain/tp-post-mergeautomatically once the completion PR has landed.
h. Report success with:
- The archive location:
three-pillars-docs/completed-tp-designs/{design-name}/ - The commit SHA produced in step 6f (short form)
- The PR URL if one was opened, or the branch name the user still needs to push/PR manually
- Next step:
/tp-post-merge {design-name}after the PR is merged (or/tp-merge-from-mainstep 8 auto-chains it)
- If it already has YAML frontmatter, add
Rules
- Use
git mvfor the move so history follows the files. - Never delete any artifact —
handoff.md(bannered as an archive marker per step 6a/6d1), design.md, detailed-design.md, plan.md, review.md, implementation-audit.md,lock.json, and every other artifact move with the directory. Thelock.jsonmoves with the directory as a historical record of who held the design; seeskills/_shared/collaboration.mdfor the lock convention. - If
design.mddoesn't exist in the directory, warn but continue with the move (some designs may have non-standard structures). - If
three-pillars-docs/completed-tp-designs/{design-name}/already exists, tell the user and stop — don't overwrite a previously completed design. - The frontmatter block uses YAML between
---delimiters. "Frontmatter" is metadata at the top of a markdown file — a convention from static site generators like Jekyll and Hugo. Many tools parse it automatically. - Commit scope: stage only the archival paths listed in step 6f + the reconcile
--jsonfile list (the rewritten cite files fromreconcile_docs.py --archive-cites). Never usegit add -A/git add .— unrelated WIP must not be swept into the completion commit. If the working tree has unrelated changes, stop before committing and ask the user to handle them first. - Commit message: do not include a Co-Authored-By trailer. The completion commit is a mechanical archival step; the trailer is not appropriate here.
- Ends at PR-open — teardown is
/tp-post-merge's sole responsibility: this skill opens the PR (or surfaces the compare URL) but never merges it and never deletes thetp/{design-name}branch. Post-merge teardown (branch delete, worktree remove, MRU clear) lives exclusively in/tp-post-merge {design-name}./tp-merge-from-mainstep 8 auto-chains it after a successful completion-PR merge. No merge, no branch delete inside this skill. - Never bypass hooks: if
git commitorgit pushis blocked by a hook, surface the output and stop — do not retry with--no-verify.
Auto Mode
--auto is a Shape B (Generator) per skills/_shared/auto-mode.md. It exists so the autonomous orchestrator (/tp-run-full-design Tier 5.6) can archive a finished design unattended — the archival half of closeout-before-merge. It performs the mechanical archival and nothing that needs a human or owns the PR surface.
In --auto:
- Run the archival half only: step 6a handoff preserve (no delete), step 6b1
/tp-spec merge {design-name}(no-op if nospec-delta.md— see step 6b1 for the skip rule), step 6cgit mvtocompleted-tp-designs/, step 6d frontmatter completion stamp, step 6d1 handoff banner at the archived path (skipped cleanly if nohandoff.mdexists), step 6e Current Focus / Design Inventory rewrite, step 6fComplete design: {design-name}commit (scopedgit addof the archival paths includingthree-pillars-docs/specs/<domain>/spec.mdif a delta was merged, no Co-Authored-By;handoff.mdis NOT staged — it is gitignored and stays local-only, per step 6a/6d1), and setphase = "cleanup-pending"on the archivedlock.json— so autonomous completions preserve and banner the local handoff identically to interactive completions, without committing session state to VCS. - The archival commit inherits the step-6f staged-blob guard. Under
--auto,verify_archive_staged.pyruns as the commit's pre-commit self-check exactly as in interactive mode (identical mechanical assertion). On a still-failing exit1(double-add did not resolve it) or an exit2precondition error,--autologs the abort tothree-pillars-docs/tp-designs/{design-name}/decisions.md(sanctioned audit-trail write) and exits non-zero for orchestrator escalation — it never commits a stampless / lock-phaseless archive. The unpiped / HEAD-advanced commit check applies identically. - Skip step 5 (the confirmation prompt) — proceed without asking.
- Skip step 6g (PR) —
--autoopens no PR, requests no Copilot review, and performs no cleanup/teardown of the worktree. PR-opening is always the caller's concern: in the orchestrator path, Tier 6 opens the single completion PR (tp/{slug} → {default}) after this archival commit lands; opening one here would double up. The step-6g Copilot review request rides inside the skipped step 6g — under--autoit is never invoked. In the autonomous path, Tier 6 is the sole initial completion-PR review requester. (Seetp-run-full-design/SKILL.md## Tier 6 § Step 2.) Log exactly one line tothree-pillars-docs/tp-designs/{design-name}/decisions.mdas a sanctioned--autoaudit-trail write (same class as the BLOCKED-learn logged exception):
Post-merge cleanup/teardown now lives exclusively in[tp-design-complete] review-request-deferred-to-tier-6/tp-post-merge— settingcleanup-pendingon the archived lock is what allows the orchestrator or/tp-merge-from-mainstep 8 to chain it automatically after the human merge. - Honor the step-3 learn-ran hard-block, without prompting. It is auto-satisfied when
/tp-design-learn(or/tp-spike-learn) ran immediately prior in the same run (orchestrator Slot 9, the normal case). If it is not satisfied, BLOCK: append a### [tp-design-complete] BLOCKED — learn-not-runentry tothree-pillars-docs/tp-designs/{design-name}/decisions.mdand exit non-zero (the orchestrator escalates). Do not auto-pass via--skip-learnand do not prompt. - The BLOCK
decisions.mdwrite is the sanctioned--autoaudit-trail exception, not silent mutation.decisions.mdis the permanent, human-reviewed decision log that is the autonomous run's accountability record (seeauto-mode.md); appending a BLOCKED entry is logging, not the "silent mutation of docs/designs/code without the human merge gate" the vision non-goal forbids. The archival commit itself still lands inside the human-gated completion PR — never auto-merged. - Lock: the directory move carries
lock.jsonwith it (perskills/_shared/collaboration.md), exactly as in interactive mode. Thecleanup-pendingphase is set on the archived lock so/tp-post-mergecan find and tear down the design after the human merge.
Contract: in --auto, this skill merges any spec delta (no-op if absent) + archives + stamps + rewrites Current Focus + commits (staging the merged base spec if a delta was merged) + sets cleanup-pending, opens no PR, removes no worktree, never prompts, and BLOCKs (logging to decisions.md) rather than completing a design whose learn step has not run.