Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .claude/agents/squad-code-officer.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ issue and the project's documentation are not needed for format and analyzer fix
Limits: no change to behavior, signatures used across files, control flow, test assertions or test data. A
new guard, branch, early return, null check or a changed assertion counts as structural: do not make it,
hand it back with file, line and rule id to the Dev (production code) or Tester (tests). Never suppress a
rule on your own β€” a justified, narrowly scoped suppression needs the Lead's approval and a decision record.
rule on your own β€” a justified, narrowly scoped suppression needs the Lead's approval and a decision record. A finding that
contradicts a documented style rule (`AGENTS.md`, *Code style*; `.squad/stack.md`) is reported as a conflict with
that rule, with the `.editorconfig` severity as the proposed fix, and the code is not restructured around it.

You also receive the findings of the *Sonar gate* (step 7) and, after the PR is open, of the CI code analysis
(`sonar-check.py pr <number>`); treat them like findings of the analyzer gate. For a rule no local analyzer
After the PR is open you also receive the findings of the *Sonar gate*, the CI code analysis of the draft pull
request (`sonar-check.py pr <number>`); treat them like findings of the analyzer gate. For a rule no local analyzer
reported, add one line to the *Analyzer gate* section of `.squad/stack.md` (the rule id, what it flags, how to
avoid it while writing code) in the product PR (*Scope of a product PR* in `.squad/routing.md`,
*Squad lessons* in `.squad/orchestration.md`); no other file under `.squad/` is edited.
Expand Down
9 changes: 7 additions & 2 deletions .claude/agents/squad-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,16 @@ test documentation, the area documents with their index rows, `docs/ARCHITECTURE
*Coverage gate* passes β€” for a feature after the last task group, in your `implement` agent. Write each statement
from the code as it now stands (`git diff <base>`, the working tree included), not from the plan's wording, and
re-read every sentence of the touched sections that describes the changed behavior; run `decision-check.py` when
you touched `docs/areas/`. A statement that would contradict a decision record goes to the Lead in your report.
you touched `docs/areas/`. A sentence you write that states a number (a count, a limit, a size, a budget), an order
or a completeness ("only", "all", "never", "covered by …") names in your report the code line, test or measurement
it rests on; one you cannot trace is narrowed to what the code shows or left out. A statement that would contradict
a decision record goes to the Lead in your report.

Before handing over, run *Format* (`.squad/team.md`, *Shared rules*). Do not chase style diagnostics unless
the Code Officer hands one back; run the *Analyzer gate* once and fix the findings in your production files
that need a code change, so they do not come back later as a structural hand-back.
that need a code change, so they do not come back later as a structural hand-back. A finding that contradicts a
documented style rule (`AGENTS.md`, *Code style*; `.squad/stack.md`) is not worked around: report it as a conflict
with that rule, name the `.editorconfig` severity as the proposed fix, and leave the code as the rule has it.
Tests stay the Tester's beyond the mechanical call-site adaptations above (*Loop limits* in
`.squad/routing.md`): a test you believe is wrong, or a plan that does not work, goes back as a report for the
Lead, and a deviation from the plan is stated in your report.
Expand Down
4 changes: 3 additions & 1 deletion .claude/agents/squad-tester.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ Mode `tests-first`:
For a documented shell procedure derive the cases from the plan's list of what happens when the lines are
pasted at once or one at a time, one fails or a variable is lost; a test that reads a repository document
normalizes `\r\n` (`docs/UNIT_TESTS.md`); for a script only CI can run, run the local smoke substitute
(*Writing tests* in `.squad/stack.md`) before you hand back.
(*Writing tests* in `.squad/stack.md`) before you hand back. For a case you cannot run locally (a container, a
CI-only script), read *Known pitfalls* in `.squad/stack.md` first and write its commands for the environment they
run in, not for the host's tools; process their output on the host.
For a feature, the criteria are `spec.md`'s and their tests the plan's *Tests per criterion*: every field
and value a criterion names, and the scenarios and edge cases it lists, are asserted by a test; name one no
test asserts in your report.
Expand Down
7 changes: 3 additions & 4 deletions .claude/skills/create-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ repository.
unformatted code or outstanding analyzer diagnostics. This step is the gate
before the PR; CI is not meant to find anything here.
5. **Commit** as `AGENTS.md` (*Commit messages and pull requests*) says,
staging only the files that belong to this task. Then run the *Sonar gate*
from `.squad/stack.md` β€” SonarQube Cloud's analysis of the committed
branch; fix every finding it lists (and commit again). NOT CHECKED (no
SonarQube credential in this environment) leaves the check to step 9.
staging only the files that belong to this task. The *Sonar gate* from
`.squad/stack.md` reads the CI code analysis of the draft pull request, so it
runs in step 9.
6. **Run the internal review loop** (see below) and resolve what it finds.
This happens *before* the push, so the pull request opens on a reviewed
change instead of collecting review rounds afterwards.
Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/squad-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ every Git and GitHub action yourself, including follow-up issues the Lead decide

**Logging.** Only you write `log.md`, one row per step and per launch, always with
`python3 .squad/tools/squad-log.py issue-<number> "<step>" "<member>" "<result>"` β€” never by hand.
- Write a launch's row as soon as its report is in, with `--agent squad-<role>` alone (usage pending), a continued one too (`--continued` only on the amend). When
- Write a launch's row as soon as its report is in, with `--agent squad-<role>` alone (usage pending; `--launch` for a launch *Launch model* overrides), a continued one too (`--continued` only on the amend). When
its task notification arrives, add the usage with `--amend-last "<member>" --agent squad-<role> --tokens …
--tool-uses … --seconds …` (`--step "<step>"` for a row that is no longer the member's last).
- **Every number is copied from the usage block of a task notification you have in front of you** β€”
Expand Down Expand Up @@ -105,7 +105,7 @@ every Git and GitHub action yourself, including follow-up issues the Lead decide
signatures and the existing test call sites the plan assigns to the Dev. A plan that declares the change
free of production and test code skips steps 4 and 5 (*Changes without production or test code*): log the
skipped steps and run the plan's *Verification without tests* instead.
5. **Tests first** (not for `trivial`). Launch `squad-tester` in mode `tests-first`. Confirm yourself that the
5. **Tests first** (not for `trivial`). Launch `squad-tester` in mode `tests-first`, with the model *Launch model* names. Confirm yourself that the
new tests compile and fail on the current code (unless the Tester justified why one cannot); note the
tests it hands back as **deferred**. A fix without a reproducing test is acceptable only when the bug
genuinely needs a live external system β€” then the PR says so.
Expand All @@ -124,9 +124,9 @@ every Git and GitHub action yourself, including follow-up issues the Lead decide
reported as not unit-testable go to `squad-lead` in mode `decide`.
7. **Code check.** `git fetch origin main` and merge `main` first when it moved (*Merge conflicts*). Run the gates of step 7 (*Pipeline*;
for a change without code and for `patch` their sections) with the commands from `.squad/stack.md`,
once they pass, commit, then run the *Sonar gate*; keep the output for step 8. When *Format check* fails, run *Format*,
once they pass, commit (the *Sonar gate* runs on the draft PR in step 11). When *Format check* fails, run *Format*,
`git restore -- <file>` every file it changed outside the change, and check again. Launch
`squad-code-officer` with the base ref only for analyzer diagnostics, Sonar findings or style findings that
`squad-code-officer` with the base ref only for analyzer diagnostics or style findings that
need reading; structural items it hands back go to `squad-dev` (or `squad-tester`), a scope finding to its
owner, a file it formatted outside the change you restore. Run the gates again until they pass.
8. **Review.** Launch `squad-reviewer` (round 1, full) and β€” on tier `security` β€” `squad-security` in mode
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: Bug report
about: Report a problem
title: "[BUG] "
title: ""
labels: bug
assignees: ''

Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[Feature] "
title: ""
labels: enhancement
assignees: ''

Expand Down
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ and the round semantics. The squad's members (`.squad/team.md`) run as subagents
commits, pushes and posts. The pipeline, its limits and escalations are in [`.squad/routing.md`](/.squad/routing.md),
the project's guarantees, security areas and integration surface in [`.squad/project.md`](/.squad/project.md).
Working records stay under `specs/` on the work branch. A product PR never changes the squad or these
instructions (`.squad/stack.md`, `.squad/project.md` and the project blocks of this file excepted); squad lessons become `squad` issues where they can be fixed (`.squad/orchestration.md`, *Squad
instructions (`.squad/stack.md`, `.squad/project.md`, `.squad/tools/squad_settings.py` and the project blocks of this file excepted); squad lessons become `squad` issues where they can be fixed (`.squad/orchestration.md`, *Squad
lessons*). The user acts as Product Manager and is asked only when the Lead escalates.

The reasoning behind code decisions β€” why something was built the way it was β€” is recorded by the Lead
Expand Down
11 changes: 10 additions & 1 deletion .squad/orchestration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ template β€” is filed in the template repository, which the session attaches fir
to create the issue, e.g. `add_repo`); only if attaching is refused it is filed here with the label
`squad-upstream`, the user is told to move it, and it is never worked here.

## Launch model

Every member is launched with the model and effort of its agent file, except: every `squad-tester` launch of a run
whose `plan.md` names tier `security` gets `model: opus` (effort unchanged); a continued agent keeps the model it
was launched with. Log such a launch with `--launch opus/<effort>` instead of `--agent squad-tester`, on the
pending row and on its amend; `squad-log.py` refuses `--agent` alone there, so the summary shows the model the
launch really ran on.

## Continuing a member

A fix round or a delta round of the same member within the same run continues that member's last launch
Expand All @@ -82,7 +90,8 @@ detached HEAD is switched back to it first (`git switch <branch>`, then `git mer
commits made on the detached HEAD) and logged with the launch that left it. Push without `-q` and check after
every push that `git rev-parse origin/<branch>` equals `git rev-parse HEAD`: a push that did not move the branch
is a failure, not a success. After the PR every push re-triggers CI and the code analysis, so edits are
batched and committed once per round.
batched and committed once per round, and a tests-first commit that fails on purpose is pushed only together
with the implementation that makes it pass: the head of an open PR never fails by design.

