release-skill 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +89 -0
- package/INSTALL.md +216 -5
- package/INSTALL.zh-CN.md +358 -0
- package/README.md +411 -67
- package/README.zh-CN.md +377 -59
- package/adapters/claude/.claude-plugin/marketplace.json +1 -1
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +79284 -0
- package/adapters/claude/bin/release-skill.mjs +34 -0
- package/adapters/claude/native/safe-write/binding.gyp +40 -0
- package/adapters/claude/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/claude/native/safe-write/prebuilds.json +24 -0
- package/adapters/claude/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/claude/schemas/.render-manifest.json +37 -0
- package/adapters/claude/schemas/approval-record.schema.json +115 -0
- package/adapters/claude/schemas/artifact-lock.schema.json +111 -0
- package/adapters/claude/schemas/artifact-plan.schema.json +52 -0
- package/adapters/claude/schemas/artifact-policy.schema.json +76 -0
- package/adapters/claude/schemas/evidence-event.schema.json +89 -0
- package/adapters/claude/schemas/release-plan.schema.json +860 -0
- package/adapters/claude/schemas/release-project.schema.json +736 -0
- package/adapters/claude/schemas/release-run.schema.json +342 -0
- package/adapters/claude/skills/release-assess/SKILL.md +5 -6
- package/adapters/claude/skills/release-help/SKILL.md +14 -18
- package/adapters/claude/skills/release-prepare/SKILL.md +16 -6
- package/adapters/claude/skills/release-publish/SKILL.md +7 -7
- package/adapters/claude/skills/release-reconcile/SKILL.md +6 -6
- package/adapters/claude/skills/release-setup/SKILL.md +95 -0
- package/adapters/claude/skills/release-verify/SKILL.md +7 -7
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +79284 -0
- package/adapters/codex/bin/release-skill.mjs +34 -0
- package/adapters/codex/native/safe-write/binding.gyp +40 -0
- package/adapters/codex/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/codex/native/safe-write/prebuilds.json +24 -0
- package/adapters/codex/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/codex/schemas/.render-manifest.json +37 -0
- package/adapters/codex/schemas/approval-record.schema.json +115 -0
- package/adapters/codex/schemas/artifact-lock.schema.json +111 -0
- package/adapters/codex/schemas/artifact-plan.schema.json +52 -0
- package/adapters/codex/schemas/artifact-policy.schema.json +76 -0
- package/adapters/codex/schemas/evidence-event.schema.json +89 -0
- package/adapters/codex/schemas/release-plan.schema.json +860 -0
- package/adapters/codex/schemas/release-project.schema.json +736 -0
- package/adapters/codex/schemas/release-run.schema.json +342 -0
- package/adapters/codex/skills/release-assess/SKILL.md +12 -6
- package/adapters/codex/skills/release-help/SKILL.md +21 -18
- package/adapters/codex/skills/release-prepare/SKILL.md +23 -6
- package/adapters/codex/skills/release-publish/SKILL.md +14 -7
- package/adapters/codex/skills/release-reconcile/SKILL.md +13 -6
- package/adapters/codex/skills/release-setup/SKILL.md +102 -0
- package/adapters/codex/skills/release-verify/SKILL.md +14 -7
- package/bin/release-skill-cli.mjs +807 -0
- package/bin/release-skill.bundle.mjs +79284 -0
- package/bin/release-skill.mjs +23 -732
- package/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/native/safe-write/prebuilds.json +22 -2
- package/native/safe-write/src/safe_write.cc +11 -2
- package/package.json +8 -2
- package/references/02-project-config.md +55 -4
- package/references/05-evidence-and-errors.md +6 -2
- package/schemas/release-plan.schema.json +556 -65
- package/schemas/release-project.schema.json +406 -29
- package/schemas/release-run.schema.json +165 -18
- package/scripts/build-bundle.mjs +133 -0
- package/skills/release-assess/SKILL.md +5 -6
- package/skills/release-help/SKILL.md +14 -18
- package/skills/release-prepare/SKILL.md +16 -6
- package/skills/release-publish/SKILL.md +7 -7
- package/skills/release-reconcile/SKILL.md +6 -6
- package/skills/release-setup/SKILL.md +95 -0
- package/skills/release-verify/SKILL.md +7 -7
- package/skills-src/release-assess/SKILL.md +5 -6
- package/skills-src/release-help/SKILL.md +14 -18
- package/skills-src/release-prepare/SKILL.md +16 -6
- package/skills-src/release-publish/SKILL.md +7 -7
- package/skills-src/release-reconcile/SKILL.md +6 -6
- package/skills-src/release-setup/SKILL.md +95 -0
- package/skills-src/release-verify/SKILL.md +7 -7
- package/src/adapters/contract.mjs +3 -0
- package/src/adapters/git-github.mjs +84 -2
- package/src/adapters/npm.mjs +5 -13
- package/src/adapters/plugin-marketplace.mjs +132 -52
- package/src/adapters/push-snapshot.mjs +84 -17
- package/src/artifacts/policy.mjs +4 -7
- package/src/artifacts/safe-fs-backend-internal.mjs +69 -21
- package/src/commands/prepare.mjs +244 -20
- package/src/commands/publish.mjs +46 -0
- package/src/commands/reconcile.mjs +152 -0
- package/src/commands/setup.mjs +1525 -0
- package/src/commands/verify.mjs +122 -26
- package/src/core/approval.mjs +4 -6
- package/src/core/config.mjs +42 -8
- package/src/core/errors.mjs +4 -0
- package/src/core/pkg-root.mjs +22 -0
- package/src/core/plan.mjs +132 -4
- package/src/core/previous-public-baseline.mjs +21 -1
- package/src/core/run.mjs +4 -4
- package/src/core/trusted-resource.mjs +96 -0
- package/src/core/verification-gates.mjs +451 -0
- package/src/docs/version-gate.mjs +164 -0
- package/src/producers/build-adapters.mjs +512 -55
- package/src/snapshot/frozen.mjs +221 -7
- package/src/snapshot/public-map.mjs +7 -4
- package/src/snapshot/scan.mjs +2 -1
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# release-skill
|
|
2
2
|
|
|
3
|
-
[简体中文](README.zh-CN.md)
|
|
3
|
+
[简体中文](README.zh-CN.md) · Installation: [English](INSTALL.md) / [简体中文](INSTALL.zh-CN.md)
|
|
4
4
|
|
|
5
|
+
<!-- release-skill:release-version: 0.1.4 -->
|
|
5
6
|
Release preparation for Claude Code and Codex, with human-edited files kept intact.
|
|
6
7
|
|
|
7
8
|
release-skill helps a maintainer answer three questions: what will be released,
|
|
@@ -10,28 +11,29 @@ reviewed artifacts first and publishes those same artifacts later; it does not
|
|
|
10
11
|
regenerate a README or re-pack the live workspace at the last step.
|
|
11
12
|
|
|
12
13
|
<!-- release-skill:capability:external-write-boundary -->
|
|
13
|
-
> **Current boundary:**
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
>
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
>
|
|
21
|
-
>
|
|
22
|
-
>
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
-
>
|
|
14
|
+
> **Current boundary:** v0.1.4 is the current release. v0.1.1 completed a real production release
|
|
15
|
+
> to GitHub and npm — the first production-verified milestone — followed by
|
|
16
|
+
> exact npm installation and Claude/Codex consumer installation verification
|
|
17
|
+
> from the frozen Git ref; "current release" and "first production-verified
|
|
18
|
+
> milestone" are two distinct facts and must not be conflated. The same
|
|
19
|
+
> workflow also has a local production-equivalent protocol suite using the
|
|
20
|
+
> real release-skill CLI and frozen artifacts, local bare Git remotes, and
|
|
21
|
+
> protocol fakes for `gh`, `npm`, Claude, and Codex. The suite does not
|
|
22
|
+
> provide OS-level network isolation, and it does not prove that another
|
|
23
|
+
> project's credentials, permissions, rate limits, or eventual-consistency
|
|
24
|
+
> behavior will match this release. Treat each project's first production run
|
|
25
|
+
> as a monitored canary. `prepare --online` observes bound previous-public
|
|
26
|
+
> baselines and fails closed on drift; remote uniqueness checks run during
|
|
27
|
+
> publish global preflight.
|
|
26
28
|
|
|
27
29
|
<!-- release-skill:capability:safe-first-command -->
|
|
28
|
-
> **v0.1.1
|
|
29
|
-
>
|
|
30
|
-
>
|
|
30
|
+
> **Production path verified since the v0.1.1 milestone; v0.1.4 is the current
|
|
31
|
+
> release.** The npm-installed CLI is the supported user entry. Source checkout
|
|
32
|
+
> is the development/contributor fallback.
|
|
31
33
|
>
|
|
32
34
|
> **Start here:**
|
|
33
|
-
> -
|
|
34
|
-
> -
|
|
35
|
+
> - npm install: `npm install -g release-skill` → `release-skill help`
|
|
36
|
+
> - source checkout: `node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs" help`
|
|
35
37
|
|
|
36
38
|
<!-- release-skill:maturity:v0.1-boundary -->
|
|
37
39
|
<!-- release-skill:maturity:boundary -->
|
|
@@ -58,6 +60,13 @@ slogans, examples, prose, formatting, and later human edits.
|
|
|
58
60
|
intervention; the tool does not force or overwrite them.
|
|
59
61
|
- Only files listed in `publicFiles` are copied. Add translated READMEs, images,
|
|
60
62
|
demos, and linked documents explicitly when they belong in the release.
|
|
63
|
+
- A release freezes only the current truth: `prepare` never refreshes or
|
|
64
|
+
rewrites human docs. Maintainers update README, INSTALL, and CHANGELOG first
|
|
65
|
+
— including the machine-readable `release-skill:release-version` markers,
|
|
66
|
+
which must equal the `package.json` version, and the formal CHANGELOG
|
|
67
|
+
heading for the current version — then prepare, review, and approve. A
|
|
68
|
+
pre-release gate fails closed when any doc version marker or the CHANGELOG
|
|
69
|
+
current-version entry drifts.
|
|
61
70
|
|
|
62
71
|
This is the preservation contract: **copy current truth, freeze reviewed
|
|
63
72
|
truth, and never rewrite human truth.**
|
|
@@ -70,12 +79,7 @@ truth, and never rewrite human truth.**
|
|
|
70
79
|
- Git 2.30+
|
|
71
80
|
- A target Git repository with at least one commit
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
> npm registry may return 404. Use the source-checkout path below for review.
|
|
75
|
-
> After `npm view release-skill version` returns `0.1.1`, the npm-installed CLI
|
|
76
|
-
> is the supported user entry and the source checkout is a development fallback.
|
|
77
|
-
|
|
78
|
-
**Install from npm (supported after v0.1.1 publication):**
|
|
82
|
+
**Install from npm (recommended):**
|
|
79
83
|
|
|
80
84
|
```bash
|
|
81
85
|
npm install -g release-skill
|
|
@@ -93,7 +97,7 @@ npx release-skill help
|
|
|
93
97
|
release-skill help
|
|
94
98
|
```
|
|
95
99
|
|
|
96
|
-
**Development install (from source checkout):**
|
|
100
|
+
**Development install (contributor fallback, from source checkout):**
|
|
97
101
|
|
|
98
102
|
Set the checkout location and install dependencies:
|
|
99
103
|
|
|
@@ -105,8 +109,6 @@ npm exec --yes pnpm@10.17.1 -- install --frozen-lockfile
|
|
|
105
109
|
|
|
106
110
|
Then use the CLI via `node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs"`.
|
|
107
111
|
|
|
108
|
-
Create `.release-skill/project.yaml` in the target project:
|
|
109
|
-
|
|
110
112
|
First keep local plans, approvals, and frozen artifacts out of Git:
|
|
111
113
|
|
|
112
114
|
```gitignore
|
|
@@ -114,7 +116,194 @@ First keep local plans, approvals, and frozen artifacts out of Git:
|
|
|
114
116
|
!.release-skill/project.yaml
|
|
115
117
|
```
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
### First use: deterministic setup without loading the full report
|
|
120
|
+
|
|
121
|
+
Setup is read-only by default. Keep its potentially large report in temporary
|
|
122
|
+
files; show the user or Agent only the deterministic `compactSummary` review
|
|
123
|
+
view. The summary does not replace authorization: `setupDigest` still binds the
|
|
124
|
+
complete facts, candidates, and answers.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
PROJECT=/absolute/path/to/my-project
|
|
128
|
+
SETUP_SESSION="$(mktemp -d "${TMPDIR:-/tmp}/release-setup.XXXXXX")"
|
|
129
|
+
REPORT="$SETUP_SESSION/discovery.json"
|
|
130
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
131
|
+
BOUND_REPORT="$SETUP_SESSION/bound.json"
|
|
132
|
+
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
133
|
+
|
|
134
|
+
release-skill setup --root "$PROJECT" --json > "$REPORT" || test "$?" -eq 2
|
|
135
|
+
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(!r.compactSummary){console.error("compactSummary missing");process.exit(2)}process.stdout.write(JSON.stringify(r.compactSummary,null,2)+"\n")' "$REPORT"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`NEEDS_INPUT` and `LOCAL_ONLY_DETECTED` intentionally exit with code 2. If
|
|
139
|
+
`proposalConflicts` is non-empty—including `PUBLIC_REPO_AUTHORITY_CONFLICT` or
|
|
140
|
+
a public-file mapping conflict—stop and let a human correct the conflicting
|
|
141
|
+
repository or mapping authority, then rerun setup. Do not guess a winner.
|
|
142
|
+
|
|
143
|
+
With no conflicts, copy the machine proposal mechanically. The Agent must not
|
|
144
|
+
rewrite or transcribe it:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
SETUP_SESSION='/session-directory-absolute-path-printed-above'
|
|
148
|
+
PROJECT='/project-absolute-path-printed-above'
|
|
149
|
+
REPORT="$SETUP_SESSION/discovery.json"
|
|
150
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
151
|
+
BOUND_REPORT="$SETUP_SESSION/bound.json"
|
|
152
|
+
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if((r.proposalConflicts??[]).length){console.error("proposal conflicts require human resolution");process.exit(2)}if(!r.recommendedAnswers){console.error("recommendedAnswers missing");process.exit(2)}fs.writeFileSync(process.argv[2],JSON.stringify(r.recommendedAnswers,null,2)+"\n",{flag:"wx",mode:0o600})' "$REPORT" "$ANSWERS"
|
|
153
|
+
|
|
154
|
+
release-skill setup --root "$PROJECT" --answers "$ANSWERS" --json > "$BOUND_REPORT"
|
|
155
|
+
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(!r.compactSummary||!r.setupDigest){console.error("bound setup report incomplete");process.exit(2)}process.stdout.write(JSON.stringify({compactSummary:r.compactSummary,setupDigest:r.setupDigest},null,2)+"\n")' "$BOUND_REPORT"
|
|
156
|
+
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Review that bound summary and exact digest once. After explicit human
|
|
160
|
+
confirmation, use the confirmed digest literal to create the configuration:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
SETUP_SESSION=<session-directory-absolute-path-printed-above>
|
|
164
|
+
PROJECT=<project-absolute-path-printed-above>
|
|
165
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
166
|
+
CREATED_REPORT="$SETUP_SESSION/created.json"
|
|
167
|
+
POST_REPORT="$SETUP_SESSION/post-setup.json"
|
|
168
|
+
ASSESS_REPORT="$SETUP_SESSION/assess.json"
|
|
169
|
+
release-skill setup --root "$PROJECT" --answers "$ANSWERS" \
|
|
170
|
+
--write --confirm-setup <confirmed-setupDigest> --json > "$CREATED_REPORT"
|
|
171
|
+
release-skill setup --root "$PROJECT" --json > "$POST_REPORT"
|
|
172
|
+
set +e
|
|
173
|
+
release-skill assess --root "$PROJECT" --offline --json > "$ASSESS_REPORT"
|
|
174
|
+
ASSESS_EXIT=$?
|
|
175
|
+
set -e
|
|
176
|
+
[ "$ASSESS_EXIT" -eq 0 ] || [ "$ASSESS_EXIT" -eq 1 ] || exit "$ASSESS_EXIT"
|
|
177
|
+
node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>JSON.parse(fs.readFileSync(x,"utf8")));if(c.status!=="CONFIG_CREATED"||p.status!=="ALREADY_CONFIGURED"||!["ASSESSED","NEEDS_INPUT","BLOCKED"].includes(a.status)){process.exit(2)}process.stdout.write(JSON.stringify({created:c.status,postSetup:p.status,assessment:{status:a.status,summary:a.summary,gapCount:(a.gaps??[]).length,blockingCodes:(a.gaps??[]).filter(g=>g.severity==="error").map(g=>g.code)}},null,2)+"\n")' "$CREATED_REPORT" "$POST_REPORT" "$ASSESS_REPORT"
|
|
178
|
+
node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The write must return `CONFIG_CREATED`; the next setup must return
|
|
182
|
+
`ALREADY_CONFIGURED`. Existing configuration is never regenerated—make only
|
|
183
|
+
reviewed incremental edits. Discovered interpreter/package-manager scripts are
|
|
184
|
+
`SIDE_EFFECTS_UNPROVEN` and are not selected automatically. Add a project-specific
|
|
185
|
+
hook or gate only after human review: edit `projectConfig.hooks`, or edit
|
|
186
|
+
`verificationGates` and add the same id to `selectedGateIds`, then rerun the
|
|
187
|
+
bound dry-run. Keep human files at `mode: preserve`, and
|
|
188
|
+
use `sourceScope: workspace` only for explicit cross-unit shared sources.
|
|
189
|
+
|
|
190
|
+
#### Advanced schema reference—not the first-use path
|
|
191
|
+
|
|
192
|
+
The wrapper below illustrates the schema only. Do not hand-write it during the
|
|
193
|
+
normal setup path; mechanically extract `recommendedAnswers` as shown above.
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"projectConfig": {
|
|
198
|
+
"apiVersion": "release-skill/v1",
|
|
199
|
+
"kind": "ReleaseProject",
|
|
200
|
+
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
201
|
+
"releaseUnits": [{
|
|
202
|
+
"id": "my-project",
|
|
203
|
+
"source": ".",
|
|
204
|
+
"publicRepo": "owner/my-project",
|
|
205
|
+
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
206
|
+
"distributions": [{
|
|
207
|
+
"type": "npm",
|
|
208
|
+
"package": "my-project",
|
|
209
|
+
"access": "public",
|
|
210
|
+
"provenance": false,
|
|
211
|
+
"tag": "latest",
|
|
212
|
+
"registry": "https://registry.npmjs.org",
|
|
213
|
+
"publisher": "my-npm-username"
|
|
214
|
+
}],
|
|
215
|
+
"publicFiles": [
|
|
216
|
+
{ "from": "README.md", "to": "README.md", "mode": "preserve" },
|
|
217
|
+
{ "from": "package.json", "to": "package.json", "mode": "preserve" }
|
|
218
|
+
],
|
|
219
|
+
"requiredPublicFiles": ["README.md", "package.json"],
|
|
220
|
+
"previousPublicBaseline": { "mode": "none" },
|
|
221
|
+
"production": {
|
|
222
|
+
"branchTemplate": "release/{tag}",
|
|
223
|
+
"branchStrategy": "create-release-branch"
|
|
224
|
+
}
|
|
225
|
+
}]
|
|
226
|
+
},
|
|
227
|
+
"selectedGateIds": []
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
This is a schema reference, not an onboarding template. Normal setup must use
|
|
232
|
+
the machine proposal. `mode: none` is valid only when no public version exists.
|
|
233
|
+
|
|
234
|
+
The following reference shows the exact relationship between a manually
|
|
235
|
+
reviewed gate and `selectedGateIds`. Apply that relationship only as an
|
|
236
|
+
incremental edit to the extracted machine proposal:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"projectConfig": {
|
|
241
|
+
"apiVersion": "release-skill/v1",
|
|
242
|
+
"kind": "ReleaseProject",
|
|
243
|
+
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
244
|
+
"releaseUnits": [{
|
|
245
|
+
"id": "my-project",
|
|
246
|
+
"source": ".",
|
|
247
|
+
"publicRepo": "owner/my-project",
|
|
248
|
+
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
249
|
+
"distributions": [{
|
|
250
|
+
"type": "npm",
|
|
251
|
+
"package": "my-project",
|
|
252
|
+
"access": "public",
|
|
253
|
+
"provenance": false,
|
|
254
|
+
"tag": "latest",
|
|
255
|
+
"registry": "https://registry.npmjs.org",
|
|
256
|
+
"publisher": "my-npm-username"
|
|
257
|
+
}],
|
|
258
|
+
"publicFiles": [
|
|
259
|
+
{ "from": "package.json", "to": "package.json", "mode": "preserve" }
|
|
260
|
+
],
|
|
261
|
+
"requiredPublicFiles": ["package.json"],
|
|
262
|
+
"previousPublicBaseline": { "mode": "none" },
|
|
263
|
+
"production": {
|
|
264
|
+
"branchTemplate": "release/{tag}",
|
|
265
|
+
"branchStrategy": "create-release-branch"
|
|
266
|
+
}
|
|
267
|
+
}],
|
|
268
|
+
"verificationGates": [{
|
|
269
|
+
"id": "my-project-script-test",
|
|
270
|
+
"phase": "snapshot-verify",
|
|
271
|
+
"scope": { "unit": "my-project" },
|
|
272
|
+
"command": ["node", "-e", "const p=require('./package.json');if(!p.name)process.exit(1)"],
|
|
273
|
+
"cwd": ".",
|
|
274
|
+
"timeoutMs": 30000,
|
|
275
|
+
"envAllowlist": []
|
|
276
|
+
}]
|
|
277
|
+
},
|
|
278
|
+
"selectedGateIds": ["my-project-script-test"]
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
The id must be copied from the current `gateCandidates`; do not invent one.
|
|
283
|
+
The example command is self-contained in the public snapshot. A project script
|
|
284
|
+
is valid only when the script and every dependency it needs are included in
|
|
285
|
+
`publicFiles`; a snapshot gate cannot see the parent workspace's tests,
|
|
286
|
+
development dependencies, or `node_modules` unless they are explicitly public.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
release-skill setup --root /absolute/path/to/my-project \
|
|
290
|
+
--answers /absolute/path/to/setup-answers.json --json
|
|
291
|
+
release-skill setup --root /absolute/path/to/my-project \
|
|
292
|
+
--answers /absolute/path/to/setup-answers.json \
|
|
293
|
+
--write --confirm-setup <setupDigest> --json
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Setup atomically creates only an absent `.release-skill/project.yaml`.
|
|
297
|
+
That create-once step uses the digest-registered `darwin-arm64` native
|
|
298
|
+
prebuild shipped in v0.1.3; unsupported platforms fail closed with
|
|
299
|
+
`SAFE_WRITE_UNAVAILABLE` instead of falling back to path-based writes.
|
|
300
|
+
`ALREADY_CONFIGURED`/`CONFIG_EXISTS` means the existing file remains
|
|
301
|
+
human-owned and must be edited incrementally. README, slogans, CHANGELOG, and
|
|
302
|
+
business scripts are never generated or overwritten. A project with no remote
|
|
303
|
+
channel reports `LOCAL_ONLY_DETECTED` instead of inventing production support.
|
|
304
|
+
|
|
305
|
+
The following is a minimal human-authored configuration. npm visibility,
|
|
306
|
+
public-file boundaries, and remote targets must be explicit:
|
|
118
307
|
|
|
119
308
|
```yaml
|
|
120
309
|
apiVersion: release-skill/v1
|
|
@@ -162,6 +351,7 @@ releaseUnits:
|
|
|
162
351
|
# status: READY
|
|
163
352
|
production:
|
|
164
353
|
branchTemplate: release/{tag}
|
|
354
|
+
branchStrategy: create-release-branch
|
|
165
355
|
releaseTitleTemplate: "{unit} {version}"
|
|
166
356
|
releaseNotes: "Human-maintained release notes"
|
|
167
357
|
```
|
|
@@ -192,6 +382,58 @@ After `merge` or `adopt`, rebind `previousPublicBaseline` to the accepted
|
|
|
192
382
|
immutable `repo`/`ref`/`commit`, then run a new `prepare --online --production`,
|
|
193
383
|
review, and approval.
|
|
194
384
|
|
|
385
|
+
Choose a branch strategy that matches the real repository:
|
|
386
|
+
|
|
387
|
+
- `create-release-branch` creates an absent immutable release branch and stops
|
|
388
|
+
if the name already exists.
|
|
389
|
+
- `advance-existing-branch` creates a single-parent commit on the exact
|
|
390
|
+
`previousPublicBaseline` commit and permits only an ordinary fast-forward
|
|
391
|
+
push; concurrent drift requires human intervention.
|
|
392
|
+
- `initialize-default-branch` creates an absent standard branch under control.
|
|
393
|
+
Only explicit `setAsDefaultBranch` and `expectedCurrentDefaultBranch` values
|
|
394
|
+
add a separately approved, observed, and reconcilable default-branch action.
|
|
395
|
+
|
|
396
|
+
Minimal configurations for the three strategies are:
|
|
397
|
+
|
|
398
|
+
```yaml
|
|
399
|
+
# New immutable release branch; the target must not exist.
|
|
400
|
+
previousPublicBaseline: { mode: none } # only for a true first public release
|
|
401
|
+
production:
|
|
402
|
+
branchTemplate: release/{tag}
|
|
403
|
+
branchStrategy: create-release-branch
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
```yaml
|
|
407
|
+
# Advance main; the bound ref must be exactly the target branch.
|
|
408
|
+
previousPublicBaseline:
|
|
409
|
+
mode: bound
|
|
410
|
+
repo: owner/my-project
|
|
411
|
+
ref: refs/heads/main
|
|
412
|
+
commit: 0123456789abcdef0123456789abcdef01234567
|
|
413
|
+
production:
|
|
414
|
+
branchTemplate: main
|
|
415
|
+
branchStrategy: advance-existing-branch
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
```yaml
|
|
419
|
+
# One-time creation of an absent main and an explicit default-branch switch.
|
|
420
|
+
previousPublicBaseline:
|
|
421
|
+
mode: bound
|
|
422
|
+
repo: owner/my-project
|
|
423
|
+
ref: refs/heads/old-public-branch
|
|
424
|
+
commit: 0123456789abcdef0123456789abcdef01234567
|
|
425
|
+
production:
|
|
426
|
+
branchTemplate: main
|
|
427
|
+
branchStrategy: initialize-default-branch
|
|
428
|
+
setAsDefaultBranch: true
|
|
429
|
+
expectedCurrentDefaultBranch: old-public-branch
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
The latter two require `prepare --online --production`. If the observed branch,
|
|
433
|
+
commit, target absence, or current default branch differs, stop and update the
|
|
434
|
+
human-owned source/config only after reviewing the real remote state; never
|
|
435
|
+
force-push or weaken the baseline.
|
|
436
|
+
|
|
195
437
|
This is a mechanics-only local example, not a complete npm publication map.
|
|
196
438
|
Before a real release, enumerate every public runtime file, executable, type
|
|
197
439
|
declaration, image, and linked document. In a monorepo, set `source` to a path
|
|
@@ -206,48 +448,71 @@ causes baseline validation to stop.
|
|
|
206
448
|
|
|
207
449
|
### Main workflow
|
|
208
450
|
|
|
209
|
-
Run these steps in order. Steps 1–
|
|
210
|
-
steps
|
|
451
|
+
Run these steps in order. Steps 1–4 are safe default (read-only or local-only);
|
|
452
|
+
steps 5–9 are production publishing with explicit human gates.
|
|
211
453
|
|
|
212
454
|
```bash
|
|
213
|
-
#
|
|
214
|
-
CLI=(
|
|
455
|
+
# npm-installed CLI (recommended):
|
|
456
|
+
CLI=(release-skill)
|
|
215
457
|
PROJECT=/absolute/path/to/my-project
|
|
216
|
-
|
|
217
|
-
#
|
|
458
|
+
ACTOR=your-name
|
|
459
|
+
# Development fallback (source checkout):
|
|
460
|
+
# CLI=(node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs")
|
|
218
461
|
```
|
|
219
462
|
|
|
220
|
-
The
|
|
221
|
-
|
|
463
|
+
The npm-installed CLI is the supported user entry after v0.1.1 production
|
|
464
|
+
publication. The source checkout remains the development/contributor fallback.
|
|
222
465
|
|
|
223
466
|
1. **Environment check:**
|
|
224
467
|
```bash
|
|
225
468
|
"${CLI[@]}" help
|
|
226
469
|
```
|
|
227
|
-
2. **
|
|
470
|
+
2. **First-use setup (only when config is absent; read-only):**
|
|
471
|
+
```bash
|
|
472
|
+
"${CLI[@]}" setup --root "$PROJECT" --json
|
|
473
|
+
```
|
|
474
|
+
Follow the mechanical `compactSummary` and `recommendedAnswers` path above;
|
|
475
|
+
confirm the bound `setupDigest` once, and skip this step when configuration exists.
|
|
476
|
+
3. **Readiness assessment (read-only):**
|
|
228
477
|
```bash
|
|
229
478
|
"${CLI[@]}" assess --root "$PROJECT" --offline --json
|
|
230
479
|
```
|
|
231
|
-
|
|
480
|
+
4. **Local snapshot and plan freeze:**
|
|
232
481
|
```bash
|
|
233
|
-
"${CLI[@]}" prepare --root "$PROJECT" --offline
|
|
482
|
+
"${CLI[@]}" prepare --root "$PROJECT" --offline \
|
|
483
|
+
--acknowledge-hook-side-effects \
|
|
484
|
+
--acknowledge-gate-side-effects --json
|
|
234
485
|
```
|
|
235
|
-
|
|
486
|
+
Omit an acknowledgement only when that project config has no corresponding
|
|
487
|
+
hook or snapshot gate. Never grant either acknowledgement before reviewing
|
|
488
|
+
the configured executable, arguments, working directory, and side effects.
|
|
489
|
+
5. **Human review:** inspect the returned `planPath`, `externalActions`,
|
|
236
490
|
`units[].targetVersion`, and `planDigest`. Each unit's snapshot is under
|
|
237
|
-
`<evidenceDir>/snapshots/<unit-id>/`. The
|
|
238
|
-
data under `.release-skill
|
|
239
|
-
|
|
491
|
+
`<evidenceDir>/snapshots/<unit-id>/`. The release-skill pipeline writes its
|
|
492
|
+
own data under `.release-skill/`; acknowledged project hooks and gates are
|
|
493
|
+
unsandboxed processes and may write elsewhere or access the network.
|
|
494
|
+
6. **Production plan freeze:**
|
|
240
495
|
```bash
|
|
241
|
-
"${CLI[@]}" prepare --root "$PROJECT" --online --production
|
|
496
|
+
PRODUCTION_JSON=$("${CLI[@]}" prepare --root "$PROJECT" --online --production \
|
|
497
|
+
--acknowledge-hook-side-effects \
|
|
498
|
+
--acknowledge-gate-side-effects --json)
|
|
499
|
+
printf '%s\n' "$PRODUCTION_JSON" | jq .
|
|
500
|
+
PLAN_PATH=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planPath')
|
|
501
|
+
PLAN_DIGEST=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planDigest')
|
|
242
502
|
```
|
|
503
|
+
As above, omit only acknowledgements that are not required by the project
|
|
504
|
+
config, and review every configured process before granting them.
|
|
243
505
|
Review the new plan's externalActions, npm policy, branch/tag, and frozen
|
|
244
506
|
digests. `prepare --json` returns the immutable production authority as
|
|
245
507
|
`<project>/.release-skill/plans/<planDigest>.json`; always carry that returned
|
|
246
508
|
`planPath` forward. `.release-skill/release-plan.json` is only a mutable
|
|
247
509
|
convenience alias and must not be passed to production approve/publish/reconcile.
|
|
248
|
-
|
|
510
|
+
7. **Approval:**
|
|
249
511
|
```bash
|
|
250
|
-
"${CLI[@]}" approve --plan
|
|
512
|
+
APPROVAL_JSON=$("${CLI[@]}" approve --plan "$PLAN_PATH" \
|
|
513
|
+
--digest "$PLAN_DIGEST" --actor "$ACTOR" --json)
|
|
514
|
+
printf '%s\n' "$APPROVAL_JSON" | jq .
|
|
515
|
+
APPROVAL_PATH=$(printf '%s\n' "$APPROVAL_JSON" | jq -r '.approvalPath')
|
|
251
516
|
```
|
|
252
517
|
Returns the immutable production authority as `approvalPath` at
|
|
253
518
|
`<project>/.release-skill/approvals/<planDigest>/<approvalDigest>.json`.
|
|
@@ -257,18 +522,28 @@ verified; after that, the installed npm entry is the supported user default.
|
|
|
257
522
|
hours; a PARTIAL recovery may create a new approval for the same plan while
|
|
258
523
|
preserving every earlier approval byte-for-byte. Use the returned
|
|
259
524
|
`approvalPath` and `expiresAt` as authority.
|
|
260
|
-
|
|
525
|
+
8. **Publish (remote writes start here):**
|
|
261
526
|
```bash
|
|
262
|
-
"${CLI[@]}" publish --root "$PROJECT" \
|
|
263
|
-
--plan
|
|
264
|
-
--confirm-production
|
|
527
|
+
PUBLISH_JSON=$("${CLI[@]}" publish --root "$PROJECT" \
|
|
528
|
+
--plan "$PLAN_PATH" --approval "$APPROVAL_PATH" \
|
|
529
|
+
--confirm-production "$PLAN_DIGEST" --json)
|
|
530
|
+
printf '%s\n' "$PUBLISH_JSON" | jq .
|
|
531
|
+
PUBLISH_RUN_PATH=$(printf '%s\n' "$PUBLISH_JSON" | jq -r '.runPath')
|
|
265
532
|
```
|
|
266
533
|
Save the returned `runPath`. `PUBLISHED` is **not** the terminal state.
|
|
267
|
-
|
|
534
|
+
9. **Verify (consumer install check):**
|
|
268
535
|
```bash
|
|
269
536
|
"${CLI[@]}" verify --root "$PROJECT" \
|
|
270
|
-
--plan
|
|
537
|
+
--plan "$PLAN_PATH" --run "$PUBLISH_RUN_PATH" \
|
|
538
|
+
--acknowledge-gate-side-effects --json
|
|
271
539
|
```
|
|
540
|
+
Omit the acknowledgement only when the plan has neither consumer gates nor
|
|
541
|
+
a configured npm `smokeBin`. Both execute installed project code without an
|
|
542
|
+
OS or network sandbox.
|
|
543
|
+
|
|
544
|
+
The handoff example requires `jq`. Without it, copy the same four returned JSON
|
|
545
|
+
fields exactly; do not pass the angle-bracket labels shown elsewhere as shell
|
|
546
|
+
syntax.
|
|
272
547
|
|
|
273
548
|
Production prepare seals a standalone Git commit/tree for every public snapshot
|
|
274
549
|
and creates a fixed tarball for every npm unit. Publish globally preflights all
|
|
@@ -411,17 +686,24 @@ Instead, use `reconcile` to inspect actual remote state, skip already-consistent
|
|
|
411
686
|
steps, and safely retry incomplete actions:
|
|
412
687
|
|
|
413
688
|
```bash
|
|
414
|
-
"${CLI[@]}" reconcile --root "$PROJECT" \
|
|
415
|
-
--run
|
|
416
|
-
--plan
|
|
417
|
-
--approval
|
|
418
|
-
--confirm-production
|
|
419
|
-
|
|
689
|
+
RECONCILE_JSON=$("${CLI[@]}" reconcile --root "$PROJECT" \
|
|
690
|
+
--run "$PUBLISH_RUN_PATH" \
|
|
691
|
+
--plan "$PLAN_PATH" \
|
|
692
|
+
--approval "$APPROVAL_PATH" \
|
|
693
|
+
--confirm-production "$PLAN_DIGEST" --json)
|
|
694
|
+
printf '%s\n' "$RECONCILE_JSON" | jq .
|
|
695
|
+
RECONCILE_RUN_PATH=$(printf '%s\n' "$RECONCILE_JSON" | jq -r '.runPath')
|
|
420
696
|
# Save reconcile's new runPath, then perform the fresh install verification.
|
|
421
697
|
"${CLI[@]}" verify --root "$PROJECT" \
|
|
422
|
-
--plan
|
|
698
|
+
--plan "$PLAN_PATH" --run "$RECONCILE_RUN_PATH" \
|
|
699
|
+
--acknowledge-gate-side-effects --json
|
|
423
700
|
```
|
|
424
701
|
|
|
702
|
+
Omit the verify acknowledgement only when the frozen plan has neither consumer
|
|
703
|
+
gates nor an npm `smokeBin`. The variables above are the exact values captured
|
|
704
|
+
by the main flow; if approval expired during recovery, create a fresh approval
|
|
705
|
+
for the same immutable plan and replace `APPROVAL_PATH` before reconcile.
|
|
706
|
+
|
|
425
707
|
`reconcile` queries the actual remote state (Git refs, npm version, GitHub
|
|
426
708
|
Release, marketplace install), skips any step whose evidence already matches
|
|
427
709
|
the frozen plan, and retries only safe and incomplete steps. Remote conflicts
|
|
@@ -435,6 +717,10 @@ Successful reconcile returns `PUBLISHED`, not `VERIFIED`; only the fresh
|
|
|
435
717
|
- validates project configuration and release units;
|
|
436
718
|
- reports readiness without changing the project during `assess`;
|
|
437
719
|
- copies configured public files into an isolated snapshot;
|
|
720
|
+
- discovers first-use candidates read-only and creates a config only once after
|
|
721
|
+
exact `setupDigest` confirmation;
|
|
722
|
+
- runs human-selected project gates in frozen-snapshot copies and exact
|
|
723
|
+
consumer installation roots;
|
|
438
724
|
- checks required files, path safety, exact bytes/modes, and obvious leaks;
|
|
439
725
|
- records Git/workspace identity and freezes a digest-bound release plan;
|
|
440
726
|
- binds approval to the plan digest, expiry, and explicit action allowlist;
|
|
@@ -447,6 +733,52 @@ Successful reconcile returns `PUBLISHED`, not `VERIFIED`; only the fresh
|
|
|
447
733
|
- stops subsequent checkpoints on failure and writes a separate run record
|
|
448
734
|
without mutating the frozen plan or undoing successful remote actions.
|
|
449
735
|
|
|
736
|
+
## Project-specific verification: hooks and gates
|
|
737
|
+
|
|
738
|
+
`hooks.docs/build/test/typecheck/lint` run before the snapshot is frozen. Use
|
|
739
|
+
them only for work that genuinely needs the parent workspace or generates
|
|
740
|
+
source files. They can modify files or access the network, so prepare requires
|
|
741
|
+
`--acknowledge-hook-side-effects`.
|
|
742
|
+
|
|
743
|
+
`verificationGates` are the controlled extension point for release calibration:
|
|
744
|
+
|
|
745
|
+
```yaml
|
|
746
|
+
verificationGates:
|
|
747
|
+
- id: package-contract
|
|
748
|
+
phase: snapshot-verify
|
|
749
|
+
scope: { unit: my-project }
|
|
750
|
+
command:
|
|
751
|
+
- node
|
|
752
|
+
- -e
|
|
753
|
+
- "const p=require('./package.json'); if (!p.name) process.exit(1)"
|
|
754
|
+
cwd: .
|
|
755
|
+
timeoutMs: 120000
|
|
756
|
+
envAllowlist: [CI]
|
|
757
|
+
- id: installed-help
|
|
758
|
+
phase: consumer-verify
|
|
759
|
+
scope: { unit: my-project, distribution: npm }
|
|
760
|
+
command: [node, scripts/check-installed-help.mjs]
|
|
761
|
+
cwd: .
|
|
762
|
+
timeoutMs: 30000
|
|
763
|
+
envAllowlist: []
|
|
764
|
+
expectedJson: { status: READY }
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
The snapshot example is deliberately self-contained and reads only a mapped
|
|
768
|
+
public file. Any replacement script and every dependency it needs must exist
|
|
769
|
+
in the frozen public snapshot. The consumer script must likewise be present in
|
|
770
|
+
the exact installed distribution; gates cannot borrow tests, development
|
|
771
|
+
dependencies, or `node_modules` from the parent workspace.
|
|
772
|
+
|
|
773
|
+
`snapshot-verify` runs in a disposable writable copy of the frozen public
|
|
774
|
+
snapshot. `consumer-verify` runs from an exact isolated npm/Claude/Codex install
|
|
775
|
+
root. Both use executable arrays instead of shell strings; definitions and
|
|
776
|
+
results enter digest-bound evidence, and prepare/verify require
|
|
777
|
+
`--acknowledge-gate-side-effects`. Gates are still project processes without a
|
|
778
|
+
network sandbox, so release-skill cannot promise that they will not write files
|
|
779
|
+
or access the network. Push, tag, default-branch changes, GitHub Releases, and
|
|
780
|
+
npm publish may never be hooks/gates; they remain controlled plan actions.
|
|
781
|
+
|
|
450
782
|
## What it does not do yet
|
|
451
783
|
|
|
452
784
|
<!-- release-skill:capability:unsupported-scope -->
|
|
@@ -455,17 +787,22 @@ Successful reconcile returns `PUBLISHED`, not `VERIFIED`; only the fresh
|
|
|
455
787
|
- no claim that a real production canary has run for marketplace verification;
|
|
456
788
|
- `prepare --online` observes previous public baselines (bound mode) and defers
|
|
457
789
|
remote uniqueness checks to publish global preflight;
|
|
458
|
-
- no
|
|
790
|
+
- no overwrite of branches/tags/releases or npm unpublish; create-only refs use
|
|
791
|
+
`--force-with-lease=<ref>:` solely as an atomic compare-and-set assertion that
|
|
792
|
+
the ref is absent, while existing branches use an ordinary non-force push;
|
|
459
793
|
- no promise of Windows or broad multi-platform native write support;
|
|
460
794
|
- no hidden commit, push, tag, release, or package publication.
|
|
461
795
|
|
|
462
796
|
### Write Safety
|
|
463
797
|
|
|
464
|
-
`
|
|
798
|
+
`setup` is read-only by default and may create a config only once after exact
|
|
799
|
+
digest confirmation. `assess` is read-only unless an explicit report output is requested. `prepare`
|
|
465
800
|
writes local files under `.release-skill/`; it does not write project source
|
|
466
801
|
files or remote services. If hooks are configured, they are arbitrary local
|
|
467
802
|
processes and require `--acknowledge-hook-side-effects`; hooks may have their
|
|
468
|
-
own filesystem or network side effects.
|
|
803
|
+
own filesystem or network side effects. Gates are also project processes and
|
|
804
|
+
require `--acknowledge-gate-side-effects`; they may have the same side effects.
|
|
805
|
+
`publish` is the production write entry
|
|
469
806
|
and requires both approval and the current plan digest. Omit hooks and use local
|
|
470
807
|
sandbox targets for the smallest safe rehearsal.
|
|
471
808
|
|
|
@@ -473,12 +810,18 @@ sandbox targets for the smallest safe rehearsal.
|
|
|
473
810
|
|
|
474
811
|
| Result | What to do |
|
|
475
812
|
|---|---|
|
|
813
|
+
| `NEEDS_INPUT` | Complete setup's repository, tag, channel, baseline, and gate decisions. |
|
|
814
|
+
| `LOCAL_ONLY_DETECTED` | Establish a remote channel or keep only a local configuration design; do not claim production readiness. |
|
|
815
|
+
| `SETUP_DIGEST_MISMATCH` | Facts or answers changed; rerun dry-run, review, and confirm the new digest. |
|
|
816
|
+
| `CONFIG_EXISTS` | Setup never overwrites the existing config; assess it and edit incrementally. |
|
|
817
|
+
| `SAFE_WRITE_UNAVAILABLE` | Automatic create-once setup is unsupported on this platform; keep the dry-run report and create the reviewed config manually without overwriting an existing file. |
|
|
476
818
|
| `CONFIG_INVALID` | Correct `.release-skill/project.yaml`, then rerun `assess`. |
|
|
477
819
|
| `PUBLIC_FILE_MISSING` | Add or correct the configured public file. |
|
|
478
820
|
| `FORBIDDEN_CONTENT_DETECTED` | Remove the leaked/private content, then prepare again. |
|
|
479
821
|
| `SNAPSHOT_FIDELITY_FAILED` | Inspect the source/snapshot path and rerun `prepare`. |
|
|
480
822
|
| `BASELINE_CHANGED` | Keep the human edit, then prepare, review, and approve again. |
|
|
481
|
-
| `GATE_FAILED` |
|
|
823
|
+
| `GATE_FAILED` during `prepare` | Fix the snapshot gate or frozen public artifact, then run a new `prepare`; the failed plan cannot be approved. |
|
|
824
|
+
| `GATE_FAILED` during `verify` | If the consumer environment failed, repair it and rerun `verify` from the same `PUBLISHED` run. If the published artifact is defective, release a new patch version; never overwrite it. |
|
|
482
825
|
| `PARTIAL` | Do not restart or delete remote state; review the returned `runPath` and run `reconcile` (see above). |
|
|
483
826
|
| `PUBLISHED` | Run `verify --plan <planPath> --run <publishRunPath>`; this is not terminal success. |
|
|
484
827
|
| `VERIFIED` | Remote state, exact npm install, and configured plugin consumer installs all matched the frozen plan. |
|
|
@@ -486,15 +829,16 @@ sandbox targets for the smallest safe rehearsal.
|
|
|
486
829
|
## Skills
|
|
487
830
|
|
|
488
831
|
- `release-help`: environment check and next-step guidance.
|
|
832
|
+
- `release-setup`: read-only discovery, human calibration, and create-once first-use configuration.
|
|
489
833
|
- `release-assess`: read-only release readiness report.
|
|
490
834
|
- `release-prepare`: local snapshot and reviewable release plan.
|
|
491
835
|
- `release-publish`: approved, digest-confirmed frozen GitHub+npm publishing.
|
|
492
836
|
- `release-reconcile`: evidence-based PARTIAL recovery with human intervention on conflicts.
|
|
493
837
|
- `release-verify`: post-publish verification; only `VERIFIED` is the happy end.
|
|
494
838
|
|
|
495
|
-
Conflicts still default to human intervention.
|
|
496
|
-
the
|
|
497
|
-
|
|
839
|
+
Conflicts still default to human intervention. The npm-installed `release-skill`
|
|
840
|
+
CLI is the supported user entry after v0.1.1 production publication; source
|
|
841
|
+
checkout remains the development/contributor fallback.
|
|
498
842
|
|
|
499
843
|
## License
|
|
500
844
|
|