acstack 0.0.0-stage → 0.47.1
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.
- package/.claude-plugin/plugin.json +19 -0
- package/LICENSE +21 -0
- package/README.md +389 -2
- package/THIRD_PARTY_NOTICES +14 -0
- package/TROUBLESHOOTING.md +225 -0
- package/agents/codex/frontend-verifier.toml +352 -0
- package/agents/codex/task-checker.toml +345 -0
- package/agents/codex/task-executor.toml +157 -0
- package/agents/codex/test-writer.toml +149 -0
- package/agents/frontend-verifier.md +351 -0
- package/agents/task-checker.md +344 -0
- package/agents/task-executor.md +156 -0
- package/agents/test-writer.md +148 -0
- package/assets/playwriter-bridge/build-launcher.ps1 +32 -0
- package/assets/playwriter-bridge/doctor.ps1 +450 -0
- package/assets/playwriter-bridge/launcher-src.cs +131 -0
- package/assets/playwriter-bridge/opener.js +330 -0
- package/assets/playwriter-bridge/opener.ps1 +63 -0
- package/assets/playwriter-bridge/register-tasks.ps1 +328 -0
- package/assets/playwriter-bridge/relay.ps1 +50 -0
- package/assets/playwriter-bridge/stop.ps1 +125 -0
- package/assets/playwriter-bridge/sync.ps1 +271 -0
- package/assets/playwriter-bridge/tunnel.ps1 +325 -0
- package/assets/playwriter-bridge/vm-free-port.sh +166 -0
- package/assets/terminal-workspace/client-keybindings.md +87 -0
- package/assets/terminal-workspace/config.example.yaml +334 -0
- package/assets/terminal-workspace/setup.sh +4404 -0
- package/cli/README.md +47 -0
- package/cli/bin/acstack.js +3 -0
- package/cli/dist/index.js +25984 -0
- package/cli/dist/index.js.map +7 -0
- package/cli/package.json +59 -0
- package/docs/adr/0001-ste-writing-standard.md +16 -0
- package/docs/adr/0002-version-gate-not-auto-bump.md +35 -0
- package/docs/adr/0003-handoff-ack-command.md +19 -0
- package/docs/adr/0004-dev-setup-per-host.md +13 -0
- package/docs/adr/0005-two-orchestrators-per-host.md +25 -0
- package/docs/adr/0006-document-opener-service.md +89 -0
- package/docs/adr/0007-lead-check-reads-the-transcript.md +87 -0
- package/docs/adr/0008-cli-audits-skill-interviews.md +37 -0
- package/docs/adr/0009-verify-the-write-not-the-writer.md +51 -0
- package/docs/adr/0010-promote-dev-to-main-by-fast-forward.md +115 -0
- package/docs/adr/0011-node-header-is-the-edge-encoding.md +20 -0
- package/docs/adr/0012-node-kind-is-a-closed-set-of-five.md +31 -0
- package/docs/adr/0013-the-diagram-renderer-is-pure.md +23 -0
- package/docs/adr/0014-reading-a-node-hides-its-generated-diagram.md +29 -0
- package/docs/adr/0015-a-node-id-links-to-its-issue-through-an-anchor.md +37 -0
- package/docs/adr/0016-the-map-root-carries-no-status-of-its-own.md +21 -0
- package/docs/adr/0017-call-impeccable-copy-only-its-questions.md +13 -0
- package/docs/adr/index.md +17 -0
- package/docs/config-reference.md +572 -0
- package/docs/dev-setups.md +164 -0
- package/docs/migrate-0.8.md +28 -0
- package/docs/playwriter-bridge-windows.md +15 -0
- package/docs/terminal-workspace-keys.md +137 -0
- package/docs/terminal-workspace.md +1780 -0
- package/docs/workflows.md +309 -0
- package/hooks/ac-writing-style-reminder.sh +86 -0
- package/hooks/context-pressure.sh +583 -0
- package/hooks/hooks.json +50 -0
- package/hooks/session-start-handoff.sh +165 -0
- package/hooks/session-start.sh +214 -0
- package/orchestrator/AGENTS.md +532 -0
- package/output-styles/ac-writing-style.md +286 -0
- package/package.json +50 -4
- package/pi/agents/frontend-verifier.md +357 -0
- package/pi/agents/task-checker.md +348 -0
- package/pi/agents/task-executor.md +160 -0
- package/pi/agents/test-writer.md +154 -0
- package/pi/extension.ts +723 -0
- package/profiles/fullstack-python.yaml +29 -0
- package/profiles/node-typescript.yaml +23 -0
- package/profiles/python.yaml +24 -0
- package/skills/archive/SKILL.md +160 -0
- package/skills/bootstrap/SKILL.md +109 -0
- package/skills/bridge/HANDOFF.md +93 -0
- package/skills/bridge/SKILL-VM.md +292 -0
- package/skills/bridge/SKILL-WINDOWS.md +526 -0
- package/skills/bridge/SKILL.md +121 -0
- package/skills/browser-verify/SKILL.md +229 -0
- package/skills/code-review/SKILL.md +44 -0
- package/skills/commit/SKILL.md +106 -0
- package/skills/compact-and-continue/SKILL.md +241 -0
- package/skills/explore/SKILL.md +149 -0
- package/skills/grilling/SKILL.md +134 -0
- package/skills/handoff/SKILL.md +250 -0
- package/skills/handoff/launch-herdr.md +197 -0
- package/skills/handoff/launch-without-herdr.md +30 -0
- package/skills/handoff/lead-check.md +59 -0
- package/skills/handoff/outcomes.md +162 -0
- package/skills/handoff/running-agent.md +50 -0
- package/skills/handoff/watch.md +115 -0
- package/skills/host/SKILL.md +247 -0
- package/skills/host/detect-host.sh +297 -0
- package/skills/host/herdr.md +79 -0
- package/skills/host/install-herdr-block.sh +467 -0
- package/skills/host/install-orca.sh +512 -0
- package/skills/host/notes.md +97 -0
- package/skills/host/orca.md +160 -0
- package/skills/host/questions.md +163 -0
- package/skills/host/report.md +42 -0
- package/skills/implement/SKILL.md +230 -0
- package/skills/implement/decision-log.md +62 -0
- package/skills/implement/design-pass.md +32 -0
- package/skills/implement/relaxed-tdd.md +28 -0
- package/skills/map/SKILL.md +250 -0
- package/skills/map/frontend.md +227 -0
- package/skills/map/trackers/files.md +74 -0
- package/skills/map/trackers/github.md +180 -0
- package/skills/map/visuals.md +387 -0
- package/skills/new-worktree/SKILL.md +155 -0
- package/skills/new-worktree/detect-orchestrator.sh +328 -0
- package/skills/new-worktree/detect-orchestrator.test.sh +894 -0
- package/skills/new-worktree/herdr.md +84 -0
- package/skills/new-worktree/orca.md +101 -0
- package/skills/pre-commit-review/SKILL.md +242 -0
- package/skills/pre-commit-review/auto-fix.md +19 -0
- package/skills/pre-commit-review/interactive.md +35 -0
- package/skills/quick-fix/SKILL.md +125 -0
- package/skills/record-context/SKILL.md +106 -0
- package/skills/setup/SKILL.md +250 -0
- package/skills/setup/browser.md +123 -0
- package/skills/setup/design-review.md +97 -0
- package/skills/setup/first-run.md +114 -0
- package/skills/setup/report.md +68 -0
- package/skills/setup/row-fixes.md +196 -0
- package/skills/setup/terminal-workspace.md +153 -0
- package/skills/sync/SKILL.md +171 -0
- package/skills/teardown-worktree/SKILL.md +245 -0
- package/skills/teardown-worktree/detector.md +39 -0
- package/skills/teardown-worktree/herdr.md +113 -0
- package/skills/teardown-worktree/orca.md +61 -0
- package/skills/terminal-workspace/SKILL.md +249 -0
- package/skills/terminal-workspace/components.md +36 -0
- package/skills/terminal-workspace/config-choices.md +69 -0
- package/skills/terminal-workspace/emulator-keys.md +48 -0
- package/skills/terminal-workspace/headless-clipboard.md +175 -0
- package/skills/terminal-workspace/turn-off-and-update.md +104 -0
- package/skills/test-conventions/SKILL.md +59 -0
- package/skills/visual-docs/SKILL.md +246 -0
- package/skills/writing/SKILL.md +231 -0
- package/skills/writing/examples.md +153 -0
- package/skills/writing/vocabulary.md +96 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Fullstack Python (backend) + Node/TS (frontend) profile for acstack
|
|
2
|
+
# Used by /acstack:setup to generate acstack/project.yaml
|
|
3
|
+
|
|
4
|
+
commands:
|
|
5
|
+
test: "pytest tests/ --tb=short -x"
|
|
6
|
+
test_collect: "pytest tests/ --co -q 2>/dev/null | tail -1 | grep -oP '\\d+'"
|
|
7
|
+
build: null
|
|
8
|
+
lint: "ruff check --fix"
|
|
9
|
+
typecheck: null
|
|
10
|
+
format: "ruff format"
|
|
11
|
+
|
|
12
|
+
directories:
|
|
13
|
+
source: "src/"
|
|
14
|
+
tests: "tests/"
|
|
15
|
+
|
|
16
|
+
test_markers:
|
|
17
|
+
exclude: "slow,integration"
|
|
18
|
+
|
|
19
|
+
venv:
|
|
20
|
+
activate: "source .venv/bin/activate"
|
|
21
|
+
|
|
22
|
+
frontend:
|
|
23
|
+
directory: "frontend/"
|
|
24
|
+
dev_server_url: "http://localhost:3000"
|
|
25
|
+
dev_server_check: "curl -s -o /dev/null -w '%{http_code}' http://localhost:3000"
|
|
26
|
+
commands:
|
|
27
|
+
build: "npx tsc --noEmit"
|
|
28
|
+
lint: "npm run lint -- --fix"
|
|
29
|
+
test: "npm test"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Node/TypeScript project profile for acstack
|
|
2
|
+
# Used by /acstack:setup to generate acstack/project.yaml
|
|
3
|
+
|
|
4
|
+
commands:
|
|
5
|
+
test: "npm test"
|
|
6
|
+
test_collect: null
|
|
7
|
+
build: "npm run build"
|
|
8
|
+
lint: "npm run lint -- --fix"
|
|
9
|
+
typecheck: "npx tsc --noEmit"
|
|
10
|
+
format: "npx prettier --write ."
|
|
11
|
+
|
|
12
|
+
directories:
|
|
13
|
+
source: "src/"
|
|
14
|
+
tests: "tests/"
|
|
15
|
+
|
|
16
|
+
test_markers:
|
|
17
|
+
exclude: null
|
|
18
|
+
|
|
19
|
+
venv: null
|
|
20
|
+
|
|
21
|
+
frontend:
|
|
22
|
+
dev_server_url: "http://localhost:3000"
|
|
23
|
+
dev_server_check: "curl -s -o /dev/null -w '%{http_code}' http://localhost:3000"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Python project profile for acstack
|
|
2
|
+
# Used by /acstack:setup to generate acstack/project.yaml
|
|
3
|
+
|
|
4
|
+
commands:
|
|
5
|
+
test: "pytest tests/ --tb=short -x"
|
|
6
|
+
test_collect: "pytest tests/ --co -q 2>/dev/null | tail -1 | grep -oP '\\d+'"
|
|
7
|
+
build: null
|
|
8
|
+
lint: "ruff check --fix"
|
|
9
|
+
typecheck: "mypy ."
|
|
10
|
+
format: "ruff format"
|
|
11
|
+
|
|
12
|
+
directories:
|
|
13
|
+
source: "src/"
|
|
14
|
+
tests: "tests/"
|
|
15
|
+
|
|
16
|
+
test_markers:
|
|
17
|
+
# Markers to exclude from default test runs (comma-separated for pytest -m)
|
|
18
|
+
exclude: "slow,integration"
|
|
19
|
+
|
|
20
|
+
venv:
|
|
21
|
+
# If set, commands are prefixed with activation
|
|
22
|
+
activate: "source .venv/bin/activate"
|
|
23
|
+
|
|
24
|
+
frontend: null
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: archive
|
|
3
|
+
description: Close out a cleared map – one whose frontier is empty with no fog and no claims left – by verifying the durable residue, meaning what the effort leaves behind in living specs, ADRs and the glossary, was extracted, then closing the root and disposing of the nodes per workflow.maps.persist. Invoke when a map has just been cleared, when the last node on a map resolves, or when the user asks to archive or close out a map. Refuses and asks first if anything is still open. Also archives legacy acstack/changes/ directories from the pre-map workflow.
|
|
4
|
+
argument-hint: "[map or legacy change name]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## User input
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
$ARGUMENTS
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You **MUST** consider the user input before proceeding (if not empty).
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
A map is scaffolding. It exists to clear fog – the questions nobody could
|
|
18
|
+
state precisely when the effort started.
|
|
19
|
+
|
|
20
|
+
Once the fog clears, the answers belong in living specs, ADRs and the
|
|
21
|
+
glossary, not in a second copy that drifts. That is the residue – what
|
|
22
|
+
survives the map.
|
|
23
|
+
|
|
24
|
+
Archive verifies the residue reached those three places. It then closes the
|
|
25
|
+
map's root node and disposes of the rest.
|
|
26
|
+
|
|
27
|
+
## Step 1: Locate the map
|
|
28
|
+
|
|
29
|
+
If `$ARGUMENTS` names a map, use it. Otherwise list maps on the configured
|
|
30
|
+
tracker (`workflow.maps.tracker`): `ls acstack/maps/` on the files backend,
|
|
31
|
+
`gh label list --search "map:" --json name` on GitHub.
|
|
32
|
+
|
|
33
|
+
If exactly one, use it. If several, ask. If `$ARGUMENTS` names a legacy
|
|
34
|
+
`acstack/changes/` directory instead, jump to Legacy below.
|
|
35
|
+
|
|
36
|
+
## Step 2: Verify no open work remains
|
|
37
|
+
|
|
38
|
+
A map counts as cleared when nothing remains to work – no open nodes, no
|
|
39
|
+
fog, no claims. Check all three on the files backend:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
~/.claude/acstack/bin/acstack node list --map <name> --status open --json
|
|
43
|
+
~/.claude/acstack/bin/acstack node list --map <name> --status fog --json
|
|
44
|
+
~/.claude/acstack/bin/acstack node list --map <name> --status claimed --json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
On GitHub, compose the same checks per `trackers/github.md` in the map skill.
|
|
48
|
+
`gh issue list --label "map:<name>" --state open` must come back empty, or
|
|
49
|
+
hold the issue labelled `root-node` alone. Any other open issue is open, fog
|
|
50
|
+
or claimed, and all three fail the gate.
|
|
51
|
+
|
|
52
|
+
Never run the files commands against a GitHub-tracked map. They come back
|
|
53
|
+
empty because the directory does not exist, so the gate would pass on no
|
|
54
|
+
evidence.
|
|
55
|
+
|
|
56
|
+
All three must come back empty, apart from the root.
|
|
57
|
+
|
|
58
|
+
The root is the map's one node with no `answers`, and on GitHub it carries the
|
|
59
|
+
`root-node` label. It stays open until Step 4 closes it. Ignore it in all
|
|
60
|
+
three lists – a list holding the root alone still passes the gate.
|
|
61
|
+
|
|
62
|
+
Count open nodes directly rather than through the frontier query, because the
|
|
63
|
+
frontier only lists nodes with no unresolved blockers. Two nodes that block
|
|
64
|
+
each other show an empty frontier while both questions stay open. An empty
|
|
65
|
+
frontier is therefore no proof of a cleared map.
|
|
66
|
+
|
|
67
|
+
If anything remains, WARN with what it is and ask for confirmation –
|
|
68
|
+
archiving an uncleared map throws away open questions.
|
|
69
|
+
|
|
70
|
+
## Step 3: Extract the residue
|
|
71
|
+
|
|
72
|
+
Walk the resolved nodes – read them in order, root first, then each node that
|
|
73
|
+
hangs off it. On the files backend, run `acstack node walk --map <name> --full`.
|
|
74
|
+
On GitHub, compose the walk per `trackers/github.md`.
|
|
75
|
+
|
|
76
|
+
Check each resolution left what it should have:
|
|
77
|
+
|
|
78
|
+
1. **Living specs** – behaviour the effort built should already be in
|
|
79
|
+
`acstack/specs/` via commit-time sync. Spot-check the affected domains.
|
|
80
|
+
Fix gaps on sight per the Spec Correction Protocol.
|
|
81
|
+
|
|
82
|
+
2. **ADRs and glossary** – invoke `record-context` for any resolved decision
|
|
83
|
+
that meets the bar and that nobody recorded. This is the last chance.
|
|
84
|
+
|
|
85
|
+
3. **Out-of-scope nodes** – report them. A scope boundary is worth the user
|
|
86
|
+
hearing once more before the map disappears.
|
|
87
|
+
|
|
88
|
+
4. **The decision log** – read `<main checkout>/acstack/.decisions/<name>.tsv`
|
|
89
|
+
if it exists. The main checkout is `dirname` of `git rev-parse
|
|
90
|
+
--path-format=absolute --git-common-dir`.
|
|
91
|
+
|
|
92
|
+
afk runs append one row per decision an agent made alone. Hand each
|
|
93
|
+
lasting decision to `record-context`. A later row supersedes an earlier
|
|
94
|
+
one it contradicts.
|
|
95
|
+
|
|
96
|
+
## Step 4: Close the root
|
|
97
|
+
|
|
98
|
+
The root carries no status of its own – it stays open while any node below it
|
|
99
|
+
still needs work. Step 2 proved nothing does. Resolve the root now.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# files backend
|
|
103
|
+
~/.claude/acstack/bin/acstack node update <root id> --map <name> --status resolved
|
|
104
|
+
|
|
105
|
+
# github backend
|
|
106
|
+
gh issue close <root issue number> --reason completed
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
A root the map already resolved or closed stays that way. Never reopen it.
|
|
110
|
+
|
|
111
|
+
## Step 5: Dispose of the nodes
|
|
112
|
+
|
|
113
|
+
**Confirm first when you invoked this yourself.** A user who typed
|
|
114
|
+
`/acstack:archive` has already asked for disposal – proceed.
|
|
115
|
+
|
|
116
|
+
If you reached this skill on your own after a map cleared, name what you
|
|
117
|
+
will delete or move. Then wait for the user's go-ahead. Deletion is
|
|
118
|
+
irreversible and they never asked for it.
|
|
119
|
+
|
|
120
|
+
`workflow.maps.persist` in `acstack/project.yaml` decides (default `false`):
|
|
121
|
+
|
|
122
|
+
| Value | Action |
|
|
123
|
+
| ----------------- | ------------------------------------------------------------ |
|
|
124
|
+
| `false` (default) | delete `acstack/maps/<name>/` |
|
|
125
|
+
| `true` | move the nodes to `acstack/archive/[YYYY-MM-DD]-[name]/nodes/` |
|
|
126
|
+
|
|
127
|
+
Default is delete because keeping the nodes leaves a second copy of every
|
|
128
|
+
decision, and the two drift. On the GitHub tracker there is nothing to
|
|
129
|
+
dispose – closed issues are already the archive.
|
|
130
|
+
|
|
131
|
+
Also dispose of `acstack/handoffs/<name>/` if it exists. Consumed handoffs
|
|
132
|
+
hold conversation content and should not outlive the map they served.
|
|
133
|
+
|
|
134
|
+
Delete the map's decision log, `<main checkout>/acstack/.decisions/<name>.tsv`,
|
|
135
|
+
on either tracker. Step 3 already extracted what it held. Leave the directory
|
|
136
|
+
and its `.gitignore` for the next map.
|
|
137
|
+
|
|
138
|
+
## Step 6: Report
|
|
139
|
+
|
|
140
|
+
- Nodes resolved / out-of-scope counts
|
|
141
|
+
- Residue: domains spot-checked, ADRs and glossary entries written
|
|
142
|
+
- Disposal: deleted, or archive path
|
|
143
|
+
- Reminder: commit with `/acstack:commit`
|
|
144
|
+
|
|
145
|
+
## Legacy: archiving a `acstack/changes/` directory
|
|
146
|
+
|
|
147
|
+
The pre-map workflow created changes that hold proposal.md, design.md and
|
|
148
|
+
tasks.md. They still archive the old way, so an upgrade never strands work:
|
|
149
|
+
|
|
150
|
+
1. Read the change's artifacts. Derive the affected domains from the file
|
|
151
|
+
paths in `tasks.md` via `acstack/domain-map.yaml`.
|
|
152
|
+
|
|
153
|
+
2. For each domain, merge what the feature ADDED, MODIFIED or REMOVED into
|
|
154
|
+
`acstack/specs/[domain]/spec.md`.
|
|
155
|
+
|
|
156
|
+
3. Write a `delta.md` into the change directory.
|
|
157
|
+
|
|
158
|
+
Then run the CLI's `acstack archive <name>`. It moves the artifacts,
|
|
159
|
+
delta included, to `acstack/changes/archive/[YYYY-MM-DD]-[change-name]/`.
|
|
160
|
+
It also removes the change from `acstack/changes/`.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bootstrap
|
|
3
|
+
description: Multi-pass AI crawl to generate initial living specs from the existing codebase. Use when acstack/specs/ domains need their initial spec.md files bootstrapped from code.
|
|
4
|
+
argument-hint: "[domain-names (optional)]"
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## User input
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
$ARGUMENTS
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Consider the user input before you proceed, if it is not empty.
|
|
15
|
+
|
|
16
|
+
## Purpose
|
|
17
|
+
|
|
18
|
+
This skill bootstraps cumulative living specs in `acstack/specs/`. It crawls the existing codebase with multiple independent AI passes. It then merges the passes and validates the results.
|
|
19
|
+
|
|
20
|
+
**IMPORTANT**: This is a one-time bootstrapping operation. Only run when `acstack/specs/` domains have no `spec.md` files yet.
|
|
21
|
+
|
|
22
|
+
## Your role: orchestrator only
|
|
23
|
+
|
|
24
|
+
**You do NOT read code, explore the codebase, or write specs yourself.**
|
|
25
|
+
|
|
26
|
+
Your job is to:
|
|
27
|
+
|
|
28
|
+
1. Run the pre-flight check (read domain-map.yaml)
|
|
29
|
+
2. Launch subagents with the prompts below
|
|
30
|
+
3. Pass outputs from one phase to the next
|
|
31
|
+
4. Present summaries to the user for review
|
|
32
|
+
5. Coordinate the phases sequentially
|
|
33
|
+
|
|
34
|
+
## Pre-flight check
|
|
35
|
+
|
|
36
|
+
1. Read `acstack/domain-map.yaml` to get the list of domains and their file path mappings.
|
|
37
|
+
2. If `$ARGUMENTS` specifies domain names, filter to only those domains.
|
|
38
|
+
3. Check if any `acstack/specs/*/spec.md` files already exist:
|
|
39
|
+
- If specs exist, warn the user. Ask for confirmation before overwriting.
|
|
40
|
+
- If no specs exist, proceed automatically.
|
|
41
|
+
|
|
42
|
+
## Phase 1: independent exploration (passes 1-3)
|
|
43
|
+
|
|
44
|
+
Launch **3 parallel `Explore` subagents** at once. Each gets a different exploration strategy:
|
|
45
|
+
|
|
46
|
+
### Pass 1 – entry points strategy
|
|
47
|
+
|
|
48
|
+
Explore from entry points (main files, route handlers, API endpoints, page components) to discover functionality domain by domain.
|
|
49
|
+
|
|
50
|
+
### Pass 2 – data models strategy
|
|
51
|
+
|
|
52
|
+
Explore from data models outward (database models, schemas, interfaces) to map data flow from storage through services to API to UI.
|
|
53
|
+
|
|
54
|
+
### Pass 3 – tests strategy
|
|
55
|
+
|
|
56
|
+
Explore from test files to understand expected behaviors by reading test names, assertions, and cross-referencing with source code.
|
|
57
|
+
|
|
58
|
+
Each pass outputs domain drafts using this format:
|
|
59
|
+
|
|
60
|
+
```markdown
|
|
61
|
+
# [Domain Name] - Living Specification
|
|
62
|
+
|
|
63
|
+
## Overview
|
|
64
|
+
[1-2 paragraph description]
|
|
65
|
+
|
|
66
|
+
## Key Entities
|
|
67
|
+
[List major classes, services, models]
|
|
68
|
+
|
|
69
|
+
## Functional Requirements
|
|
70
|
+
|
|
71
|
+
### FR-001: [Requirement Name]
|
|
72
|
+
- **Description**: [What the system does]
|
|
73
|
+
- **Behavior**: Given [precondition], When [action], Then [result]
|
|
74
|
+
- **Source**: [File path where this is implemented]
|
|
75
|
+
|
|
76
|
+
### FR-002: ...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Write each functional requirement (FR) per the `writing` skill.
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
## Integration Points
|
|
83
|
+
## Configuration
|
|
84
|
+
## Constraints & Invariants
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Phase 2: judge merge (pass 4)
|
|
88
|
+
|
|
89
|
+
Launch a single subagent to merge the 3 independent drafts per domain. It resolves conflicts, deduplicates, and picks the most accurate description for each FR.
|
|
90
|
+
|
|
91
|
+
## Phase 3: validation (passes 5-7)
|
|
92
|
+
|
|
93
|
+
Launch 3 parallel Explore subagents to validate ALL domains independently – each checks that FRs match actual code behavior.
|
|
94
|
+
|
|
95
|
+
## Phase 4: correction merge (pass 8)
|
|
96
|
+
|
|
97
|
+
Launch a single subagent to apply validated corrections from Phase 3.
|
|
98
|
+
|
|
99
|
+
## Phase 5: human review (pass 9)
|
|
100
|
+
|
|
101
|
+
Present a summary to the user. Ask: "Review the specs in `acstack/specs/`. Want to edit any domain before finalizing?"
|
|
102
|
+
|
|
103
|
+
## Phase 6: finalization (pass 10)
|
|
104
|
+
|
|
105
|
+
Launch a single subagent to finalize all specs. It removes markers, makes sure the formatting is consistent, and re-numbers FR entries.
|
|
106
|
+
|
|
107
|
+
## Completion
|
|
108
|
+
|
|
109
|
+
Report: the number of domain specs created, the total functional requirements, and the suggested next step.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Cross-device handoff format
|
|
2
|
+
|
|
3
|
+
The bridge spans two devices. When a coding agent on one side needs the
|
|
4
|
+
other side to act, it emits a **handoff block** in this exact shape:
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
--- BEGIN <WINDOWS|VM>-SIDE HANDOFF ---
|
|
8
|
+
Context: <one line describing what happened and why the other side must act>
|
|
9
|
+
Run on <device>:
|
|
10
|
+
<exact command(s)>
|
|
11
|
+
Expected result:
|
|
12
|
+
<exact success criterion>
|
|
13
|
+
Report back:
|
|
14
|
+
<exact output the requesting side needs>
|
|
15
|
+
--- END <WINDOWS|VM>-SIDE HANDOFF ---
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The `WINDOWS-SIDE` or `VM-SIDE` tag names the side that **produced** the
|
|
19
|
+
block, so the other side knows who asked. `Run on <device>` names who
|
|
20
|
+
**executes** it.
|
|
21
|
+
|
|
22
|
+
The other side pastes the block verbatim into another coding agent. If
|
|
23
|
+
the user on that side has no coding agent, they paste it into a plain
|
|
24
|
+
PowerShell or SSH shell instead.
|
|
25
|
+
|
|
26
|
+
## Worked example 1 – Windows → VM, free a stuck port
|
|
27
|
+
|
|
28
|
+
`doctor.ps1` produces this block on the Windows laptop when
|
|
29
|
+
tunnel-<host>.log shows the stuck-port signature:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
--- BEGIN WINDOWS-SIDE HANDOFF (to VM agent on vm1.example.com) ---
|
|
33
|
+
Context: the Playwriter bridge tunnel to vm1.example.com is stuck.
|
|
34
|
+
tunnel-vm1.example.com.log shows "remote port forwarding failed for
|
|
35
|
+
listen port 19988", meaning something on the VM already holds the port.
|
|
36
|
+
|
|
37
|
+
Run on vm1.example.com:
|
|
38
|
+
bash ~/.claude/acstack/bin/vm-free-port.sh
|
|
39
|
+
|
|
40
|
+
Expected result:
|
|
41
|
+
ss -lnt 'sport = :19988' is empty, or vm-free-port.sh refuses and
|
|
42
|
+
tells you the port is held by your own interactive session (in which
|
|
43
|
+
case exit that session and retry).
|
|
44
|
+
|
|
45
|
+
Report back:
|
|
46
|
+
The exit status of vm-free-port.sh and the final ss output.
|
|
47
|
+
--- END WINDOWS-SIDE HANDOFF ---
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
After the VM side acts, the Windows side confirms recovery with:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
Start-ScheduledTask Playwriter-Tunnel-VM1
|
|
54
|
+
doctor.ps1
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Success criterion: all rows green.
|
|
58
|
+
|
|
59
|
+
## Worked example 2 – VM → Windows, restart a tunnel task
|
|
60
|
+
|
|
61
|
+
A VM-side agent produces this block when `agent-browser` cannot reach
|
|
62
|
+
`http://127.0.0.1:19988/json/version`:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
--- BEGIN VM-SIDE HANDOFF (to Windows agent) ---
|
|
66
|
+
Context: agent-browser on vm1.example.com cannot reach the CDP endpoint
|
|
67
|
+
at 127.0.0.1:19988 (connection refused). The tunnel appears down.
|
|
68
|
+
|
|
69
|
+
Run on the Windows laptop:
|
|
70
|
+
Stop-ScheduledTask Playwriter-Tunnel-VM1
|
|
71
|
+
Start-ScheduledTask Playwriter-Tunnel-VM1
|
|
72
|
+
.\doctor.ps1
|
|
73
|
+
|
|
74
|
+
Expected result:
|
|
75
|
+
doctor.ps1 exits with all green rows, including "Relay listening on
|
|
76
|
+
19988" and no tunnel-*.stuck markers.
|
|
77
|
+
|
|
78
|
+
Report back:
|
|
79
|
+
The doctor.ps1 output (paste the table).
|
|
80
|
+
--- END VM-SIDE HANDOFF ---
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Rules for writing a handoff
|
|
84
|
+
|
|
85
|
+
- **Exact commands.** No "figure out the right flag" – the other side
|
|
86
|
+
may be a human at a shell, not a coding agent.
|
|
87
|
+
|
|
88
|
+
- **One verifiable success criterion.** Not "looks ok".
|
|
89
|
+
- **Small.** One problem per block. If two things break, emit two
|
|
90
|
+
blocks.
|
|
91
|
+
|
|
92
|
+
- **Scrub internal names.** No employer names, people names, internal IP
|
|
93
|
+
ranges, ticket IDs. Use placeholders like `<host>`, `vm1.example.com`.
|