@plainconceptsplatform/agent-harness 3.1.1 → 3.2.0

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.
Files changed (64) hide show
  1. package/README.md +452 -434
  2. package/cli/commands/update.js +121 -121
  3. package/cli/fragments/archive/az.md +97 -97
  4. package/cli/fragments/archive/gh.md +96 -96
  5. package/cli/fragments/archive/gl.md +96 -96
  6. package/cli/fragments/archive/none.md +75 -75
  7. package/cli/fragments/guardrails/codegraph.md +5 -5
  8. package/cli/fragments/guardrails/humanizer.md +4 -4
  9. package/cli/fragments/guardrails/memory.md +4 -4
  10. package/cli/fragments/guardrails/rtk.md +3 -3
  11. package/cli/fragments/guardrails/simple-english.md +4 -4
  12. package/cli/fragments/ops-ship/az.md +81 -81
  13. package/cli/presets/agents-content.json +34 -34
  14. package/cli/presets/browser.json +10 -10
  15. package/cli/steps/browser/index.js +48 -48
  16. package/cli/steps/copy/commands.js +79 -79
  17. package/cli/steps/copy/index.js +88 -88
  18. package/cli/steps/copy/skills.js +307 -307
  19. package/cli/steps/metadata/index.js +115 -115
  20. package/cli/steps/models/write.js +38 -38
  21. package/cli/utils/copy.js +5 -2
  22. package/cli/utils/paths.js +80 -80
  23. package/harness/.opencode/_gitignore +9 -9
  24. package/harness/.opencode/commands/init.md +5 -5
  25. package/harness/.opencode/commands/make-architecture.md +5 -5
  26. package/harness/.opencode/commands/make-design.md +5 -5
  27. package/harness/.opencode/commands/make-engineer.md +5 -5
  28. package/harness/.opencode/commands/make-guardrails.md +5 -5
  29. package/harness/.opencode/commands/make-user-model.md +5 -5
  30. package/harness/.opencode/commands/plan-apply.md +9 -9
  31. package/harness/.opencode/commands/plan-goal.md +5 -5
  32. package/harness/.opencode/commands/plan-quick.md +5 -5
  33. package/harness/.opencode/commands/plan-story.md +9 -9
  34. package/harness/.opencode/commands/repo-audit.md +5 -5
  35. package/harness/.opencode/commands/repo-initialize.md +5 -5
  36. package/harness/.opencode/commands/repo-onboard.md +5 -5
  37. package/harness/.opencode/commands/repo-verify.md +5 -5
  38. package/harness/.opencode/scripts/check-diff.mjs +225 -0
  39. package/harness/.opencode/scripts/code-rules.mjs +280 -0
  40. package/harness/AGENTS.md +49 -49
  41. package/package.json +1 -1
  42. package/skills/README.md +18 -18
  43. package/skills/browser-automation/SKILL.md +72 -72
  44. package/skills/pc-guardrails-generic/SKILL.md +2 -1
  45. package/skills/pc-make-architecture/SKILL.md +32 -32
  46. package/skills/pc-make-design/SKILL.md +45 -45
  47. package/skills/pc-make-engineer/signal-mapping.md +53 -53
  48. package/skills/pc-make-guardrails/SKILL.md +44 -44
  49. package/skills/pc-make-user-model/SKILL.md +56 -56
  50. package/skills/pc-plan-apply/SKILL.md +1 -1
  51. package/skills/pc-plan-apply/simple-mode.md +21 -21
  52. package/skills/pc-plan-archive/SKILL.md +66 -66
  53. package/skills/pc-plan-goal/branching.md +39 -39
  54. package/skills/pc-plan-goal/output.md +71 -71
  55. package/skills/pc-plan-quick/SKILL.md +46 -46
  56. package/skills/pc-plan-story/SKILL.md +93 -93
  57. package/skills/pc-repo-help/SKILL.md +87 -87
  58. package/skills/pc-repo-initialize/SKILL.md +119 -119
  59. package/skills/pc-repo-onboard/SKILL.md +32 -32
  60. package/skills/pc-repo-verify/SKILL.md +150 -150
  61. package/skills/pc-userstory-az/SKILL.md +71 -71
  62. package/skills/pc-userstory-browser/SKILL.md +64 -64
  63. package/skills/pc-userstory-gh/SKILL.md +63 -63
  64. package/skills/pc-userstory-jira/SKILL.md +74 -74
