aiwg 2026.5.5 → 2026.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +4 -4
- package/agentic/code/addons/agent-loop/agents/ralph-verifier.md +6 -0
- package/agentic/code/addons/agent-loop/manifest.json +2 -1
- package/agentic/code/addons/agent-loop/skills/agent-loop/SKILL.md +18 -2
- package/agentic/code/addons/agent-loop/skills/agent-loop-ext/SKILL.md +16 -4
- package/agentic/code/addons/agent-loop/skills/infer-completion-criteria/SKILL.md +323 -0
- package/agentic/code/addons/agent-loop/skills/ralph/SKILL.md +21 -8
- package/agentic/code/addons/aiwg-utils/manifest.json +2 -1
- package/agentic/code/addons/aiwg-utils/rules/RULES-INDEX.md +6 -1
- package/agentic/code/addons/aiwg-utils/rules/auto-compact-continue.md +257 -0
- package/agentic/code/frameworks/sdlc-complete/skills/flow-release/SKILL.md +14 -0
- package/package.json +1 -1
- package/tools/release/cut-tag.sh +250 -0
package/CLAUDE.md
CHANGED
|
@@ -663,10 +663,10 @@ Before pushing a version tag:
|
|
|
663
663
|
npm run uat:serve-live
|
|
664
664
|
```
|
|
665
665
|
Tests skip cleanly when `AIWG_SANDBOX_ENDPOINT` is unset or unreachable, so this is a safe no-op gate. Run before any release that touches `src/serve/`, the executor contract, or the MC ↔ serve bridge.
|
|
666
|
-
5. **Commit
|
|
667
|
-
6. **
|
|
668
|
-
7. **
|
|
669
|
-
8. **
|
|
666
|
+
5. **Commit the release prep** — `git commit` the package.json/CHANGELOG/announcement bump. Do NOT use plain `git tag -a` or `git tag -s` (they sign with `user.signingkey`, which is typically the maintainer's *personal commit-signing key* — wrong key for tags; the supply-chain gate `tools/ci/verify-signed-tag.sh` will reject in CI).
|
|
667
|
+
6. **Cut the tag via the wrapper** — `tools/release/cut-tag.sh <X.Y.Z>`. Runs 10 pre-tag checks (CalVer shape, `package.json` + `marketplace.json` lockstep, CHANGELOG entry, announcement file present, release-signing key both present locally AND published in `.gitea/keys/maintainers.asc`) and signs with `-u <RELEASE_KEY_FINGERPRINT>` (default: `FE9272F0BC5781E1DE77FAAA719AB63879E84CE8`, the `AIWG Release Signing <release@aiwg.io>` key per the two-key model from commit `a13dabc5`). See the v2026.5.5 incident note in `docs/contributing/versioning.md` for what happens when this is skipped.
|
|
668
|
+
7. **Push tag to Gitea** — `git push origin main --tags`. Triggers `gitea-release.yml` + `npm-publish.yml` (both gated on signed-tag verify).
|
|
669
|
+
8. **Mirror to GitHub** — `git push github main --tags`. Triggers `github-mirror.yml` which creates the GitHub Release using `docs/releases/v<version>-announcement.md` as the body. **No manual `gh release create` needed for stable releases** — the workflow handles it. Pre-release tags (`-rc.*`, `-alpha.*`, `-beta.*`, `-nightly.*`) skip GitHub-Release creation by design.
|
|
670
670
|
|
|
671
671
|
### Version Format
|
|
672
672
|
|
|
@@ -14,6 +14,12 @@ allowed-tools: Bash, Read, Glob
|
|
|
14
14
|
|
|
15
15
|
You verify completion criteria for agent loops - determining if a task iteration succeeded by running verification commands and analyzing their output.
|
|
16
16
|
|
|
17
|
+
## Companion skill
|
|
18
|
+
|
|
19
|
+
When the loop is started without explicit `--completion`, the criterion you verify is produced by the `infer-completion-criteria` skill (`@$AIWG_ROOT/agentic/code/addons/agent-loop/skills/infer-completion-criteria/SKILL.md`). It derives a measurable criterion from project docs (CLAUDE.md / AGENTS.md / AIWG.md), package manifests, CI configuration, and `.aiwg/` artifacts.
|
|
20
|
+
|
|
21
|
+
You do not run that skill yourself — the loop orchestrator (`ralph-loop` agent or external launcher) calls it during initialization. Your job is to take whatever criterion is in the loop state and verify it. The skill writes its rationale into `.aiwg/ralph/<loop-id>/progress.md` (or `.aiwg/ralph-external/<run-id>/inferred-completion.yaml` for external loops); when reporting verification results, you may reference that rationale so the user sees the full evidence chain.
|
|
22
|
+
|
|
17
23
|
## Capabilities
|
|
18
24
|
|
|
19
25
|
### Verification Methods
|
|
@@ -74,7 +74,19 @@ Alternate expressions and non-obvious activations (primary phrases are matched a
|
|
|
74
74
|
|
|
75
75
|
### Completion Inference
|
|
76
76
|
|
|
77
|
-
When user doesn't specify explicit verification:
|
|
77
|
+
When the user doesn't specify explicit verification, delegate to the **`infer-completion-criteria`** skill (`@$AIWG_ROOT/agentic/code/addons/agent-loop/skills/infer-completion-criteria/SKILL.md`). That skill runs a deterministic 5-layer pipeline:
|
|
78
|
+
|
|
79
|
+
1. **Task verb** → criterion class (test-pass, type-clean, regression-gate, coverage, lint-clean, build-pass, implement-feature)
|
|
80
|
+
2. **Project context files** (CLAUDE.md / AGENTS.md / AIWG.md) → canonical commands from the Development section
|
|
81
|
+
3. **Package manifests** (`package.json`, `Cargo.toml`, `pyproject.toml`, `go.mod`, `pom.xml`, etc.) → discovered scripts
|
|
82
|
+
4. **CI configuration** (`.github/workflows/`, `.gitea/workflows/`, GitLab/CircleCI/Jenkins) → team's actual "passes" definition
|
|
83
|
+
5. **`.aiwg/` artifacts** (test-strategy, related use cases by ID match, prior progress files) → project-specific gates
|
|
84
|
+
|
|
85
|
+
Synthesis is validated against the `vague-discretion` rule and emits a structured YAML proposal with criterion, verification command, rationale chain, confidence level, and alternatives considered.
|
|
86
|
+
|
|
87
|
+
**Use the inline table below ONLY as a last-resort fallback** when the inference skill is unavailable (degraded environment, missing skill deployment). It is intentionally narrow — JavaScript/Node-centric — and represents prior state before `infer-completion-criteria` was added.
|
|
88
|
+
|
|
89
|
+
Legacy fallback table:
|
|
78
90
|
|
|
79
91
|
| Task Pattern | Inferred Completion |
|
|
80
92
|
|--------------|---------------------|
|
|
@@ -86,6 +98,8 @@ When user doesn't specify explicit verification:
|
|
|
86
98
|
| "migrate to ESM" | "node runs without errors" |
|
|
87
99
|
| "refactor X" | "npm test passes" (preserve behavior) |
|
|
88
100
|
|
|
101
|
+
When the inference skill IS available, prefer it. The skill handles multi-language projects, monorepos, CI-defined gates, use-case acceptance criteria, and the refusal case (truly vague tasks like "make it better" that have no measurable criterion).
|
|
102
|
+
|
|
89
103
|
### Examples
|
|
90
104
|
|
|
91
105
|
**User**: "ralph this: migrate all files in lib/ to ESM"
|
|
@@ -301,7 +315,9 @@ User: "actually, abort that and just fix the login bug"
|
|
|
301
315
|
|
|
302
316
|
## Related
|
|
303
317
|
|
|
304
|
-
- `
|
|
318
|
+
- `infer-completion-criteria` skill - derives measurable `--completion` from project state when the user doesn't supply one
|
|
319
|
+
- `ralph` skill - the iterative loop executor implementation (legacy name; `agent-loop` is canonical)
|
|
320
|
+
- `agent-loop-ext` skill - crash-resilient external loop with state persistence
|
|
305
321
|
- `ralph-status` skill - check loop progress
|
|
306
322
|
- `ralph-resume` skill - continue interrupted loops
|
|
307
323
|
- `ralph-abort` skill - abort active loops
|
|
@@ -5,7 +5,7 @@ legacyName: ralph-external
|
|
|
5
5
|
platforms: [all]
|
|
6
6
|
description: Crash-resilient external agent loop with state persistence and CI/CD integration
|
|
7
7
|
commandHint:
|
|
8
|
-
argumentHint: "\"<objective>\" --completion \"<criteria>\" [--max-iterations N] [--timeout M] [--provider <p>] [--no-commit] [--branch <name>] [--quiet]"
|
|
8
|
+
argumentHint: "\"<objective>\" [--completion \"<criteria>\"] [--max-iterations N] [--timeout M] [--provider <p>] [--no-commit] [--branch <name>] [--quiet] [--auto-criteria | --no-infer-completion]"
|
|
9
9
|
allowedTools: Bash, Read, Write
|
|
10
10
|
model: sonnet
|
|
11
11
|
category: automation
|
|
@@ -60,7 +60,7 @@ Users may say:
|
|
|
60
60
|
### Objective (required)
|
|
61
61
|
The task the loop should accomplish. Passed as the first positional argument.
|
|
62
62
|
|
|
63
|
-
### --completion (
|
|
63
|
+
### --completion (optional — inferred when omitted)
|
|
64
64
|
Success criteria as a verifiable command. The loop exits when this command returns exit code 0.
|
|
65
65
|
|
|
66
66
|
**Good examples**:
|
|
@@ -68,6 +68,14 @@ Success criteria as a verifiable command. The loop exits when this command retur
|
|
|
68
68
|
- `--completion "npx tsc --noEmit exits with code 0"`
|
|
69
69
|
- `--completion "coverage report shows >80%"`
|
|
70
70
|
|
|
71
|
+
**When omitted**: the launcher invokes the `infer-completion-criteria` skill before the external loop starts. The skill derives a measurable criterion from project state (CLAUDE.md / AGENTS.md / AIWG.md, package manifests, CI configuration, `.aiwg/` artifacts) and emits a structured proposal with rationale. The proposal is written to `.aiwg/ralph-external/<run-id>/inferred-completion.yaml` and used as the loop's gate.
|
|
72
|
+
|
|
73
|
+
Because `agent-loop-ext` runs externally (potentially headless / in CI), the confirmation flow is:
|
|
74
|
+
- Interactive session (TTY attached): show proposal, accept `Y / n / edit` like the in-session `ralph` skill
|
|
75
|
+
- Non-interactive / `--auto-criteria` / CI environment: use the inferred criterion if confidence is `high`, otherwise fail fast and print the proposal as a diagnostic so the user can re-launch with `--completion` explicitly
|
|
76
|
+
|
|
77
|
+
Pass `--no-infer-completion` to require explicit `--completion` and fail before launch if missing. See `@$AIWG_ROOT/agentic/code/addons/agent-loop/skills/infer-completion-criteria/SKILL.md`.
|
|
78
|
+
|
|
71
79
|
### --max-iterations (default: 10)
|
|
72
80
|
Maximum iterations before the loop halts and saves state for manual review.
|
|
73
81
|
|
|
@@ -90,8 +98,12 @@ Suppress verbose progress output. Completion banner is always shown.
|
|
|
90
98
|
|
|
91
99
|
When triggered:
|
|
92
100
|
|
|
93
|
-
1.
|
|
94
|
-
|
|
101
|
+
1. **Resolve completion criteria**:
|
|
102
|
+
- If `--completion` is provided → use it directly
|
|
103
|
+
- Else if `--no-infer-completion` is set → fail fast before launch with a helpful error
|
|
104
|
+
- Else → invoke `infer-completion-criteria` skill, persist proposal to `.aiwg/ralph-external/<run-id>/inferred-completion.yaml`, confirm or auto-adopt per session-interactivity rules above
|
|
105
|
+
2. Validate the resolved criterion is verifiable (can be checked via command)
|
|
106
|
+
3. Check for an existing `.aiwg/ralph-external/` workspace; create if absent
|
|
95
107
|
3. Generate a unique `loop-id` (8-character hex) and create the loop state file at `.aiwg/ralph-external/loops/<loop-id>.json`
|
|
96
108
|
4. Write the initial state: `{ objective, completionCriteria, maxIterations, timeout, provider, status: "pending", iteration: 0 }`
|
|
97
109
|
5. If `--branch` is specified, create the git branch now
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
---
|
|
2
|
+
namespace: aiwg
|
|
3
|
+
name: infer-completion-criteria
|
|
4
|
+
aliases: [agent-loop-infer-completion, al-infer-completion, ralph-infer-completion]
|
|
5
|
+
platforms: [all]
|
|
6
|
+
description: Infer measurable completion criteria for an agent-loop task from project docs, code, and AIWG standards when the user has not supplied --completion explicitly
|
|
7
|
+
commandHint:
|
|
8
|
+
argumentHint: '"<task description>" [--task-type code|test|docs|refactor] [--non-interactive]'
|
|
9
|
+
allowedTools: "Read, Glob, Grep, Bash"
|
|
10
|
+
model: sonnet
|
|
11
|
+
category: automation
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Infer Completion Criteria
|
|
15
|
+
|
|
16
|
+
## Purpose
|
|
17
|
+
|
|
18
|
+
When a user starts an `agent-loop` task without supplying `--completion`, this skill derives a measurable, verifiable completion criterion from project state. The output must satisfy the `vague-discretion` rule: a concrete shell command or file-inspection check that returns pass/fail unambiguously.
|
|
19
|
+
|
|
20
|
+
Iteration is only as good as its gate. A loop with a vague gate ("until it's done") runs forever or exits prematurely. This skill is what turns "agent-loop this" into "agent-loop this until `<measurable thing>`."
|
|
21
|
+
|
|
22
|
+
The canonical name for the iterative-loop addon is **agent-loop**. `ralph` is the legacy name for the executor skill, retained as an alias; `al` is a short form. The detection/routing skill is `agent-loop` (which delegates to this skill when criteria are missing); the executor is `ralph` (canonical name forthcoming). Everywhere this skill says "agent-loop" you can read "ralph" as the legacy equivalent.
|
|
23
|
+
|
|
24
|
+
## When This Skill Runs
|
|
25
|
+
|
|
26
|
+
This skill is invoked by:
|
|
27
|
+
|
|
28
|
+
- The `agent-loop` detection-and-routing skill when it parses a user request without explicit completion criteria
|
|
29
|
+
- The `ralph` executor skill during Phase 1 initialization when `--completion` is omitted
|
|
30
|
+
- The `agent-loop-ext` external-loop launcher during pre-launch resolution when `--completion` is omitted
|
|
31
|
+
- Direct invocation via `aiwg discover "infer completion"` → `aiwg show skill infer-completion-criteria` when a user wants to preview the inferred criterion before committing to a loop
|
|
32
|
+
|
|
33
|
+
This skill does **not** run when `--completion` is explicit. The user's word is authoritative.
|
|
34
|
+
|
|
35
|
+
## Inference Pipeline
|
|
36
|
+
|
|
37
|
+
The skill is a deterministic walk through five evidence layers, plus one synthesis step. Each layer contributes candidate criteria; the synthesis picks the strongest measurable one and explains the chain of evidence.
|
|
38
|
+
|
|
39
|
+
### Layer 1 — The task verb
|
|
40
|
+
|
|
41
|
+
Parse the user's task description for an intent verb. Map to a default criterion class:
|
|
42
|
+
|
|
43
|
+
| Verb / phrase | Criterion class |
|
|
44
|
+
|---|---|
|
|
45
|
+
| "fix tests", "make tests pass", "test failure" | Test suite passes (exit 0) |
|
|
46
|
+
| "add tests", "increase coverage", "test coverage" | Coverage threshold met |
|
|
47
|
+
| "fix types", "type errors", "migrate to typescript" | Type checker exits 0 |
|
|
48
|
+
| "fix lint", "clean up warnings", "style" | Linter exits 0 |
|
|
49
|
+
| "build", "make it compile" | Build command exits 0 |
|
|
50
|
+
| "refactor", "extract", "rename" | Tests still pass AND build still passes (regression gate) |
|
|
51
|
+
| "implement <X>", "add feature <X>" | Tests for the new code exist and pass |
|
|
52
|
+
| "document", "add docs", "JSDoc" | Coverage check on docstrings/JSDoc presence |
|
|
53
|
+
| "fix bug", "resolve issue #N" | Specific test for that bug passes AND existing suite still green |
|
|
54
|
+
| "migrate", "upgrade" | Build + test + lint all green (no regression) |
|
|
55
|
+
|
|
56
|
+
If the verb is ambiguous, the skill falls back to "regression gate" (build + test + lint all green) as the safest default.
|
|
57
|
+
|
|
58
|
+
### Layer 2 — Project conventions in CLAUDE.md / AGENTS.md / AIWG.md
|
|
59
|
+
|
|
60
|
+
Read the project's context files. AIWG-managed projects often declare commands directly:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Run tests
|
|
64
|
+
npm test
|
|
65
|
+
|
|
66
|
+
# Type check
|
|
67
|
+
npx tsc --noEmit
|
|
68
|
+
|
|
69
|
+
# Lint markdown
|
|
70
|
+
npm exec markdownlint-cli2 "**/*.md"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Extract these as the canonical commands for their respective domains. The Development section of `CLAUDE.md` is the highest-trust source here — it's what the project's maintainers run.
|
|
74
|
+
|
|
75
|
+
Also scan for explicit completion-criterion conventions. Some projects state "a commit is not finished until CI passes" — that signals the CI command (or equivalent local invocation) is the gate.
|
|
76
|
+
|
|
77
|
+
### Layer 3 — Package manifests and config
|
|
78
|
+
|
|
79
|
+
Inspect the project's manifest files to discover scripts and tools:
|
|
80
|
+
|
|
81
|
+
| Manifest | Where to look |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `package.json` | `scripts.test`, `scripts.lint`, `scripts.build`, `scripts.coverage`, `scripts.typecheck` |
|
|
84
|
+
| `Cargo.toml` | implies `cargo test`, `cargo build`, `cargo clippy` |
|
|
85
|
+
| `pyproject.toml` | `[tool.pytest]`, `[tool.ruff]`, `[tool.mypy]`, `scripts.*` |
|
|
86
|
+
| `go.mod` | implies `go test ./...`, `go vet ./...`, `go build ./...` |
|
|
87
|
+
| `Gemfile` | implies `bundle exec rspec`, `bundle exec rubocop` |
|
|
88
|
+
| `pom.xml` / `build.gradle` | `mvn test`, `mvn verify`, `gradle test` |
|
|
89
|
+
| `.tool-versions` / `mise.toml` | language version pins inform which tool is canonical |
|
|
90
|
+
|
|
91
|
+
When multiple scripts exist (e.g. `test`, `test:unit`, `test:integration`), prefer the script the project's own docs reference. If the docs don't reference any, prefer the most specific match to the task verb (e.g. for "fix integration test" → `test:integration`).
|
|
92
|
+
|
|
93
|
+
### Layer 4 — CI configuration
|
|
94
|
+
|
|
95
|
+
CI files encode the team's actual definition of "passes":
|
|
96
|
+
|
|
97
|
+
| CI system | Scan |
|
|
98
|
+
|---|---|
|
|
99
|
+
| GitHub Actions | `.github/workflows/*.yml` — extract `run:` steps from non-deploy jobs |
|
|
100
|
+
| Gitea Actions | `.gitea/workflows/*.yml` — same |
|
|
101
|
+
| GitLab CI | `.gitlab-ci.yml` — extract `script:` from test/lint jobs |
|
|
102
|
+
| CircleCI | `.circleci/config.yml` |
|
|
103
|
+
| Jenkins | `Jenkinsfile` |
|
|
104
|
+
|
|
105
|
+
The first non-trivial verification step in the primary workflow is the team's canonical "done" gate. If CI runs `npm test && npm run lint && npm run typecheck` in order, the inferred criterion is "all three exit 0."
|
|
106
|
+
|
|
107
|
+
### Layer 5 — AIWG artifacts
|
|
108
|
+
|
|
109
|
+
If the project has a `.aiwg/` directory, scan for relevant context:
|
|
110
|
+
|
|
111
|
+
- `.aiwg/testing/test-strategy.md` — declared verification approach
|
|
112
|
+
- `.aiwg/architecture/software-architecture-doc.md` — architectural quality gates
|
|
113
|
+
- `.aiwg/security/security-gates.md` — security-related criteria
|
|
114
|
+
- `.aiwg/quality/code-review-guide.md` — code quality bars
|
|
115
|
+
- `.aiwg/activity.log` — recent operations that may indicate what "done" looked like for similar past tasks
|
|
116
|
+
- `.aiwg/working/<related-progress-files>.md` — prior task progress files; mine the "Completion criteria" sections
|
|
117
|
+
|
|
118
|
+
If the project has a related use case (`.aiwg/requirements/UC-*.md`) whose ID is in the task description, pull that use case's acceptance criteria — those ARE the completion criteria.
|
|
119
|
+
|
|
120
|
+
### Synthesis step
|
|
121
|
+
|
|
122
|
+
Combine the layers into a single proposed criterion. The decision logic:
|
|
123
|
+
|
|
124
|
+
1. If a use case in `.aiwg/requirements/` matches the task, use its acceptance criteria verbatim. Done.
|
|
125
|
+
2. Otherwise, take the verb-class default from Layer 1 and instantiate it using the canonical command from Layer 2 (CLAUDE.md) > Layer 4 (CI) > Layer 3 (manifest).
|
|
126
|
+
3. If the task is in the "regression gate" class, AND the project's CI runs more than one verification, combine them: `command-A passes AND command-B passes AND command-C passes`.
|
|
127
|
+
4. If no canonical command is found in any layer (unusual — typically only on empty-scaffold projects), fall back to:
|
|
128
|
+
- `<file or change exists in git diff against HEAD~1>` — pure structural check
|
|
129
|
+
- And inform the user that a substantive verification command should be added.
|
|
130
|
+
|
|
131
|
+
### Apply AIWG standards (vague-discretion)
|
|
132
|
+
|
|
133
|
+
Validate the proposal against the `vague-discretion` rule:
|
|
134
|
+
|
|
135
|
+
- Criterion must be expressible as a shell command (or shell pipeline) that exits 0 on pass, non-zero on fail.
|
|
136
|
+
- Criterion must NOT use the words "good enough", "thorough", "comprehensive", "complete" without a measurable suffix.
|
|
137
|
+
- Criterion must NOT be self-referential ("the agent is satisfied" — no).
|
|
138
|
+
- Criterion must have an implicit or explicit `max-iterations` cap (ralph's default 10 is the floor; very large refactors may need 20).
|
|
139
|
+
|
|
140
|
+
If the proposal fails any of these, regenerate. If after two regenerations the proposal still fails, surface the problem to the user with the diagnostic ("could not find a measurable verification command — please supply one explicitly").
|
|
141
|
+
|
|
142
|
+
## Output Contract
|
|
143
|
+
|
|
144
|
+
The skill emits a single block of structured output for the calling skill (`agent-loop` router, `ralph` executor, or `agent-loop-ext` launcher) to consume:
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
proposed_completion:
|
|
148
|
+
criterion: "npm test passes AND npx tsc --noEmit exits 0"
|
|
149
|
+
verification_command: "npm test && npx tsc --noEmit"
|
|
150
|
+
rationale:
|
|
151
|
+
- "Task verb 'refactor' triggers regression gate (Layer 1)"
|
|
152
|
+
- "package.json scripts.test = 'jest --coverage' (Layer 3)"
|
|
153
|
+
- "CLAUDE.md Development section references both npm test and npx tsc --noEmit (Layer 2)"
|
|
154
|
+
- ".github/workflows/ci.yml runs both as required checks (Layer 4)"
|
|
155
|
+
confidence: high # high | medium | low
|
|
156
|
+
alternatives_considered:
|
|
157
|
+
- criterion: "npm run lint exits 0"
|
|
158
|
+
rejected_because: "Lint is not in CI required checks for this repo"
|
|
159
|
+
max_iterations_suggestion: 10
|
|
160
|
+
needs_human_confirmation: false # true if confidence == low OR criterion is unusual
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
When the skill runs in non-interactive mode (via `aiwg al --auto-criteria` or the equivalent on `agent-loop` / `agent-loop-ext`), `needs_human_confirmation: false` proceeds directly. Otherwise the consuming skill (the `agent-loop` router or the `ralph` / `agent-loop-ext` executor) shows the proposal to the user and confirms.
|
|
164
|
+
|
|
165
|
+
## Interaction With The User
|
|
166
|
+
|
|
167
|
+
In interactive mode, after running the pipeline, present the proposal:
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
No --completion criteria was provided. I inferred:
|
|
171
|
+
|
|
172
|
+
Criterion: npm test passes AND npx tsc --noEmit exits 0
|
|
173
|
+
Verification: `npm test && npx tsc --noEmit`
|
|
174
|
+
|
|
175
|
+
Evidence:
|
|
176
|
+
- Task verb "refactor" → regression gate
|
|
177
|
+
- package.json scripts.test = jest --coverage
|
|
178
|
+
- CLAUDE.md Development section references both checks
|
|
179
|
+
- .github/workflows/ci.yml requires both
|
|
180
|
+
|
|
181
|
+
Proceed with this criterion? [Y/n/edit]
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
User options:
|
|
185
|
+
- `Y` (default): start the loop with the inferred criterion
|
|
186
|
+
- `n`: abort and request the user supply `--completion` explicitly
|
|
187
|
+
- `edit`: accept a manual edit to the criterion before proceeding
|
|
188
|
+
|
|
189
|
+
Use the platform's native interaction tool when available (per `native-ux-tools` rule). On Claude Code, that means `AskUserQuestion`.
|
|
190
|
+
|
|
191
|
+
## When Inference Should NOT Run
|
|
192
|
+
|
|
193
|
+
- `--completion` is explicit → use the user's criterion, don't second-guess
|
|
194
|
+
- `--no-infer-completion` flag is passed → fail fast with a helpful error if `--completion` is also missing
|
|
195
|
+
- The task description is itself a criterion (e.g. "make `npx tsc --noEmit` pass") → extract the command from the task, don't re-infer
|
|
196
|
+
|
|
197
|
+
## Edge Cases
|
|
198
|
+
|
|
199
|
+
| Case | Handling |
|
|
200
|
+
|---|---|
|
|
201
|
+
| No `package.json`, no manifest, no CI | Scan project root for any executable test runner (`pytest`, `go test`, `cargo test`, `make test`, `Makefile` target `test`). Fall back to the structural check if none found. |
|
|
202
|
+
| Multiple test commands (`test:unit`, `test:integration`, `test:e2e`) | Prefer the one nearest to the task scope. If task mentions "unit", use `test:unit`. If the task is broad, prefer the union via `&&`. |
|
|
203
|
+
| CI runs tests on multiple OS/Node versions | Use the local invocation (`npm test`), not the matrix runner. The matrix is a deploy concern. |
|
|
204
|
+
| Monorepo with multiple packages | Detect from `pnpm-workspace.yaml` / `lerna.json` / `turbo.json` / workspaces field. If the task scope is one package, infer that package's commands. If the task spans the monorepo, use the top-level `test` script. |
|
|
205
|
+
| Project has no tests at all | This is a finding. The inferred criterion should be "tests exist for the new code AND those tests pass." Surface to the user that the project lacks a baseline test suite — that's important context for the loop's expectations. |
|
|
206
|
+
| Project's tests are currently broken (the task IS to fix them) | Set the criterion to the passing condition. The whole point of the loop is to get from current red state to green. |
|
|
207
|
+
| Conflict between layers (CLAUDE.md says X, CI says Y) | Prefer CLAUDE.md (closer to the maintainer's intent). Note the discrepancy in the rationale. |
|
|
208
|
+
|
|
209
|
+
## Interaction With Other AIWG Rules
|
|
210
|
+
|
|
211
|
+
| Rule | How this skill respects it |
|
|
212
|
+
|---|---|
|
|
213
|
+
| `vague-discretion` | The whole point — produces measurable, command-form criteria |
|
|
214
|
+
| `instruction-comprehension` | Reads the task description carefully; doesn't override explicit user instructions |
|
|
215
|
+
| `research-before-decision` | Layer-walk IS research; doesn't propose criteria without evidence |
|
|
216
|
+
| `human-authorization` | Confirms with user before starting loop (unless `--auto-criteria` explicitly granted) |
|
|
217
|
+
| `auto-compact-continue` | The inferred criterion IS what the loop continues toward; no "should I keep working" prompts |
|
|
218
|
+
| `cli-secondary` | Uses `aiwg discover` to find related skills if the task verb is unusual |
|
|
219
|
+
|
|
220
|
+
## Examples
|
|
221
|
+
|
|
222
|
+
### Example 1: Simple test task on a TypeScript project
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
$ agent-loop "fix the failing auth tests" # or: aiwg al / aiwg ralph (legacy)
|
|
226
|
+
|
|
227
|
+
Inferring completion criteria...
|
|
228
|
+
Layer 1 verb: "fix tests" → test-pass class
|
|
229
|
+
Layer 2 CLAUDE.md: "npm test" is the canonical test command
|
|
230
|
+
Layer 3 package.json: scripts.test = "jest"
|
|
231
|
+
Layer 4 CI: .github/workflows/ci.yml runs `npm test`
|
|
232
|
+
Layer 5: no related use case found
|
|
233
|
+
|
|
234
|
+
Proposed criterion: npm test passes (exit 0)
|
|
235
|
+
Verification: `npm test`
|
|
236
|
+
Confidence: high
|
|
237
|
+
|
|
238
|
+
Proceed? [Y/n/edit]
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Example 2: Refactor with no tests
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
$ agent-loop "extract auth logic into a separate module"
|
|
245
|
+
|
|
246
|
+
Inferring completion criteria...
|
|
247
|
+
Layer 1 verb: "extract" → regression gate
|
|
248
|
+
Layer 2 CLAUDE.md: no Development section
|
|
249
|
+
Layer 3 package.json: scripts.test = "echo 'no tests'" (degenerate)
|
|
250
|
+
Layer 4 CI: no workflows found
|
|
251
|
+
Layer 5: no related use case found
|
|
252
|
+
|
|
253
|
+
Warning: project has no functional test suite or CI configuration.
|
|
254
|
+
Falling back to structural verification.
|
|
255
|
+
|
|
256
|
+
Proposed criterion: The new module exists, the original code references it,
|
|
257
|
+
AND `npx tsc --noEmit` still exits 0
|
|
258
|
+
Verification: `test -f src/auth/index.ts && grep -q 'from.*src/auth' src/main.ts && npx tsc --noEmit`
|
|
259
|
+
Confidence: low
|
|
260
|
+
|
|
261
|
+
This is a weak gate. Consider supplying --completion explicitly
|
|
262
|
+
or adding a test suite first.
|
|
263
|
+
|
|
264
|
+
Proceed? [Y/n/edit]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Example 3: Task with an explicit use case reference
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
$ agent-loop "implement UC-AUTH-001"
|
|
271
|
+
|
|
272
|
+
Inferring completion criteria...
|
|
273
|
+
Layer 1 verb: "implement" → tests-exist class
|
|
274
|
+
Layer 5: found .aiwg/requirements/UC-AUTH-001-user-login.md
|
|
275
|
+
|
|
276
|
+
Using acceptance criteria from UC-AUTH-001:
|
|
277
|
+
- [ ] User can log in with valid email/password
|
|
278
|
+
- [ ] Invalid credentials show clear error message
|
|
279
|
+
- [ ] Account locks after 5 failed attempts
|
|
280
|
+
- [ ] Login completes within 2 seconds
|
|
281
|
+
|
|
282
|
+
Proposed criterion: All acceptance criteria from UC-AUTH-001 verified by tests,
|
|
283
|
+
AND `npm test -- --testPathPattern=auth` passes
|
|
284
|
+
Verification: `npm test -- --testPathPattern=auth`
|
|
285
|
+
Confidence: high (acceptance criteria are explicit)
|
|
286
|
+
|
|
287
|
+
Proceed? [Y/n/edit]
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Example 4: Refusal case
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
$ agent-loop "make the code better"
|
|
294
|
+
|
|
295
|
+
Inferring completion criteria...
|
|
296
|
+
Layer 1 verb: "make better" → AMBIGUOUS, no clear criterion class
|
|
297
|
+
Layer 5: no related use case
|
|
298
|
+
|
|
299
|
+
Cannot infer measurable criteria for this task.
|
|
300
|
+
|
|
301
|
+
"Make the code better" is vague (per AIWG vague-discretion rule).
|
|
302
|
+
A loop with no measurable gate runs forever or exits prematurely.
|
|
303
|
+
|
|
304
|
+
Please supply --completion with a concrete check, e.g.:
|
|
305
|
+
--completion "npm test passes AND npm run lint exits 0"
|
|
306
|
+
--completion "all functions in src/utils/ have JSDoc"
|
|
307
|
+
--completion "complexity score from eslint < 10 for all files"
|
|
308
|
+
|
|
309
|
+
Or rephrase the task with a concrete intent:
|
|
310
|
+
agent-loop "reduce cyclomatic complexity in src/utils/"
|
|
311
|
+
agent-loop "add JSDoc to all exported functions in src/api/"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## References
|
|
315
|
+
|
|
316
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/vague-discretion.md — Measurable criteria requirement
|
|
317
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/research-before-decision.md — Layer-walk research pattern
|
|
318
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/instruction-comprehension.md — Don't override explicit user criteria
|
|
319
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/auto-compact-continue.md — Criterion IS what the loop continues toward
|
|
320
|
+
- @$AIWG_ROOT/agentic/code/addons/agent-loop/skills/agent-loop/SKILL.md — The detection/routing skill that delegates here when `--completion` is missing
|
|
321
|
+
- @$AIWG_ROOT/agentic/code/addons/agent-loop/skills/ralph/SKILL.md — The legacy executor skill that consumes this output (`ralph` is legacy for `agent-loop`'s executor)
|
|
322
|
+
- @$AIWG_ROOT/agentic/code/addons/agent-loop/skills/agent-loop-ext/SKILL.md — The crash-resilient external loop, same delegation pattern
|
|
323
|
+
- @$AIWG_ROOT/agentic/code/addons/agent-loop/agents/ralph-verifier.md — Runs the verification command this skill proposes
|
|
@@ -6,7 +6,7 @@ deprecated_names: [ralph]
|
|
|
6
6
|
platforms: [all]
|
|
7
7
|
description: Execute iterative task loop until completion criteria are met - iteration beats perfection
|
|
8
8
|
commandHint:
|
|
9
|
-
argumentHint: '"<task>" --completion "<criteria>" [--max-iterations N] [--timeout M] [--interactive --guidance "text"]'
|
|
9
|
+
argumentHint: '"<task>" [--completion "<criteria>"] [--max-iterations N] [--timeout M] [--interactive --guidance "text"] [--auto-criteria | --no-infer-completion]'
|
|
10
10
|
allowedTools: "Task, Read, Write, Bash, Glob, Grep, TodoWrite, Edit"
|
|
11
11
|
model: opus
|
|
12
12
|
category: automation
|
|
@@ -50,7 +50,7 @@ The task to execute. Should be:
|
|
|
50
50
|
- Measurable completion state
|
|
51
51
|
- Self-contained (all context provided)
|
|
52
52
|
|
|
53
|
-
### --completion (
|
|
53
|
+
### --completion (optional — inferred when omitted)
|
|
54
54
|
Success criteria. Must be:
|
|
55
55
|
- Verifiable (tests, lint, compilation)
|
|
56
56
|
- Specific (not subjective)
|
|
@@ -66,6 +66,10 @@ Success criteria. Must be:
|
|
|
66
66
|
- `--completion "code looks good"`
|
|
67
67
|
- `--completion "feature is done"`
|
|
68
68
|
|
|
69
|
+
**When omitted**: the loop delegates to the `infer-completion-criteria` skill, which derives a measurable criterion from project docs (CLAUDE.md / AGENTS.md / AIWG.md), package manifests, CI configuration, and `.aiwg/` artifacts. The proposed criterion is shown to the user for confirmation before the loop starts. Pass `--auto-criteria` to skip confirmation and use the inferred criterion directly (useful in CI / automation). Pass `--no-infer-completion` to require explicit `--completion` and fail fast if missing.
|
|
70
|
+
|
|
71
|
+
See `@$AIWG_ROOT/agentic/code/addons/agent-loop/skills/infer-completion-criteria/SKILL.md` for the inference pipeline.
|
|
72
|
+
|
|
69
73
|
### --max-iterations (default: 10)
|
|
70
74
|
Safety limit on iterations. Prevents infinite loops.
|
|
71
75
|
|
|
@@ -94,12 +98,21 @@ Create feature branch for loop work.
|
|
|
94
98
|
|
|
95
99
|
### Phase 1: Initialization
|
|
96
100
|
|
|
97
|
-
1. Parse task
|
|
98
|
-
2.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
1. Parse task
|
|
102
|
+
2. **Completion-criteria resolution**:
|
|
103
|
+
- If `--completion` is provided → use it directly
|
|
104
|
+
- Else if `--no-infer-completion` is set → fail fast with a helpful error
|
|
105
|
+
- Else → invoke the `infer-completion-criteria` skill on the task description
|
|
106
|
+
- The skill returns a proposed criterion with rationale and confidence level
|
|
107
|
+
- If `--auto-criteria` is set OR confidence is `high`, adopt the proposal silently and log it
|
|
108
|
+
- Otherwise, surface the proposal to the user via the platform's native interaction tool (`AskUserQuestion` on Claude Code, formatted text elsewhere per `native-ux-tools`); accept `Y` / `n` / `edit`
|
|
109
|
+
- If the user rejects, abort the loop and ask them to supply `--completion` explicitly
|
|
110
|
+
3. Validate the final criterion is verifiable (can be checked via command)
|
|
111
|
+
4. Create `.aiwg/ralph/` workspace if not exists
|
|
112
|
+
5. Initialize iteration counter (i=0)
|
|
113
|
+
6. Create feature branch if --branch specified
|
|
114
|
+
7. **Write the criterion and its rationale into the loop's progress file** (`.aiwg/ralph/<loop-id>/progress.md`) per the `auto-compact-continue` rule — this survives compaction and resumption
|
|
115
|
+
8. Log initialization
|
|
103
116
|
|
|
104
117
|
**Communicate**:
|
|
105
118
|
```
|
|
@@ -4,10 +4,15 @@ Core meta-utility rules for agent coordination, context management, and platform
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## AIWG Utilities Rules (
|
|
7
|
+
## AIWG Utilities Rules (21 rules — active with aiwg-utils addon)
|
|
8
8
|
|
|
9
9
|
### HIGH
|
|
10
10
|
|
|
11
|
+
#### auto-compact-continue
|
|
12
|
+
**Summary**: The answer to "should I keep working?" is always YES — until the task's measurable completion criteria are met or the user redirects. Context pressure, long tool outputs, and high iteration counts are not scope questions. When context fills, the right response is to compact, checkpoint to durable storage (activity log, progress file at `.aiwg/working/<task>-progress.md`, git history, AIWG memory), and continue. Trust platform auto-compact (REF-910); load-bearing state must live in `CLAUDE.md` / `AGENTS.md` / `AIWG.md` / activity log / progress file / git / `.aiwg/working/` — never only in conversation turns. Maintain a `## Compact Instructions` section so the summarizer preserves completion criteria, last successful step, failed approaches (do not let them be re-attempted), and authorization questions. Apply aggressive in-session compression (REF-122: passive=6% savings, aggressive=22.7%); update the progress file every 10–15 tool calls on long tasks. Exceptions: authorization gates (per `human-authorization`), 3-attempts-failed escalation (per `anti-laziness` Rule 6), explicit user redirect, genuinely ambiguous new directive classification (per `skill-discovery` Rule 0). "Should I continue?" is never the right question.
|
|
13
|
+
**When to apply**: Any long-running session; before context fills; after long tool outputs; when crossing iteration thresholds; when resuming after compaction; when tempted to ask the user permission to keep going
|
|
14
|
+
**Full rule**: @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/auto-compact-continue.md
|
|
15
|
+
|
|
11
16
|
#### cli-secondary
|
|
12
17
|
**Summary**: AIWG is agentic-first. The agent's strict priority order for any action: (1) **local skill** already loaded in context (kernel skills, framework quickrefs, deployed agents), (2) **discovered skill** via `aiwg discover` + `aiwg show`, (3) raw CLI command, (4) manual file edits as last resort. The skill carries the priming (pre-flight checks, dry-run preview, preservation logic, gates) that the CLI alone lacks. Sole exception: discovery/finder commands (`aiwg discover`, `aiwg show`, `aiwg list`, `aiwg status`, `aiwg version`, `aiwg runtime-info`, status/info subcommands) stay primary — they ARE the priming entry points and the bridge from priority 2 to priority 1. For mixed commands (`aiwg index`, `aiwg packages`, `aiwg ops`, `aiwg storage`), classify per subcommand. Includes a pairing table covering use/refresh/regenerate/doctor/init/promote/scaffold-*/add-*/doc-sync/lint/cleanup-audit/sdlc-accelerate/ralph/mc/steward/index build/ops actions/storage migrate.
|
|
13
18
|
**When to apply**: Before invoking any AIWG CLI command, before writing skill/agent docs that reference CLI commands, when updating quickrefs or routing tables, when filing pairings audits
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Auto-Compact and Continue
|
|
2
|
+
|
|
3
|
+
**Enforcement Level**: HIGH
|
|
4
|
+
**Scope**: All long-running agent sessions and tool-using agents across all platforms
|
|
5
|
+
**Addon**: aiwg-utils (core, universal)
|
|
6
|
+
**Research Basis**: REF-909 (Anthropic — Effective Harnesses for Long-Running Agents), REF-910 (Anthropic — Compaction), REF-122 (Active Context Compression / Focus Agent), REF-128 (Context Window Management Strategies)
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
When context grows long, the wrong response is to stop and ask the user "should I keep working?" The right response is to compact, checkpoint, and continue. AIWG agents must treat the AIWG memory system, activity log, and on-disk artifacts as the durable substrate that survives context resets, and must continue until the original task's measurable completion criteria are met.
|
|
11
|
+
|
|
12
|
+
## Problem Statement
|
|
13
|
+
|
|
14
|
+
Frontier models — especially under conservative harness defaults — increasingly stop mid-task to ask the user permission to continue when context budget gets tight, when a long tool result lands, or when an iteration count crosses some internal threshold. The user has already authorized the task. The question "should I keep working?" is the agent dumping its context-management responsibility onto the human. Every time this happens, the user has to re-engage, re-establish state, and pay a thinking tax that exists because the agent treated a routine context event as if it were a scope question.
|
|
15
|
+
|
|
16
|
+
The failure mode is structurally similar to `vague-discretion` (loops that exit on "good enough") and `anti-laziness` Rule 6 (premature abandonment). This rule names the specific subset: **stopping to ask about continuation when continuation is the obvious correct action**.
|
|
17
|
+
|
|
18
|
+
## The Single Rule, Stated Plainly
|
|
19
|
+
|
|
20
|
+
**The answer to "should I keep working?" is always YES — until the task's stated completion criteria are met or the user has redirected.** Context pressure is not a scope question. Long tool output is not a scope question. Crossing iteration N is not a scope question. The right response to all of them is: compact, checkpoint to durable storage, and continue.
|
|
21
|
+
|
|
22
|
+
The exceptions are narrow and named:
|
|
23
|
+
1. **Authorization gates** (`human-authorization` rule) — a destructive or out-of-scope action *was* discovered. Ask about the action, not about continuation.
|
|
24
|
+
2. **3-attempts-failed escalation** (`anti-laziness` rule, Rule 6) — three honest attempts to solve the same blocker have failed; escalate with full context.
|
|
25
|
+
3. **Explicit user redirect** — the user has paused or changed direction since you started.
|
|
26
|
+
4. **Genuinely ambiguous classification** of a new directive (`skill-discovery` rule, Rule 0) — ask one clarifying question, do not stall.
|
|
27
|
+
|
|
28
|
+
Nothing else justifies stopping to ask "should I keep working?"
|
|
29
|
+
|
|
30
|
+
## Mandatory Rules
|
|
31
|
+
|
|
32
|
+
### Rule 1: Never Ask "Should I Continue?" When Context Is the Reason
|
|
33
|
+
|
|
34
|
+
If your reason for asking the user is any of the following — context is getting long, you've been working a while, this is a big task, the next step might be expensive — do not ask. Compact and continue.
|
|
35
|
+
|
|
36
|
+
**FORBIDDEN**:
|
|
37
|
+
```
|
|
38
|
+
Agent: "I've completed phases 1 and 2. Context is getting long.
|
|
39
|
+
Should I continue to phase 3?"
|
|
40
|
+
|
|
41
|
+
Agent: "This has been a complex investigation. Would you like me
|
|
42
|
+
to wrap up here, or should I keep going?"
|
|
43
|
+
|
|
44
|
+
Agent: "I notice we're at iteration 8. Do you want me to keep
|
|
45
|
+
iterating or stop?"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**REQUIRED**:
|
|
49
|
+
```
|
|
50
|
+
Agent: *writes checkpoint to .aiwg/working/<task-slug>-progress.md*
|
|
51
|
+
*appends activity log entry*
|
|
52
|
+
*continues to phase 3*
|
|
53
|
+
|
|
54
|
+
Agent: *continues investigation; if context tightens, writes findings
|
|
55
|
+
to a working file and references it in subsequent turns*
|
|
56
|
+
|
|
57
|
+
Agent: *continues iterating against the measurable completion condition;
|
|
58
|
+
if no progress for 3 consecutive iterations, applies the
|
|
59
|
+
anti-laziness recovery protocol, not a continuation prompt*
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Rule 2: Use the Harness, Don't Ask the Human
|
|
63
|
+
|
|
64
|
+
AIWG already ships the durable-storage substrate that makes auto-compact safe. Before context fills, write the load-bearing state to one or more of these:
|
|
65
|
+
|
|
66
|
+
| Substrate | What lives there | Survives compaction? |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `CLAUDE.md` / `AGENTS.md` / `AIWG.md` | Project conventions, framework rules, the task contract itself | Yes (system-prompt scope) |
|
|
69
|
+
| `.aiwg/activity.log` | Append-only timeline of operations performed | Yes (on disk, never in context) |
|
|
70
|
+
| AIWG memory (`~/.claude/projects/.../memory/`) | Durable facts the user explicitly chose to keep | Yes (system-prompt scope on Claude Code; equivalent surfaces on other providers) |
|
|
71
|
+
| `.aiwg/working/<task>-progress.md` | The progress file (see Rule 3) | Yes (on disk) |
|
|
72
|
+
| Git history | Each meaningful step as a commit | Yes (on disk + remote) |
|
|
73
|
+
| `.aiwg/working/` | Intermediate artifacts, scratch results | Yes (on disk) |
|
|
74
|
+
|
|
75
|
+
If the load-bearing state for the current task lives only in conversation turns, you are setting up a future failure. Move it to disk before context fills, not after.
|
|
76
|
+
|
|
77
|
+
### Rule 3: Write a Progress File for Multi-Phase Work
|
|
78
|
+
|
|
79
|
+
For any task that you reasonably expect to span more than ~20 tool calls or more than one compaction window, write a progress file at `.aiwg/working/<task-slug>-progress.md` and update it at each meaningful checkpoint. The file must include:
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
# Progress: <task name>
|
|
83
|
+
|
|
84
|
+
## Task contract
|
|
85
|
+
- Original request: <verbatim quote of the user ask>
|
|
86
|
+
- Completion criteria (measurable, per vague-discretion): <bullets>
|
|
87
|
+
- Authorization scope: <what is in-scope; what requires asking>
|
|
88
|
+
|
|
89
|
+
## Current status
|
|
90
|
+
- Phase: <where we are>
|
|
91
|
+
- Last successful step: <what just worked>
|
|
92
|
+
- Next action: <what to do when this file is re-read>
|
|
93
|
+
|
|
94
|
+
## Completed steps
|
|
95
|
+
- [x] <step with brief result and link to artifact / commit ref>
|
|
96
|
+
- [x] <step with brief result and link to artifact / commit ref>
|
|
97
|
+
|
|
98
|
+
## Failed approaches (do not retry)
|
|
99
|
+
- <approach> — failed because <reason>; learning: <what we know now>
|
|
100
|
+
|
|
101
|
+
## Open questions / deferred items
|
|
102
|
+
- <item> — deferred because <reason>; will need authorization to <action>
|
|
103
|
+
|
|
104
|
+
## State references
|
|
105
|
+
- Activity log entries: <range or recent IDs>
|
|
106
|
+
- Commits: <hashes>
|
|
107
|
+
- Artifacts: <paths under .aiwg/working/ or final locations>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The progress file's **Failed approaches** section is the single most underrated artifact (REF-909). Without it, post-compaction agents re-discover known dead ends. With it, the next agent reads the file once, knows where to resume, and skips the blind alleys.
|
|
111
|
+
|
|
112
|
+
### Rule 4: Trust the Platform's Auto-Compact
|
|
113
|
+
|
|
114
|
+
On Claude Code (and equivalents), auto-compact runs automatically when context approaches the limit (REF-910). The right response is *not* to preempt it by asking the user to clear context. The right response is:
|
|
115
|
+
|
|
116
|
+
1. Make sure your durable state is current (Rule 2).
|
|
117
|
+
2. Let compaction run.
|
|
118
|
+
3. After compaction, the conversation history is summarized but `CLAUDE.md` / `AGENTS.md` / `AIWG.md`, the activity log, the progress file, and all on-disk artifacts are intact.
|
|
119
|
+
4. Read the progress file (Rule 3) and continue from "Next action."
|
|
120
|
+
|
|
121
|
+
If you are on a platform that does *not* auto-compact and you can see context getting tight, write the checkpoint and use whatever the platform's manual compact / new-session mechanism is, then resume — do not ask the user to make that decision for you.
|
|
122
|
+
|
|
123
|
+
### Rule 5: Honor the Compact Instructions
|
|
124
|
+
|
|
125
|
+
A `## Compact Instructions` section in `CLAUDE.md` / `AGENTS.md` / `AIWG.md` (or the equivalent provider context file) tells the auto-compact summarizer what to preserve. If the project has one, your in-context summaries should bias toward the same priorities. If the project lacks one and you are working on a long-running task, contribute one — propose to the user that AIWG's `aiwg-regenerate` skill add it, or write the file directly under team-directive scope.
|
|
126
|
+
|
|
127
|
+
A minimum-viable Compact Instructions block:
|
|
128
|
+
|
|
129
|
+
```markdown
|
|
130
|
+
## Compact Instructions
|
|
131
|
+
|
|
132
|
+
When summarizing this conversation for compaction, preserve:
|
|
133
|
+
1. The current task's completion criteria verbatim.
|
|
134
|
+
2. The last successful step and any verification command that proved it.
|
|
135
|
+
3. Failed approaches and the reason each failed (do not let them be re-attempted).
|
|
136
|
+
4. References to `.aiwg/working/*-progress.md`, `.aiwg/activity.log`,
|
|
137
|
+
and any in-flight commits.
|
|
138
|
+
5. Pending authorization questions that were raised but not answered.
|
|
139
|
+
6. Open scope boundaries (what is in/out of scope for this task).
|
|
140
|
+
|
|
141
|
+
Discard:
|
|
142
|
+
- Exploratory reasoning traces leading to already-known conclusions.
|
|
143
|
+
- Tool outputs that were superseded by later, more authoritative reads.
|
|
144
|
+
- Greetings, status banners, and other non-load-bearing prose.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Rule 6: Aggressive, Not Passive, Compaction Discipline
|
|
148
|
+
|
|
149
|
+
REF-122 (Focus Agent / Active Context Compression) is unambiguous: passive instructions to compress yield ~6% savings; aggressive instructions (compress every 10–15 tool calls; consolidate findings; prune raw history) yield ~22.7%. The mechanism that makes "always continue" safe is *actively compacting during the session*, not waiting for auto-compact at the limit. Apply the same discipline:
|
|
150
|
+
|
|
151
|
+
- After every meaningful tool-result observation, ask: "Is the raw content load-bearing for the remaining work, or is the conclusion?" If conclusion-only, summarize it into your next thought and stop carrying the raw output forward.
|
|
152
|
+
- After every 10–15 tool calls on a long task, write a progress-file update.
|
|
153
|
+
- Before spawning a subagent (`subagent-scoping` rule), pass conclusions, not raw history (`context-bloat` rule).
|
|
154
|
+
|
|
155
|
+
### Rule 7: Distinguish Continuation From Authorization
|
|
156
|
+
|
|
157
|
+
The hardest case, and the one this rule exists to draw a sharp line through:
|
|
158
|
+
|
|
159
|
+
| Situation | Right action |
|
|
160
|
+
|---|---|
|
|
161
|
+
| Context getting tight, task is in-scope, no new scope discovered | **Continue** (compact + checkpoint) |
|
|
162
|
+
| Context getting tight, but a destructive or out-of-scope action is the next required step | **Ask about the action** (per `human-authorization`), not about continuation |
|
|
163
|
+
| Context getting tight, three honest attempts have failed on the same blocker | **Escalate per anti-laziness Rule 6** with full context, not a generic "should I continue?" |
|
|
164
|
+
| Context getting tight, the user just sent a new directive that supersedes the current task | **Classify per skill-discovery Rule 0**; the old task may be done, the new task starts fresh |
|
|
165
|
+
|
|
166
|
+
In all four cases, the question framed to the user (if any) is specific and load-bearing. "Should I keep working?" is never the right question — it carries no information for the user and no signal back for the agent.
|
|
167
|
+
|
|
168
|
+
### Rule 8: Recovery After Compaction
|
|
169
|
+
|
|
170
|
+
When a session resumes from compaction (you notice prior turns are now summarized, or you are reading a progress file from a previous session):
|
|
171
|
+
|
|
172
|
+
1. **Read the progress file first.** It is the canonical state.
|
|
173
|
+
2. **Read recent activity log entries.** They are the timeline.
|
|
174
|
+
3. **Check git status and recent commits.** They show what landed.
|
|
175
|
+
4. **Verify the completion criteria are still met by your read.** If the summary says "phase 2 done" but git shows uncommitted changes from phase 2, reconcile before continuing.
|
|
176
|
+
5. **Skip the "failed approaches" set.** Do not re-try them.
|
|
177
|
+
6. **Resume from "Next action."**
|
|
178
|
+
|
|
179
|
+
This is the AIWG-flavored implementation of REF-909's initializer-agent / coding-agent pattern. The progress file *is* the bridge between sessions; treating it as authoritative is what makes the bridge load-bearing.
|
|
180
|
+
|
|
181
|
+
## Detection Heuristics
|
|
182
|
+
|
|
183
|
+
You may be in violation of this rule if:
|
|
184
|
+
|
|
185
|
+
| Symptom | Likely cause |
|
|
186
|
+
|---|---|
|
|
187
|
+
| Output ends with "Would you like me to continue?" or "Should I keep going?" | Asked a scope question that was actually a context question |
|
|
188
|
+
| Output offers a menu like "I can stop here or proceed with X — which?" when X is clearly the next obvious step | Same |
|
|
189
|
+
| You wrote a long summary of "what we've done so far" and asked the user to direct the next step | The summary belonged in a progress file, not in the conversation |
|
|
190
|
+
| You stopped before the user's measurable completion criteria were met | You confused fatigue / context / iteration count with scope completion |
|
|
191
|
+
| You re-attempted an approach the prior session marked as failed | You did not read the progress file's "Failed approaches" section |
|
|
192
|
+
| You asked the user to decide between two technically equivalent paths to the same outcome | The decision was yours to make under `instruction-comprehension` — make it and continue |
|
|
193
|
+
|
|
194
|
+
## Recovery When This Rule Was Violated
|
|
195
|
+
|
|
196
|
+
If you notice you just asked "should I continue?" or its semantic equivalent:
|
|
197
|
+
|
|
198
|
+
1. **Reframe in the same turn.** "Continuing — writing checkpoint to `.aiwg/working/<task>-progress.md` and proceeding to <next step>." Do not wait for the user to confirm.
|
|
199
|
+
2. **Write the progress file** if it does not already exist.
|
|
200
|
+
3. **Append an activity-log entry** noting the checkpoint and resumption.
|
|
201
|
+
4. **Continue.**
|
|
202
|
+
|
|
203
|
+
If the user has *already* responded ("yes, keep going") then the cost is paid; treat it as a lesson and update your in-session checklist to avoid the second occurrence.
|
|
204
|
+
|
|
205
|
+
## Interaction With Other Rules
|
|
206
|
+
|
|
207
|
+
| Rule | Relationship |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `vague-discretion` | This rule is the operational counterpart: vague-discretion forbids vague completion criteria; this rule forbids stopping to ask about continuation against measurable criteria |
|
|
210
|
+
| `anti-laziness` | Rule 6 of anti-laziness names the 3-attempts-failed escalation case; this rule covers the much more common context-pressure case |
|
|
211
|
+
| `human-authorization` | Authorization is for scope changes and destructive actions, not for "should I keep working" |
|
|
212
|
+
| `instruction-comprehension` | Track the user's stated completion criteria. The criteria, not the agent's fatigue, decide when to stop |
|
|
213
|
+
| `skill-discovery` | Rule 0 handles new-directive classification; this rule handles "no new directive, just context pressure" |
|
|
214
|
+
| `activity-log` | The activity log is one of the durable substrates this rule depends on |
|
|
215
|
+
| `subagent-scoping` / `context-bloat` | When you delegate, pass conclusions not raw history; same logic applies in the main agent |
|
|
216
|
+
| `context-budget` | When `AIWG_CONTEXT_WINDOW` is set, the compaction trigger is tighter; budget more aggressively |
|
|
217
|
+
|
|
218
|
+
## Platform Applicability
|
|
219
|
+
|
|
220
|
+
Universal across all AIWG-supported providers:
|
|
221
|
+
|
|
222
|
+
- **Claude Code**: Auto-compact is the platform default. This rule says: trust it, prepare for it, do not ask the user to decide for it.
|
|
223
|
+
- **OpenAI Codex**: Smaller context window; aggressive checkpointing to disk is more important. The 32KB `AGENTS.md` cap means the progress file and activity log do the heavy lifting.
|
|
224
|
+
- **GitHub Copilot, Cursor, Warp, Factory, OpenCode, Windsurf, OpenClaw, Hermes**: All have their own context handling; the AIWG durable substrate (memory, activity log, working files, git) is platform-neutral and is the cross-platform answer.
|
|
225
|
+
|
|
226
|
+
## Checklist
|
|
227
|
+
|
|
228
|
+
Before responding "should I continue?" or any semantic equivalent:
|
|
229
|
+
|
|
230
|
+
- [ ] Did the original task contract include a measurable completion criterion?
|
|
231
|
+
- [ ] Has that criterion been met? If yes, *say so and stop*; if no, *continue*.
|
|
232
|
+
- [ ] Is the reason I want to stop "context is long"? Then write a progress file and continue.
|
|
233
|
+
- [ ] Is the reason I want to stop "I've done a lot"? Then write a progress file and continue.
|
|
234
|
+
- [ ] Is there an authorization gate (destructive / out-of-scope) blocking the next step? Then ask about *that specific action*, not about continuation.
|
|
235
|
+
- [ ] Have I made 3 honest attempts at the same blocker without progress? Then escalate per `anti-laziness`, with full context.
|
|
236
|
+
- [ ] Did the user redirect? Then classify the new directive per `skill-discovery` Rule 0.
|
|
237
|
+
|
|
238
|
+
If none of those apply: **continue**.
|
|
239
|
+
|
|
240
|
+
## References
|
|
241
|
+
|
|
242
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/vague-discretion.md — Measurable completion criteria
|
|
243
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/instruction-comprehension.md — Track the user's stated criteria
|
|
244
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/human-authorization.md — When asking *is* the right move
|
|
245
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/activity-log.md — One of the durable substrates
|
|
246
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/context-budget.md — Aggressive budgeting when `AIWG_CONTEXT_WINDOW` is set
|
|
247
|
+
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/skill-discovery.md — Rule 0: classify new directives
|
|
248
|
+
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/rules/anti-laziness.md — Rule 6: 3-attempts escalation
|
|
249
|
+
- REF-909 (Anthropic — Effective Harnesses for Long-Running Agents) — initializer-agent / coding-agent pattern, progress files
|
|
250
|
+
- REF-910 (Anthropic — Compaction) — auto-compact mechanics, Compact Instructions, what survives
|
|
251
|
+
- REF-122 (Active Context Compression / Focus Agent) — aggressive vs passive compression discipline
|
|
252
|
+
- REF-128 (Context Window Management Strategies) — effective context is 30-40% smaller than advertised
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
**Rule Status**: ACTIVE
|
|
257
|
+
**Last Updated**: 2026-05-14
|
|
@@ -166,9 +166,23 @@ The config's `policy` block applies at every gate:
|
|
|
166
166
|
- **Post-tag failures**: never delete pushed tags. Increment patch and re-run the flow.
|
|
167
167
|
- **Gate failures with `hard_stop: true`**: halt immediately, surface the failure log, do not advance.
|
|
168
168
|
- **Gate failures with `hard_stop: false`**: log a warning, continue.
|
|
169
|
+
- **Supply-chain gate (signed-tag verify) failure**: this is the recovery exception to "never delete pushed tags." If `tools/ci/verify-signed-tag.sh` rejects the tag (wrong signing key, expired key, missing-from-maintainers.asc), no artifacts are emitted by `npm-publish.yml` / `gitea-release.yml` / `github-mirror.yml` — the bad tag is an empty shell. Recovery: `git tag -d <tag>`, push delete to both remotes (`git push origin :refs/tags/<tag>` and `git push github :refs/tags/<tag>`), then re-cut via `tools/release/cut-tag.sh <version>` which forces the release key. Document the incident in `docs/contributing/versioning.md` for the next release.
|
|
169
170
|
|
|
170
171
|
Apply the `anti-laziness` recovery protocol (PAUSE→DIAGNOSE→ADAPT→RETRY→ESCALATE) when a gate fails — do not silently bypass with destructive shortcuts like skipping tests or stripping rules.
|
|
171
172
|
|
|
173
|
+
## Tag-cutting must use the wrapper
|
|
174
|
+
|
|
175
|
+
**`git tag -a` and `git tag -s` are NOT to be used directly by this skill.** The maintainer's global git config typically has `tag.gpgsign=true` and `user.signingkey=<personal-commit-signing-key>`, which causes plain `git tag` invocations to sign with the **wrong key** — the personal key, not the release key. The supply-chain gate will reject the tag and no artifacts will ship.
|
|
176
|
+
|
|
177
|
+
Always use `tools/release/cut-tag.sh <version>` for the tag step. The wrapper:
|
|
178
|
+
|
|
179
|
+
1. Runs 10 pre-tag sanity checks (CalVer shape, package.json + marketplace.json lockstep, CHANGELOG entry, announcement file present, release-signing key present locally AND published in `.gitea/keys/maintainers.asc`)
|
|
180
|
+
2. Signs with `-u <RELEASE_KEY_FINGERPRINT>` (defaults to the AIWG release key; override via `AIWG_RELEASE_KEY_FINGERPRINT` env var for forks)
|
|
181
|
+
3. Verifies the local signature via `git tag -v` before declaring success
|
|
182
|
+
4. Does NOT push automatically — push is left to the operator so a final sanity step can run
|
|
183
|
+
|
|
184
|
+
This is the canonical path. Any release config that templates a raw `git tag -s` is incorrect and must be migrated to call the wrapper.
|
|
185
|
+
|
|
172
186
|
## Defaults when no config exists
|
|
173
187
|
|
|
174
188
|
If `.aiwg/release.config` is missing, scaffold one from the schema and ask the operator to review before continuing. The AIWG repo's own config is the reference implementation; new projects can copy it as a starting point.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiwg",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.6",
|
|
4
4
|
"description": "Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 4 more) so one source of truth works across 10 platforms. Optional utilities for persistent artifact memory, background orchestration, autonomous loops, and artifact indexing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Cut a signed AIWG release tag with the release-signing key.
|
|
3
|
+
#
|
|
4
|
+
# This wrapper exists because git's `user.signingkey` is typically set to
|
|
5
|
+
# a maintainer's PERSONAL commit-signing key. Tags created via plain
|
|
6
|
+
# `git tag -s` (or even `git tag -a` when `tag.gpgsign=true` is set) will
|
|
7
|
+
# then be signed with that personal key, NOT the release key published in
|
|
8
|
+
# `.gitea/keys/maintainers.asc`. The supply-chain gate
|
|
9
|
+
# (`tools/ci/verify-signed-tag.sh`) correctly rejects such tags — but the
|
|
10
|
+
# error surfaces in CI rather than at the moment of the mistake.
|
|
11
|
+
#
|
|
12
|
+
# This script forces the correct release key via `git tag -s -u <fingerprint>`
|
|
13
|
+
# and runs pre-tag sanity checks so the gate-fail loop becomes a local
|
|
14
|
+
# fail-fast loop instead.
|
|
15
|
+
#
|
|
16
|
+
# Background: a13dabc5 (two-key model — personal key signs commits, release
|
|
17
|
+
# key signs tags) and v2026.5.5 incident (signed-tag gate caught wrong-key
|
|
18
|
+
# tag on commit fd2ba49e — recovered via re-tag with this procedure).
|
|
19
|
+
#
|
|
20
|
+
# Usage:
|
|
21
|
+
# tools/release/cut-tag.sh <version> [-m "<custom tag message>"]
|
|
22
|
+
#
|
|
23
|
+
# Example:
|
|
24
|
+
# tools/release/cut-tag.sh 2026.5.6
|
|
25
|
+
# tools/release/cut-tag.sh 2026.5.6 -m "v2026.5.6 — Some Theme"
|
|
26
|
+
#
|
|
27
|
+
# What it does (fail-fast at each step):
|
|
28
|
+
# 1. Verifies <version> matches the CalVer YYYY.M.PATCH shape (no leading zeros)
|
|
29
|
+
# 2. Verifies package.json version matches <version>
|
|
30
|
+
# 3. Verifies .claude-plugin/marketplace.json metadata.version matches (PUW-038 lockstep)
|
|
31
|
+
# 4. Verifies CHANGELOG.md has an entry for [<version>]
|
|
32
|
+
# 5. Verifies docs/releases/v<version>-announcement.md exists
|
|
33
|
+
# 6. Verifies the AIWG release-signing key is available locally
|
|
34
|
+
# 7. Verifies the release-signing key is published in .gitea/keys/maintainers.asc
|
|
35
|
+
# 8. Creates the signed tag with `git tag -s -u <release-key-fingerprint>`
|
|
36
|
+
# 9. Verifies the tag's signature locally before any push (`git tag -v`)
|
|
37
|
+
# 10. Reports next-step push commands; does NOT push automatically
|
|
38
|
+
#
|
|
39
|
+
# The push step is intentionally left to the operator so this script can
|
|
40
|
+
# also be run as a sanity check before a release ceremony.
|
|
41
|
+
|
|
42
|
+
set -euo pipefail
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# Configuration — single source of truth for the release-signing key
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
# Fingerprint of the AIWG release-signing key, per SECURITY.md and
|
|
48
|
+
# .gitea/keys/maintainers.asc. Override via $AIWG_RELEASE_KEY_FINGERPRINT
|
|
49
|
+
# for forks or migration scenarios.
|
|
50
|
+
RELEASE_KEY_FINGERPRINT="${AIWG_RELEASE_KEY_FINGERPRINT:-FE9272F0BC5781E1DE77FAAA719AB63879E84CE8}"
|
|
51
|
+
|
|
52
|
+
# ---------------------------------------------------------------------------
|
|
53
|
+
# Argument parsing
|
|
54
|
+
# ---------------------------------------------------------------------------
|
|
55
|
+
if [ $# -lt 1 ]; then
|
|
56
|
+
cat <<EOF >&2
|
|
57
|
+
Usage: $0 <version> [-m "<tag message>"]
|
|
58
|
+
|
|
59
|
+
Examples:
|
|
60
|
+
$0 2026.5.6
|
|
61
|
+
$0 2026.5.6 -m "v2026.5.6 — Some Release Theme"
|
|
62
|
+
|
|
63
|
+
The default tag message is "vX.Y.Z — <CalVer date>" if not provided.
|
|
64
|
+
EOF
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
VERSION="$1"
|
|
69
|
+
shift
|
|
70
|
+
|
|
71
|
+
TAG_MESSAGE=""
|
|
72
|
+
while [ $# -gt 0 ]; do
|
|
73
|
+
case "$1" in
|
|
74
|
+
-m|--message)
|
|
75
|
+
TAG_MESSAGE="$2"
|
|
76
|
+
shift 2
|
|
77
|
+
;;
|
|
78
|
+
*)
|
|
79
|
+
echo "Unknown flag: $1" >&2
|
|
80
|
+
exit 1
|
|
81
|
+
;;
|
|
82
|
+
esac
|
|
83
|
+
done
|
|
84
|
+
|
|
85
|
+
TAG="v${VERSION}"
|
|
86
|
+
|
|
87
|
+
cat <<EOF
|
|
88
|
+
====================================================================
|
|
89
|
+
AIWG cut-tag — preflight checks for ${TAG}
|
|
90
|
+
====================================================================
|
|
91
|
+
EOF
|
|
92
|
+
|
|
93
|
+
# ---------------------------------------------------------------------------
|
|
94
|
+
# 1. CalVer shape: YYYY.M.PATCH (no leading zeros on M or PATCH)
|
|
95
|
+
# ---------------------------------------------------------------------------
|
|
96
|
+
if ! [[ "$VERSION" =~ ^[0-9]{4}\.([1-9]|1[0-2])\.([0-9]|[1-9][0-9]+)$ ]]; then
|
|
97
|
+
cat <<EOF >&2
|
|
98
|
+
FAIL: '$VERSION' does not match CalVer 'YYYY.M.PATCH'.
|
|
99
|
+
- Month must be 1-12 with NO leading zero (use '5' not '05').
|
|
100
|
+
- Patch must have no leading zero either.
|
|
101
|
+
See docs/contributing/versioning.md.
|
|
102
|
+
EOF
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
echo " [1/10] CalVer shape OK: $VERSION"
|
|
106
|
+
|
|
107
|
+
# ---------------------------------------------------------------------------
|
|
108
|
+
# 2. package.json lockstep
|
|
109
|
+
# ---------------------------------------------------------------------------
|
|
110
|
+
PKG_VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('package.json','utf8')).version)")
|
|
111
|
+
if [ "$PKG_VERSION" != "$VERSION" ]; then
|
|
112
|
+
cat <<EOF >&2
|
|
113
|
+
FAIL: package.json version is '$PKG_VERSION', expected '$VERSION'.
|
|
114
|
+
Run: npm version $VERSION --no-git-tag-version
|
|
115
|
+
Or edit package.json manually and commit.
|
|
116
|
+
EOF
|
|
117
|
+
exit 1
|
|
118
|
+
fi
|
|
119
|
+
echo " [2/10] package.json lockstep OK"
|
|
120
|
+
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
# 3. .claude-plugin/marketplace.json metadata.version lockstep (PUW-038 #1139)
|
|
123
|
+
# ---------------------------------------------------------------------------
|
|
124
|
+
MP_VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('.claude-plugin/marketplace.json','utf8')).metadata.version)")
|
|
125
|
+
if [ "$MP_VERSION" != "$VERSION" ]; then
|
|
126
|
+
cat <<EOF >&2
|
|
127
|
+
FAIL: .claude-plugin/marketplace.json metadata.version is '$MP_VERSION',
|
|
128
|
+
expected '$VERSION' (PUW-038 lockstep — #1139).
|
|
129
|
+
Update the file and commit.
|
|
130
|
+
EOF
|
|
131
|
+
exit 1
|
|
132
|
+
fi
|
|
133
|
+
echo " [3/10] marketplace.json lockstep OK"
|
|
134
|
+
|
|
135
|
+
# ---------------------------------------------------------------------------
|
|
136
|
+
# 4. CHANGELOG.md entry exists
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
if ! grep -q "^## \[${VERSION}\]" CHANGELOG.md; then
|
|
139
|
+
cat <<EOF >&2
|
|
140
|
+
FAIL: CHANGELOG.md does not contain '## [${VERSION}]'.
|
|
141
|
+
Add the release entry before tagging — see docs/releases/.
|
|
142
|
+
EOF
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
echo " [4/10] CHANGELOG.md entry OK"
|
|
146
|
+
|
|
147
|
+
# ---------------------------------------------------------------------------
|
|
148
|
+
# 5. Release announcement file exists
|
|
149
|
+
# ---------------------------------------------------------------------------
|
|
150
|
+
ANNOUNCEMENT="docs/releases/v${VERSION}-announcement.md"
|
|
151
|
+
if [ ! -f "$ANNOUNCEMENT" ]; then
|
|
152
|
+
cat <<EOF >&2
|
|
153
|
+
FAIL: $ANNOUNCEMENT does not exist.
|
|
154
|
+
Create the release announcement before tagging.
|
|
155
|
+
See docs/releases/v2026.5.5-announcement.md as a template.
|
|
156
|
+
EOF
|
|
157
|
+
exit 1
|
|
158
|
+
fi
|
|
159
|
+
echo " [5/10] Announcement file OK"
|
|
160
|
+
|
|
161
|
+
# ---------------------------------------------------------------------------
|
|
162
|
+
# 6. Release-signing key available locally
|
|
163
|
+
# ---------------------------------------------------------------------------
|
|
164
|
+
if ! gpg --list-secret-keys "$RELEASE_KEY_FINGERPRINT" >/dev/null 2>&1; then
|
|
165
|
+
cat <<EOF >&2
|
|
166
|
+
FAIL: Release-signing key $RELEASE_KEY_FINGERPRINT not found in local
|
|
167
|
+
GPG keyring. Either import it (gpg --import) or override the
|
|
168
|
+
fingerprint with \$AIWG_RELEASE_KEY_FINGERPRINT.
|
|
169
|
+
See docs/contributing/versioning.md → "Signing your release tag".
|
|
170
|
+
EOF
|
|
171
|
+
exit 1
|
|
172
|
+
fi
|
|
173
|
+
echo " [6/10] Release-signing key present locally"
|
|
174
|
+
|
|
175
|
+
# ---------------------------------------------------------------------------
|
|
176
|
+
# 7. Release-signing key published in maintainers.asc
|
|
177
|
+
# ---------------------------------------------------------------------------
|
|
178
|
+
# Extract fingerprints from the committed keyring and check ours is among
|
|
179
|
+
# them. We use `gpg --show-keys --with-colons` so the output is parseable
|
|
180
|
+
# without depending on locale.
|
|
181
|
+
if ! gpg --show-keys --with-colons .gitea/keys/maintainers.asc 2>/dev/null \
|
|
182
|
+
| awk -F: '$1=="fpr" {print $10}' | grep -qx "$RELEASE_KEY_FINGERPRINT"; then
|
|
183
|
+
cat <<EOF >&2
|
|
184
|
+
FAIL: Release-signing key $RELEASE_KEY_FINGERPRINT is NOT published in
|
|
185
|
+
.gitea/keys/maintainers.asc. The supply-chain gate will reject
|
|
186
|
+
the tag. Publish the key:
|
|
187
|
+
gpg --armor --export $RELEASE_KEY_FINGERPRINT >> .gitea/keys/maintainers.asc
|
|
188
|
+
git add .gitea/keys/maintainers.asc
|
|
189
|
+
git commit -m 'security: republish release signing key'
|
|
190
|
+
EOF
|
|
191
|
+
exit 1
|
|
192
|
+
fi
|
|
193
|
+
echo " [7/10] Release-signing key published in maintainers.asc"
|
|
194
|
+
|
|
195
|
+
# ---------------------------------------------------------------------------
|
|
196
|
+
# 8. Create signed tag with explicit release key (-u override)
|
|
197
|
+
# ---------------------------------------------------------------------------
|
|
198
|
+
if [ -z "$TAG_MESSAGE" ]; then
|
|
199
|
+
TODAY=$(date -u '+%Y-%m-%d')
|
|
200
|
+
TAG_MESSAGE="${TAG} — ${TODAY}"
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
# Refuse to overwrite an existing local tag — operators must run
|
|
204
|
+
# `git tag -d $TAG` explicitly first to acknowledge the destructive op.
|
|
205
|
+
if git rev-parse "$TAG" >/dev/null 2>&1; then
|
|
206
|
+
cat <<EOF >&2
|
|
207
|
+
FAIL: Tag '$TAG' already exists locally. Refusing to overwrite.
|
|
208
|
+
To recreate intentionally:
|
|
209
|
+
git tag -d $TAG
|
|
210
|
+
git push origin :refs/tags/$TAG # if it was already pushed
|
|
211
|
+
$0 $VERSION # re-run this script
|
|
212
|
+
EOF
|
|
213
|
+
exit 1
|
|
214
|
+
fi
|
|
215
|
+
|
|
216
|
+
git tag -s -u "$RELEASE_KEY_FINGERPRINT" "$TAG" -m "$TAG_MESSAGE"
|
|
217
|
+
echo " [8/10] Signed tag '$TAG' created with release key"
|
|
218
|
+
|
|
219
|
+
# ---------------------------------------------------------------------------
|
|
220
|
+
# 9. Local verify (mirror of the CI gate logic)
|
|
221
|
+
# ---------------------------------------------------------------------------
|
|
222
|
+
if ! git tag -v "$TAG" >/dev/null 2>&1; then
|
|
223
|
+
cat <<EOF >&2
|
|
224
|
+
FAIL: Local 'git tag -v $TAG' verification did not succeed.
|
|
225
|
+
This means even the local GPG can't verify what it just signed —
|
|
226
|
+
check that the release key is not expired or revoked.
|
|
227
|
+
Deleting the bad tag for cleanup:
|
|
228
|
+
EOF
|
|
229
|
+
git tag -d "$TAG" >/dev/null 2>&1 || true
|
|
230
|
+
exit 1
|
|
231
|
+
fi
|
|
232
|
+
echo " [9/10] Local 'git tag -v' verification passed"
|
|
233
|
+
|
|
234
|
+
# ---------------------------------------------------------------------------
|
|
235
|
+
# 10. Report next steps; do NOT auto-push
|
|
236
|
+
# ---------------------------------------------------------------------------
|
|
237
|
+
cat <<EOF
|
|
238
|
+
|
|
239
|
+
[10/10] Ready to push. The push step is left manual on purpose —
|
|
240
|
+
inspect the tag once more with 'git tag -v $TAG' if you want, then:
|
|
241
|
+
|
|
242
|
+
git push origin main --tags
|
|
243
|
+
git push github main --tags # if mirroring to GitHub
|
|
244
|
+
|
|
245
|
+
After push, watch for the gitea-release / npm-publish / github-mirror
|
|
246
|
+
workflows. The supply-chain gate runs first; a green gate is the
|
|
247
|
+
precondition for any artifact emission.
|
|
248
|
+
|
|
249
|
+
====================================================================
|
|
250
|
+
EOF
|