@mmerterden/multi-agent-pipeline 20.36.0 → 20.37.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/CHANGELOG.md +37 -0
- package/docs/facts.json +2 -2
- package/docs/features.md +1 -1
- package/docs/recovery-guide.md +1 -1
- package/install/catalog-history.json +1 -1
- package/manifest.json +225 -148
- package/package.json +1 -1
- package/pipeline/commands/multi-agent/SKILL.md +33 -154
- package/pipeline/commands/multi-agent/analysis/SKILL.md +14 -68
- package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +5 -8
- package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +38 -109
- package/pipeline/commands/multi-agent/channels/SKILL.md +38 -167
- package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +37 -144
- package/pipeline/commands/multi-agent/design-check/SKILL.md +27 -131
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +22 -48
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +37 -180
- package/pipeline/commands/multi-agent/jira/SKILL.md +16 -46
- package/pipeline/commands/multi-agent/manual-test/SKILL.md +12 -7
- package/pipeline/commands/multi-agent/refactor/SKILL.md +23 -184
- package/pipeline/commands/multi-agent/resume/SKILL.md +30 -136
- package/pipeline/commands/multi-agent/review/SKILL.md +24 -199
- package/pipeline/commands/multi-agent/setup/SKILL.md +25 -181
- package/pipeline/commands/multi-agent/stack/SKILL.md +9 -53
- package/pipeline/commands/multi-agent/status/SKILL.md +13 -2
- package/pipeline/commands/multi-agent/store-ready/SKILL.md +27 -226
- package/pipeline/commands/multi-agent/sync/SKILL.md +35 -164
- package/pipeline/commands/multi-agent/test-gen/SKILL.md +2 -4
- package/pipeline/commands/multi-agent/update/SKILL.md +18 -60
- package/pipeline/contract/CHANGELOG.md +9 -0
- package/pipeline/contract/fixtures/error-invalid-request.json +1 -1
- package/pipeline/contract/fixtures/error-unauthorized.json +1 -1
- package/pipeline/contract/fixtures/error-unsigned.json +1 -1
- package/pipeline/contract/fixtures/runs-awaiting-question.json +1 -1
- package/pipeline/contract/fixtures/runs-empty.json +1 -1
- package/pipeline/contract/fixtures/runs-failed.json +1 -1
- package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +1 -1
- package/pipeline/contract/fixtures/runs-pr-opened.json +1 -1
- package/pipeline/contract/fixtures/runs-running.json +1 -1
- package/pipeline/contract/manifest.json +5 -5
- package/pipeline/contract/types/index.d.ts +3 -2
- package/pipeline/multi-agent-refs/audit-guide.md +20 -0
- package/pipeline/multi-agent-refs/autopilot-on/details.md +148 -0
- package/pipeline/multi-agent-refs/channels/generator.md +14 -0
- package/pipeline/multi-agent-refs/channels/preview.md +13 -0
- package/pipeline/multi-agent-refs/channels/reference.md +46 -0
- package/pipeline/multi-agent-refs/complaint-analysis/phases.md +159 -0
- package/pipeline/multi-agent-refs/design-check/export.md +1 -0
- package/pipeline/multi-agent-refs/design-check/init-inventory.md +1 -1
- package/pipeline/multi-agent-refs/design-check/scope-and-ledger.md +64 -0
- package/pipeline/multi-agent-refs/features/analysis-command-notes.md +53 -0
- package/pipeline/multi-agent-refs/features/commit-multi-repo.md +63 -0
- package/pipeline/multi-agent-refs/features/dev-multi-repo.md +51 -0
- package/pipeline/multi-agent-refs/features/test-gap.md +40 -0
- package/pipeline/multi-agent-refs/features/worktree-finalize.md +1 -1
- package/pipeline/multi-agent-refs/garbage-collect/phases.md +60 -0
- package/pipeline/multi-agent-refs/ios-coding-standard/plan.md +71 -0
- package/pipeline/multi-agent-refs/ios-coding-standard/resolve-and-scan.md +135 -0
- package/pipeline/multi-agent-refs/jira/picker-detail.md +71 -0
- package/pipeline/multi-agent-refs/orchestrator/copilot-pipeline.md +88 -0
- package/pipeline/multi-agent-refs/orchestrator/dispatcher.md +96 -1
- package/pipeline/multi-agent-refs/orchestrator/phase-3-user-test.md +12 -9
- package/pipeline/multi-agent-refs/phases/phase-1-plan.md +4 -4
- package/pipeline/multi-agent-refs/phases/phase-2-dev.md +8 -47
- package/pipeline/multi-agent-refs/phases/phase-3-review.md +21 -65
- package/pipeline/multi-agent-refs/phases/phase-4-commit.md +9 -59
- package/pipeline/multi-agent-refs/phases/phase-5-report.md +0 -31
- package/pipeline/multi-agent-refs/refactor/sweep.md +190 -0
- package/pipeline/multi-agent-refs/resume/details.md +115 -2
- package/pipeline/multi-agent-refs/review/inputs.md +33 -1
- package/pipeline/multi-agent-refs/review/module-guides.md +9 -1
- package/pipeline/multi-agent-refs/review/panel.md +75 -0
- package/pipeline/multi-agent-refs/review/valven.md +5 -1
- package/pipeline/multi-agent-refs/rules.md +1 -1
- package/pipeline/multi-agent-refs/setup/hooks-and-plugins.md +4 -0
- package/pipeline/multi-agent-refs/setup/token-save-flow.md +13 -0
- package/pipeline/multi-agent-refs/stack/background.md +72 -0
- package/pipeline/multi-agent-refs/store-ready/gates.md +139 -0
- package/pipeline/multi-agent-refs/store-ready/report.md +40 -2
- package/pipeline/multi-agent-refs/sync/office.md +10 -0
- package/pipeline/multi-agent-refs/sync/overview.md +61 -0
- package/pipeline/multi-agent-refs/sync/repo.md +91 -0
- package/pipeline/multi-agent-refs/update/details.md +83 -0
- package/pipeline/office/index.html +6 -3
- package/pipeline/office/toolkit.json +1 -1
- package/pipeline/rules/figma-pipeline.md +6 -3
- package/pipeline/schemas/prefs.schema.json +1 -1
- package/pipeline/schemas/runs-index.schema.json +2 -1
- package/pipeline/scripts/_memory-policy.mjs +27 -5
- package/pipeline/scripts/checkpoint-fold.sh +59 -0
- package/pipeline/scripts/contract-server.mjs +1 -1
- package/pipeline/scripts/gate-ledger.mjs +1 -1
- package/pipeline/scripts/office-control.mjs +41 -15
- package/pipeline/scripts/offload-ref.sh +1 -1
- package/pipeline/scripts/rework-rulings.mjs +5 -3
- package/pipeline/scripts/runs-index.mjs +34 -7
- package/pipeline/scripts/scope-check-gate.mjs +15 -2
- package/pipeline/scripts/status-overview.mjs +401 -0
- package/pipeline/scripts/user-test-handoff.sh +203 -0
- package/pipeline/scripts/validate-planning.mjs +5 -3
- package/pipeline/scripts/validate-triage.mjs +2 -1
- package/pipeline/scripts/write-state.mjs +13 -4
- package/pipeline/skills/.skill-manifest.json +64 -64
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +7 -70
- package/pipeline/skills/shared/core/apple-archive-compliance/references/examples.md +67 -0
- package/pipeline/skills/shared/core/apple-archive-compliance/references/version-history.md +8 -0
- package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +10 -72
- package/pipeline/skills/shared/core/google-play-compliance/references/examples.md +69 -0
- package/pipeline/skills/shared/core/google-play-compliance/references/notes.md +7 -0
- package/pipeline/skills/shared/core/google-play-compliance/references/version-history.md +5 -0
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +39 -262
- package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +35 -73
- package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +37 -337
- package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +27 -122
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +8 -340
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +37 -180
- package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +12 -7
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +23 -184
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +14 -82
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +25 -277
- package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +13 -2
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +73 -217
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +11 -162
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-code.md +257 -0
- package/pipeline/skills/shared/external/android-architecture/SKILL.md +7 -58
- package/pipeline/skills/shared/external/android-architecture/references/code-examples.md +68 -0
- package/pipeline/skills/shared/external/app-intents/SKILL.md +3 -45
- package/pipeline/skills/shared/external/app-intents/references/code-examples.md +54 -0
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +5 -81
- package/pipeline/skills/shared/external/app-store-optimization/references/engagement-and-localization.md +96 -0
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +6 -112
- package/pipeline/skills/shared/external/app-store-review/references/monetization-and-submission.md +138 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +10 -117
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models-code.md +186 -0
- package/pipeline/skills/shared/external/authentication/SKILL.md +3 -50
- package/pipeline/skills/shared/external/authentication/references/code-examples.md +59 -0
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +3 -84
- package/pipeline/skills/shared/external/callkit-voip/references/code-examples.md +93 -0
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +7 -263
- package/pipeline/skills/shared/external/ci-cd-pipelines/references/pipeline-examples.md +281 -0
- package/pipeline/skills/shared/external/clean-code/SKILL.md +8 -41
- package/pipeline/skills/shared/external/clean-code/references/code-examples.md +56 -0
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +8 -146
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-code.md +214 -0
- package/pipeline/skills/shared/external/compose-components/SKILL.md +6 -80
- package/pipeline/skills/shared/external/compose-components/references/code-examples.md +89 -0
- package/pipeline/skills/shared/external/compose-navigation/SKILL.md +5 -64
- package/pipeline/skills/shared/external/compose-navigation/references/code-examples.md +70 -0
- package/pipeline/skills/shared/external/core-data/SKILL.md +9 -157
- package/pipeline/skills/shared/external/core-data/references/core-data-code.md +221 -0
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +3 -89
- package/pipeline/skills/shared/external/core-nfc/references/code-examples.md +98 -0
- package/pipeline/skills/shared/external/coreml/SKILL.md +17 -133
- package/pipeline/skills/shared/external/coreml/references/coreml-code.md +208 -0
- package/pipeline/skills/shared/external/css-modern/SKILL.md +8 -131
- package/pipeline/skills/shared/external/css-modern/references/code-examples.md +142 -0
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +6 -103
- package/pipeline/skills/shared/external/database-patterns/references/orm-examples.md +112 -0
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +7 -48
- package/pipeline/skills/shared/external/html-semantic/references/code-examples.md +54 -0
- package/pipeline/skills/shared/external/humanizer/SKILL.md +6 -19
- package/pipeline/skills/shared/external/humanizer/references/voice.md +24 -0
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +13 -170
- package/pipeline/skills/shared/external/ios-accessibility/references/assistive-tech-review.md +224 -0
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +2 -24
- package/pipeline/skills/shared/external/ios-localization/references/code-examples.md +30 -0
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +3 -58
- package/pipeline/skills/shared/external/ios-networking/references/code-examples.md +67 -0
- package/pipeline/skills/shared/external/ios-security/SKILL.md +4 -64
- package/pipeline/skills/shared/external/ios-security/references/code-examples.md +74 -0
- package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -90
- package/pipeline/skills/shared/external/live-activities/references/code-examples.md +108 -0
- package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +9 -23
- package/pipeline/skills/shared/external/localization-reuse-map/references/project-settings.md +22 -0
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +5 -95
- package/pipeline/skills/shared/external/mapkit-location/references/code-examples.md +117 -0
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +7 -106
- package/pipeline/skills/shared/external/nextjs-app-router/references/app-router-examples.md +124 -0
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -31
- package/pipeline/skills/shared/external/permissionkit/references/code-examples.md +37 -0
- package/pipeline/skills/shared/external/play-store-review/SKILL.md +6 -74
- package/pipeline/skills/shared/external/play-store-review/references/signing-and-policies.md +83 -0
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +8 -125
- package/pipeline/skills/shared/external/push-notifications/references/notification-code.md +176 -0
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +7 -158
- package/pipeline/skills/shared/external/python-patterns/references/python-examples.md +176 -0
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +7 -157
- package/pipeline/skills/shared/external/rest-api-design/references/api-examples.md +175 -0
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +11 -230
- package/pipeline/skills/shared/external/swift-architecture/references/pattern-examples.md +295 -0
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +17 -149
- package/pipeline/skills/shared/external/swift-codable/references/codable-recipes.md +207 -0
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +12 -99
- package/pipeline/skills/shared/external/swift-concurrency/references/code-examples.md +100 -0
- package/pipeline/skills/shared/external/swift-concurrency/references/swift-6-2-additions.md +18 -0
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +9 -78
- package/pipeline/skills/shared/external/swift-formatstyle/references/formatstyle-examples.md +113 -0
- package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -56
- package/pipeline/skills/shared/external/swift-language/references/code-examples.md +65 -0
- package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +1 -0
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +6 -122
- package/pipeline/skills/shared/external/swiftdata/references/code-examples.md +140 -0
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +12 -139
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/interop-code.md +198 -0
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +9 -81
- package/pipeline/skills/shared/external/tailwind-css/references/code-examples.md +91 -0
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +7 -207
- package/pipeline/skills/shared/external/testing-backend/references/testing-examples.md +225 -0
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +8 -89
- package/pipeline/skills/shared/external/typescript-patterns/references/code-examples.md +100 -0
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -20
- package/pipeline/skills/shared/external/vision-framework/references/code-examples.md +26 -0
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +7 -169
- package/pipeline/skills/shared/external/vue-composition/references/vue-examples.md +187 -0
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +7 -174
- package/pipeline/skills/shared/external/web-accessibility/references/a11y-examples.md +192 -0
- package/pipeline/skills/shared/external/web-performance/SKILL.md +8 -66
- package/pipeline/skills/shared/external/web-performance/references/code-examples.md +77 -0
- package/pipeline/skills/shared/external/web-testing/SKILL.md +11 -186
- package/pipeline/skills/shared/external/web-testing/references/testing-examples.md +213 -0
- /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/format-and-output.md +0 -0
- /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/publish-and-snapshot.md +0 -0
- /package/pipeline/skills/shared/external/localization-reuse-map/{reference → references}/sources-and-recipes.md +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Phase 4 Commit - Multi-Repo Mode
|
|
2
|
+
|
|
3
|
+
> Loaded on demand from `phases/phase-4-commit.md`. Conditional on
|
|
4
|
+
> `state.projects[].length > 1`; a single-repo run never needs it. The
|
|
5
|
+
> Push-must-succeed policy stays in the phase doc because every run uses it.
|
|
6
|
+
|
|
7
|
+
Active when `state.projects[].length > 1`. The single-repo flow in the phase doc is preserved verbatim - multi-repo is an extension, not a replacement.
|
|
8
|
+
|
|
9
|
+
## Per-repo commit (shared message, per-repo scope)
|
|
10
|
+
|
|
11
|
+
For each repo in `state.projects[]` (sequentially, in dependency order from Phase 1):
|
|
12
|
+
|
|
13
|
+
1. `cd "$WT_PATH"` - switch into the repo's worktree.
|
|
14
|
+
2. Build the commit message using the **shared subject** + **per-repo scope** rule:
|
|
15
|
+
```
|
|
16
|
+
{type}({repo-scope}): {shared subject} [{tracker-id}]
|
|
17
|
+
|
|
18
|
+
Part of multi-repo change - see sibling PR(s) in repo `{other repo names}`.
|
|
19
|
+
```
|
|
20
|
+
`repo-scope` is the repo's short name (e.g. `common`, `uicomponents`). The subject and `[tracker-id]` are identical across all repos.
|
|
21
|
+
3. Fold this repo's checkpoint commits first: `bash $HOME/.claude/scripts/checkpoint-fold.sh --repo "$WT_PATH" --task "{tracker-id}" --base "$BASE_BRANCH"`. Then `git add` (specific files only - same rules as the single-repo staging step, item 4 of the Standard path in `phases/phase-4-commit.md` Step 2)
|
|
22
|
+
4. `git -C "$WT_PATH" commit -m "$MESSAGE"` (heredoc body) - using identity already pinned in Phase 0 Step 8.
|
|
23
|
+
5. Capture `state.projects[i].commit = {"sha": "<sha>"}`.
|
|
24
|
+
|
|
25
|
+
Push each repo through the Push-must-succeed policy in `phases/phase-4-commit.md`, then continue here.
|
|
26
|
+
|
|
27
|
+
## Per-repo PR with cross-links
|
|
28
|
+
|
|
29
|
+
After all repos are pushed, open PRs sequentially, one per `state.projects[]` entry, each through its remote's usual path (gh / Bitbucket REST) with the per-stack body template (Standard / UI Component / etc). Append to each body:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
## Sibling PRs (multi-repo task)
|
|
33
|
+
This PR is part of a multi-repo change. Sibling PRs (review together):
|
|
34
|
+
- <url of each PR opened before this one>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
After the last PR opens, `update_sibling_links`: go back to the first N-1 PRs and add the sibling URLs that were not yet known when they were created.
|
|
38
|
+
|
|
39
|
+
**Then finalize each repo's worktree**, serially and only now - `update_sibling_links` updates one PR per repo and the loop `cd`s per repo, so removing repo 1's worktree mid-loop breaks 2..N. Run `worktree-finalize.sh` once per repo with that repo's `--worktree` / `--project-root` / `--project`; each skips or removes independently.
|
|
40
|
+
|
|
41
|
+
`update_sibling_links` does an UPDATE call per PR (Bitbucket: the `channels/pr.md` PUT payload, current `version`; GitHub: `gh pr edit --body-file`). Idempotent.
|
|
42
|
+
|
|
43
|
+
## GitHub issue body - list all PRs
|
|
44
|
+
|
|
45
|
+
Step 10's "Issue body update" extends to multi-repo: instead of a single `### Pull Requests` line, write one row per repo:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
### Pull Requests
|
|
49
|
+
- **common:** {pr-1-url}
|
|
50
|
+
- **uicomponents:** {pr-2-url}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Match the existing template's table/list shape - do not introduce new markers (per existing single-repo rule).
|
|
54
|
+
|
|
55
|
+
## `recentGroups` update on success
|
|
56
|
+
|
|
57
|
+
After ALL repos in the task have `pushStatus ∈ {"pushed", "rebase-pushed"}`:
|
|
58
|
+
|
|
59
|
+
1. Find the matching `recentGroups[]` entry by **order-independent compare** of `repos` array (sort + JSON.stringify).
|
|
60
|
+
2. If found: `entry.count += 1`, `entry.lastUsed = ISO timestamp`, bump to front of array (LRU).
|
|
61
|
+
3. If not found: prepend a new entry `{ label: <auto-generated>, repos: [...], count: 1, lastUsed: ... }`. Cap the array at 10 (drop oldest).
|
|
62
|
+
|
|
63
|
+
A task ending with one or more `pushStatus === "skipped"` repos does NOT bump `recentGroups` count - only fully-successful multi-repo tasks earn LRU bumps.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Phase 2 Dev - Multi-Repo Mode
|
|
2
|
+
|
|
3
|
+
> Loaded on demand from `phases/phase-2-dev.md`. Conditional on
|
|
4
|
+
> `state.projects[].length > 1` (set by Phase 0 multi-select); a single-repo run
|
|
5
|
+
> never needs it. Token forwarding and the build-log offload stay in the phase
|
|
6
|
+
> doc because every run uses them.
|
|
7
|
+
|
|
8
|
+
Active when `state.projects[].length > 1`. The single-repo flow in the phase doc is preserved verbatim - this file adds the deltas.
|
|
9
|
+
|
|
10
|
+
**Todo tagging**: Phase 1 plan items in multi-repo mode carry a `repo` field naming the target project root. The dev agent uses this tag to dispatch each todo:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"id": "T-3",
|
|
15
|
+
"title": "Add tokenResolver public API",
|
|
16
|
+
"repo": "common", // ← matches state.projects[i].name
|
|
17
|
+
"files": ["Sources/Common/TokenResolver.swift"],
|
|
18
|
+
"tdd": { "test": "...", "code": "..." }
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If a todo has no `repo` tag in multi-repo mode → log warning + ask user, do not auto-pick.
|
|
23
|
+
|
|
24
|
+
**Per-todo worktree switch**: Before each todo's TDD cycle, resolve `WT_PATH = state.projects[ findIndex(name === todo.repo) ].worktreePath` and run **all** subsequent commands with `git -C "$WT_PATH"` and `cd "$WT_PATH"` for build/test. Identity (`user.name`/`user.email`) was already pinned per worktree by Phase 0 Step 8 - no re-config needed here.
|
|
25
|
+
|
|
26
|
+
**Status update (single ticket, multi-repo)**: The Jira/GitHub issue is shared across all repos in the group - call the status-update API exactly **once per todo** (not once per repo per todo). The post-mutation verify rule still applies.
|
|
27
|
+
|
|
28
|
+
**Build serialization**:
|
|
29
|
+
- Xcode worktrees still share `BUILD_LOCK = /tmp/claude-xcodebuild.lock` - multi-repo just means more callers contending for the same lock; the existing `mkdir`-based queue handles it correctly.
|
|
30
|
+
- Non-Xcode repos may build in parallel across worktrees - but ONLY when builds are independent. If repo B's build depends on repo A's freshly-published artifact (e.g. SPM local path dependency), serialize them in dependency order. Plan items declare dependencies via Phase 1's `dependsOn` field; multi-repo dispatch respects that order.
|
|
31
|
+
|
|
32
|
+
**Failure isolation**: A build/test failure in one repo's worktree must NOT silently leave the other repos in a half-built state. On failure:
|
|
33
|
+
1. Capture the failure into `state.projects[i].buildStatus = { ok: false, attempts: N, lastError: "..." }`
|
|
34
|
+
2. The ENTIRE Phase 2 retries within that repo's worktree (max 3, same as single-repo)
|
|
35
|
+
3. After 3 attempts, escalate; do NOT proceed to Phase 3 with any unbuilt repo
|
|
36
|
+
|
|
37
|
+
**Recording a pass (default-FAIL evidence gate):** before setting `buildStatus.ok = true`, the build output must be tee'd to a log and that log must substantiate the success - a zero exit code alone is not trusted. Run the evidence gate; on exit 1, do NOT record a pass:
|
|
38
|
+
```bash
|
|
39
|
+
<build-command> 2>&1 | tee "{worktreePath}/.build.log" \
|
|
40
|
+
| bash $HOME/.claude/scripts/offload-ref.sh --phase 2 --label build --root "$WORKTREE"
|
|
41
|
+
node $HOME/.claude/scripts/evidence-gate.mjs --claim build --status passed --evidence "$WORKTREE/.build.log"
|
|
42
|
+
```
|
|
43
|
+
Non-zero from the gate: the build pass is unverified, so treat it as a failure and keep `buildStatus.ok=false`.
|
|
44
|
+
This closes the gap where an agent records "built" without ever producing build output.
|
|
45
|
+
The offload pipe is explained in the phase doc ("Why the pipe").
|
|
46
|
+
|
|
47
|
+
**Telemetry**: Per-repo metrics in addition to per-task metrics:
|
|
48
|
+
```bash
|
|
49
|
+
$HOME/.claude/scripts/log-metric.sh "$TASK_ID" 2 build.completed repo=common duration_ms=$D status=ok
|
|
50
|
+
$HOME/.claude/scripts/log-metric.sh "$TASK_ID" 2 build.completed repo=uicomponents duration_ms=$D status=ok
|
|
51
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Phase 3 User Test - Test Gap Report detail
|
|
2
|
+
|
|
3
|
+
> Loaded on demand from `phases/phase-3-review.md` (User test, Step 0) when the
|
|
4
|
+
> gap scan produced a report. The phase doc keeps the call and the skip rules;
|
|
5
|
+
> this file carries the report shape, severities, gating and telemetry.
|
|
6
|
+
|
|
7
|
+
## What the report contains
|
|
8
|
+
|
|
9
|
+
Per `$HOME/.claude/schemas/test-gap.schema.json`:
|
|
10
|
+
|
|
11
|
+
| Field | Meaning |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `gaps[].sourcePath` | source file with the unprotected symbol |
|
|
14
|
+
| `gaps[].symbol` | symbol name |
|
|
15
|
+
| `gaps[].kind` | rule id (e.g. `public_func`, `composable_fun`, `named_export`) |
|
|
16
|
+
| `gaps[].severity` | `blocking` / `important` / `suggestion` (see severity table below) |
|
|
17
|
+
| `gaps[].expectedTestPaths` | likely test paths the user should land at, in priority order |
|
|
18
|
+
| `gaps[].hint` | stack-specific testing reminder (e.g. swiftui-qa.md 3-layer) |
|
|
19
|
+
|
|
20
|
+
## Severity defaults
|
|
21
|
+
|
|
22
|
+
| Symbol kind | Severity |
|
|
23
|
+
|---|---|
|
|
24
|
+
| `composable_fun`, `view_struct`, `config_struct`, `interface`, `objc_export`, `public_proto` | important |
|
|
25
|
+
| Other public API additions (`public_func`, `open_fun`, `named_export`, `default_export`, ...) | suggestion |
|
|
26
|
+
|
|
27
|
+
## Gating (opt-in)
|
|
28
|
+
|
|
29
|
+
If `prefs.testGap.blockingThreshold` is set and `gapBySeverity.important + gapBySeverity.blocking` exceeds it, Phase 3 surfaces the report as a Phase 3 rework finding and loops back. **Default off** - gaps render as advisory under "Test Gap Report" only.
|
|
30
|
+
|
|
31
|
+
## Telemetry
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
LOG_METRIC_FORWARD_TO_TRACKER=0 $HOME/.claude/scripts/log-metric.sh "$TASK_ID" 3 test_gap.scanned \
|
|
35
|
+
stack=$SCAN_STACK \
|
|
36
|
+
sources=$(jq '.totals.sourcesScanned' <<< "$GAP_JSON") \
|
|
37
|
+
gaps=$(jq '.totals.gapCount' <<< "$GAP_JSON")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
(No tracker forwarding - the scanner has no token cost.)
|
|
@@ -10,7 +10,7 @@ Removing it at PR-open is only safe because of the salvage, so the two are one s
|
|
|
10
10
|
|
|
11
11
|
## What it will not do
|
|
12
12
|
|
|
13
|
-
**No `git checkout` of the task branch.** `git worktree remove` leaves the branch as an ordinary local branch: the ref, its commits, and the ability to `git checkout <branch>` later all survive untouched. Checking it out here would move the user's HEAD out from under them and can collide with their own uncommitted work on another branch. Phase
|
|
13
|
+
**No `git checkout` of the task branch.** `git worktree remove` leaves the branch as an ordinary local branch: the ref, its commits, and the ability to `git checkout <branch>` later all survive untouched. Checking it out here would move the user's HEAD out from under them and can collide with their own uncommitted work on another branch. Phase 3's user test removes-then-checks-out on purpose, because it is handing the branch over for manual testing; this step is not.
|
|
14
14
|
|
|
15
15
|
**No `git branch -D`.** The branch is the deliverable.
|
|
16
16
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# garbage-collect: what each phase covers
|
|
2
|
+
|
|
3
|
+
Read by `/multi-agent:garbage-collect` when a phase's output needs explaining,
|
|
4
|
+
or before answering what a sweep would or would not touch.
|
|
5
|
+
|
|
6
|
+
## /tmp scratch (phase 1)
|
|
7
|
+
|
|
8
|
+
Each run writes ephemeral scratch under `/tmp`: picker state
|
|
9
|
+
(`multi-agent-picker-*`), PR/review diffs (`multi-agent-review-*`), issue
|
|
10
|
+
progress bodies (`issue-progress-*`), channel payloads (`channels-*`),
|
|
11
|
+
external-context bundles (`context-links-*` / `context-by-type-*`), and analysis
|
|
12
|
+
drafts (`analysis-*`). Most are never cleaned up, so a long-lived machine
|
|
13
|
+
accumulates them. `gc-tmp.sh` sweeps the known prefixes only.
|
|
14
|
+
|
|
15
|
+
## Worktree residue (phase 2)
|
|
16
|
+
|
|
17
|
+
`gc-worktrees.sh` covers: stale worktree admin entries (`git worktree prune`,
|
|
18
|
+
applied immediately - it only drops bookkeeping for dirs that are already gone),
|
|
19
|
+
orphan `.worktrees/*` dirs no longer registered as worktrees, gitlink residue in
|
|
20
|
+
the index (`.worktrees/{id}` recorded as a "Subproject commit" entry by a
|
|
21
|
+
pre-guard `git add -A`), and a missing `.worktrees/` line in
|
|
22
|
+
`.git/info/exclude`.
|
|
23
|
+
|
|
24
|
+
## Offloaded payloads (phase 3)
|
|
25
|
+
|
|
26
|
+
`offload-ref.sh` parks build logs, diffs and test output under
|
|
27
|
+
`.multi-agent/refs/<node_id>.md`. In worktree modes that directory dies with the
|
|
28
|
+
worktree; when the run chose a local workspace it lands in the real checkout,
|
|
29
|
+
and because it is gitignored it never shows up in `git status`. Only files
|
|
30
|
+
matching the node-id shape are touched - anything else in that directory is left
|
|
31
|
+
alone, and files inside the grace window are spared so a sweep cannot pull a ref
|
|
32
|
+
out from under a running phase.
|
|
33
|
+
|
|
34
|
+
## Abandoned runs (phase 4, `--abandoned`)
|
|
35
|
+
|
|
36
|
+
Nothing else collects these. `gc-worktrees.sh` skips registered worktrees on
|
|
37
|
+
purpose, because a registered worktree belongs to a live run - and a run that
|
|
38
|
+
stopped never stops being "live".
|
|
39
|
+
|
|
40
|
+
The output has four kinds of line and they are not interchangeable:
|
|
41
|
+
|
|
42
|
+
| Line | Meaning |
|
|
43
|
+
|---|---|
|
|
44
|
+
| `would remove` / `would remove worktree` | reapable: stopped past its age limit, or finished with its worktree left behind |
|
|
45
|
+
| `would stash` | uncommitted work found - it goes into a stash entry labelled `autopilot/abandoned/<task-id>` (`git stash list`) and the worktree is **kept** |
|
|
46
|
+
| `would mark abandoned` | the state is stale but there is no worktree left to remove |
|
|
47
|
+
| `unattributed` | a worktree with no run state. **Never removed, whatever the flags.** `.worktrees/` is not exclusively ours, and nothing distinguishes a hand-made worktree from a pipeline one whose log was pruned. Report the list and its size; the user decides |
|
|
48
|
+
|
|
49
|
+
A path outside `<repo>/.worktrees/` is never removed because a state file can
|
|
50
|
+
record the repo root as its `worktreePath`.
|
|
51
|
+
|
|
52
|
+
## Scope of each phase
|
|
53
|
+
|
|
54
|
+
The /tmp phase only touches `/tmp` scratch; the worktree phase only touches the
|
|
55
|
+
current repo's `.worktrees/` residue and index; the payload phase only touches
|
|
56
|
+
node-id files under `.multi-agent/refs/`. Persistent per-task logs live under
|
|
57
|
+
`~/.claude/logs/multi-agent/` and are cleaned by `/multi-agent:prune-logs`. The
|
|
58
|
+
per-repo memory stores under `~/.claude/memory/multi-agent/` are durable
|
|
59
|
+
knowledge, not scratch: they are removed only by `/multi-agent:uninstall
|
|
60
|
+
--all-data`, or one entry at a time with `learnings-ledger.mjs forget`.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# ios-coding-standard: plan contents
|
|
2
|
+
|
|
3
|
+
Read by `/multi-agent:ios-coding-standard` before writing the Phase 4 plan. The
|
|
4
|
+
plan contains, in order:
|
|
5
|
+
|
|
6
|
+
1. **Coverage ledger** - total targets · audited · skipped with reasons. Not 100% accounted for
|
|
7
|
+
means the plan is not deliverable.
|
|
8
|
+
2. **Summary** - counts by severity and source, resolved vocabulary, branch to create.
|
|
9
|
+
3. **Sensitive-data inventory** (Phase 2d) - first, because it is the highest-risk content.
|
|
10
|
+
4. **Screen × role matrix** `[STRUCT-02]` - screens as rows, manifest roles as columns, cells
|
|
11
|
+
`✓ / missing / misplaced`. The structural map a newcomer reads first.
|
|
12
|
+
5. **Type placement table** `[STRUCT-05]` - type · location · consumer count · correct tier ·
|
|
13
|
+
move required. Paired with the nested-type list `[STRUCT-01]`: owner · nested type · kind ·
|
|
14
|
+
reference count · verdict.
|
|
15
|
+
6. **Visibility report** `[VIS-01, VIS-02]` - over-exposed declarations per file, non-final
|
|
16
|
+
classes with no subclass.
|
|
17
|
+
7. **Boundary report** `[MOD-*]` - import graph (allowed vs forbidden, with coupling depth) ·
|
|
18
|
+
manifest graph (declared vs legal for the role, plus dead edges) · **removability delta**
|
|
19
|
+
("removing X touches N files: ...") · inbound test (tests compile with no sibling present).
|
|
20
|
+
8. **Testability seam report** `[TEST-*]` - types reaching for the environment, logic requiring a
|
|
21
|
+
view to execute, doubles whose signatures have drifted.
|
|
22
|
+
9. **Change-cost probe** `[FLEX-*]` - pick two plausible upcoming changes (a new variant of an
|
|
23
|
+
existing screen; a new field on a shared entity) and state what each costs in files today.
|
|
24
|
+
10. **Findings table** - rule ID · `file:line` · current state · proposed fix · severity · source ·
|
|
25
|
+
onboarding impact.
|
|
26
|
+
11. **Per-file work** - grouped per file, blocking → important → suggestion; within a severity,
|
|
27
|
+
highest onboarding impact first.
|
|
28
|
+
12. **Behaviour-preservation guard** - splitting files, adding MARKs, extracting extensions and
|
|
29
|
+
moving types must not change behaviour. Anything requiring a behaviour change (a missing
|
|
30
|
+
analytics event, a wrong result type, a timezone fix, a storage migration) goes in a
|
|
31
|
+
**separate group**, reviewed and tested on its own, never inside a mechanical split commit.
|
|
32
|
+
13. **Tooling delegation & the ratchet** - the section that decides whether any of this survives.
|
|
33
|
+
- Classify each applied rule by its registry `enforcement`. For every `lint` / `format` /
|
|
34
|
+
`scan` rule, state the concrete mechanism and whether that toolchain exists in the repo
|
|
35
|
+
(`LintToolchain`). **When it does not exist, saying so is a finding**, ranked above most
|
|
36
|
+
individual violations it would have caught.
|
|
37
|
+
- Recommend **baseline-and-ratchet, never big-bang**: grandfather existing violations, surface
|
|
38
|
+
only new ones, drain the backlog behind a green build. Order the plan the same way - stop
|
|
39
|
+
the bleeding, then clean up.
|
|
40
|
+
- Custom lint rule identifiers **are** the registry IDs (`sec_01_no_plaintext_persistence`,
|
|
41
|
+
`mod_01_no_sibling_import`) so a violation points straight at the rule entry.
|
|
42
|
+
- **Linting is local-only by decision** - the skill's `references/lint-local.sh` with `references/swiftlint.draft.yml`, config
|
|
43
|
+
and baseline kept outside the repository; no committed config, no build phase, no CI job.
|
|
44
|
+
State this honestly in the plan rather than describing a gate that does not exist: a
|
|
45
|
+
pre-PR habit catches less than a wall, so the residual risk is real and belongs in the
|
|
46
|
+
report. Adopting it project-wide remains an open decision - record it as one so it stays
|
|
47
|
+
visible instead of quietly lapsing.
|
|
48
|
+
- Never imply the audit substitutes for the linter, or the linter for a gate. The audit finds
|
|
49
|
+
the debt once; the linter keeps a developer honest; only a gate stops it returning.
|
|
50
|
+
14. **Numeric exit criteria** - target and today's measured value side by side: lint violations
|
|
51
|
+
per 1k lines (<1) · public-surface ratio, public declarations ÷ externally consumed symbols
|
|
52
|
+
(≈1) · forbidden cross-module imports (0) · removability delta · files over threshold and
|
|
53
|
+
files >120 lines with no sectioning (0) · screens missing a manifest role (0) · escape-hatch
|
|
54
|
+
count `[CONC-03]` (flat or falling) · exception-marker count (flat or falling) · dead code (0)
|
|
55
|
+
· screens with logic and no mirrored tests (0) · unclassified sensitive symbols (0).
|
|
56
|
+
15. **Exception ledger** - every `// standard:exception(<ID>)` in the module: rule · reason ·
|
|
57
|
+
expiry · expired yes/no.
|
|
58
|
+
16. **Open Questions** - Phase 2b dimensions with no majority, and unclassifiable symbols.
|
|
59
|
+
17. **Suggested commit slicing** - one commit per file-group / concern.
|
|
60
|
+
18. **Scope guard** - only this module is touched; definition of done is the module's own
|
|
61
|
+
verification path.
|
|
62
|
+
|
|
63
|
+
## Onboarding summary
|
|
64
|
+
|
|
65
|
+
Then write a **separate one-page onboarding summary** beside the plan, aimed at a developer
|
|
66
|
+
joining next week rather than at whoever does the remediation: the ten always/never lines
|
|
67
|
+
specialised to this module, the screen file manifest, the placement ladder, the sensitive-data
|
|
68
|
+
classes in play, and the verification command. Nobody learns a codebase from a 40-finding audit -
|
|
69
|
+
this page is the actual deliverable, and the audit is how you earn the right to write it
|
|
70
|
+
accurately. Derive it from `references/STANDARD.md section 0`, do not re-invent it.
|
|
71
|
+
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# ios-coding-standard: resolve and scan detail
|
|
2
|
+
|
|
3
|
+
<!-- toc -->
|
|
4
|
+
- [Phase 2](#phase-2)
|
|
5
|
+
- [Phase 3](#phase-3)
|
|
6
|
+
- [Verification reality](#verification-reality)
|
|
7
|
+
<!-- /toc -->
|
|
8
|
+
|
|
9
|
+
Read by `/multi-agent:ios-coding-standard` at the start of Phase 2 and again
|
|
10
|
+
before Phase 3. The rules themselves live in the `ai-ios-toolkit:ios-coding-standard`
|
|
11
|
+
skill (`references/rules.yml`); this file is procedure only.
|
|
12
|
+
|
|
13
|
+
## Phase 2
|
|
14
|
+
|
|
15
|
+
Module roles from Phase 1 decide which dependency edges are legal: **feature** ·
|
|
16
|
+
**core/common** · **seam** (cross-module contracts/bridges/navigation) ·
|
|
17
|
+
**composition root** (legitimately knows every module).
|
|
18
|
+
|
|
19
|
+
### 2a. The registry is the standard - in-module prose docs are NOT consulted
|
|
20
|
+
|
|
21
|
+
The skill's `references/rules.yml` (+ a project `modules/<Module>.yml` overlay) is the single
|
|
22
|
+
source of truth. Module prose docs are being retired so there is one place a rule can live;
|
|
23
|
+
consulting them re-creates the split this command exists to remove. If such a file exists and
|
|
24
|
+
contradicts the registry, that is a finding against the file, not against the code.
|
|
25
|
+
|
|
26
|
+
The only in-repo inputs are **code and manifests**: sources, tests, `Package.swift`, `Info.plist`,
|
|
27
|
+
the specs the generator reads, and the module registry from Phase 1.
|
|
28
|
+
|
|
29
|
+
### 2b. Per-module overlay, then inference
|
|
30
|
+
|
|
31
|
+
1. **`modules/<Module>.yml`** beside the project's own config carries what code cannot state: the vocabulary
|
|
32
|
+
bindings, the module's role, prohibitions that currently have **zero** instances, deliberate
|
|
33
|
+
carve-outs, name locks, and the real verification command. Registry-backed, so its findings may
|
|
34
|
+
be `blocking`.
|
|
35
|
+
*Why prohibitions need to be written down:* inference reads dominant patterns, and a rule
|
|
36
|
+
obeyed everywhere has no counter-example to infer from. A ban at 100% compliance is invisible
|
|
37
|
+
to a scan - it survives only if the overlay states it.
|
|
38
|
+
2. **Repo-level rules** (root `CLAUDE.md`, contributing docs) apply to every module.
|
|
39
|
+
3. **The module's own dominant pattern is its de-facto convention.** Count variants per dimension;
|
|
40
|
+
the minority instances are the finding. Internal consistency beats conformity to a sibling.
|
|
41
|
+
4. No majority (even split, single instance) → not a finding. Record an Open Question.
|
|
42
|
+
|
|
43
|
+
Findings from step 3 are tagged `inferred` and capped at **suggestion**. Only registry- or
|
|
44
|
+
overlay-backed rules may be `blocking`.
|
|
45
|
+
|
|
46
|
+
**When the overlay is missing**, generate a draft from code evidence, print it for confirmation,
|
|
47
|
+
and mark every slot it could not derive - a frozen UI target, a name lock, a carve-out and an
|
|
48
|
+
operational constraint all look like ordinary code from the outside. Do not guess them; list them
|
|
49
|
+
as Open Questions.
|
|
50
|
+
|
|
51
|
+
### 2c. Vocabulary
|
|
52
|
+
|
|
53
|
+
Bind each slot to a real symbol by grepping the module, then the reference module. **An unbound
|
|
54
|
+
slot disables its rules** - never invent a name, never import a sibling's.
|
|
55
|
+
|
|
56
|
+
`HandlerName` · `EventParam` · `CoordinatorType` · `ResultType` / `ErrorType` / `ErrorFactory` ·
|
|
57
|
+
`DIResolver` / `DIConfigurator` · `RequestModelSuffix` / `ResponseModelSuffix` / `TransportSuffix` ·
|
|
58
|
+
`MapperShape` · `SafeEnumProtocol` / `UnknownCase` · `CopySurface` · `AnalyticsSurface` ·
|
|
59
|
+
`A11yIdentifierSource` · `GeneratedServiceRoot` · `SharedComponentsDir` / `SharedEntitiesDir` ·
|
|
60
|
+
`MicroComponentLibrary` · `FrozenUITarget` · `DesignTokenNamespaces` · `CalendarDayHelper` ·
|
|
61
|
+
`LoggerAPI` · `FileHeaderShape` · `ScreenRoot` · `ScreenRoleSuffixes` · `AsyncStyle` ·
|
|
62
|
+
`CompositionRoot` · `SeamLayer` · `ModuleEntrySurface` · `ConcurrencyPosture` · `LintToolchain` ·
|
|
63
|
+
`CredentialStore` (the module's Keychain wrapper, if any).
|
|
64
|
+
|
|
65
|
+
Print the resolved table before scanning so a wrong binding is caught early.
|
|
66
|
+
|
|
67
|
+
### 2d. Sensitive-data inventory - required before any SEC rule runs
|
|
68
|
+
|
|
69
|
+
The `SEC-*` rules are written against the **data classes** in `references/rules.yml →
|
|
70
|
+
sensitive_data_classes`, never against one module's field names. Resolve the module's concrete
|
|
71
|
+
instances of each class: grep entities, request/response models, storage calls and analytics
|
|
72
|
+
events for the values the module actually handles, and map each to its class.
|
|
73
|
+
|
|
74
|
+
Produce the inventory as a table - **class · concrete symbols · where it enters · required
|
|
75
|
+
lifetime (transient / survives-restart / survives-reinstall) · where it is actually stored ·
|
|
76
|
+
where it is logged · where it leaves (network, analytics, pasteboard, another module)**.
|
|
77
|
+
|
|
78
|
+
The **lifetime column is the one that decides SEC-01**, and it is filled by walking
|
|
79
|
+
`references/rules.yml → persistence_decision`, not by looking at what the code currently does. Compare it
|
|
80
|
+
against the storage column and report both mismatches:
|
|
81
|
+
- required transient but persisted anywhere (including the Keychain) → **over-persistence**;
|
|
82
|
+
- required to survive a restart but stored outside the Keychain → **under-protection**.
|
|
83
|
+
|
|
84
|
+
Then generate the SEC lint patterns *from this inventory*, so the checks match this module's real
|
|
85
|
+
vocabulary. A class with no instance here yields no finding; a symbol you cannot classify, or one
|
|
86
|
+
whose required lifetime nobody can state, is an Open Question, not a silent pass.
|
|
87
|
+
|
|
88
|
+
This table is a deliverable in its own right, independent of whether any violation is found.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## Phase 3
|
|
92
|
+
|
|
93
|
+
### Coverage gate - on disk, not in memory
|
|
94
|
+
|
|
95
|
+
Before scanning, write `.<module>-audit-coverage.tsv` to the scratch dir: one row per target
|
|
96
|
+
(every screen under `ScreenRoot`, every shared component, every entity, every file in every
|
|
97
|
+
target) with columns `path · status · rules-applied`. Mark rows as you go.
|
|
98
|
+
|
|
99
|
+
- Each target is **audited** or **explicitly skipped with a reason** (generated, fixture,
|
|
100
|
+
vendored). No third state.
|
|
101
|
+
- **The run is incomplete while any row is unmarked** - and the file, not a claim, is the proof.
|
|
102
|
+
Chunk the module if it is too large for one pass; the checklist survives a context reset.
|
|
103
|
+
- No sampling. A partial audit reported as complete certifies the unscanned screens as clean.
|
|
104
|
+
|
|
105
|
+
### Grep hygiene
|
|
106
|
+
|
|
107
|
+
Registry `mechanism` patterns are line-based and match doc comments. Filter
|
|
108
|
+
`^[[:space:]]*//` - BSD grep does not understand `\s`, so a `\s*//` filter silently lets `/// ...`
|
|
109
|
+
through - then open each surviving hit and confirm it is real code. Report pre-filter and
|
|
110
|
+
post-verification counts separately; a table padded with comment matches destroys trust.
|
|
111
|
+
|
|
112
|
+
### Judgement rules need evidence, not assertion
|
|
113
|
+
|
|
114
|
+
For any rule marked `enforcement: judgement`, a finding must carry the measurement its `check`
|
|
115
|
+
names - a reference count, a call-site count, a consumer count, a file list. **No count, no
|
|
116
|
+
finding.** This is what keeps a subjective rule from becoming an opinion.
|
|
117
|
+
|
|
118
|
+
Every judgement rule has a worked ✗/✓ pair in `EXAMPLES.md`, keyed by ID. Cite it in the finding's
|
|
119
|
+
proposed fix rather than re-describing the shape - the developer applying the fix should be
|
|
120
|
+
reading the same picture the audit used.
|
|
121
|
+
|
|
122
|
+
### Module-specific overrides
|
|
123
|
+
|
|
124
|
+
The module's own docs win over the registry, including where they contradict a sibling module.
|
|
125
|
+
Never apply one module's dialect to another. List every override honoured, so the reader sees why
|
|
126
|
+
a registry rule was not raised.
|
|
127
|
+
|
|
128
|
+
## Verification reality
|
|
129
|
+
|
|
130
|
+
Verification reality is per-module - establish it, do not assume it. Some
|
|
131
|
+
targets cannot be compiled from the CLI (asset symbol generation, UIKit-dependent
|
|
132
|
+
packages, a dependency failing earlier in the graph); there, verification is
|
|
133
|
+
Xcode and a manifest dump validates the manifest only. Never trust a piped
|
|
134
|
+
build's exit code - a pipe reports the tail's status. Record the module's actual
|
|
135
|
+
verification command in the plan.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# jira picker: list format and maturity detail
|
|
2
|
+
|
|
3
|
+
Read by `/multi-agent:jira` when rendering the issue list (step 3/4), when the
|
|
4
|
+
maturity check (step 3.5/4) returns a description or blocker case, and when
|
|
5
|
+
writing the picker state file.
|
|
6
|
+
|
|
7
|
+
## Issue list format
|
|
8
|
+
|
|
9
|
+
Priority badge prefix, status suffix:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
[3/4] Pick issue (24 found, priority-sorted):
|
|
13
|
+
> [Blocker] PROJ-12345 - Login crash on iOS 17 (In Progress)
|
|
14
|
+
[Critical] PROJ-12340 - Payment fails for refunds (In Review)
|
|
15
|
+
[High] PROJ-12338 - Dark mode polish (To Do)
|
|
16
|
+
[Medium] PROJ-12330 - Add empty state (To Do)
|
|
17
|
+
[ - ] PROJ-12300 - Refactor LoginViewModel (To Do)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Maturity shape
|
|
21
|
+
|
|
22
|
+
`~/.claude/lib/issue-fetcher.sh` returns:
|
|
23
|
+
|
|
24
|
+
```jsonc
|
|
25
|
+
"maturity": {
|
|
26
|
+
"score": 0..100,
|
|
27
|
+
"blockers": ["status_closed", "already_resolved", "description_empty"],
|
|
28
|
+
"warnings": ["short_description", "no_repro_steps", "no_acceptance_criteria", "description_empty_parent_available"],
|
|
29
|
+
"summary": "..."
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Empty description and the parent candidate
|
|
34
|
+
|
|
35
|
+
Development sub-tasks are often filed with no description of their own, with
|
|
36
|
+
the real requirements on the parent issue. Before scoring, `issue-fetcher.sh`
|
|
37
|
+
fetches the issue's `parent` (single hop, no chasing the parent's parent). If
|
|
38
|
+
the issue's own description is empty and the parent's is not, it does **not**
|
|
39
|
+
auto-substitute - it exposes `descriptor.parentKey` +
|
|
40
|
+
`descriptor.parentDescription` as a candidate and adds
|
|
41
|
+
`description_empty_parent_available` to `warnings` (not `blockers`) instead of
|
|
42
|
+
the plain `description_empty` blocker. If the parent is also empty or
|
|
43
|
+
unreachable, `description_empty` still blocks.
|
|
44
|
+
|
|
45
|
+
## Picker state file
|
|
46
|
+
|
|
47
|
+
`/tmp/multi-agent-picker-{taskId}.json`, read by `multi-repo-pipeline.sh bridge`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"taskId":"PROJ-12345-{timestamp}",
|
|
52
|
+
"shortId":<int>,
|
|
53
|
+
"branch":"<feature|bugfix>/PROJ-12345",
|
|
54
|
+
"baseBranch":"develop",
|
|
55
|
+
"issueRef":{...},
|
|
56
|
+
"primary":{"name":"...","cloneUrl":"...","provider":"github|bitbucket"},
|
|
57
|
+
"extras":[{...}],
|
|
58
|
+
"worktreeRoot":"~/.worktrees/PROJ-12345-{timestamp}",
|
|
59
|
+
"commitType":"<feat|fix>",
|
|
60
|
+
"identity":{"name":"...","email":"..."}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Blocker follow-up detail
|
|
65
|
+
|
|
66
|
+
An edit is a reason to re-check, never proof the gap closed - the check re-runs
|
|
67
|
+
on the new content, and only a DIFFERENT gap set ever earns a second comment.
|
|
68
|
+
Read the item's existing comments FIRST and derive the prior ask from the newest
|
|
69
|
+
one of ours (`priorFromComments`): a scan is a new run with a fresh state file,
|
|
70
|
+
so state alone would make every scan a first ask. Full contract:
|
|
71
|
+
`features/maturity-followup.md`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Copilot CLI orchestrator - project detection, routing and phase summaries
|
|
2
|
+
|
|
3
|
+
Detail behind the Copilot CLI orchestrator skill (`skills/shared/core/multi-agent/SKILL.md`). The skill keeps the routing skeleton, the hard rules and the gates; this file carries the project table, the full routing rows and the per-phase routing summaries. Each phase's specification is `$HOME/.claude/multi-agent-refs/phases/phase-N-<name>.md`; where a summary here and a phase ref disagree, the phase ref wins.
|
|
4
|
+
|
|
5
|
+
## Project detection
|
|
6
|
+
|
|
7
|
+
Detect the project from cwd FIRST, then validate the input format:
|
|
8
|
+
|
|
9
|
+
| cwd contains | Project | Accepted Input | Rejected Input |
|
|
10
|
+
|--------------|---------|----------------|----------------|
|
|
11
|
+
| `/my-ios-app` | my-app | `"PROJ-XXX" "branch"` | GitHub Issue URL |
|
|
12
|
+
| `/my-figma-app` | figma | `"https://github.com/.../issues/N"` | Jira ID + branch |
|
|
13
|
+
| Other | generic | Both formats | - |
|
|
14
|
+
|
|
15
|
+
If the user gives the wrong format for the project, warn:
|
|
16
|
+
|
|
17
|
+
- my-ios-app + GitHub URL: "This project expects a Jira ID + branch. Example: multi-agent \"PROJ-12345\" \"feature/PROJ-12345-desc\""
|
|
18
|
+
- my-figma-app + Jira: "This project expects a GitHub Issue URL. Example: multi-agent \"https://github.com/my-org/my-figma-app/issues/316\""
|
|
19
|
+
|
|
20
|
+
## Input types
|
|
21
|
+
|
|
22
|
+
Five types, matching the `commands/multi-agent/SKILL.md` dispatcher contract (cross-CLI parity is enforced by `smoke-cross-cli-behavior.sh`):
|
|
23
|
+
|
|
24
|
+
| # | Pattern | Type | Action |
|
|
25
|
+
|---|---------|------|--------|
|
|
26
|
+
| 1 | `#N` or bare `316` | github-issue-number | Fetch via gh after project selection |
|
|
27
|
+
| 2 | `https://github.com/.../issues/N` | github-issue-url | Extract org/repo/N, fetch via gh |
|
|
28
|
+
| 3 | `https://{JIRA_HOST}/browse/{JIRA_KEY}-XXXXX` | jira-url | Extract ID, fetch via Jira API |
|
|
29
|
+
| 4 | `{JIRA_KEY}-XXXXX` (bare) | jira-id | Fetch via Jira API |
|
|
30
|
+
| 5 | Anything else | free-text | No external fetch |
|
|
31
|
+
|
|
32
|
+
All types enter the same Phase 0 flow.
|
|
33
|
+
|
|
34
|
+
## Routing rows
|
|
35
|
+
|
|
36
|
+
| Input Pattern | Action |
|
|
37
|
+
|---------------|--------|
|
|
38
|
+
| `"PROJ-XXX" "branch"` | my-app only: Jira ID + branch name, auto-assigned incremental ID |
|
|
39
|
+
| `"https://github.com/..."` | figma only: parse the issue, extract Jira from title/body, auto-create the branch |
|
|
40
|
+
| `status` | Show all tasks with ID, phase, status |
|
|
41
|
+
| `log [id]` | Show agent-log.md for the task (latest if no id) |
|
|
42
|
+
| `resume [id]` | Resume a paused/failed task from the last successful phase |
|
|
43
|
+
| `kill [id]` | Stop the task, delete worktree + branch + logs; asks to confirm first |
|
|
44
|
+
| `clear-logs` | Superseded: redirect only |
|
|
45
|
+
| `purge` | Delete ALL worktrees, branches, logs, state, counter: full reset |
|
|
46
|
+
| `review` | Skip phases 0-3, review the current diff only |
|
|
47
|
+
| `autopilot` flag | Add to any pipeline command: skip user confirmations except destructive ops |
|
|
48
|
+
| No args / `help` | Usage guide |
|
|
49
|
+
|
|
50
|
+
Every task gets an auto-incremented short ID (`#1`, `#2`), stored in `agent-state.json`.
|
|
51
|
+
|
|
52
|
+
## Autopilot matrix
|
|
53
|
+
|
|
54
|
+
`multi-agent "PROJ-12345" "feature/PROJ-12345-desc" autopilot` skips interactive confirmations and runs end-to-end.
|
|
55
|
+
|
|
56
|
+
| Phase | Normal | Autopilot |
|
|
57
|
+
|-------|--------|-----------|
|
|
58
|
+
| Phase 1 (Plan Approval Gate) | Clarification (max 2 rounds) + approval loop; the user replies `onayla` / `iptal` / free-text | Gate skip: log the plan, go straight to Phase 2 |
|
|
59
|
+
| Phase 3 (User test) | "Want to test it?" then wait | Skip, straight to Phase 4 |
|
|
60
|
+
| Phase 4 (Commit) | "Want to commit?" then wait | Automatic commit + push |
|
|
61
|
+
| Phase 4 (PR) | "Want to open a PR?" then wait | Automatically create the PR |
|
|
62
|
+
|
|
63
|
+
`"autopilot": true` is added to `agent-state.json` and survives a resume.
|
|
64
|
+
|
|
65
|
+
## Persona models
|
|
66
|
+
|
|
67
|
+
| Persona | `preferredModel` |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `explorer` | `sonnet` |
|
|
70
|
+
| `code-reviewer` | `fable` (Reviewer 1; Phase 3 sets Reviewer 2 `opus`, Reviewer 3 `sonnet`) |
|
|
71
|
+
| `security-auditor` | `opus` |
|
|
72
|
+
| `ios-architect` / `android-architect` / `backend-architect` | `fable` |
|
|
73
|
+
|
|
74
|
+
Each persona file carries its own `modelRationale`. Observability: emit a `phase.agent.dispatch` OTel span with `{persona, resolved_model, override_source}` when `MULTI_AGENT_OTEL_SPANS=1` (see `phase-tracker.sh`).
|
|
75
|
+
|
|
76
|
+
## Phase summaries
|
|
77
|
+
|
|
78
|
+
**Phase 1: Plan.** Two halves, one approval gate. 1a Analysis (`explorer`, Sonnet): parallel explore agents scan related files, patterns and impact areas, then log `Phase 1: Plan (analysis) - {N} files identified`. 1b Planning (Fable): task breakdown into todos with dependencies, `ios-architect` review for structural changes, an approach per todo, then the Plan Approval Gate (`phases/phase-1-plan.md` Step 5). 5a clarification runs only when the description is ambiguous (vague acceptance, UI task without Figma, API task without an endpoint contract, `ambiguityScore >= 2`, parent-story scope drift), max 2 rounds, then a "best-effort" banner. 5b approval loop: `onayla` / `iptal` / free-text edit; an edit makes Fable revise and re-render, no iteration cap. Persist `clarificationRounds`, `clarificationQuestions`, `clarificationAnswers`, `planIterations`, `planApprovedAt`, `planEditRequests` to `state.phases["1"]`.
|
|
79
|
+
|
|
80
|
+
**Phase 2: Dev (Sonnet).** Per todo in dependency order: mark `in_progress`, TDD (failing test, verify RED, minimal code, verify GREEN, refactor), build via a task agent, on failure fix and rebuild (max 3, `retryCount` in `agent-state.json`), mark `done`, log `Phase 2: {todo-id} - Test ok, Build ok`.
|
|
81
|
+
|
|
82
|
+
**Phase 3: Review (parallel + triage).** Step 0 diff risk scoring is advisory: `node $HOME/.claude/scripts/diff-risk-score.mjs --base "$BASE_BRANCH" --top 5`, injected as `${PRIORITY_FILES}`; off when `prefs.global.diffRiskAdvisory = false`. Reviewers by host: Claude Code runs `claude-fable-5-1` (security + architecture), `claude-opus-5-5` (edge cases), `claude-sonnet-5-5` (quality); Copilot CLI runs `gpt-5.4`, `claude-opus-4.7`, `claude-sonnet-4.6` (no Fable). Triage is one top-tier pass (`claude-fable-5-1` on Claude Code, `claude-opus-4.7` on Copilot CLI). Blocking findings go back to Phase 2 (max 3 iterations), important ones are fixed and re-reviewed, suggestions applied when reasonable.
|
|
83
|
+
|
|
84
|
+
**Phase 4: Commit & PR.** Per-project steps and the GitHub issue body update: `orchestrator/phase-4-5-projects.md`.
|
|
85
|
+
|
|
86
|
+
**Phase 5: Report.** Finalize `agent-log.md` with: timeline table (phase, agent, model, duration, status, detail), agent activity report, token estimate, per-phase time distribution, review iterations, files changed (`git diff --stat`), review consensus, and test scenarios in Turkish for Jira (precondition, steps, expected result). Then print a compact terminal summary: task id and status, total time, agent calls, files changed, commit and PR, the wiki page when one was pushed, and the path to the full report under `~/.claude/logs/multi-agent/{project}/{task-id}/agent-log.md`. Log `Phase 5: Report complete`. The wiki + Figma screenshot step runs only for a component implementation with a GitHub issue: `orchestrator/phase-4-5-projects.md`.
|
|
87
|
+
|
|
88
|
+
**Localization scope.** Phase labels are English on every host. Reviewer-count qualifiers such as `(parallel + triage)` stay English. Out of scope for localization (always English, per `prefs.schema.json`): reviewer and triage system prompts, commit messages, PR titles and bodies, Jira comments, wiki content and log payloads inside `agent-log.md`.
|