@@ -1,56 +1,56 @@
1
- ---
2
- name: pc-make-user-model
3
- description: Set the model for a tier (plan, build, or fast). Team-wide or user-local override. Invoked by the /make-user-model command.
4
- license: MIT
5
- ---
6
-
7
- Point one tier at one model, in the team config or in a machine-local override.
8
-
9
- ## Rules
10
-
11
- - Only `models.<tier>` in `.opencode/harness.json` or `.opencode/harness.user.json` changes. Agent files, `opencode.jsonc` and `tasks.md` are not this command's business, and tier variants are rebuilt from these configs at startup anyway.
12
- - Never guess the id behind `current`: read it from the status line. A guessed id writes a model that does not exist into the team's config.
13
- - Never write anything when the arguments do not parse. Print the usage and stop.
14
- - Preserve the file's other fields and its 2-space formatting.
15
-
16
- ## Contract
17
-
18
- ```
19
- /make-user-model <tier> <model>
20
- /make-user-model user <tier> <model>
21
- ```
22
-
23
- `user` writes `.opencode/harness.user.json`, which is gitignored and wins on this machine only; without it the target is `.opencode/harness.json`, which is shared. `<tier>` is exactly `plan`, `build` or `fast`. `<model>` is a fully-qualified id (`opencode/big-pickle`) or `current` for the model this session is running.
24
-
25
- No arguments means show the `models` block from both files, team first, then the usage. Change nothing.
26
-
27
- A team config that does not exist yet is a stop: onboarding has not run. A missing user config is created as `{ "models": {} }`.
28
-
29
- An id with no `/` in it is malformed; confirm before writing it:
30
-
31
- ```json
32
- {
33
- "questions": [
34
- {
35
- "header": "Malformed model id",
36
- "question": "\"<model>\" doesn't look like a valid model id (expected provider/model-id). Write it anyway?",
37
- "options": [
38
- { "label": "yes", "description": "Write the value as-is to the config file." },
39
- { "label": "no", "description": "Cancel. Do not write anything." }
40
- ]
41
- }
42
- ]
43
- }
44
- ```
45
-
46
- ## Report
47
-
48
- ```
49
- <team|user> config updated
50
- <tier> model -> <resolved-id>
51
- file: <path written>
52
- ```
53
-
54
- The change lands on the next opencode start, when `pc-subagent-tiers` reads the configs and rebuilds the tier variants.
55
-
56
- Arguments: `$ARGUMENTS`
1
+ ---
2
+ name: pc-make-user-model
3
+ description: Set the model for a tier (plan, build, or fast). Team-wide or user-local override. Invoked by the /make-user-model command.
4
+ license: MIT
5
+ ---
6
+
7
+ Point one tier at one model, in the team config or in a machine-local override.
8
+
9
+ ## Rules
10
+
11
+ - Only `models.<tier>` in `.opencode/harness.json` or `.opencode/harness.user.json` changes. Agent files, `opencode.jsonc` and `tasks.md` are not this command's business, and tier variants are rebuilt from these configs at startup anyway.
12
+ - Never guess the id behind `current`: read it from the status line. A guessed id writes a model that does not exist into the team's config.
13
+ - Never write anything when the arguments do not parse. Print the usage and stop.
14
+ - Preserve the file's other fields and its 2-space formatting.
15
+
16
+ ## Contract
17
+
18
+ ```
19
+ /make-user-model <tier> <model>
20
+ /make-user-model user <tier> <model>
21
+ ```
22
+
23
+ `user` writes `.opencode/harness.user.json`, which is gitignored and wins on this machine only; without it the target is `.opencode/harness.json`, which is shared. `<tier>` is exactly `plan`, `build` or `fast`. `<model>` is a fully-qualified id (`opencode/big-pickle`) or `current` for the model this session is running.
24
+
25
+ No arguments means show the `models` block from both files, team first, then the usage. Change nothing.
26
+
27
+ A team config that does not exist yet is a stop: onboarding has not run. A missing user config is created as `{ "models": {} }`.
28
+
29
+ An id with no `/` in it is malformed; confirm before writing it:
30
+
31
+ ```json
32
+ {
33
+ "questions": [
34
+ {
35
+ "header": "Malformed model id",
36
+ "question": "\"<model>\" doesn't look like a valid model id (expected provider/model-id). Write it anyway?",
37
+ "options": [
38
+ { "label": "yes", "description": "Write the value as-is to the config file." },
39
+ { "label": "no", "description": "Cancel. Do not write anything." }
40
+ ]
41
+ }
42
+ ]
43
+ }
44
+ ```
45
+
46
+ ## Report
47
+
48
+ ```
49
+ <team|user> config updated
50
+ <tier> model -> <resolved-id>
51
+ file: <path written>
52
+ ```
53
+
54
+ The change lands on the next opencode start, when `pc-subagent-tiers` reads the configs and rebuilds the tier variants.
55
+
56
+ Arguments: `$ARGUMENTS`
@@ -79,7 +79,7 @@ wave = pick groups whose file-sets are pairwise DISJOINT, capped at maxConcu
79
79
 