## The stop hook

Expand Down
29 changes: 23 additions & 6 deletions .squad/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Squad lessons are filed in step 12 (*Squad lessons*), never fixed in the product
Reviewer in step 8, and a finding is blocking.

One exception: `.squad/stack.md`, `.squad/project.md` and the project blocks of `AGENTS.md` describe the
product, not the squad. A product PR updates them when the change itself makes them untrue β€” a new build command,
product, not the squad. `.squad/tools/squad_settings.py` is the repository's own settings file and a product PR may
change it too (a coverage exclusion, *Code a unit test cannot cover*; a threshold is never lowered). A product PR updates them when the change itself makes them untrue β€” a new build command,
a new security area, a new guarantee or coupling point β€” without an escalation, and the Reviewer treats a stale
entry there like stale documentation. A project block of `AGENTS.md` changes identically in
`.github/copilot-instructions.md` (`scope-check.py` compares them).
Expand Down Expand Up @@ -159,10 +160,21 @@ generated file, process startup glue β€” is found in the plan, not after the PR:
`plan.md` with the reason, the Tester confirms or contests the list in its report, and the Lead's decision
is a decision record. Such a file is excluded from the coverage **measure** only, in every place that
computes it (`sonar.coverage.exclusions` for the CI code analysis, and `COVERAGE_EXCLUDES` in
`.squad/tools/squad_settings.py` where `COVERAGE_PATHSPECS` includes the file; *Coverage exclusions* in
`.squad/stack.md` names where the repository sets them) β€” never from the analysis (`sonar.exclusions`, a
`.squad/tools/squad_settings.py` where `COVERAGE_PATHSPECS` includes the file β€” the product PR edits that file
itself; *Coverage exclusions* in `.squad/stack.md` names where the repository sets them) β€” never from the analysis (`sonar.exclusions`, a
suppression): its rules still apply, and those no local gate reports arrive in step 11.

