chore(skills): workflow skills sweep — whats-next/workshop-start/pr-review/pr-process (T-1102)
De-sprint pr-review, dynamic repo-root paths, gate-aligned checks; workshop-start Agent-tool rename + roster fixes (IMPROVEMENTS.md folded in and removed); whats-next pql-durability notes; pr-process orphan-check + full-suite alignment. New helper scripts tooling/godot-cold-parse + tooling/pr-watchlist-diff (allowlist entries deferred to first-use per permission policy). Part of T-1099. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -118,22 +118,22 @@ systems.db is stale — run `make regen-db` before pushing.
|
|||||||
```
|
```
|
||||||
|
|
||||||
Fix: run `make regen-db`, stage `server/data/systems.db`, amend or add a commit.
|
Fix: run `make regen-db`, stage `server/data/systems.db`, amend or add a commit.
|
||||||
Or use `/pr-push` — it detects stale generator sources and reruns `make regen-db`
|
Or use `/pr-process` — it detects stale generator sources and reruns `make regen-db`
|
||||||
automatically before pushing.
|
automatically before pushing.
|
||||||
|
|
||||||
The check script is `tooling/check-systems-db-stamp`. Run it interactively with
|
The check script is `tooling/check-systems-db-stamp`. Run it interactively with
|
||||||
`make check-systems-db` or `python3 tooling/check-systems-db-stamp --verbose`. The
|
`make check-systems-db` or `python3 tooling/check-systems-db-stamp --verbose`. The
|
||||||
`GENERATOR_SOURCES` dict in `tooling/generator_sources.py` is the single registry
|
`GENERATOR_SOURCES` dict in `tooling/generator_sources.py` is the single registry
|
||||||
(T-1067) — the check script and the importer's stamp writer both import it, and
|
(T-1067) — the check script and the importer's stamp writer both import it, and
|
||||||
the `/pr-push` skill derives its source-file watch list from
|
the `/pr-process` skill derives its source-file watch list from
|
||||||
`python3 tooling/generator_sources.py --list`. When you add a new generator or
|
`python3 tooling/generator_sources.py --list`. When you add a new generator or
|
||||||
source file, register it there and nowhere else.
|
source file, register it there and nowhere else.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## /pr-push integration (T-858)
|
## /pr-process integration (T-858)
|
||||||
|
|
||||||
The `/pr-push` skill checks whether any generator source files are modified on the
|
The `/pr-process` skill checks whether any generator source files are modified on the
|
||||||
branch. If they are, it automatically runs `make regen-db` and stages the updated
|
branch. If they are, it automatically runs `make regen-db` and stages the updated
|
||||||
`server/data/systems.db` before pushing — preventing pre-push hook rejections on
|
`server/data/systems.db` before pushing — preventing pre-push hook rejections on
|
||||||
branches that modify generators without regenerating.
|
branches that modify generators without regenerating.
|
||||||
|
|||||||
@@ -27,14 +27,14 @@ current branch — never touches main.
|
|||||||
|
|
||||||
### 0. Dry-run mode check
|
### 0. Dry-run mode check
|
||||||
|
|
||||||
If the user invokes `/pr-push --dry-run`:
|
If the user invokes `/pr-process --dry-run`:
|
||||||
- Print: "Dry-run mode — inspecting state, nothing will be pushed or committed."
|
- Print: "Dry-run mode — inspecting state, nothing will be pushed or committed."
|
||||||
- Run steps 1 through 4a in **inspect-only** mode:
|
- Run steps 1 through 4a in **inspect-only** mode:
|
||||||
- Step 4: run `make check-systems-db` to check current stamp freshness (no merge)
|
- Step 4: run `make check-systems-db` to check current stamp freshness (no merge)
|
||||||
- Step 4a: report which watched files changed vs origin/main; show whether `make regen-db`
|
- Step 4a: report which watched files changed vs origin/main; show whether `make regen-db`
|
||||||
would be triggered; do NOT run the regen, stage, or commit
|
would be triggered; do NOT run the regen, stage, or commit
|
||||||
- Print a summary: watched files changed (list), regen needed (yes/no), DB stamp fresh (yes/no)
|
- Print a summary: watched files changed (list), regen needed (yes/no), DB stamp fresh (yes/no)
|
||||||
- Print "Dry run complete — use /pr-push to apply."
|
- Print "Dry run complete — use /pr-process to apply."
|
||||||
- Stop. Do not push or create a PR.
|
- Stop. Do not push or create a PR.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -55,8 +55,8 @@ step (1b, 1c), check for long-lived Godot processes from prior stuck test
|
|||||||
runs:
|
runs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# List any godot/gdunit processes running longer than 5 minutes
|
# List any godot/gdUnit4 processes running longer than 5 minutes
|
||||||
ps -eo pid,etimes,cmd | awk '$2 > 300 && /godot.*gdunit4-run/ {print $1, $2"s", substr($0, index($0,$3))}'
|
ps -eo pid,etimes,cmd | awk '$2 > 300 && /godot.*(GdUnitCmdTool|[Gg]d[Uu]nit)/ {print $1, $2"s", substr($0, index($0,$3))}'
|
||||||
```
|
```
|
||||||
|
|
||||||
If any are listed: they are almost certainly orphans from a prior test
|
If any are listed: they are almost certainly orphans from a prior test
|
||||||
@@ -85,9 +85,12 @@ ignore` comment with a reason.
|
|||||||
|
|
||||||
**For server branches:**
|
**For server branches:**
|
||||||
```bash
|
```bash
|
||||||
cargo clippy -- -D warnings 2>&1
|
cargo clippy --manifest-path server/Cargo.toml --all-targets -- -D warnings 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This must match the pre-push gate's own invocation exactly (`--all-targets` is
|
||||||
|
easy to drop locally and then miss warnings the gate still catches).
|
||||||
|
|
||||||
**For CI/tooling branches:**
|
**For CI/tooling branches:**
|
||||||
```bash
|
```bash
|
||||||
ruff check tooling/ 2>&1
|
ruff check tooling/ 2>&1
|
||||||
@@ -105,62 +108,41 @@ bugs (parse errors, depth sorting, scene tree failures).
|
|||||||
|
|
||||||
**For client/visual branches:**
|
**For client/visual branches:**
|
||||||
|
|
||||||
First, **wipe the script class cache before parsing**. Sprint 36 close
|
`tooling/godot-cold-parse` wipes the cached script-class registry (matching
|
||||||
caught this: the team added a new `class_name MetaScreen` base class and
|
the cold-start ordering CI / fresh clones see — Sprint 36 close caught a
|
||||||
six scripts extending it. Warm cache on developer machines parsed fine,
|
`class_name` base-class registration bug that warm caches masked) and runs a
|
||||||
but CI / fresh clones / post-merge parses hit `Could not find base class
|
headless parse, filtering known pre-existing noise. Pass `--run-menu` if the
|
||||||
"MetaScreen"` because the autoload-vs-class_name registration order only
|
branch has UI changes to also launch the main menu briefly:
|
||||||
resolves correctly once the class cache is seeded. Wiping the cache here
|
|
||||||
(client-side, before push) simulates the cold-start path and catches the
|
|
||||||
bug locally — keeping the pre-push hook fast.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Cold-cache parse check. Deleting the cached class registry forces
|
tooling/godot-cold-parse --run-menu
|
||||||
# Godot to rebuild it from source on the next parse, matching the
|
|
||||||
# cold-start ordering CI and fresh clones see.
|
|
||||||
rm -f client/.godot/global_script_class_cache.cfg
|
|
||||||
|
|
||||||
# Headless parse + scanner check. Godot's resource scanner emits
|
|
||||||
# category errors (e.g. "Export type can only be built-in, a resource,
|
|
||||||
# a node, or an enum" for @export on a RefCounted) that do NOT always
|
|
||||||
# prefix with SCRIPT ERROR — they appear as plain ERROR lines. Widen
|
|
||||||
# the grep to catch both, then filter known pre-existing noise from
|
|
||||||
# the autoload class_name parse-order trap (documented in CLAUDE.md).
|
|
||||||
godot --headless --path client --quit 2>&1 | \
|
|
||||||
grep -iE "^(SCRIPT )?ERROR|Parse Error|Export type" | \
|
|
||||||
grep -v "Failed loading resource: res://assets" | \
|
|
||||||
grep -v "Cannot infer the type" | \
|
|
||||||
grep -vE "(Messagepack|LocalBridge|ServerProcess|Constants)\" not declared"
|
|
||||||
|
|
||||||
# If the branch has UI changes, also run the game briefly:
|
|
||||||
timeout 10 godot --path client res://scenes/main_menu.tscn 2>&1 | \
|
|
||||||
grep -iE "^(SCRIPT )?ERROR|Parse Error|Export type"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If the cold parse reports a "Could not find base class X" error, the fix
|
If it reports a "Could not find base class X" error, the fix is almost
|
||||||
is almost always an autoload-order issue (see `CLAUDE.md` → GDScript
|
always an autoload-order issue (see `CLAUDE.md` → GDScript conventions →
|
||||||
conventions → Autoload parse-order rule). Rebuilding the cache with
|
Autoload parse-order rule) — fix the ordering, don't just rebuild the cache
|
||||||
`godot --editor --headless --quit` will mask it locally but the same error
|
to mask it locally (the same error resurfaces post-merge).
|
||||||
will re-surface post-merge — fix the actual ordering problem, don't paper
|
|
||||||
over it with a cache rebuild.
|
|
||||||
|
|
||||||
Any lines that come through the filter represent new errors introduced
|
Any lines it reports are new errors introduced by this branch. Fix them
|
||||||
by this branch. Fix them before pushing — Sprint 36 shipped commit
|
before pushing.
|
||||||
`84105916` with an `@export var descriptor: CharacterVisualDescriptor`
|
|
||||||
scanner error that the old narrower grep missed; Tyre caught it five
|
|
||||||
commits later during W6 review.
|
|
||||||
|
|
||||||
**For server branches:**
|
**For server branches:**
|
||||||
```bash
|
```bash
|
||||||
cd server && cargo test --lib 2>&1
|
cargo test --manifest-path server/Cargo.toml 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Full suite, not `--lib` — `--lib` skips the believability/derivation golden
|
||||||
|
harnesses (separate test binaries) and would silently under-test cascade
|
||||||
|
changes. This must match the pre-push gate's own invocation (`team-patterns.md`)
|
||||||
|
exactly; a weaker local pass here just gives false confidence right before the
|
||||||
|
gate catches it anyway.
|
||||||
|
|
||||||
If any errors are found, **stop and fix them before pushing**. Do not
|
If any errors are found, **stop and fix them before pushing**. Do not
|
||||||
push broken code for reviewers to find — that wastes everyone's time.
|
push broken code for reviewers to find — that wastes everyone's time.
|
||||||
|
|
||||||
If the branch includes visual changes (character creation, UI, rendering),
|
If the branch includes visual changes (character creation, UI, rendering),
|
||||||
the team should have manually launched the game and verified the change
|
the team should have manually launched the game and verified the change
|
||||||
works on screen before invoking `/pr-push`. If they haven't, ask:
|
works on screen before invoking `/pr-process`. If they haven't, ask:
|
||||||
"Have you run `make game` and verified this works visually?"
|
"Have you run `make game` and verified this works visually?"
|
||||||
|
|
||||||
### 2. Commit uncommitted changes
|
### 2. Commit uncommitted changes
|
||||||
@@ -171,9 +153,8 @@ git diff --stat
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Run both commands from the repo root** (`git rev-parse --show-toplevel`).
|
**Run both commands from the repo root** (`git rev-parse --show-toplevel`).
|
||||||
Running from a subdirectory can cause paths to not resolve, hiding real
|
Running from a subdirectory can hide real changes (Sprint 30: a wrong-CWD
|
||||||
changes — Sprint 30 proved this when `git diff HEAD -- server/src/bin/atlas.rs`
|
`git diff` returned 0 lines, masking uncommitted work).
|
||||||
returned 0 lines from the wrong CWD, masking uncommitted agent work.
|
|
||||||
|
|
||||||
**CRITICAL: Do not trust "already done" claims without checking git state.**
|
**CRITICAL: Do not trust "already done" claims without checking git state.**
|
||||||
If agents report that work was "already implemented in a prior commit," verify
|
If agents report that work was "already implemented in a prior commit," verify
|
||||||
@@ -197,7 +178,7 @@ git fetch --all
|
|||||||
git log --oneline origin/<branch>..<branch>
|
git log --oneline origin/<branch>..<branch>
|
||||||
```
|
```
|
||||||
|
|
||||||
If no unpushed commits, skip to step 5 (PR check).
|
If no unpushed commits, skip to step 6 (PR check).
|
||||||
|
|
||||||
### 4. Check for conflicts with main
|
### 4. Check for conflicts with main
|
||||||
|
|
||||||
@@ -222,24 +203,13 @@ versus `origin/main`. This list covers generator code AND the data files that fe
|
|||||||
The stamped generator sources come from the shared registry
|
The stamped generator sources come from the shared registry
|
||||||
`tooling/generator_sources.py` (T-1067) — the same module the stamp writer and
|
`tooling/generator_sources.py` (T-1067) — the same module the stamp writer and
|
||||||
`tooling/check-systems-db-stamp` use, so the lists can no longer drift (PR #136
|
`tooling/check-systems-db-stamp` use, so the lists can no longer drift (PR #136
|
||||||
review T7). The CLI call below expands to one repo-relative path per line; the
|
review T7). `tooling/pr-watchlist-diff` wraps the comparison — its header comment
|
||||||
extra hardcoded entries are non-stamped watch items (retired/one-time planet-gen
|
documents the non-stamped watch items it also checks (the surviving one-time
|
||||||
importers, the schema DDL whose SHA is stamped separately, and the data
|
planet-gen importers, the schema DDL whose SHA is stamped separately, and the
|
||||||
directories that feed the generators).
|
wiki data directories that feed the generators):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git diff --name-only origin/main...HEAD -- \
|
tooling/pr-watchlist-diff origin/main HEAD
|
||||||
$(python3 tooling/generator_sources.py --list) \
|
|
||||||
tooling/planet-gen/generate_atlas.py \
|
|
||||||
tooling/planet-gen/gemma_naming.py \
|
|
||||||
tooling/planet-gen/naming_core.py \
|
|
||||||
tooling/planet-gen/import_city_names.py \
|
|
||||||
tooling/planet-gen/import_heightmaps.py \
|
|
||||||
tooling/planet-gen/import_province_boundaries.py \
|
|
||||||
server/data/systems-schema.sql \
|
|
||||||
wiki/star-systems/ \
|
|
||||||
wiki/economics/ \
|
|
||||||
content/economics/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**If output is empty:** skip this step entirely.
|
**If output is empty:** skip this step entirely.
|
||||||
@@ -377,5 +347,5 @@ Suggest: "PR processed. Run `/pr-review` from main to review, or `/whats-next` f
|
|||||||
|
|
||||||
## Arguments
|
## Arguments
|
||||||
|
|
||||||
If the user passes arguments (e.g., `/pr-push "my title"`), use them as the
|
If the user passes arguments (e.g., `/pr-process "my title"`), use them as the
|
||||||
PR title instead of generating one.
|
PR title instead of generating one.
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
name: pr-review
|
name: pr-review
|
||||||
description: >
|
description: >
|
||||||
Review a branch diff with team-appropriate agents before merge. Use when the
|
Review a Gitea branch diff with team-appropriate agents before merge. Use when
|
||||||
user says "review-pr", "review this PR", "review this branch", or invokes
|
the user says "review-pr", "review this PR", "review this branch", or invokes
|
||||||
/pr-review. Spawns reviewers matched to the branch type (code, copy, visual,
|
/pr-review. Spawns reviewers matched to the branch type (code, copy, visual,
|
||||||
audio) in parallel. Reports approve/reject with inline comments.
|
audio) in parallel. Reports approve/reject with inline comments.
|
||||||
user-invocable: true
|
user-invocable: true
|
||||||
allowed-tools: Bash, Read, Grep, Glob, Task
|
allowed-tools: Bash, Read, Grep, Glob, Task, Write
|
||||||
---
|
---
|
||||||
|
|
||||||
# PR Review Skill
|
# PR Review Skill
|
||||||
@@ -30,8 +30,8 @@ Stop and wait for the user to invoke `/pr-review` from main.
|
|||||||
### 0b. Verify runtime smoke test was performed
|
### 0b. Verify runtime smoke test was performed
|
||||||
|
|
||||||
Before spawning reviewers, check that the pushing team performed basic
|
Before spawning reviewers, check that the pushing team performed basic
|
||||||
runtime verification. This was the #1 process failure of Sprint 28 —
|
runtime verification — the #1 process failure of Sprint 28 (3 review
|
||||||
3 review rounds without anyone launching the game missed critical bugs.
|
rounds shipped without anyone launching the game).
|
||||||
|
|
||||||
Ask: "Did the team run `make game` or a headless smoke test before
|
Ask: "Did the team run `make game` or a headless smoke test before
|
||||||
pushing this PR?"
|
pushing this PR?"
|
||||||
@@ -40,13 +40,6 @@ If the PR description or commit messages don't mention runtime testing,
|
|||||||
note this in the review output as a process gap. Reviewers should still
|
note this in the review output as a process gap. Reviewers should still
|
||||||
proceed (the PR exists and needs reviewing) but the gap should be visible.
|
proceed (the PR exists and needs reviewing) but the gap should be visible.
|
||||||
|
|
||||||
For **client/visual branches**, run a quick headless parse check from main:
|
|
||||||
```bash
|
|
||||||
godot --headless --path client --quit 2>&1 | grep -i "SCRIPT ERROR"
|
|
||||||
```
|
|
||||||
If script errors appear in the branch diff files, flag them immediately
|
|
||||||
before spawning reviewers — no point reviewing code that doesn't parse.
|
|
||||||
|
|
||||||
#### 0b-i. Merge-path smoke test gate
|
#### 0b-i. Merge-path smoke test gate
|
||||||
|
|
||||||
When the branch diff touches any of:
|
When the branch diff touches any of:
|
||||||
@@ -69,18 +62,17 @@ Unchecked merge-path smoke boxes downgrade the verdict from APPROVED to
|
|||||||
REQUEST_CHANGES even if reviewers have no code comments. The smoke is a
|
REQUEST_CHANGES even if reviewers have no code comments. The smoke is a
|
||||||
deliverable, not a suggestion.
|
deliverable, not a suggestion.
|
||||||
|
|
||||||
### 0c. Zero warnings check
|
### 0c. Parse/lint — deferred to the push gate
|
||||||
|
|
||||||
The project enforces a **zero warnings policy**. Before spawning reviewers,
|
`/pr-review` runs on an already-pushed branch (step 0's branch guard means the
|
||||||
check if the branch introduces lint warnings:
|
reviewer's only local tree is **main**). Re-running `gdlint`/`cargo clippy`/`ruff`
|
||||||
|
here would check main's code, not the branch's — and `cargo clippy` fails outright
|
||||||
- **client/visual:** `gdlint client/scripts/ client/ui/` should report 0 issues
|
at the repo root (no root `Cargo.toml`; the server crate is `server/`). None of
|
||||||
- **server:** `cargo clippy -- -D warnings` should be clean
|
that is necessary anyway: the pre-push hook (`.config/hooks/pre-push`, declared
|
||||||
- **ci/tooling:** `ruff check tooling/` should be clean
|
authoritative by `team-patterns.md`) already ran `cargo fmt --check` / `cargo
|
||||||
|
clippy --all-targets -- -D warnings` / `cargo test` (server changes) or the full
|
||||||
If warnings exist, note the count in the review output. Reviewers should
|
gdUnit4 suite via `tests/run-godot` (client changes) before this push succeeded.
|
||||||
flag any **new** warnings introduced by the branch as `warning` severity.
|
Trust the gate; don't duplicate it here with a weaker, wrong-tree variant.
|
||||||
Pre-existing warnings are not PR blockers but should be tracked for cleanup.
|
|
||||||
|
|
||||||
### 1. Determine the branch to review
|
### 1. Determine the branch to review
|
||||||
|
|
||||||
@@ -113,7 +105,9 @@ git diff --stat main...<branch>
|
|||||||
|
|
||||||
Examine the changed file paths to determine the dominant change type:
|
Examine the changed file paths to determine the dominant change type:
|
||||||
|
|
||||||
- Mostly `server/` changes → **code** reviewers
|
- Mostly `server/` changes → **code** reviewers — *except* `server/content/`
|
||||||
|
(game content data: campaigns, gauntlet, global, `content.yaml`), which routes
|
||||||
|
to **copy** reviewers despite living under `server/`
|
||||||
- Mostly `client/` changes (excluding `client/ui/` art assets) → **code** reviewers
|
- Mostly `client/` changes (excluding `client/ui/` art assets) → **code** reviewers
|
||||||
- Mostly `wiki/`, `docs/atlas/`, `content/` changes → **copy** reviewers
|
- Mostly `wiki/`, `docs/atlas/`, `content/` changes → **copy** reviewers
|
||||||
- Mostly `client/ui/` or asset changes (`.tres`, `.tscn`, textures) → **visual** reviewers
|
- Mostly `client/ui/` or asset changes (`.tres`, `.tscn`, textures) → **visual** reviewers
|
||||||
@@ -140,59 +134,54 @@ If the diff is empty, report "No changes to review" and stop.
|
|||||||
- `Cargo.lock` (auto-generated)
|
- `Cargo.lock` (auto-generated)
|
||||||
- `client/addons/gdUnit4/` (vendor test framework)
|
- `client/addons/gdUnit4/` (vendor test framework)
|
||||||
- `*.uid` (Godot-generated)
|
- `*.uid` (Godot-generated)
|
||||||
- `docs/backups/settledreach.db.backup` (binary)
|
- `docs/backups/*` (binary DB backups, e.g. `settledreach.db.backup.pre35`)
|
||||||
|
|
||||||
Three-dot diff with pathspec exclusions is unreliable. Instead, either:
|
Three-dot diff with pathspec exclusions is unreliable. Instead, either:
|
||||||
1. Use `git diff main...<branch>` (full diff) and filter in the prompt, or
|
1. Use `git diff main...<branch>` (full diff) and filter in the prompt, or
|
||||||
2. Read source files directly from the team directory (see below).
|
2. Read source files directly from the worktree (see below).
|
||||||
|
|
||||||
For large diffs (>1000 lines of source), provide **source files** rather than
|
For large diffs (>1000 lines of source), provide **source files** rather than
|
||||||
raw diff to reviewers — cleaner context, better reviews.
|
raw diff to reviewers — cleaner context, better reviews.
|
||||||
|
|
||||||
**Reviewer agents read source files from the team worktree.**
|
**Reviewer agents read source files from the branch worktree — verified, not
|
||||||
|
assumed — or via `git show`.**
|
||||||
|
|
||||||
Sprint branches follow `sprint-{N}/{team}`. Mid-sprint, a worktree
|
Topic branches from `/whats-next` may have a worktree at
|
||||||
of each branch exists at `$(dirname <repo_root>)/.sprint/sprint-{N}/{team}/`
|
`<repo_root>/.worktrees/<branch-name>` (the kanban convention, D-221 — see
|
||||||
— a *sibling* of the repo root, not a child. This worktree IS the
|
`tooling/worktree-setup`):
|
||||||
branch: Read/Grep on paths rooted there resolve against the branch's
|
|
||||||
checkout, not main's.
|
|
||||||
|
|
||||||
**Why this matters:** Sprint 37 PR #138 review produced 6 false-
|
|
||||||
positive findings because the reviewer defaulted to Read/Grep on the
|
|
||||||
main repo path (`/var/mnt/data/projects/settled-reach/main/`) instead
|
|
||||||
of the branch worktree. Every finding was a verbatim match against
|
|
||||||
main's state but irrelevant to the branch — the branch had already
|
|
||||||
cleaned the residue the reviewer flagged as "still present." Sending
|
|
||||||
those findings to the team would have caused busywork on already-clean
|
|
||||||
code, and more dangerously, the same drift hides *false negatives*
|
|
||||||
(branch-introduced bugs the reviewer never saw because it never read
|
|
||||||
the branch).
|
|
||||||
|
|
||||||
Fix: before spawning reviewers, resolve the worktree path and pass it
|
|
||||||
into every reviewer prompt with prominent language. The reviewer
|
|
||||||
reads from the worktree, not from main.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Find worktree for this branch (if one exists)
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
WORKTREE=$(git worktree list --porcelain | grep -B2 "branch refs/heads/<branch>" | grep "worktree " | sed 's/worktree //')
|
WORKTREE="$REPO_ROOT/.worktrees/<branch-name>"
|
||||||
|
|
||||||
# Verify it exists and matches the branch tip
|
|
||||||
git -C "$WORKTREE" rev-parse HEAD # should equal `git rev-parse origin/<branch>`
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If the worktree exists and its HEAD matches `origin/<branch>`, use it
|
If that path doesn't exist, fall back to the generic resolution (also used by
|
||||||
as the reviewer's source of truth. If it doesn't exist (e.g. the
|
`/pr-review` §7a cleanup):
|
||||||
worktree has been torn down or you're reviewing a branch without a
|
|
||||||
worktree), fall back to `git show origin/<branch>:<path>` — explicitly
|
```bash
|
||||||
flag this fallback in the reviewer prompt so the reviewer knows
|
WORKTREE=$(git worktree list --porcelain | grep -B2 "branch refs/heads/<branch>" | grep "worktree " | sed 's/worktree //')
|
||||||
Read/Grep on any local path would be wrong.
|
```
|
||||||
|
|
||||||
|
Use the worktree as the reviewer's source of truth **only if both** hold —
|
||||||
|
otherwise fall back to `git show origin/<branch>:<path>` and flag the fallback
|
||||||
|
in the reviewer prompt:
|
||||||
|
|
||||||
|
1. **HEAD matches the branch tip:** `git -C "$WORKTREE" rev-parse HEAD` equals `git rev-parse origin/<branch>`.
|
||||||
|
2. **Not a sparse checkout:** `git -C "$WORKTREE" sparse-checkout list` is empty or errors ("not a sparse checkout").
|
||||||
|
|
||||||
|
Two incidents motivate both checks — cited once, here, so they don't drift
|
||||||
|
back into two contradictory rules: Sprint 37 (a reviewer defaulted to reading
|
||||||
|
the main repo root instead of the branch worktree — 6 false positives) and
|
||||||
|
Sprint 33 (a sparse worktree silently excluded the wiki directory — a false
|
||||||
|
"missing prose" finding). One rule now covers both: verify HEAD *and*
|
||||||
|
sparse-checkout status, or use `git show`.
|
||||||
|
|
||||||
In the reviewer prompt, state the rule non-negotiably:
|
In the reviewer prompt, state the rule non-negotiably:
|
||||||
|
|
||||||
> **Read source from `<WORKTREE_PATH>` only.** Do NOT Read or Grep
|
> **Read source from `<WORKTREE_PATH>` only** (or `git show
|
||||||
> paths under the main repo root (`/var/mnt/data/projects/settled-reach/main/`).
|
> origin/<branch>:<path>` if no valid worktree exists). Do NOT Read or Grep
|
||||||
> Those resolve to main, not the branch. The worktree at `<WORKTREE_PATH>`
|
> paths under the main repo root (`$(git rev-parse --show-toplevel)`) — that
|
||||||
> IS the branch — point all file tools there.
|
> resolves to main, not the branch.
|
||||||
|
|
||||||
Also tell agents to read relevant `governance/**/*.md` files for context
|
Also tell agents to read relevant `governance/**/*.md` files for context
|
||||||
(these can be read from either path — they're usually identical —
|
(these can be read from either path — they're usually identical —
|
||||||
@@ -200,7 +189,7 @@ but for consistency, use the worktree path).
|
|||||||
|
|
||||||
### 4. Spawn reviewers in parallel
|
### 4. Spawn reviewers in parallel
|
||||||
|
|
||||||
Use the Task tool to spawn **all reviewers simultaneously** in a single message.
|
Use the Agent tool to spawn **all reviewers simultaneously** in a single message.
|
||||||
|
|
||||||
Read `references/reviewer-profiles.md` for the full per-branch-type reviewer
|
Read `references/reviewer-profiles.md` for the full per-branch-type reviewer
|
||||||
specifications (agent types, models, prompt focus areas). Match the branch type
|
specifications (agent types, models, prompt focus areas). Match the branch type
|
||||||
@@ -269,7 +258,7 @@ Verdict rules:
|
|||||||
something can be better, say so.
|
something can be better, say so.
|
||||||
```
|
```
|
||||||
|
|
||||||
## 6. Posting results to Gitea
|
### 6. Posting results to Gitea
|
||||||
|
|
||||||
After presenting results to the user, post the review as a PR comment.
|
After presenting results to the user, post the review as a PR comment.
|
||||||
|
|
||||||
@@ -283,8 +272,8 @@ Post using the `tea-comment` wrapper (handles temp files and cleanup).
|
|||||||
`tooling/tea-comment` in a separate short Bash call.
|
`tooling/tea-comment` in a separate short Bash call.
|
||||||
2. **Run `tooling/tea-comment` in the FOREGROUND, never with
|
2. **Run `tooling/tea-comment` in the FOREGROUND, never with
|
||||||
`run_in_background`.** The background execution path silently fails —
|
`run_in_background`.** The background execution path silently fails —
|
||||||
the comment never reaches Gitea and the team never sees the review.
|
the comment never reaches Gitea and the team never sees the review
|
||||||
Sprint 38 lost an entire review round this way. Always foreground.
|
(Sprint 38 lost an entire review round this way).
|
||||||
|
|
||||||
```
|
```
|
||||||
# Step 1: Use the Write tool to create the file
|
# Step 1: Use the Write tool to create the file
|
||||||
@@ -297,7 +286,7 @@ tooling/tea-comment <PR_NUMBER> @/tmp/pr-review-<NUMBER>.md
|
|||||||
Do NOT use `cat << 'EOF'` heredocs for review content — they create
|
Do NOT use `cat << 'EOF'` heredocs for review content — they create
|
||||||
massive permission prompts that are slow to render and often get stuck.
|
massive permission prompts that are slow to render and often get stuck.
|
||||||
|
|
||||||
## 7. Merging approved PRs
|
### 7. Merging approved PRs
|
||||||
|
|
||||||
`tea pr merge` fails (405) when branches have conflicts with main. Merge
|
`tea pr merge` fails (405) when branches have conflicts with main. Merge
|
||||||
locally instead:
|
locally instead:
|
||||||
|
|||||||
@@ -2,23 +2,18 @@
|
|||||||
|
|
||||||
Use `model: sonnet` for all reviewers — sufficient for review, saves cost.
|
Use `model: sonnet` for all reviewers — sufficient for review, saves cost.
|
||||||
|
|
||||||
**Reviewer agents read source files via `git show` or from sprint
|
**Reviewer agents read source files from the branch worktree or via `git
|
||||||
worktrees.** Sprint branches use `sprint-{N}/{team}` naming. Include
|
show`** — see SKILL.md §3 for the full resolution + validation rule (prefer
|
||||||
the branch name and a list of changed files in every prompt. The
|
the worktree only when its HEAD matches the branch tip AND it isn't a sparse
|
||||||
default approach is `git show origin/<branch>:<path>`. If an active
|
checkout; otherwise `git show origin/<branch>:<path>`). Include the branch
|
||||||
worktree exists under `.sprint/`, agents can also use the Read tool
|
name and a list of changed files in every prompt.
|
||||||
with the worktree path. **Always prefer `git show` over worktree
|
|
||||||
reads** — worktrees may use sparse checkouts that silently exclude
|
|
||||||
files, causing reviewers to miss content and produce false findings
|
|
||||||
(Sprint 33 lesson: Paula reported missing prose that was actually
|
|
||||||
present, because the worktree excluded the wiki directory).
|
|
||||||
|
|
||||||
## Code reviews (`server`, `client`, `ci`)
|
## Code reviews (`server`, `client`, `ci`)
|
||||||
|
|
||||||
**Hoshe (Code Quality)**
|
**Hoshe (Code Quality)**
|
||||||
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Hoshe to read source files from the team directory, then review for:
|
Tell Hoshe to read source files from the worktree, then review for:
|
||||||
- Correctness and bug risks
|
- Correctness and bug risks
|
||||||
- Error handling gaps
|
- Error handling gaps
|
||||||
- Test coverage (are new features tested?)
|
- Test coverage (are new features tested?)
|
||||||
@@ -28,8 +23,8 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Tyre (Architecture)**
|
**Tyre (Architecture)**
|
||||||
- `subagent_type`: `tyre`, `model`: `sonnet`
|
- `subagent_type`: `tyre`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Tyre to read the relevant `governance/**/*.md` files from the team directory
|
Tell Tyre to read the relevant `governance/**/*.md` files from the worktree
|
||||||
first, then review for:
|
first, then review for:
|
||||||
- Architectural consistency with project decisions
|
- Architectural consistency with project decisions
|
||||||
- API/interface design quality
|
- API/interface design quality
|
||||||
@@ -41,8 +36,8 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Hoshe (QA)**
|
**Hoshe (QA)**
|
||||||
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Hoshe to read the changed files from the team directory, then review for:
|
Tell Hoshe to read the changed files from the worktree, then review for:
|
||||||
- Formatting consistency (markdown, file naming, frontmatter)
|
- Formatting consistency (markdown, file naming, frontmatter)
|
||||||
- Broken references or links
|
- Broken references or links
|
||||||
- Spelling and grammar
|
- Spelling and grammar
|
||||||
@@ -51,9 +46,9 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Paula (Narrative Depth)**
|
**Paula (Narrative Depth)**
|
||||||
- `subagent_type`: `paula`, `model`: `sonnet`
|
- `subagent_type`: `paula`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, commit log, and
|
- Prompt: Provide the worktree path, list of changed files, commit log, and
|
||||||
list of relevant `governance/**/*.md` files to read. Tell Paula to read all
|
list of relevant `governance/**/*.md` files to read. Tell Paula to read all
|
||||||
files from the team directory using the Read tool, then review for:
|
files from the worktree using the Read tool, then review for:
|
||||||
- Narrative quality and character voice consistency
|
- Narrative quality and character voice consistency
|
||||||
- Whether dialogue and monologue feel authentic to the characters
|
- Whether dialogue and monologue feel authentic to the characters
|
||||||
- Consequences and stakes — do choices carry weight?
|
- Consequences and stakes — do choices carry weight?
|
||||||
@@ -62,9 +57,9 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Miri (World Consistency)**
|
**Miri (World Consistency)**
|
||||||
- `subagent_type`: `miri`, `model`: `sonnet`
|
- `subagent_type`: `miri`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, commit log, and
|
- Prompt: Provide the worktree path, list of changed files, commit log, and
|
||||||
list of relevant `governance/**/*.md` files to read. Tell Miri to read all
|
list of relevant `governance/**/*.md` files to read. Tell Miri to read all
|
||||||
files from the team directory using the Read tool, then review for:
|
files from the worktree using the Read tool, then review for:
|
||||||
- Lore accuracy — do facts match established setting?
|
- Lore accuracy — do facts match established setting?
|
||||||
- Internal consistency across files
|
- Internal consistency across files
|
||||||
- IP originality — nothing should read as a copy from another franchise
|
- IP originality — nothing should read as a copy from another franchise
|
||||||
@@ -75,8 +70,8 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Hoshe (QA)**
|
**Hoshe (QA)**
|
||||||
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Hoshe to read the changed files from the team directory, then review for:
|
Tell Hoshe to read the changed files from the worktree, then review for:
|
||||||
- File format and naming conventions
|
- File format and naming conventions
|
||||||
- Asset organization and directory structure
|
- Asset organization and directory structure
|
||||||
- Missing or broken references in scene/resource files
|
- Missing or broken references in scene/resource files
|
||||||
@@ -84,7 +79,7 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Araminta (Art Direction)**
|
**Araminta (Art Direction)**
|
||||||
- `subagent_type`: `araminta`, `model`: `sonnet`
|
- `subagent_type`: `araminta`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Araminta to read the style guide and relevant design docs from the
|
Tell Araminta to read the style guide and relevant design docs from the
|
||||||
worktree first, then review for:
|
worktree first, then review for:
|
||||||
- Visual consistency with the established style guide
|
- Visual consistency with the established style guide
|
||||||
@@ -97,8 +92,8 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Hoshe (QA)**
|
**Hoshe (QA)**
|
||||||
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
- `subagent_type`: `hoshe`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Hoshe to read the changed files from the team directory, then review for:
|
Tell Hoshe to read the changed files from the worktree, then review for:
|
||||||
- File format and naming conventions
|
- File format and naming conventions
|
||||||
- Audio asset organization and directory structure
|
- Audio asset organization and directory structure
|
||||||
- Missing or broken references
|
- Missing or broken references
|
||||||
@@ -106,8 +101,8 @@ present, because the worktree excluded the wiki directory).
|
|||||||
|
|
||||||
**Ozzie (Player Experience)**
|
**Ozzie (Player Experience)**
|
||||||
- `subagent_type`: `ozzie`, `model`: `sonnet`
|
- `subagent_type`: `ozzie`, `model`: `sonnet`
|
||||||
- Prompt: Provide the team directory path, list of changed files, and commit log.
|
- Prompt: Provide the worktree path, list of changed files, and commit log.
|
||||||
Tell Ozzie to read all files from the team directory using the Read tool, then
|
Tell Ozzie to read all files from the worktree using the Read tool, then
|
||||||
review for:
|
review for:
|
||||||
- Emotional impact — does the audio enhance the moment?
|
- Emotional impact — does the audio enhance the moment?
|
||||||
- Atmosphere and tone — does it feel like the Settled Reach?
|
- Atmosphere and tone — does it feel like the Settled Reach?
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ lowest-numbered non-`done` phase epic):
|
|||||||
pql ticket list --under T-745 --status in_progress --fields id,type,status,title
|
pql ticket list --under T-745 --status in_progress --fields id,type,status,title
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> `--status` takes a SINGLE value (not a comma list — `backlog,in_progress` matches
|
||||||
|
> nothing and silently returns `[]`). Most tickets here sit in `backlog` or `done`;
|
||||||
|
> if you need multiple statuses at once (e.g. both `backlog` and `in_progress`), run
|
||||||
|
> the query once per status.
|
||||||
|
|
||||||
The phase epic is the `"type": "epic"` row. Use pql natively — no ad-hoc python/jq
|
The phase epic is the `"type": "epic"` row. Use pql natively — no ad-hoc python/jq
|
||||||
projections over its output: since pql 1.11.0, `ticket list` omits `description` by
|
projections over its output: since pql 1.11.0, `ticket list` omits `description` by
|
||||||
default and supports `--fields id,type,parent_id,priority,status,title` (the batch-
|
default and supports `--fields id,type,parent_id,priority,status,title` (the batch-
|
||||||
@@ -179,6 +184,23 @@ For each ticket in the batch (batch with commas: `pql ticket status T-1,T-2 in_p
|
|||||||
pql does **not** enforce the WIP limit — check it yourself in step 1d and warn if the
|
pql does **not** enforce the WIP limit — check it yourself in step 1d and warn if the
|
||||||
batch pushes in-progress past 5.
|
batch pushes in-progress past 5.
|
||||||
|
|
||||||
|
> **Then make sure it persists.** Ticket mutations (status here, and any
|
||||||
|
> `ticket append` in Step 2) land only in the gitignored `.pql/pql.db`. The
|
||||||
|
> pre-commit hook runs `pql plan export --stage` automatically — the changelog
|
||||||
|
> is exported and staged on every commit, so never hand-run the export or
|
||||||
|
> `git add .pql/changelog`. The rule is simpler: the turn must land at least
|
||||||
|
> one commit (through the git-commit skill). A ticket-only turn with no commit
|
||||||
|
> leaves the mutations in `pql.db` only, and the post-checkout/post-merge hooks
|
||||||
|
> rebuild that DB from the committed changelog on the next branch switch —
|
||||||
|
> silently dropping them. See the pql skill's "Versioning planning state"
|
||||||
|
> section for the full mechanics.
|
||||||
|
>
|
||||||
|
> - Don't hand-export or hand-stage `.pql/changelog/` — the pre-commit hook does
|
||||||
|
> both on every commit. The real footgun is a turn that mutates tickets but
|
||||||
|
> never commits: `pql.db` is gitignored and gets rebuilt from the committed
|
||||||
|
> changelog on branch switch, silently dropping un-committed mutations. Land
|
||||||
|
> at least one commit per ticket-mutating turn.
|
||||||
|
|
||||||
### 3b. Create topic branch
|
### 3b. Create topic branch
|
||||||
|
|
||||||
Name the branch after the epic or logical grouping. Examples:
|
Name the branch after the epic or logical grouping. Examples:
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
# workshop-start — Improvement Log
|
|
||||||
|
|
||||||
Running notes on friction and fixes observed while running workshops. Fold the
|
|
||||||
confirmed ones into `SKILL.md` periodically; delete once applied.
|
|
||||||
|
|
||||||
## From the `system-economic-specialization` relaunch (2026-05-31)
|
|
||||||
|
|
||||||
- **Tool name drift.** SKILL.md §5 says "Use the **Task tool** to spawn each
|
|
||||||
agent." The actual spawn tool is **`Agent`** (with `team_name` + `name` +
|
|
||||||
`subagent_type`). "Task" reads as the TaskCreate/TaskUpdate family and is
|
|
||||||
misleading. Rename to "Agent tool" throughout §5.
|
|
||||||
|
|
||||||
- **SI has no Round 1 work — say so.** The skill adds SI to every workshop but
|
|
||||||
SI's job is Round 2 ticket creation. Round 1 there is no SI task, so SI sits
|
|
||||||
with an empty TaskList and no instruction. Recommend the skill explicitly note:
|
|
||||||
"SI joins on standby; SI gets no task until Round 2 — spawn it in background
|
|
||||||
with a 'load context and wait for Round 2' prompt." Avoids an idle/confused
|
|
||||||
agent on spawn.
|
|
||||||
|
|
||||||
- **Spawn order vs. task creation.** Following the skill literally (§4 create
|
|
||||||
tasks → §5 spawn) matters: if you spawn agents before the tasks exist, they
|
|
||||||
check TaskList, find nothing, and may idle. Worth a one-line warning in §5:
|
|
||||||
"Create and assign all Round 1 tasks BEFORE spawning, or the agents wake to an
|
|
||||||
empty list." (Recoverable by messaging them after, but cleaner to order it
|
|
||||||
right.)
|
|
||||||
|
|
||||||
- **`TaskCreate` is one-task-per-call.** No batch/array form. A batch attempt is
|
|
||||||
rejected. The skill could state this so the lead emits N separate TaskCreate
|
|
||||||
calls (and assigns owners via TaskUpdate, since TaskCreate takes no `owner`).
|
|
||||||
|
|
||||||
- **Read-only participants can't write their own files.** Several workshop agent
|
|
||||||
types (paula, gore, nigel, ozzie, and the read-only miri variant) have NO Write
|
|
||||||
tool — yet SKILL.md §4 makes "write your full output to disk" a hard
|
|
||||||
requirement for every participant. Paula hit this: she produced her full Round 1
|
|
||||||
doc but had to send it to the lead to write `paula-round1.md`. The skill should
|
|
||||||
state up front: "Participants without a Write tool deliver their output via
|
|
||||||
SendMessage; the lead writes the file and marks the task complete on their
|
|
||||||
behalf." Or: assign a write-capable scribe. Either way, don't make disk-write a
|
|
||||||
per-agent requirement for read-only agent types — it guarantees a manual relay.
|
|
||||||
|
|
||||||
- **Participants self-claim, which races owner assignment.** Paula picked up
|
|
||||||
task #3 on her own before the lead assigned owners. Harmless here, but if tasks
|
|
||||||
aren't clearly scoped per-agent an agent could grab the wrong one. The skill's
|
|
||||||
per-agent task titles ("Round 1 — Miri …") mitigate this; keep titles
|
|
||||||
agent-named.
|
|
||||||
|
|
||||||
## Candidate feature — per-round "scout" critic (user idea, 2026-05-31)
|
|
||||||
|
|
||||||
Add an optional independent **scout** agent that runs per round, AFTER the round's
|
|
||||||
output files land and BEFORE the user checkpoint, to surface missed options,
|
|
||||||
simpler designs, internal contradictions, and external design prior-art.
|
|
||||||
|
|
||||||
- **Value is mostly the independent adversarial review**, not the web. Participants
|
|
||||||
build on each other and converge; a fresh agent with no stake catches blind
|
|
||||||
spots convergence hides. Web search is a bonus, useful for the *mechanism* (real
|
|
||||||
economic geography, how other games encode X, schema-granularity tradeoffs) —
|
|
||||||
NOT the lore.
|
|
||||||
- **Hard guardrails:** (1) lore is authored-canonical and fictional — the scout must
|
|
||||||
NOT "correct" the fiction with real-world/web facts; scope web to design/mechanism
|
|
||||||
prior-art only. (2) Only surface findings that would CHANGE a decision — a critic
|
|
||||||
that always finds 10 things gets ignored.
|
|
||||||
- **Shape:** cheap model (Haiku), `run_in_background: true`, reads the round files +
|
|
||||||
relevant D-records, writes `scout-round{N}.md`. Lead folds decision-changing items
|
|
||||||
into the checkpoint presented to the user. Escalate to Sonnet only to dig into a
|
|
||||||
real find.
|
|
||||||
- Pairs well with the quality-over-scope-creep principle: the scout is a cheap way
|
|
||||||
to pressure-test that "quality" claims actually hold and nothing simpler was missed.
|
|
||||||
|
|
||||||
## Wrap-up gotchas (2026-05-31)
|
|
||||||
|
|
||||||
- **`pql decisions claim` is side-effect-free** (it just prints the next available ID).
|
|
||||||
This fixes the old `tooling/db/decision claim` footgun, which burned an ID and appended
|
|
||||||
a placeholder on every call — retrying it created duplicate records. With pql, claim is
|
|
||||||
safe to re-run; the record only exists once you write the `### D-NNN: …` heading into the
|
|
||||||
governance file. Still claim each ID once and write it immediately so parallel branches
|
|
||||||
don't pick the same number.
|
|
||||||
- **Read-only documenter can still file** — the lead hands it the claimed ID(s); the
|
|
||||||
documenter writes the records into `governance/{decisions,questions,rejected}/<domain>.md`.
|
|
||||||
- **Background (`run_in_background`) teammates can be slow/unreliable to consume
|
|
||||||
`shutdown_request`.** At wrap-up, qatux + si (both spawned in background per the
|
|
||||||
skill's §5 guidance) stayed "active" through multiple shutdown sends, blocking
|
|
||||||
TeamDelete. Foreground participants shut down immediately. Options to fold into
|
|
||||||
the skill: (a) don't background the always-present agents, or (b) document that
|
|
||||||
wrap-up may need several shutdown retries / a longer settle, and that the lead
|
|
||||||
should not spin indefinitely — the work is already on disk, TeamDelete is just
|
|
||||||
resource cleanup. Consider whether the skill should note the team can be left to
|
|
||||||
expire rather than blocking the session on cleanup.
|
|
||||||
@@ -4,7 +4,7 @@ description: >
|
|||||||
Start a multi-agent design workshop from a workshop brief. Use when the user says
|
Start a multi-agent design workshop from a workshop brief. Use when the user says
|
||||||
"start workshop", "run workshop", "let's start the workshop", or invokes /workshop-start.
|
"start workshop", "run workshop", "let's start the workshop", or invokes /workshop-start.
|
||||||
Parses the workshop brief to extract participants, questions, and round format.
|
Parses the workshop brief to extract participants, questions, and round format.
|
||||||
Creates a team, tasks, and spawns agents as teammates via the Task tool.
|
Creates a team, tasks, and spawns agents as teammates via the Agent tool.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Start Workshop
|
# Start Workshop
|
||||||
@@ -24,7 +24,8 @@ Read the workshop brief. Extract:
|
|||||||
- Workshop name (from directory name)
|
- Workshop name (from directory name)
|
||||||
- Participant list (from `**Participants:**` line)
|
- Participant list (from `**Participants:**` line)
|
||||||
- Per-participant questions (scan for `**{AgentName}**:` patterns in questions sections)
|
- Per-participant questions (scan for `**{AgentName}**:` patterns in questions sections)
|
||||||
- Round count and round descriptions (from `**Workshop Format**` section)
|
- Round count and round descriptions (from the `## Workshop Format` heading — a real
|
||||||
|
heading, not a bold marker; every brief under `docs/workshops/` uses this form)
|
||||||
|
|
||||||
### 2. Create Team
|
### 2. Create Team
|
||||||
|
|
||||||
@@ -38,8 +39,8 @@ Two agents join every workshop regardless of the participant list:
|
|||||||
|
|
||||||
| Agent | Role | Task | Participates in discussion? |
|
| Agent | Role | Task | Participates in discussion? |
|
||||||
|-------|------|------|-----------------------------|
|
|-------|------|------|-----------------------------|
|
||||||
| **Qatux** | Documenter | Captures all decisions, questions, dissent, consensus. Writes `workshop-notes.md` per round, produces final `workshop-outcomes.md`. | No — observes and records only |
|
| **Qatux** | Documenter | Captures all decisions, questions, dissent, consensus. Writes `round-{N}-notes.md` per round, produces final `workshop-outcomes.md`. | No — observes and records only |
|
||||||
| **SI** | Sprint prep | Suggest adding when outputs include tickets. Creates tickets from decisions, links to sprint backlog. | No — execution prep only |
|
| **SI** | Refinement reviewer | Suggest adding when outputs include tickets. Reviews `workshop-outcomes.md` for ticket-worthy items and context completeness — does **not** create tickets (si.md's "What you do NOT do" list is explicit: no ticket creation or DB writes). The lead creates tickets via the `/ticket` skill; SI reviews them for gaps. | No — execution prep only |
|
||||||
|
|
||||||
Qatux and SI are **never dismissed early.** If the user reduces the team mid-workshop, keep qatux and si (if added). Documenting everything prevents loss of valuable information.
|
Qatux and SI are **never dismissed early.** If the user reduces the team mid-workshop, keep qatux and si (if added). Documenting everything prevents loss of valuable information.
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ One task per participant containing:
|
|||||||
- The specific questions assigned to that participant (extracted from all layers)
|
- The specific questions assigned to that participant (extracted from all layers)
|
||||||
- The output format from the brief's round description
|
- The output format from the brief's round description
|
||||||
- **IMPORTANT — file output requirement:** Instruct each agent to write their full output to `docs/workshops/{name}/{agent}-round{N}.md` (e.g., `docs/workshops/test-architecture/gestalt-round1.md`). Agents must write to disk, not just send messages. This ensures Qatux and other agents can read all outputs directly without relying on message forwarding.
|
- **IMPORTANT — file output requirement:** Instruct each agent to write their full output to `docs/workshops/{name}/{agent}-round{N}.md` (e.g., `docs/workshops/test-architecture/gestalt-round1.md`). Agents must write to disk, not just send messages. This ensures Qatux and other agents can read all outputs directly without relying on message forwarding.
|
||||||
|
**Several participant types have no Write tool** (ozzie, gore, nigel, paula, miri — verify current grants in `.claude/agents/*.md` frontmatter). Participants without a Write tool deliver their output via SendMessage instead; the lead writes `{agent}-round{N}.md` on their behalf and marks the task complete.
|
||||||
|
|
||||||
One task for Qatux: "Document Round N — read all agent output files at `docs/workshops/{name}/*-round{N}.md` and capture decisions, questions, and dissent."
|
One task for Qatux: "Document Round N — read all agent output files at `docs/workshops/{name}/*-round{N}.md` and capture decisions, questions, and dissent."
|
||||||
|
|
||||||
@@ -57,16 +59,21 @@ Assign all tasks using TaskUpdate with `owner` = agent name.
|
|||||||
|
|
||||||
### 5. Spawn Agents
|
### 5. Spawn Agents
|
||||||
|
|
||||||
Use the Task tool to spawn each agent as a teammate. Each call should:
|
**Create and assign all Round 1 tasks (§4) before spawning.** Spawning first means
|
||||||
|
agents wake to an empty TaskList and may idle. SI joins on standby with no Round 1
|
||||||
|
task — SI's job starts at Round 2 ticket review — so give it a "load context and
|
||||||
|
wait" prompt rather than an empty task.
|
||||||
|
|
||||||
|
Use the Agent tool to spawn each agent as a teammate. Each call should:
|
||||||
- Set `team_name` to the workshop team name
|
- Set `team_name` to the workshop team name
|
||||||
- Set `name` to the agent name (e.g., "gestalt")
|
- Set `name` to the agent name (e.g., "gestalt")
|
||||||
- Set `subagent_type` to the matching agent type (same as name — see reference table)
|
- Set `subagent_type` to the matching agent type (same as name — see reference table)
|
||||||
- **Set `model: "sonnet"`** — team-mode participants pin to Sonnet 4.6 for literal-rule-following discipline. Opus 4.7 was observed ignoring scope rules and failing to report back in team mode (Sprint 37). The *team lead* (this session) stays on whatever model the user has selected.
|
- **Set `model: "sonnet"`** — team-mode participants pin to Sonnet 4.6 for literal-rule-following discipline. Opus 4.7 was observed ignoring scope rules and failing to report back in team mode (Sprint 37). The *team lead* (this session) stays on whatever model the user has selected.
|
||||||
- Provide a prompt telling the agent to check TaskList for their assigned task
|
- Provide a prompt telling the agent to check TaskList for their assigned task
|
||||||
|
|
||||||
Spawn all agents in parallel (one Task call per agent in a single message). Agents will appear as teammates in the Claude Code UI and pick up their tasks from the shared task list.
|
Spawn all agents in parallel (one Agent call per agent in a single message). Agents will appear as teammates in the Claude Code UI and pick up their tasks from the shared task list.
|
||||||
|
|
||||||
For large workshops (>6 agents), spawn participants in batches to avoid overwhelming the system. Always-present agents (Qatux, SI) can run in background via `run_in_background: true`.
|
For large workshops (>6 agents), spawn participants in batches to avoid overwhelming the system. Always-present agents (Qatux, SI) can run in background via `run_in_background: true` — but background teammates can be slow or unreliable to consume `shutdown_request`, so wrap-up (§8) may need several shutdown retries. Don't spin indefinitely waiting on it: the work is already on disk, and the team can be left to expire rather than blocking the session on `TeamDelete`.
|
||||||
|
|
||||||
### 6. Monitor
|
### 6. Monitor
|
||||||
|
|
||||||
@@ -96,9 +103,9 @@ When all Round N tasks are complete:
|
|||||||
Before the user dismisses the team, the following are **hard requirements**:
|
Before the user dismisses the team, the following are **hard requirements**:
|
||||||
|
|
||||||
1. **User reviews final outcomes** — Present `workshop-outcomes.md` content to the user via AskUserQuestion. Get explicit approval before proceeding to filing.
|
1. **User reviews final outcomes** — Present `workshop-outcomes.md` content to the user via AskUserQuestion. Get explicit approval before proceeding to filing.
|
||||||
2. **D-records filed** — All new D-records, amendments, and supersessions are written to `governance/` domain files. This is non-negotiable — workshops that produce decisions MUST file them before shutdown.
|
2. **D-records filed** — **Claim each ID first** with `pql decisions claim D <domain> "title"` (side-effect-free — safe to re-run, just prints the next free id) and write the record immediately after claiming, so parallel branches don't collide on the same number (CLAUDE.md requirement). All new D-records, amendments, and supersessions are written to `governance/` domain files. This is non-negotiable — workshops that produce decisions MUST file them before shutdown.
|
||||||
3. **Discussion captured** — Qatux produces final `workshop-outcomes.md` from accumulated notes. Qatux creates or updates diagrams (via `/d2-diagram`) for any new D-records produced by the workshop.
|
3. **Discussion captured** — Qatux produces final `workshop-outcomes.md` from accumulated notes. Qatux creates or updates diagrams (via `/d2-diagram`) for any new D-records produced by the workshop.
|
||||||
4. **Tickets created** — If SI is present, SI creates tickets from decided items and the user reviews the ticket list.
|
4. **Tickets created** — The lead creates tickets from decided items via the `/ticket` skill, grounded in `workshop-outcomes.md`. If SI is present, SI reviews the drafted tickets for context completeness before the user reviews the ticket list.
|
||||||
5. **User gives explicit go-ahead to dismiss** — Only after steps 1-4 are complete AND the user confirms, send shutdown_request to all agents (qatux and si last).
|
5. **User gives explicit go-ahead to dismiss** — Only after steps 1-4 are complete AND the user confirms, send shutdown_request to all agents (qatux and si last).
|
||||||
6. TeamDelete to clean up.
|
6. TeamDelete to clean up.
|
||||||
|
|
||||||
@@ -156,3 +163,5 @@ Agent name maps directly to subagent_type:
|
|||||||
| inigo | Sound design | Audio, soundscape, spatial audio |
|
| inigo | Sound design | Audio, soundscape, spatial audio |
|
||||||
| troblum | Tech consultant | Second opinion on architecture/tech choices |
|
| troblum | Tech consultant | Second opinion on architecture/tech choices |
|
||||||
| hoshe | QA/testing | Test plans, verification, quality |
|
| hoshe | QA/testing | Test plans, verification, quality |
|
||||||
|
| burnelli-sheldon | Economist | Market models, price formation, economic credibility |
|
||||||
|
| justine | Polish/deployment | Build, performance, release quality |
|
||||||
|
|||||||
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# tooling/godot-cold-parse [--run-menu] — cold-cache headless parse check.
|
||||||
|
#
|
||||||
|
# Used by /pr-process step 1c before push. Deletes the cached script-class
|
||||||
|
# registry so the parse simulates the cold-start ordering CI / fresh clones
|
||||||
|
# see: Sprint 36 close caught a new `class_name MetaScreen` base class and
|
||||||
|
# six extending scripts that parsed fine on warm developer caches but hit
|
||||||
|
# `Could not find base class "MetaScreen"` post-merge, because the
|
||||||
|
# autoload-vs-class_name registration order only resolves correctly once the
|
||||||
|
# class cache is seeded (see CLAUDE.md -> GDScript conventions -> Autoload
|
||||||
|
# parse-order rule).
|
||||||
|
#
|
||||||
|
# Godot's resource scanner emits category errors (e.g. "Export type can only
|
||||||
|
# be built-in, a resource, a node, or an enum") that do NOT always prefix
|
||||||
|
# with SCRIPT ERROR — they appear as plain ERROR lines. The filter below
|
||||||
|
# catches both, then drops known pre-existing noise from the autoload
|
||||||
|
# class_name parse-order trap. Sprint 36 shipped a scanner error the old
|
||||||
|
# narrower grep missed; this is why the filter stays wide.
|
||||||
|
#
|
||||||
|
# --run-menu: also launch main_menu.tscn briefly (for branches with UI changes).
|
||||||
|
#
|
||||||
|
# Exit 0 + "clean" if no matches. Exit 1 + the matched lines if any are found.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
|
RUN_MENU=false
|
||||||
|
[ "${1:-}" = "--run-menu" ] && RUN_MENU=true
|
||||||
|
|
||||||
|
rm -f "$REPO_ROOT/client/.godot/global_script_class_cache.cfg"
|
||||||
|
|
||||||
|
FILTER='^(SCRIPT )?ERROR|Parse Error|Export type'
|
||||||
|
|
||||||
|
MATCHES=$(godot --headless --path "$REPO_ROOT/client" --quit 2>&1 \
|
||||||
|
| grep -iE "$FILTER" \
|
||||||
|
| grep -v "Failed loading resource: res://assets" \
|
||||||
|
| grep -v "Cannot infer the type" \
|
||||||
|
| grep -vE '(Messagepack|LocalBridge|ServerProcess|Constants)" not declared' || true)
|
||||||
|
|
||||||
|
if [ "$RUN_MENU" = true ]; then
|
||||||
|
MENU_MATCHES=$(timeout 10 godot --path "$REPO_ROOT/client" res://scenes/main_menu.tscn 2>&1 \
|
||||||
|
| grep -iE "$FILTER" || true)
|
||||||
|
if [ -n "$MENU_MATCHES" ]; then
|
||||||
|
MATCHES="$MATCHES
|
||||||
|
$MENU_MATCHES"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$MATCHES" ]; then
|
||||||
|
echo "$MATCHES"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "godot-cold-parse: clean"
|
||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# tooling/pr-watchlist-diff <base> <head> — list watch-list files changed
|
||||||
|
# between <base> and <head>.
|
||||||
|
#
|
||||||
|
# Used by /pr-process step 4a (T-858) to decide whether `make regen-db` must
|
||||||
|
# run before push. The stamped generator sources come from the shared
|
||||||
|
# registry tooling/generator_sources.py (T-1067) — imported live here so this
|
||||||
|
# list can't drift from the stamp writer / tooling/check-systems-db-stamp.
|
||||||
|
#
|
||||||
|
# The extra hardcoded paths below are non-stamped watch items: the surviving
|
||||||
|
# one-time planet-gen importers (import_heightmaps.py, import_province_
|
||||||
|
# boundaries.py — not part of `make regen-db`, but their data feeds the
|
||||||
|
# committed DB), the schema DDL (stamped separately via schema_sha), and the
|
||||||
|
# wiki data directories that feed the generators.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE="${1:?usage: tooling/pr-watchlist-diff <base> <head>}"
|
||||||
|
HEAD="${2:?usage: tooling/pr-watchlist-diff <base> <head>}"
|
||||||
|
|
||||||
|
mapfile -t GENERATOR_SOURCES < <(python3 tooling/generator_sources.py --list)
|
||||||
|
|
||||||
|
git diff --name-only "$BASE...$HEAD" -- \
|
||||||
|
"${GENERATOR_SOURCES[@]}" \
|
||||||
|
tooling/planet-gen/import_heightmaps.py \
|
||||||
|
tooling/planet-gen/import_province_boundaries.py \
|
||||||
|
server/data/systems-schema.sql \
|
||||||
|
wiki/star-systems/ \
|
||||||
|
wiki/economics/
|
||||||
Reference in New Issue
Block a user