80
80
  **9. Progress guard.** If a full wave moved zero tasks to DONE: STOP (do not re-spawn the identical failing set). Otherwise recompute `eligible` and loop to step 5.
81
81
 
82
- **10. Verify.** In this (lead) session, run the project's lint, typecheck, test, build, and proposal-required validation commands. Every command must exit 0. On failure, reopen the offending tasks (uncheck, mark failed) so they re-enter `eligible` and run another wave. When every task is checked, no eligible task remains, and every command passes, report `VERIFIED` to the caller.
82
+ **10. Verify.** In this (lead) session, run the project's lint, typecheck, test, build, and proposal-required validation commands, then `node .opencode/scripts/check-diff.mjs`. Every command must exit 0. A `check-diff` failure lists file, line and fix: reopen the tasks that own those files. On failure, reopen the offending tasks (uncheck, mark failed) so they re-enter `eligible` and run another wave. When every task is checked, no eligible task remains, and every command passes, report `VERIFIED` to the caller.
83
83
 
84
84
  **11. Close.** Mark all `tasks.md` checkboxes, run `openspec status --change "<name>" --json`, and report progress (N/M tasks). The wave state in `.opencode/harness-run.json` persists for resume.
85
85
 
@@ -1,21 +1,21 @@
1
- # Simple mode: sequential in-session
2
-
3
- When the plan lives in the Todo pane (from `/plan-quick`) and no OpenSpec change exists:
4
-
5
- 1. Read the task list from the Todo pane (the `pending` items created by `/plan-quick`).
6
- 2. Create a feature branch if not already on one: `git switch -c feature/{slug}`. (Skip when the caller passed `start_from: load-plan`.)
7
- 3. Work through tasks one at a time, in order, directly in this session:
8
- - Read the task text from the Todo item.
9
- - Mark it `in_progress` via `todowrite`.
10
- - Implement it (edit files, run commands as needed).
11
- - Mark it `completed` via `todowrite`.
12
- - Commit the change: `git add <the paths this task wrote> && git commit -m "task {id}: {summary}"`. Unscoped staging is denied (`pc-system-reminders`).
13
- 4. After all tasks are done, run the project's typecheck/build check if one exists. Fix any errors.
14
- 5. Report: tasks N/N completed, commits made, branch name.
15
-
16
- Rules:
17
- - Work in this session only. No subagent spawning.
18
- - No OpenSpec commands.
19
- - Keep each commit focused on one task.
20
- - Use `todowrite` to track progress: `pending` -> `in_progress` -> `completed`.
21
- - Never mark a task `completed` that you did not finish. Use `cancelled` with the reason and continue with the next; a false green is invisible to whoever reads the report.
1
+ # Simple mode: sequential in-session
2
+
3
+ When the plan lives in the Todo pane (from `/plan-quick`) and no OpenSpec change exists:
4
+
5
+ 1. Read the task list from the Todo pane (the `pending` items created by `/plan-quick`).
6
+ 2. Create a feature branch if not already on one: `git switch -c feature/{slug}`. (Skip when the caller passed `start_from: load-plan`.)
7
+ 3. Work through tasks one at a time, in order, directly in this session:
8
+ - Read the task text from the Todo item.
9
+ - Mark it `in_progress` via `todowrite`.
10
+ - Implement it (edit files, run commands as needed).
11
+ - Mark it `completed` via `todowrite`.
12
+ - Commit the change: `git add <the paths this task wrote> && git commit -m "task {id}: {summary}"`. Unscoped staging is denied (`pc-system-reminders`).
13
+ 4. After all tasks are done, run the project's typecheck/build check if one exists, then `node .opencode/scripts/check-diff.mjs`. Fix any errors until both exit 0.
14
+ 5. Report: tasks N/N completed, commits made, branch name.
15
+
16
+ Rules:
17
+ - Work in this session only. No subagent spawning.
18
+ - No OpenSpec commands.
19
+ - Keep each commit focused on one task.
20
+ - Use `todowrite` to track progress: `pending` -> `in_progress` -> `completed`.
21
+ - Never mark a task `completed` that you did not finish. Use `cancelled` with the reason and continue with the next; a false green is invisible to whoever reads the report.
@@ -1,66 +1,66 @@
1
- ---
2
- name: pc-plan-archive
3
- description: Archive a completed OpenSpec change and update documentation. Interactive mode finds the oldest merged unarchived change and opens an archive PR; autonomous mode archives a named change in place on the current branch. Invoked by the /plan-archive command (interactive) and the plan-goal pipeline (autonomous).
4
- license: MIT
5
- ---
6
-
7
- # Plan Archive
8
-
9
- <!-- PC-OPTIMIZATION-MEMORY-START -->
10
- <!-- PC-OPTIMIZATION-MEMORY-END -->
11
-
12
- ## Input
13
-
14
- The caller provides (all optional):
15
- - A mode (see below). Default: `interactive`.
16
- - In autonomous mode: the change id to archive (required in that mode; the caller knows which change it just implemented).
17
-
18
- ## Modes
19
-
20
- - interactive (default): full flow below. Find the oldest unarchived change with a completed PR, confirm with the user, archive it, update docs with approval, and open an archive PR. No input required.
21
- - autonomous: the caller names the change to archive. Skip the working-tree prep, the PR lookup, the confirmation prompt, and the archive-PR step. Instead, archive in place on the current branch:
22
- 1. Archive the change by its id. Prefer the `@openspec-archive-change` skill if it is available. If it is not available, run the CLI directly, and it must be non-interactive, because there is no user to answer prompts:
23
-
24
- ```bash
25
- openspec archive "<change-id>" -y
26
- ```
27
-
28
- `-y` skips the confirmation prompt (without it the command blocks forever in an unattended run). Add `--skip-specs` only for infra/tooling/doc-only changes that produced no spec deltas. If the command reports the change is already archived, treat that as success.
29
- 2. Verify the archive actually moved. The change folder must no longer exist at `openspec/changes/<change-id>/`, and a dated copy must now exist under `openspec/changes/archive/` (the CLI renames it to `archive/YYYY-MM-DD-<change-id>/`):
30
-
31
- ```bash
32
- REPO_ROOT="$(git rev-parse --show-toplevel)"
33
- test ! -d "$REPO_ROOT/openspec/changes/<change-id>" \
34
- && ls -d "$REPO_ROOT/openspec/changes/archive/"*"<change-id>" >/dev/null 2>&1 \
35
- && echo ARCHIVED_OK || echo ARCHIVE_FAILED
36
- ```
37
-
38
- If this prints `ARCHIVE_FAILED`, run the archive once more and repeat the check. If it still fails, report it to the caller as a failure; do not pretend it succeeded.
39
- 3. Compare the archived change's specs against `ARCHITECTURE.md` and `DESIGN.md`; apply any needed doc updates directly (no approval prompt).
40
- 4. If the change was a bug fix or new functionality with important impact, check if `@pc-guardrails-project` exists and update it.
41
- 5. Do not commit or push: the caller owns the git operations.
42
- 6. The ARCHIVE stage is complete. Hand control back to the caller (the `/plan-goal` pipeline) so it continues with output. Do not stop or end the turn here; archiving is not the end of the run.
43
-
44
- ---
45
-
46
- ## Interactive flow
47
-
48
- Steps
49
-
50
- 1. Prepare working tree
51
-
52
- ```bash
53
- REPO_ROOT="$(git rev-parse --show-toplevel)"
54
- DEFAULT_BRANCH="$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')"
55
- [ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH="main"
56
- ```
57
-
58
- 1. If the tree has uncommitted changes: `git stash push -u -m "WIP before archive"` and tell the user their work is stashed (it is restored in step 6).
59
- 2. Sync the default branch (skip the pull if there is no `origin` remote):
60
-
61
- ```bash
62
- git switch "$DEFAULT_BRANCH" && git pull origin "$DEFAULT_BRANCH"
63
- ```
64
-
65
- <!-- PC-PLATFORM-ARCHIVE-START -->
66
- <!-- PC-PLATFORM-ARCHIVE-END -->
1
+ ---
2
+ name: pc-plan-archive
3
+ description: Archive a completed OpenSpec change and update documentation. Interactive mode finds the oldest merged unarchived change and opens an archive PR; autonomous mode archives a named change in place on the current branch. Invoked by the /plan-archive command (interactive) and the plan-goal pipeline (autonomous).
4
+ license: MIT
5
+ ---
6
+
7
+ # Plan Archive
8
+
9
+ <!-- PC-OPTIMIZATION-MEMORY-START -->
10
+ <!-- PC-OPTIMIZATION-MEMORY-END -->
11
+
12
+ ## Input
13
+
14
+ The caller provides (all optional):
15
+ - A mode (see below). Default: `interactive`.
16
+ - In autonomous mode: the change id to archive (required in that mode; the caller knows which change it just implemented).
17
+
18
+ ## Modes
19
+
20
+ - interactive (default): full flow below. Find the oldest unarchived change with a completed PR, confirm with the user, archive it, update docs with approval, and open an archive PR. No input required.
21
+ - autonomous: the caller names the change to archive. Skip the working-tree prep, the PR lookup, the confirmation prompt, and the archive-PR step. Instead, archive in place on the current branch:
22
+ 1. Archive the change by its id. Prefer the `@openspec-archive-change` skill if it is available. If it is not available, run the CLI directly, and it must be non-interactive, because there is no user to answer prompts:
23
+
24
+ ```bash
25
+ openspec archive "<change-id>" -y
26
+ ```
27
+
28
+ `-y` skips the confirmation prompt (without it the command blocks forever in an unattended run). Add `--skip-specs` only for infra/tooling/doc-only changes that produced no spec deltas. If the command reports the change is already archived, treat that as success.
29
+ 2. Verify the archive actually moved. The change folder must no longer exist at `openspec/changes/<change-id>/`, and a dated copy must now exist under `openspec/changes/archive/` (the CLI renames it to `archive/YYYY-MM-DD-<change-id>/`):
30
+
31
+ ```bash
32
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
33
+ test ! -d "$REPO_ROOT/openspec/changes/<change-id>" \
34
+ && ls -d "$REPO_ROOT/openspec/changes/archive/"*"<change-id>" >/dev/null 2>&1 \
35
+ && echo ARCHIVED_OK || echo ARCHIVE_FAILED
36
+ ```
37
+
38
+ If this prints `ARCHIVE_FAILED`, run the archive once more and repeat the check. If it still fails, report it to the caller as a failure; do not pretend it succeeded.
39
+ 3. Compare the archived change's specs against `ARCHITECTURE.md` and `DESIGN.md`; apply any needed doc updates directly (no approval prompt).
40
+ 4. If the change was a bug fix or new functionality with important impact, check if `@pc-guardrails-project` exists and update it.
41
+ 5. Do not commit or push: the caller owns the git operations.
42
+ 6. The ARCHIVE stage is complete. Hand control back to the caller (the `/plan-goal` pipeline) so it continues with output. Do not stop or end the turn here; archiving is not the end of the run.
43
+
44
+ ---
45
+
46
+ ## Interactive flow
47
+
48
+ Steps
49
+
50
+ 1. Prepare working tree
51
+
52
+ ```bash
53
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
54
+ DEFAULT_BRANCH="$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')"
55
+ [ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH="main"
56
+ ```
57
+
58
+ 1. If the tree has uncommitted changes: `git stash push -u -m "WIP before archive"` and tell the user their work is stashed (it is restored in step 6).
59
+ 2. Sync the default branch (skip the pull if there is no `origin` remote):
60
+
61
+ ```bash
62
+ git switch "$DEFAULT_BRANCH" && git pull origin "$DEFAULT_BRANCH"
63
+ ```
64
+
65
+ <!-- PC-PLATFORM-ARCHIVE-START -->
66
+ <!-- PC-PLATFORM-ARCHIVE-END -->
@@ -1,39 +1,39 @@
1
- # Branching procedure
2
-
3
- Resolve and record the branch names. If the invoking workflow already placed you on a feature branch (`feature/*`, `fix/*`, etc.), it owns the branch: do not stash, switch, pull, or rename. The sandbox hosting the workflow has no git credentials, so those commands would either corrupt the tree or hang, and the workflow has already cut the branch from the default branch. Treat its result as given.
4
-
5
- ```bash
6
- BRANCH="$(git branch --show-current)"
7
- case "$BRANCH" in
8
- feature/*|fix/*|chore/*|docs/*|refactor/*)
9
- START_BRANCH="$BRANCH"
10
- DEFAULT_BRANCH="$BRANCH"
11
- GOAL_STASH="none"
12
- ;;
13
- *)
14
- START_BRANCH="$BRANCH"
15
- DEFAULT_BRANCH="$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')"
16
- [ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH="main"
17
-
18
- # Stash uncommitted work when needed and record that the goal stash exists.
19
- git stash push -u -m "goal-wip"
20
- GOAL_STASH="goal-wip"
21
-
22
- # Create the feature branch from the synchronized default branch.
23
- git switch "$DEFAULT_BRANCH"
24
-
25
- if git remote get-url origin >/dev/null 2>&1; then
26
- git pull origin "$DEFAULT_BRANCH"
27
- fi
28
-
29
- git switch -c "feature/{slug}"
30
- BRANCH="$(git branch --show-current)"
31
- ;;
32
- esac
33
- ```
34
-
35
- Record the branch name and that `feature/{slug}` was applied unconditionally, so downstream phases can restore if they move off it.
36
-
37
- Everything through archive happens on `$BRANCH`.
38
-
39
- When a later phase renames `$BRANCH` to match the canonical change slug (Phase 3 of `pc-plan-goal`), skip the rename if the workflow already fixed the name. Renaming would call `git branch -m`, which a credentialless sandbox refuses, and the workflow's `create_pull_request` is told to use the branch as named. Detect this by checking that `$BRANCH` already starts with `feature/`; if it does, keep it.
1
+ # Branching procedure
2
+
3
+ Resolve and record the branch names. If the invoking workflow already placed you on a feature branch (`feature/*`, `fix/*`, etc.), it owns the branch: do not stash, switch, pull, or rename. The sandbox hosting the workflow has no git credentials, so those commands would either corrupt the tree or hang, and the workflow has already cut the branch from the default branch. Treat its result as given.
4
+
5
+ ```bash
6
+ BRANCH="$(git branch --show-current)"
7
+ case "$BRANCH" in
8
+ feature/*|fix/*|chore/*|docs/*|refactor/*)
9
+ START_BRANCH="$BRANCH"
10
+ DEFAULT_BRANCH="$BRANCH"
11
+ GOAL_STASH="none"
12
+ ;;
13
+ *)
14
+ START_BRANCH="$BRANCH"
15
+ DEFAULT_BRANCH="$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')"
16
+ [ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH="main"
17
+
18
+ # Stash uncommitted work when needed and record that the goal stash exists.
19
+ git stash push -u -m "goal-wip"
20
+ GOAL_STASH="goal-wip"
21
+
22
+ # Create the feature branch from the synchronized default branch.
23
+ git switch "$DEFAULT_BRANCH"
24
+
25
+ if git remote get-url origin >/dev/null 2>&1; then
26
+ git pull origin "$DEFAULT_BRANCH"
27
+ fi
28
+
29
+ git switch -c "feature/{slug}"
30
+ BRANCH="$(git branch --show-current)"
31
+ ;;
32
+ esac
33
+ ```
34
+
35
+ Record the branch name and that `feature/{slug}` was applied unconditionally, so downstream phases can restore if they move off it.
36
+
37
+ Everything through archive happens on `$BRANCH`.
38
+
39
+ When a later phase renames `$BRANCH` to match the canonical change slug (Phase 3 of `pc-plan-goal`), skip the rename if the workflow already fixed the name. Renaming would call `git branch -m`, which a credentialless sandbox refuses, and the workflow's `create_pull_request` is told to use the branch as named. Detect this by checking that `$BRANCH` already starts with `feature/`; if it does, keep it.
@@ -1,71 +1,71 @@
1
- # Output procedure
2
-
3
- Before output, require `verify`, `archive`, a clean working tree, no active change directory, and an archive directory for `{change-id}`.
4
-
5
- ## Restore stash
6
-
7
- If the goal created `goal-wip`, restore it after the mode-specific operation. When restoration conflicts, leave the stash intact, report its `git stash list` reference, and do not drop user work.
8
-
9
- ## Default mode
10
-
11
- Synchronize the default branch, merge, delete the feature branch, then restore the stash:
12
-
13
- ```bash
14
- git switch "$DEFAULT_BRANCH"
15
-
16
- if git remote get-url origin >/dev/null 2>&1; then
17
- git pull origin "$DEFAULT_BRANCH"
18
- fi
19
-
20
- git merge --no-ff "$BRANCH" -m "goal: {title} ({change-id})"
21
- git branch -d "$BRANCH"
22
- ```
23
-
24
- If the merge conflicts, abort it and use the failure policy. Do not push the default branch.
25
-
26
- ## Push mode
27
-
28
- Push the feature branch:
29
-
30
- ```bash
31
- git push -u origin "$BRANCH"
32
- ```
33
-
34
- Restore the stash and leave the branch available.
35
-
36
- ## PR mode
37
-
38
- Push the feature branch, then load `pc-ops-ship` to create a PR into `$DEFAULT_BRANCH`. Supply title, change id, functional summary, delivered acceptance criteria, task count, verification result, archive path, and commits. Do not merge the PR.
39
-
40
- Restore the stash.
41
-
42
- ## Branch mode
43
-
44
- Leave `$BRANCH` in place with its commits. Merge nothing, push nothing, delete nothing.
45
-
46
- Restore the stash.
47
-
48
- ## Final report
49
-
50
- Print:
51
-
52
- ```text
53
- Goal: {title}
54
- Change ID: {change-id}
55
- Scope classification: focused | standard | complex
56
- Functional outcome: {one-sentence result}
57
- Branch: {branch}
58
- Tasks: {completed}/{total}
59
- Acceptance criteria: {passed}/{total}
60
- Commits: {proposal, apply, archive}
61
- Verification: passed | failed
62
- Archived: yes | no
63
- Archive path: {path or none}
64
- Output mode: default | push | pr | branch
65
- Final state: merged locally | pushed branch | PR URL | branch preserved | branch preserved after failure
66
- Stash restoration: not needed | restored | preserved after conflict
67
- ```
68
-
69
- ## External gate
70
-
71
- An unattended caller must verify `openspec list --json` is empty and run the project's lint and typecheck commands before any later git operation.
1
+ # Output procedure
2
+
3
+ Before output, require `verify`, `archive`, a clean working tree, no active change directory, and an archive directory for `{change-id}`.
4
+
5
+ ## Restore stash
6
+
7
+ If the goal created `goal-wip`, restore it after the mode-specific operation. When restoration conflicts, leave the stash intact, report its `git stash list` reference, and do not drop user work.
8
+
9
+ ## Default mode
10
+
11
+ Synchronize the default branch, merge, delete the feature branch, then restore the stash:
12
+
13
+ ```bash
14
+ git switch "$DEFAULT_BRANCH"
15
+
16
+ if git remote get-url origin >/dev/null 2>&1; then
17
+ git pull origin "$DEFAULT_BRANCH"
18
+ fi
19
+
20
+ git merge --no-ff "$BRANCH" -m "goal: {title} ({change-id})"
21
+ git branch -d "$BRANCH"
22
+ ```
23
+
24
+ If the merge conflicts, abort it and use the failure policy. Do not push the default branch.
25
+
26
+ ## Push mode
27
+
28
+ Push the feature branch:
29
+
30
+ ```bash
31
+ git push -u origin "$BRANCH"
32
+ ```
33
+
34
+ Restore the stash and leave the branch available.
35
+
36
+ ## PR mode
37
+
38
+ Push the feature branch, then load `pc-ops-ship` to create a PR into `$DEFAULT_BRANCH`. Supply title, change id, functional summary, delivered acceptance criteria, task count, verification result, archive path, and commits. Do not merge the PR.
39
+
40
+ Restore the stash.
41
+
42
+ ## Branch mode
43
+
44
+ Leave `$BRANCH` in place with its commits. Merge nothing, push nothing, delete nothing.
45
+
46
+ Restore the stash.
47
+
48
+ ## Final report
49
+
50
+ Print:
51
+
52
+ ```text
53
+ Goal: {title}
54
+ Change ID: {change-id}
55
+ Scope classification: focused | standard | complex
56
+ Functional outcome: {one-sentence result}
57
+ Branch: {branch}
58
+ Tasks: {completed}/{total}
59
+ Acceptance criteria: {passed}/{total}
60
+ Commits: {proposal, apply, archive}
61
+ Verification: passed | failed
62
+ Archived: yes | no
63
+ Archive path: {path or none}
64
+ Output mode: default | push | pr | branch
65
+ Final state: merged locally | pushed branch | PR URL | branch preserved | branch preserved after failure
66
+ Stash restoration: not needed | restored | preserved after conflict
67
+ ```
68
+
69
+ ## External gate
70
+
71
+ An unattended caller must verify `openspec list --json` is empty and run the project's lint and typecheck commands before any later git operation.
@@ -1,46 +1,46 @@
1
- ---
2
- name: pc-plan-quick
3
- description: "Quick plan: analyze the codebase and create a task checklist using the Todo pane. No files, no OpenSpec. Invoked by the /plan-quick command."
4
- license: MIT
5
- ---
6
-
7
- Lightweight planning for a change that is already clear: read the codebase, write the task list to the Todo pane, stop. Use `/plan-explore` then `/plan-propose` instead when the idea is half-formed, the alternatives need thinking through, or the result should outlive the session.
8
-
9
- ## Rules
10
-
11
- - Never write, edit, or create a file. The only artefacts are Todo items and one question, so there is nothing to review afterwards and nothing to undo.
12
- - Never start the work, and never invoke `/plan-apply` or `/plan-propose` on the user's behalf. The question at the end is where they choose.
13
-
14
- ## Contracts
15
-
16
- One Todo item per task, in dependency order, each one action naming the files it touches:
17
-
18
- ```json
19
- {
20
- "todos": [
21
- { "content": "Add Project model to src/types.ts", "status": "pending", "priority": "high" },
22
- { "content": "Add projectId field to LoopOptions in src/types.ts", "status": "pending", "priority": "high" },
23
- { "content": "Create Project RPC endpoints in src/rpc/project/", "status": "pending", "priority": "medium" },
24
- { "content": "Build Accept page UI in src/board/components/CreateForm.tsx", "status": "pending", "priority": "medium" },
25
- { "content": "Run typecheck and fix errors", "status": "pending", "priority": "low" }
26
- ]
27
- }
28
- ```
29
-
30
- Then ask:
31
-
32
- ```json
33
- {
34
- "questions": [
35
- {
36
- "header": "What next",
37
- "question": "What next?",
38
- "options": [
39
- { "label": "/plan-apply", "description": "Implement these tasks now (creates a feature branch and works through them)." },
40
- { "label": "/plan-propose", "description": "Turn this into a full OpenSpec proposal with agent assignments." },
41
- { "label": "Start on specific tasks", "description": "Tell me which tasks to start on." }
42
- ]
43
- }
44
- ]
45
- }
46
- ```
1
+ ---
2
+ name: pc-plan-quick
3
+ description: "Quick plan: analyze the codebase and create a task checklist using the Todo pane. No files, no OpenSpec. Invoked by the /plan-quick command."
4
+ license: MIT
5
+ ---
6
+
7
+ Lightweight planning for a change that is already clear: read the codebase, write the task list to the Todo pane, stop. Use `/plan-explore` then `/plan-propose` instead when the idea is half-formed, the alternatives need thinking through, or the result should outlive the session.
8
+
9
+ ## Rules
10
+
11
+ - Never write, edit, or create a file. The only artefacts are Todo items and one question, so there is nothing to review afterwards and nothing to undo.
12
+ - Never start the work, and never invoke `/plan-apply` or `/plan-propose` on the user's behalf. The question at the end is where they choose.
13
+
14
+ ## Contracts
15
+
16
+ One Todo item per task, in dependency order, each one action naming the files it touches:
17
+
18
+ ```json
19
+ {
20
+ "todos": [
21
+ { "content": "Add Project model to src/types.ts", "status": "pending", "priority": "high" },
22
+ { "content": "Add projectId field to LoopOptions in src/types.ts", "status": "pending", "priority": "high" },
23
+ { "content": "Create Project RPC endpoints in src/rpc/project/", "status": "pending", "priority": "medium" },
24
+ { "content": "Build Accept page UI in src/board/components/CreateForm.tsx", "status": "pending", "priority": "medium" },
25
+ { "content": "Run typecheck and check-diff, fix errors", "status": "pending", "priority": "low" }
26
+ ]
27
+ }
28
+ ```
29
+
30
+ Then ask:
31
+
32
+ ```json
33
+ {
34
+ "questions": [
35
+ {
36
+ "header": "What next",
37
+ "question": "What next?",
38
+ "options": [
39
+ { "label": "/plan-apply", "description": "Implement these tasks now (creates a feature branch and works through them)." },
40
+ { "label": "/plan-propose", "description": "Turn this into a full OpenSpec proposal with agent assignments." },
41
+ { "label": "Start on specific tasks", "description": "Tell me which tasks to start on." }
42
+ ]
43
+ }
44
+ ]
45
+ }
46
+ ```