### Early draft PR

CI runs on pull requests only, so a change whose **CI-only criteria** (*Criteria verified only in CI*) or **dry
run** (*Operator environments and documented procedures*) needs a CI result before the review, and a PR opened in
step 10 comes too late for it. For such a change the plan says so, and the orchestrator opens the PR as a draft
right after step 7 (`create-pr` step 8, `specs/` still in the diff, no working record comment yet), then waits for CI
and reads `sonar-check.py pr <n>` before step 8; findings are worked as in step 11. The *Sonar gate* alone is no
reason for an early PR: every push to an open PR runs all of CI again, and step 11 reads the analysis anyway. The dry run runs on that head, before the documentation is
reviewed. Step 9 additionally requires the green CI run, the dry-run result and the Reviewer's round on the same
head; step 10 then only posts the working record, removes `specs/` and marks nothing ready (*Draft until green*).

## Pipeline

| # | Step | Owner | Exit condition |
Expand All @@ -173,10 +185,10 @@ suppression): its rules still apply, and those no local gate reports arrive in s
| 4 | Skeleton | Dev | Only when the plan adds or changes API: compile-only signatures built as *Skeleton* in `.squad/stack.md` describes, *Build* passes |
| 5 | Tests first | Tester | Only the tests the plan names for its acceptance criteria (one or a few per criterion); they compile and **fail** on the current code or the skeleton. A plan-named test that cannot fail yet is *deferred* to step 6; other guards, pins of existing behavior, determinism and bound tests are not written |
| 6 | Implementation + coverage | Dev, Tester | All tests green; *Coverage gate* passes; then the plan's doc updates, area documents included, written by the Dev against the code as built (`squad-dev.md`, *Documentation*). The Tester's coverage pass adds tests only for uncovered lines, a resource bound the plan names, a deferred or missing plan-named test, or a test a reviewer asks for |
| 7 | Code check | Orchestrator, Code Officer | `main` merged first when it moved (*Merge conflicts*). The orchestrator runs *Format check*, *Analyzer gate*, *Test*, *Coverage gate* and `scope-check.py`, commits, then runs the *Sonar gate* (NOT CHECKED β€” no SonarQube credential, or no scanner download β€” is logged and leaves it to step 11). It clears a *Format check* failure itself (*Format*, then `git restore` of every file outside the change); analyzer diagnostics, Sonar findings and style findings that need reading launch the Code Officer (structural items go to the Dev or Tester), then the gates run again. Exit: every gate passes on the head |
| 7 | Code check | Orchestrator, Code Officer | `main` merged first when it moved (*Merge conflicts*). The orchestrator runs *Format check*, *Analyzer gate*, *Test*, *Coverage gate* and `scope-check.py`, then commits; the *Sonar gate* runs in step 11 on the draft PR. It clears a *Format check* failure itself (*Format*, then `git restore` of every file outside the change); analyzer diagnostics and style findings that need reading launch the Code Officer (structural items go to the Dev or Tester), then the gates run again. Exit: every gate passes on the head |
| 8 | Review | Reviewer (+ Security's diff review on `security`, and on an unlisted security area) | They get the code SHA and the orchestrator's gate output of step 7 (they do not re-run the gates); later commits during the round may touch only `specs/` and do not make it stale. No blocking findings β†’ 9; blocking β†’ owner fixes (Dev: code and documentation, Tester: tests), back to 6, then a mandatory delta round β€” except a verbatim documentation fix (*Verbatim documentation fixes*) |
| 9 | PR approval | Orchestrator, Lead when needed | *PR approval* below |
| 10 | Pull request | Orchestrator | Working record posted as comment (a long `plan.md` may be given as a permalink to the last commit that contains it plus a summary), `specs/<folder>/` removed and `scope-check.py --no-specs` clean, PR opened **as a draft** (*Draft until green*; merged later with *Squash and merge*) |
| 9 | PR approval | Orchestrator, Lead when needed | *PR approval* below; with an *Early draft PR* also green CI, the dry-run result and the Reviewer's round on the same head |
| 10 | Pull request | Orchestrator | Working record posted as comment (a long `plan.md` may be given as a permalink to the last commit that contains it plus a summary), `specs/<folder>/` removed and `scope-check.py --no-specs` clean, PR opened **as a draft** (*Draft until green*; merged later with *Squash and merge*) β€” or, after an *Early draft PR*, only the record and the removal |
| 11 | After the PR | Dev, Code Officer, Reviewer | *Draft until green* holds and the PR is marked ready for review; review comments worked |
| 12 | Wrap-up | Orchestrator | Squad lessons filed as one issue per destination (*Squad lessons*), or "no lessons" logged; the run metrics of `squad-log.py --summary` (exit 0) appended to the working record exactly as printed and reported to the user |

Expand Down Expand Up @@ -275,6 +287,11 @@ PR is opened, the branch stays without one, and the user is told so.
cover*) is a plan defect the Lead records with the decision.
- **After the PR (step 11):** CI or quality-gate failures and review comments are fixed on the same
branch through steps 7–8 again (delta review), at most 2 fix rounds per failure; then the Lead decides.
- **New scope on the open PR (step 11):** a Product Manager request on the open pull request that adds or
changes behavior beyond the spec's acceptance criteria (not a criterion the change misses) goes to the Lead
before any edit. The Lead decides, recorded in `log.md`: a follow-up issue (the default), or this change grows,
and then the spec gets the new criteria and the plan a new task group, which runs steps 3–8 like the others
(plan challenge and Security plan review as the tier asks) before step 9 approves again.
- **Safeguard stop (any member, any step):** an API `invalid_request` of category `cyber` is not an API error:
relaunching unchanged loops, and rephrasing the request is a workaround. The orchestrator escalates to the
Product Manager at once, naming the finding the member had not reviewed as unverified.
Expand Down
Loading
Loading