@timurproko/a1 0.2.1 → 0.2.2

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.
Files changed (67) hide show
  1. package/README.md +16 -8
  2. package/bin/pinned-pi-public.js +11 -4
  3. package/dist/app/session-shell/index.d.ts +1 -1
  4. package/dist/app/session-shell/paste-executor.js +6 -1
  5. package/dist/app/session-shell/prompt-chips.d.ts +8 -0
  6. package/dist/app/session-shell/prompt-chips.js +58 -13
  7. package/dist/app/session-shell/session-shell-root.d.ts +21 -3
  8. package/dist/app/session-shell/session-shell-root.js +110 -17
  9. package/dist/app/session-shell/session-shell.d.ts +1 -1
  10. package/dist/app/session-shell/session-shell.js +76 -31
  11. package/dist/app/session-shell/session-viewport-controller.d.ts +13 -0
  12. package/dist/app/session-shell/session-viewport-controller.js +28 -1
  13. package/dist/cli/version-stats.js +4 -7
  14. package/dist/composition/owned-ui.d.ts +7 -0
  15. package/dist/composition/owned-ui.js +71 -3
  16. package/dist/contracts/owned-ui/image-attachments.d.ts +7 -4
  17. package/dist/contracts/owned-ui/image-attachments.js +20 -7
  18. package/dist/contracts/owned-ui/index.d.ts +1 -1
  19. package/dist/contracts/owned-ui/index.js +1 -1
  20. package/dist/contracts/owned-ui/prompt-chips.d.ts +2 -2
  21. package/dist/contracts/owned-ui/prompt-chips.js +9 -6
  22. package/dist/features/owned-ui/project-trust-prompt.js +39 -3
  23. package/dist/features/owned-ui/release-note-state.d.ts +13 -0
  24. package/dist/features/owned-ui/release-note-state.js +109 -0
  25. package/dist/features/owned-ui/release-notes.d.ts +10 -0
  26. package/dist/features/owned-ui/release-notes.js +73 -0
  27. package/dist/features/owned-ui/resources/release-notes.json +9 -0
  28. package/dist/foundation/release/latest-release.d.ts +55 -0
  29. package/dist/foundation/release/latest-release.js +166 -0
  30. package/dist/foundation/release/update.js +9 -0
  31. package/dist/integrations/pi/components/index.d.ts +1 -1
  32. package/dist/integrations/pi/components/index.js +1 -1
  33. package/dist/integrations/pi/components/prompt-chip-presentation.d.ts +3 -0
  34. package/dist/integrations/pi/components/prompt-chip-presentation.js +14 -0
  35. package/dist/integrations/pi/components/shell-footer-status.js +30 -9
  36. package/dist/integrations/pi/components/shell-presenters-info.d.ts +36 -0
  37. package/dist/integrations/pi/components/shell-presenters-info.js +77 -1
  38. package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +0 -6
  39. package/dist/integrations/pi/components/shell-presenters-transcript.js +0 -19
  40. package/dist/integrations/pi/components/shell-shared-facade.d.ts +2 -1
  41. package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +1 -1
  42. package/dist/integrations/pi/components/submitted-prompt-adapter.js +13 -4
  43. package/dist/integrations/pi/engine/adapter.d.ts +12 -0
  44. package/dist/integrations/pi/engine/adapter.js +13 -0
  45. package/dist/integrations/pi/engine/session-runtime.d.ts +1 -0
  46. package/dist/integrations/pi/engine/session-runtime.js +2 -1
  47. package/dist/native/darwin-arm64/manifest.json +1 -1
  48. package/dist/native/linux-x64/manifest.json +1 -1
  49. package/dist/native/win32-x64/manifest.json +2 -2
  50. package/dist/native/win32-x64/process-guardian.exe +0 -0
  51. package/dist/product-identity.d.ts +1 -1
  52. package/dist/product-identity.js +1 -1
  53. package/dist/product-identity.json +1 -0
  54. package/dist/ui/settings/declarations.d.ts +25 -1
  55. package/dist/ui/settings/declarations.js +19 -1
  56. package/dist/ui/settings/migrations.js +14 -0
  57. package/docs/architecture/internal-naming.md +2 -2
  58. package/docs/architecture/resource-and-data-policy.md +11 -0
  59. package/docs/architecture/toolchain.md +1 -1
  60. package/docs/architecture/ui-reference-provenance.md +1 -0
  61. package/docs/ci-release-runbook.md +154 -70
  62. package/docs/local-worktree-cleanup.md +21 -4
  63. package/docs/manual-owned-ui-checkpoint.md +1 -0
  64. package/docs/openspec-archive-automation.md +1 -1
  65. package/docs/releases/0.2.2.md +47 -0
  66. package/docs/validation.md +13 -3
  67. package/package.json +3 -3
@@ -6,11 +6,32 @@ GitHub Actions is the only automation platform. Three refs are protected:
6
6
  | --- | --- | --- |
7
7
  | `develop` | `Development validation required` on every pull request | `.github/workflows/ci.yml` |
8
8
  | `master` | cannot be deleted or force-updated | stable publication |
9
- | `refs/tags/v*` | cannot be deleted or moved | stable publication |
9
+ | `refs/tags/v*` | cannot be moved; only the release-automation App may delete an unconsumed tag | native **Publish release** |
10
+
11
+ `.github/workflows/publish.yml` is the only npm publisher. A push publishes neither
12
+ channel. It starts at `03:17 UTC` for nightly development verification or as a
13
+ trusted reusable workflow: `npm run develop` dispatches `develop.yml`, the stable
14
+ release command dispatches `release-candidate.yml` to validate the prepared source
15
+ without publishing, and native **Publish release** on the prepared draft runs
16
+ `finalize-release.yml`, which publishes.
17
+ The maintainer never opens Actions or re-enters the version.
18
+
19
+ npm trusted publishing binds authorization to the exact workflow filename of the
20
+ *calling* workflow, not the reusable `publish.yml` it calls. Both `@timurproko/a1` and
21
+ `@timurproko/a1-install` must therefore list each caller as a trusted publisher on
22
+ npmjs.com, with repository `timurproko/a1` and environment `npm-publish`:
23
+
24
+ | Trusted publisher workflow | Publishes |
25
+ | --- | --- |
26
+ | `finalize-release.yml` | stable `latest` after native **Publish release** |
27
+ | `develop.yml` | numbered previews from `npm run develop` |
28
+ | `publish.yml` | nightly `next` from its own schedule |
10
29
 
11
- `.github/workflows/release.yml` is the only publisher. A push publishes neither
12
- channel. The workflow starts at `03:17 UTC` for nightly development verification,
13
- or by explicit dispatch from `npm run develop` or `npm run release`.
30
+ The retired `release.yml` entry grants nothing and should be removed. No npm token is
31
+ used: before either upload, the publish job requires npm >= 11.5.1 and completes the
32
+ trusted-publishing token exchange for both packages. A refusal fails there, before
33
+ anything is uploaded, and names the workflow and environment to register. When a
34
+ caller's path changes, update both packages before the next publication through it.
14
35
 
15
36
  `.github/workflows/documentation-auto-merge.yml` is the only pull-request
16
37
  auto-merge authority. It runs trusted policy from `develop`; it never checks out or
@@ -26,6 +47,17 @@ repository topic ref whose live object still equals the merged pull request head
26
47
  An absent ref is success; fork, unmerged, advanced, protected, default, release-owned,
27
48
  or malformed refs are preserved and reported.
28
49
 
50
+ `.github/workflows/ready-pull-request-refresh.yml` keeps ready pull requests current
51
+ after `develop` advances. It runs trusted default-branch policy after a merged close
52
+ event and after every Documentation auto-merge completion, because merges authored with
53
+ `GITHUB_TOKEN` emit no close event. One serialized, non-cancelling pass re-reads each
54
+ open pull request targeting `develop` and the current target, then calls GitHub's
55
+ update-branch operation with the exact head it just compared. It uses a short-lived
56
+ App token scoped to contents and pull requests so the new head emits `synchronize` and
57
+ ordinary finalization and CI run; it never falls back to `GITHUB_TOKEN`. Drafts, forks,
58
+ other bases, and current heads are skipped; a moved head is deferred and a conflict is
59
+ reported for manual repair. It never merges, arms auto-merge, or dispatches checks.
60
+
29
61
  `config/github-repository-governance.json` is the reviewed policy for repository
30
62
  settings, Actions defaults, security capabilities, environments, complete rulesets,
31
63
  protected refs, and workflow authority. Inspection is read-only by default:
@@ -49,10 +81,12 @@ effect of stable publication, not a trigger.
49
81
  | Pull request into `develop` | Bounded PR-cadence validation; changed/new source documentation is checked once, rendering runs as `none`, `smoke`, or `full`, exhaustive owners are reported as deferred, and only a trusted-CI-created failed-Full-regression repair adds PR-attached complete regression |
50
82
  | `npm run develop` | Preview package gates on Windows, Linux, and macOS; an existing numbered preview is an early successful no-op |
51
83
  | Nightly at `03:17 UTC` | One full documentation review plus the complete non-physical suite on Windows, Linux, and macOS, every night |
52
- | `npm run release -- ...` | Stamps the requested stable version on the open `develop` source, runs the complete exact-byte stable gates, then npm `latest`, tag, GitHub Release, and `master`; one reopening PR follows |
84
+ | `npm run release -- ...` | Creates an editable source-bound draft (or refreshes the existing draft of that version bound to an older `develop`, regenerating its notes and removing duplicate drafts of that version), starts the complete stable suite on that source in `.github/workflows/release-candidate.yml`, prints its run link, waits, and prints the draft edit link only after validation passes |
85
+ | Native **Publish release** on the prepared draft | GitHub creates the source-bound tag; `.github/workflows/finalize-release.yml` requires the successful candidate run, adopts the package pair it validated (replacing only the packaged release-note resource when the note was edited), proves npm trust, publishes both packages to npm `latest`, and proposes one manually merged reopening-and-note PR; a failure before npm returns the Release to draft |
86
+ | `.github/workflows/release-tag-cleanup.yml` | When a stable Release is deleted, or on dispatch with a version (`gh workflow run release-tag-cleanup.yml -f version=X.Y.Z`): the release-automation App deletes the leftover `vX.Y.Z` tag only while no Release uses it and npm serves neither package; a published version's tag is permanent |
53
87
  | `.github/workflows/full-regression.yml` | Additional on-demand complete regression without publication authority |
54
88
  | `.github/workflows/pi-upstream-sync.yml` | Nightly at `03:23 UTC`: when npm publishes a newer Pi than the pin that no closed proposal skipped, proposes the upgrade as a draft pull request with the vendored copies that follow upstream merged, the kept copies reported with their upstream delta, the ledger, headers, inventories, public API and feature baselines, startup graph, and parity evidence regenerated, and every gate verdict (passed, failed, or blocked by conflict markers) and review item in the body; never merges and never replaces a proposal a human has continued |
55
- | `.github/workflows/nightly-regression-triage.yml` | After every completed `Full regression` run on `develop` or scheduled `Release` validation: judges the startup budget across the three most recent runs and, after a failure or a persistent overrun, opens `fix/nightly-regression-<date>` as a draft pull request carrying the failed commands per lane, their tests, a bounded log excerpt, the `develop` commits since the last green run, and an OpenSpec fix scaffold, or refreshes the open candidate with the same failed scope set; re-runs nothing, never writes `develop`, never merges |
89
+ | `.github/workflows/nightly-regression-triage.yml` | After every completed `Full regression` run on `develop` or scheduled `Publish` validation: judges the startup budget across the three most recent runs and, after a failure or a persistent overrun, opens `fix/nightly-regression-<date>` as a draft pull request carrying the failed commands per lane, their tests, a bounded log excerpt, the `develop` commits since the last green run, and an OpenSpec fix scaffold, or refreshes the open candidate with the same failed scope set; re-runs nothing, never writes `develop`, never merges |
56
90
 
57
91
  ## Impact-aware development validation
58
92
 
@@ -60,7 +94,7 @@ effect of stable publication, not a trigger.
60
94
 
61
95
  Ordinary type, architecture, unit/contract, and dist checks always run for code changes. Changed-file documentation and rendering run as independent parallel jobs. Rendered shell/component changes select `smoke`; viewport, scheduler, terminal adapter, evidence harness, package identity, and selector changes select `full`; unrelated changes select `none`. The aggregate accepts a skipped modular job only when the current selector requested the skip.
62
96
 
63
- Integration owners declare one cadence in `config/integration-owners.json`. Impact mode selects affected `pull-request` owners: a changed production path selects its coarse owner, a changed test selects its owner, and a changed file under `test/support/` or `test/fixtures/` selects the owners of the retained tests that import it directly or through other support files (the selection lists those tests as its `shared-support` reason). A support file that no retained test imports, or a test tree the scanner cannot read, falls back to every owner the shared rule declares and records `shared-support-declared`; an invalidator, unknown operational path, or manual Development dispatch selects every `pull-request` owner. An implementation-bound PR body does not force conservative selection; it only removes the documentation-only and version-only shortcuts. The modular matrix itself is derived from the selection by `scripts/release/validation-matrix.mjs`, so inactive jobs are not scheduled at all rather than checking out and exiting early. `exhaustive` owners are never silently skipped or reported as passed: impact and aggregate evidence list them as cadence-deferred, and malformed cadence blocks selection. Full regression and nightly/stable release still execute both cadence classes. PR-attached Full regression is selected only when base policy verifies an `openspec-ci` App-authored candidate, its generated repair identity, and every qualifying failed Full regression source field in `regression-provenance.json` against GitHub's read-only workflow-run record. Release/publishing, shared-support, prerequisite, build, validation-authority, unknown-path, label, Release-only repair, and successful-run persistent-overrun changes retain bounded ordinary validation. Planning-only generated repair drafts remain exempt; eligible implementation drafts receive native lane feedback without integration authority.
97
+ Integration owners declare one cadence in `config/integration-owners.json`. Impact mode selects affected `pull-request` owners: a changed production path selects its coarse owner, a changed test selects its owner, and a changed file under `test/support/` or `test/fixtures/` selects the owners of the retained tests that import it directly or through other support files (the selection lists those tests as its `shared-support` reason). A support file that no retained test imports, or a test tree the scanner cannot read, falls back to every owner the shared rule declares and records `shared-support-declared`; an invalidator, unknown operational path, or manual Development dispatch selects every `pull-request` owner. An implementation-bound PR body does not force conservative selection; it only removes the documentation-only and version-only shortcuts. The modular matrix itself is derived from the selection by `scripts/release/validation-matrix.mjs`, so inactive jobs are not scheduled at all rather than checking out and exiting early. `exhaustive` owners are never silently skipped or reported as passed: impact and aggregate evidence list them as cadence-deferred, and malformed cadence blocks selection. Full regression and nightly/stable release still execute both cadence classes. PR-attached Full regression is selected only when base policy verifies an `openspec-ci` App-authored candidate, its generated repair identity, and every qualifying failed Full regression source field in `regression-provenance.json` against GitHub's read-only workflow-run record. Release/publishing, shared-support, prerequisite, build, validation-authority, unknown-path, label, Publish-only repair, and successful-run persistent-overrun changes retain bounded ordinary validation. Planning-only generated repair drafts remain exempt; eligible implementation drafts receive native lane feedback without integration authority.
64
98
 
65
99
  The real three-release `update-predecessor` scenario is exhaustive because four fresh npm installations dominated recent PR critical paths, and `update-performance` is exhaustive because its assertion is wall-clock timing on a shared runner; the update path's deterministic contracts stay on pull requests through `pi-release-resume` and `package-contracts`. PR validation retains deterministic predecessor command, lifecycle, fault, fixture, materialization, warmup, package, and update contracts. This permits a real published-history incompatibility or update slowdown to reach `develop` before the next exhaustive run detects it. `.github/workflows/full-regression.yml` runs every night at `02:47 UTC` against the `develop` tip with every owner and enforced budgets, independent of publication, so such a regression shows as a failed Full regression run the next morning; nightly publication's own complete validation still blocks publication. For diagnosis on any other candidate, dispatch standalone Full regression; labels and high-risk release/update impact do not add it to PR checks or change owner cadence.
66
100
 
@@ -110,12 +144,12 @@ node scripts/release/report-resource-sensitive-validation.mjs --repeats 3 --outp
110
144
 
111
145
  For applicable code changes, it requires the dedicated Defender-enabled exact-package startup lane on Windows Node 22. Development validation (including manual dispatch) does not schedule a Windows Node 24 startup lane. The Node 22 lane retains the complete package-install, image preparation/package, and durable-history checks plus startup evidence artifacts. A missing, cancelled, failed, or unexpectedly skipped required startup result still blocks the aggregate; documentation-only, version-only, and draft exemptions are unchanged.
112
146
 
113
- | Startup runtime | Development validation (PR or manual) | Development preview (`npm run develop`) | Nightly and stable publication | Manual Full regression |
147
+ | Startup runtime | Development validation (PR or manual) | Development preview (`npm run develop`) | Nightly publication and stable candidate validation | Manual Full regression |
114
148
  | --- | --- | --- | --- | --- |
115
149
  | Windows Node 22 | Required for applicable changes | Not scheduled | Retained | Retained |
116
150
  | Windows Node 24 | Not scheduled | Retained | Retained | Retained |
117
151
 
118
- Each selected startup lane runs the package-install scenarios once: a failed budget remains failed and is never retried to obtain a warmed result. The budgets are the ones the `a1-shell` capability declares (2 seconds after an update and on a warm launch, 2.5 seconds with no live supervisor); development validation, development previews, nightly publication, and Full regression record an overrun as a warning and are judged by the three-run persistent-overrun verdict, while stable publication fails on it (see `STARTUP_BUDGET_ENFORCEMENT` in [validation](validation.md)). The publication lane set comes from `scripts/release/publication-validation-matrix.mjs`: a numbered preview validates on the Windows, Linux, and macOS Node 24 lanes, and nightly covers the same head on Windows Node 22 within a day. Node 24 runtime support, other PR jobs, Defender, and publication gates are unchanged. Full validation retains every deferred startup, image, and history test through its existing suite owners.
152
+ Each selected startup lane runs the package-install scenarios once: a failed budget remains failed and is never retried to obtain a warmed result. The budgets are the ones the `a1-shell` capability declares (2 seconds after an update and on a warm launch, 2.5 seconds with no live supervisor); development validation, development previews, nightly publication, and Full regression record an overrun as a warning and are judged by the three-run persistent-overrun verdict, while stable candidate validation fails on it (see `STARTUP_BUDGET_ENFORCEMENT` in [validation](validation.md)). The publication lane set comes from `scripts/release/publication-validation-matrix.mjs`: a numbered preview validates on the Windows, Linux, and macOS Node 24 lanes, and nightly covers the same head on Windows Node 22 within a day. Node 24 runtime support, other PR jobs, Defender, and publication gates are unchanged. Full validation retains every deferred startup, image, and history test through its existing suite owners.
119
153
 
120
154
  The trade-off is delayed detection: a Node-24-specific regression can reach `develop` before nightly catches it, and the same is true for a real published-predecessor regression. A green bounded PR check does not certify Node 24 or real historical predecessor execution, and nightly failure still blocks its publication. For an unselected candidate or diagnosis, explicitly request the non-publishing standalone Full regression workflow for the desired branch or tag:
121
155
 
@@ -131,7 +165,8 @@ branch protection prevents integration until `Development validation required`
131
165
  succeeds. If validation finishes before auto-merge can be armed and GitHub already
132
166
  reports the pull request clean, the reconciler squash-merges only the validated head
133
167
  SHA. Every current and renamed-from path must be under `openspec/**`, under
134
- `docs/**`, or exactly the root `README.md`. Eligible pull requests must use a
168
+ `docs/**` other than `docs/releases/**`, or exactly the root `README.md`. Release
169
+ history always requires manual integration. Eligible pull requests must use a
135
170
  non-draft branch in this repository and target `develop`. Implementation-associated PRs and newly introduced active OpenSpec changes are held for manual integration even when their diff is documentation-only. Body edits trigger reconciliation; removing a marker cannot bypass the base/head tree check. Standalone existing-change revisions and archive moves remain eligible.
136
171
 
137
172
  The exact allowlist covers maintained OpenSpec, architecture, feature, manual,
@@ -186,9 +221,9 @@ internal `next` dist-tag and never moves `latest`.
186
221
  Users install previews with public `develop` terminology:
187
222
 
188
223
  ```sh
189
- npx -y @timurproko/a1-install --develop
190
- npx -y @timurproko/a1-install --develop 107
191
- npx -y @timurproko/a1-install --develop 0.1.8-dev.107
224
+ npm x -y -- @timurproko/a1-install --develop
225
+ npm x -y -- @timurproko/a1-install --develop 107
226
+ npm x -y -- @timurproko/a1-install --develop 0.1.8-dev.107
192
227
  a1 update --develop # update an existing installation
193
228
  a1 update --develop 107 # numbered preview
194
229
  a1 update --develop 0.1.8-dev.107 # exact full preview version
@@ -206,76 +241,121 @@ From the repository root on clean `develop` matching `origin/develop`:
206
241
  npm run release -- patch # 0.1.8-dev -> 0.1.8
207
242
  npm run release -- minor # 0.1.8-dev -> 0.2.0
208
243
  npm run release -- major # 0.1.8-dev -> 1.0.0
209
- npm run release -- 0.4.0 # exact stable target
244
+ npm run release -- 0.4.0 # prepare an exact stable target
210
245
  ```
211
246
 
212
247
  A target is required: `npm run release` alone is a mutation-free usage error.
213
248
  `patch` promotes the open prerelease, `0.1.8-dev -> 0.1.8`. `develop` must declare
214
- exactly one open `x.y.z-dev` version; a stable or numbered version there is refused.
215
- The command reports its source, stable target, and prospective reopening before
216
- touching anything, and the stable version is never committed to `develop`.
217
-
218
- 1. The helper checks that the registry and `v<version>` tag do not already hold the
219
- target, re-reads authoritative `develop`, and explicitly dispatches stable
220
- publication for that exact source with the stable version in the request. A changed source is
221
- an error, not permission to substitute a newer commit.
222
- 2. The workflow stamps the requested version on the checked-out source
223
- (`npm version <x.y.z> --no-git-tag-version`) before packing the application and
224
- stages the same exact version into the dependency-free installer before packing
225
- it. Both tarballs therefore declare `0.1.8` while the tagged commit still
226
- declares `0.1.8-dev`; their recorded digests bind them to the same source tree.
227
- 3. Only after verified publication of both `0.1.8` packages does the helper commit
228
- `0.1.9-dev` in an owned detached worktree beneath `.worktrees/` (the application
229
- manifest, root lockfile, and installer manifest versions change), open the one version PR, and wait for you to
230
- **merge it manually** with a bounded 30-minute poll. The helper never merges
231
- PRs or enables auto-merge. Until that merge the helper reports development
232
- reopening as incomplete, and previews cannot be published from a `develop`
233
- whose `-dev` version sorts below the stable release.
234
-
235
- Closed PRs, timeout, cancellation, and query failures retain identifiable phase
236
- work for inspection. Conflicting existing branches/PRs are not overwritten;
237
- a matching pending reopening PR is observed rather than replaced. Worktrees
238
- retained by an earlier attempt are not removed by a later invocation. Cleanup
239
- only removes clean, owned, confirmed-merged phase worktrees and unchanged remote
240
- phase branches. The caller is never hard-reset: a final fast-forward is attempted
241
- only when its branch, original HEAD, and cleanliness remain unchanged. Otherwise
242
- preserve local work and synchronize manually with the reported remote state.
243
-
244
- Stable publication builds the process guardian on all supported platforms, stamps
245
- the version, packs each package once, runs the complete suite and installer package
246
- check against those exact bytes on Windows, Linux, and macOS, publishes both to npm
247
- `latest` with provenance from the `npm-publish` environment, and exercises the exact
248
- published installer/application pair in isolated prefixes on every release lane.
249
- Only after those post-publication checks pass does it write `vx.y.z` on the source commit, record
250
- the GitHub Release, and fast-forward `master`. A push of the stable version does
251
- not publish it, and no automation ever pushes one.
252
-
253
- The installer package does not yet exist on npm, so its first publication needs a
254
- one-time granular token in the `npm-publish` environment secret
255
- `NPM_BOOTSTRAP_TOKEN`; the workflow still publishes the exact validated tarball
256
- with provenance. Immediately after that first successful publication, configure
257
- `.github/workflows/release.yml` and environment `npm-publish` as the package's npm
258
- trusted publisher, delete the bootstrap secret, and let npm 11 authenticate future
259
- publications through GitHub OIDC. The application package continues using its
260
- existing trusted-publisher configuration throughout.
249
+ exactly one open `x.y.z-dev` version; a stable or numbered version there is refused,
250
+ and the stable version is never committed to `develop`. The command reports its
251
+ source, stable target, and prospective reopening, creates or reuses an unpublished
252
+ draft GitHub Release, starts validation of its source, prints the validation run link,
253
+ and waits. Only after validation succeeds does it print the draft editing URL, exactly
254
+ once; after a failure it prints the failed jobs and their reasons instead. Each link
255
+ stands on its own line. Interrupting the wait is safe: validation keeps running, and
256
+ rerunning the command resumes waiting on the same run. The maintainer never re-enters
257
+ the version. The retired `--approve` form remains a mutation-free usage error.
258
+
259
+ 1. **Prepare.** The command checks npm and the target tag, takes as its baseline the
260
+ highest published, non-prerelease GitHub Release below the target whose tag on
261
+ `origin` is in the source's first-parent history (local tags are ignored, so a tag
262
+ left behind by a deleted Release cannot shorten the changelog; no such Release
263
+ stops preparation), and maps every later first-parent commit through one merged
264
+ GitHub pull request. It generates Pi-style Markdown beginning
265
+ `## [version] - YYYY-MM-DD`, followed by applicable `### Breaking Changes`,
266
+ `### New Features`, `### Added`, `### Changed`, and `### Fixed` sections, and
267
+ creates one source-bound **draft GitHub Release**. It then dispatches
268
+ `release-candidate.yml`, which stamps the stable version, packs both packages with
269
+ the generated note, and runs the complete stable suite on Windows, Linux, and macOS
270
+ without publishing. A running or successful validation of the same source and
271
+ version is reused. Ambiguous history, stale source, an existing tag, or existing
272
+ npm versions stop without mutation.
273
+ 2. **Edit.** When validation passes, open the printed Releases URL and edit the
274
+ changelog. **Save draft** is optional and starts nothing.
275
+ 3. **Publish.** Choose native **Publish release**. GitHub creates the tag at the bound
276
+ source, and its `release.published` event starts `finalize-release.yml`. Trusted default-branch code requires the
277
+ publisher to be a GitHub `User` with `write`, `maintain`, or `admin` permission,
278
+ the Release and tag to match the bound source, both npm versions to be absent, and
279
+ the candidate validation of that exact source and version to have succeeded. Apps,
280
+ bots, pushed tags, and dispatch payloads grant no npm authority. It snapshots the
281
+ published body and downloads the package pair that candidate run retained,
282
+ requiring it to bind the same source commit, tree, version, and recorded
283
+ integrity. An unchanged note publishes the validated bytes as they are; an edited
284
+ note replaces only the packaged release-note resource, and every other entry, entry
285
+ mode, and the installer are proven byte-identical. Nothing is rebuilt or
286
+ revalidated. It then proves npm trusted publishing for both packages, publishes
287
+ both to npm `latest` with provenance, verifies and exercises the published pair,
288
+ uploads the asset, fast-forwards `master`, and creates or exactly reuses
289
+ `chore/release-0.1.9-dev`. That PR's single commit changes only the application
290
+ manifest, root lockfile, installer version, and exact `docs/releases/0.1.8.md`.
291
+ Let required CI pass and **merge it manually**. Automation never merges or
292
+ enables auto-merge.
293
+
294
+ Publishing before validation finishes is safe: publication fails before npm and the
295
+ Release returns to draft. Publish the draft again once validation has succeeded.
296
+
297
+ On first interactive launch of the matching stable package, bare A1 opens the
298
+ reviewed note once in its full-screen `What's New` route after higher-priority
299
+ startup prompts. Closing a successfully rendered screen acknowledges it per profile;
300
+ previews, downgrades, load/render failures, and exits before close do not. The full
301
+ packaged history remains available with `/changelog`, latest A1 release at the top
302
+ and oldest at the bottom. Installation and `a1 update` remain non-interactive.
303
+ `a1 pi` retains Pi's pinned oldest-first in-feed changelog so the latest release is
304
+ nearest the bottom, along with Pi's settings.
305
+
306
+ Conflicting or stale draft Releases are not overwritten; retire one explicitly before
307
+ preparing a replacement for an advanced source. Reopening automation reuses only one
308
+ exact open same-repository PR on current `develop`; closed, advanced, auto-merge-enabled,
309
+ extra-path, wrong-body, or ambiguous work is refused. An existing reopening branch
310
+ without that exact PR is preserved rather than overwritten. The local preparation
311
+ checkout is never committed, reset, or used to publish package bytes.
312
+
313
+ Candidate validation builds the process guardian on all supported platforms, stamps
314
+ the version, packs each package once, runs the complete stable suite against those
315
+ bytes on Windows, Linux, and macOS, and retains the pair for 30 days as
316
+ `release-package-<version>`. Stable publication skips the guardian builds and
317
+ validation lanes, adopts that retained pair, publishes both to npm `latest` with
318
+ provenance from the `npm-publish` environment, and exercises the exact published
319
+ installer/application pair in isolated prefixes on every release lane. Only after
320
+ those post-publication checks pass does it upload the Release asset and fast-forward
321
+ `master`. A pushed tag does not publish npm packages; only native publication of the
322
+ prepared draft does. The published Release and tag are visible for the few minutes
323
+ publication takes.
324
+
325
+ If publication fails or is cancelled before either package reaches npm, the
326
+ `Return an unpublished Release to draft` job re-reads the registry and the run's npm
327
+ upload steps. When both packages are absent and no upload step ran, it returns the
328
+ Release to draft and deletes the unconsumed tag at the bound source using the
329
+ release-automation App, the only actor that may bypass the tag ruleset. It never
330
+ moves a tag, never deletes a tag at any other commit, and keeps both the Release and
331
+ tag once npm may have been reached. The `a1-protect-release-tags` ruleset must list
332
+ that App (`openspec-ci`) as its single bypass actor.
333
+
334
+ Preparation refuses any target tag that already exists; publish the draft instead of
335
+ pushing a tag.
261
336
 
262
337
  Rules that do not bend:
263
338
 
264
339
  - **Never upload locally rebuilt bytes.** The publisher uploads the artifact the validation ran against and checks its digest before and after.
265
340
  - **Never route around validation by rebuilding inside a publisher.** The publish job receives the packed artifact and does not install dependencies, build, or pack.
266
- - **Never move a release tag.** A wrong tag is superseded by the next version, not repointed.
341
+ - **Never move a release tag.** A wrong tag is superseded by the next version, not repointed. Only an unconsumed tag whose packages are absent is deleted, by automation.
267
342
 
268
343
  ## When something fails
269
344
 
270
345
  - **PR validation fails:** fix the code and push; do not mark a failed PR-cadence tier optional. If real predecessor history is needed, run Full regression rather than changing the exhaustive result into PR success.
271
- - **Nightly startup budget overruns:** a single overrun on Full regression or nightly publication is a warning in the run summary, not a failure; the triage judges the key across the three most recent `develop` runs and opens a `package-startup` candidate only when all three overran. Stable publication still fails on one overrun; rerun it with the measured phases in hand.
272
- - **Nightly regression fails:** the triage workflow opens or refreshes a draft `fix/nightly-regression-<date>` pull request whose body and change carry the evidence and whose `regression-provenance.json` binds the source run; start the fix there. A failed Full regression source created by `openspec-ci` selects PR-attached Full regression, while a Release-only failure or successful-run persistent overrun retains ordinary PR validation. Reproduce from the listed tests or commands on the failed lane and fix without weakening assertions, budgets, timeouts, or coverage. Record focused implementation evidence and pre-finalization observations in the change, then require `Development validation required` and, when selected, PR-attached Full regression on the finalized exact head. Put final run/head/selection in Actions and handoff rather than making another evidence-recording commit. Standalone dispatch remains diagnostic; numbered-package nightly recovery is independent. A day whose failed scope set differs from every open candidate opens a new one. A Full regression dispatched on a candidate's own branch is that candidate's proof but never selected PR authority; its failures never open another candidate. A failure with no candidate means the triage workflow itself failed; read its run summary and dispatch it with the failed run id and `dry_run` off.
346
+ - **Nightly startup budget overruns:** a single overrun on Full regression or nightly publication is a warning in the run summary, not a failure; the triage judges the key across the three most recent `develop` runs and opens a `package-startup` candidate only when all three overran. Stable candidate validation still fails on one overrun; rerun it with the measured phases in hand.
347
+ - **Nightly regression fails:** the triage workflow opens or refreshes a draft `fix/nightly-regression-<date>` pull request whose body and change carry the evidence and whose `regression-provenance.json` binds the source run; start the fix there. A failed Full regression source created by `openspec-ci` selects PR-attached Full regression, while a Publish-only failure or successful-run persistent overrun retains ordinary PR validation. Reproduce from the listed tests or commands on the failed lane and fix without weakening assertions, budgets, timeouts, or coverage. Record focused implementation evidence and pre-finalization observations in the change, then require `Development validation required` and, when selected, PR-attached Full regression on the finalized exact head. Put final run/head/selection in Actions and handoff rather than making another evidence-recording commit. Standalone dispatch remains diagnostic; numbered-package nightly recovery is independent. A day whose failed scope set differs from every open candidate opens a new one. A Full regression dispatched on a candidate's own branch is that candidate's proof but never selected PR authority; its failures never open another candidate. A failure with no candidate means the triage workflow itself failed; read its run summary and dispatch it with the failed run id and `dry_run` off.
273
348
  - **Nightly exhaustive predecessor validation fails:** treat the focused PR result as insufficient, keep publication blocked, and repair the incompatibility without reducing predecessor count, timeouts, or exact-package isolation.
274
349
  - **Documentation auto-merge fails:** leave the pull request open, inspect its exact
275
350
  changed-file classification, docs-sensitive inventory, and workflow permissions,
276
351
  and never broaden the allowlist to make one pull request pass.
277
352
  - **Merged-branch cleanup fails:** inspect the bounded PR/ref/SHA disposition. Never
278
353
  delete an advanced or protected ref merely because its name matches an old PR.
354
+ - **Ready pull-request refresh fails:** read the per-PR disposition in the run summary.
355
+ A `blocked` PR needs its conflict with `develop` resolved by hand; a `deferred` PR is
356
+ re-evaluated on the next pass. A credential or permission failure means the App
357
+ secrets are missing or underprivileged; restore them rather than updating branches
358
+ with another token.
279
359
  - **Repository governance drifts:** run the read-only checker, review every reported
280
360
  path, and use the confirmed apply mode only for an accepted mutable policy change.
281
361
  - **A Pi upgrade proposal needs a re-run:** the sync never force-pushes over `chore/pi-<version>` once it carries a commit the bot did not author; a scheduled re-run posts its fresh verdicts as a comment headed with the version and date and rewrites only the report between the `<!-- pi-upgrade-report -->` markers of the description. To re-run the derived steps and gates on the reviewer's head, dispatch the workflow with `refresh` and the `version`; it checks out the proposal branch, skips bump, evaluation, install, and merge, and reports without pushing. A branch whose commits are all the bot's is recreated from `develop` as before.
@@ -283,10 +363,10 @@ Rules that do not bend:
283
363
  - **Nightly documentation review fails:** inspect the reported paths and rules, identify the introducing merge from the nightly interval, and repair the invariant before unrelated work proceeds.
284
364
  - **Development publication fails:** inspect both package versions and digests, fix the cause, and rerun `npm run develop`; an npm version that already exists is verified and never overwritten.
285
365
  - **Registry verification times out:** a `has not propagated` failure after a successful `npm publish` means npm is still ingesting the upload; it warns that a provenance-signed package "may take a few minutes" and the publisher polls for ten minutes. Confirm the version and its shasum on `https://registry.npmjs.org/<name>/<version>`, then rerun the failed jobs: the final registry check finds the exact bytes, skips `npm publish`, and verification passes. A digest or tag mismatch is not a timeout and is never repaired by rerunning.
286
- - **Stable publication fails or is uncertain:** no reopening PR was prepared and `develop` still declares the open `-dev` version. Inspect the workflow run, npm, and the `v<version>` tag. When nothing was published, fix the cause and rerun the same target; the registry and tag guards refuse a version that already exists.
287
- - **Stable is published but reopening stopped:** the helper reports the reopening PR or retained worktree. Merge the pending `chore/release-<x.y.z>-dev` PR by hand once its CI passes, or repair the branch and open the PR yourself; never rerun the release for the published version.
288
- - **Stable publication fails or is uncertain:** inspect the workflow, registry version/digest, tag, and release before choosing recovery. No reopening PR is prepared. Never republish immutable bytes or move a release tag.
289
- - **Stable publication succeeded but reopening stops:** the stable version is already published. Inspect and finish the reported next-development PR manually; do not repeat stable publication. If no reopening PR was created, prepare the next-development version through a separately validated manual PR after inspecting remote state.
366
+ - **Draft preparation stops:** inspect the reported draft Release. Preparation may safely reuse an exact source-bound draft without overwriting edits, and reuses a running or successful validation of the same source and version. If `develop` advanced, retire the stale draft explicitly and prepare a new one from synchronized `develop`.
367
+ - **Candidate validation fails:** do not publish the draft. Fix the failure on `develop`, retire the draft, and prepare again; the new draft binds the new source. Publishing anyway fails before npm and returns the Release to draft.
368
+ - **Publication fails before npm:** the rollback job returns the Release to draft and deletes the unconsumed tag, so no manual tag cleanup is needed. Read the failed `Publish stable release` run, fix the cause (for example, wait for validation, undo a body edit made after publishing, rerun candidate validation when its retained package is missing or older than 30 days, or register the trusted publisher the npm preflight names), and choose **Publish release** again. If the rollback job itself failed, rerun it; never delete or move a tag by hand.
369
+ - **Publication fails after npm:** the Release and tag stay. Rerun the failed jobs of that same run: its retained candidate and digests make the final registry check an exact-byte no-op for any package already published. Any recovered reopening PR must contain only both next `-dev` version declarations and the exact approved `docs/releases/<released>.md`; merge it by hand after CI. Never republish immutable bytes. Never repeat stable publication for a published version.
290
370
 
291
371
  ## Safe release-command validation
292
372
 
@@ -297,8 +377,12 @@ npm exec --no -- vitest run test/repository-governance/release-target.test.ts te
297
377
  ```
298
378
 
299
379
  It uses disposable local Git repositories and fake GitHub, registry, and publication
300
- services. It does not publish a package or create production version PRs. A real
301
- release remains a separate deliberate operation.
380
+ services. All release-command integration bodies share one finite 45-second hang
381
+ bound; assertions are never retried or converted to success. Ordinary Windows setup
382
+ observations remain in validation-phase evidence so Git process or Defender variance
383
+ can be diagnosed without scattered undersized per-case limits. It does not publish a
384
+ package or create production version PRs. A real release remains a separate deliberate
385
+ operation.
302
386
 
303
387
  ## Branch protection rationale
304
388
 
@@ -1,6 +1,6 @@
1
1
  # Local worktree cleanup after verified delivery
2
2
 
3
- Local cleanup completes the delivery order in [the archive runbook](openspec-archive-automation.md). For version 3 that is one authorized manual implementation/acceptance/archive merge, read-only verification, remote topic-ref deletion, then safe local cleanup. Legacy versions still require their applicable acceptance-record and automatic archive merges. GitHub Actions never reaches into a developer machine. Local cleanup never publishes archives or merges PRs; `complete`, preview, and queue/watch do not delete remote refs, while explicitly confirmed closed-unmerged `discard` owns only its exact expected-SHA topic-ref deletion.
3
+ Local cleanup completes the delivery order in [the archive runbook](openspec-archive-automation.md). For version 3 that is one authorized manual implementation/acceptance/archive merge, read-only verification, remote topic-ref deletion, then safe local cleanup. Legacy versions still require their applicable acceptance-record and automatic archive merges. GitHub Actions never reaches into a developer machine. Local cleanup never publishes archives or merges PRs; `complete`, `retire-redundant`, preview, and queue/watch do not delete remote refs, while explicitly confirmed closed-unmerged `discard` owns only its exact expected-SHA topic-ref deletion.
4
4
 
5
5
  The implementation is repository tooling, not part of the installed A1 product. It requires Node, Git, and GitHub read access; the explicit closed-unmerged discard operation additionally requires authenticated permission to delete its exact remote topic ref. No product build, dependency installation, interactive UI, or OS-service provisioning is needed. It supports this repository's `origin` on github.com, via HTTPS or SSH.
6
6
 
@@ -60,7 +60,9 @@ node scripts/governance/local-worktree-cleanup.mjs complete \
60
60
 
61
61
  `complete` is explicit cleanup authorization for that exact candidate. It creates and releases an exact registration when needed, applies the repository-owned generated-path policy, verifies live merge/archive/CI/ref evidence, evaluates only that candidate, uses journaled non-force Git removal, deletes only the unchanged local topic ref, and leaves persistent watcher authority unchanged. Repeating it reports the completed candidate as already absent. Existing conflicting ownership, identity drift, unavailable evidence, or unknown content remains blocking.
62
62
 
63
- The central disposable policy is `node_modules`, `dist`, `.builds`, `.artifacts`, `native/process-guardian/target`, `native/terminal-host/target`, and the exact generated file `src/integrations/pi/engine/pi-settings-metadata.json`. The `.artifacts` root is the repository's ignored generated-artifact root (finalization and validation reports, packed candidates, agent-written logs and diffs); the two native roots contain repository-generated Cargo output; Vitest writes the metadata file for source-side settings tests and leaves it shared for overlapping test processes until worktree cleanup. Registrations that still name `.artifacts/openspec-archive` or `.artifacts/validation` stay valid and are widened to the current policy on the next `complete`. Each encountered path must be ignored and stay inside the exact worktree with no link, special file, or nested repository boundary. Authority is component-exact: near matches such as `.artifacts-user`, `artifacts`, or `pi-settings-metadata-user.json`, arbitrary `target` directories, and sibling native projects remain blocking. Tracked/staged/unstaged/untracked content and every unknown ignored path still block. A tracked regular `.gitmodules` file alone is ordinary content; actual nested `.git` metadata, gitlinks, configured submodules, and submodule changes block. Ordinary content and these approved generated paths are traversed under separate finite entry allowances, so a normal dependency installation does not consume the ordinary source-tree allowance; both allowances retain the same deadline and content-boundary checks. Once those checks pass, cleanup deletes the declared disposable roots or files itself with a bounded retry for transient Windows sharing violations before handing the worktree to Git, so non-force Git removal only has to delete tracked content. A disposable path that stays locked after the retry budget reports `blocked` with `disposable-path-locked` and the path; the worktree, its `.git` pointer, and its journal are untouched, so stop the process holding the handle and rerun the same command.
63
+ The central disposable policy is `node_modules`, `dist`, `.builds`, `.artifacts`, `native/process-guardian/target`, `native/terminal-host/target`, and the exact generated file `src/integrations/pi/engine/pi-settings-metadata.json`. The `.artifacts` root is the repository's ignored generated-artifact root (finalization and validation reports, packed candidates, agent-written logs and diffs); the two native roots contain repository-generated Cargo output; Vitest writes the metadata file for source-side settings tests and leaves it shared for overlapping test processes until worktree cleanup. Registrations that still name `.artifacts/openspec-archive` or `.artifacts/validation` stay valid and are widened to the current policy on the next `complete`.
64
+
65
+ Each root itself must be an ignored non-link regular file or directory inside the exact worktree. A descendant symbolic link or Windows junction is accepted only when its canonical target stays inside that same exact disposable root. Inspection records the link's path, filesystem identity, and target; purge revalidates them and removes the link entry without traversing it before removing the root. Root-level links, escapes, drift, unresolved/cyclic targets, special files, and nested repository boundaries remain blocking. Authority is component-exact: near matches such as `.artifacts-user`, `artifacts`, or `pi-settings-metadata-user.json`, arbitrary `target` directories, and sibling native projects remain blocking. Tracked/staged/unstaged/untracked content and every unknown ignored path still block. A tracked regular `.gitmodules` file alone is ordinary content; actual nested `.git` metadata, gitlinks, configured submodules, and submodule changes block. Ordinary content and these approved generated paths are traversed under separate finite entry allowances, so a normal dependency installation does not consume the ordinary source-tree allowance; both allowances retain the same deadline and content-boundary checks. Once those checks pass, cleanup deletes the declared disposable roots or files itself with a bounded retry for transient Windows sharing violations before handing the worktree to Git, so non-force Git removal only has to delete tracked content. A disposable path that stays locked after the retry budget reports `blocked` with `disposable-path-locked` and the path; the worktree, its `.git` pointer, and its journal are untouched, so stop the process holding the handle and rerun the same command.
64
66
 
65
67
  Agents do not manually remove generated content, call `git worktree remove`, or delete the local branch after delivery. The JSON result is authoritative: report success only for `removed` or verified `already-absent`; otherwise retain the worktree and report the exact blocker. A handed-off entry whose worktree was deleted by hand completes through its journal, and its branch is deleted under the accepted-ancestry rule. Legacy roles can supply separate `--source-pr`, `--candidate-pr`, and `--role` values.
66
68
 
@@ -81,6 +83,21 @@ node scripts/governance/local-worktree-cleanup.mjs discard \
81
83
 
82
84
  An open, merged, reopened, forked, protected, reserved, advanced, dirty, active, linked, nested, replaced, current, or unverifiable candidate remains blocking. Remote deletion followed by a Windows lock or later local blocker is reported as `partial`; the journal preserves the remaining worktree/local ref for the same exact confirmed command to inspect and resume. The command never scans by age or name, adopts another session's checkout, enables queue/watch, or turns PR close events into automatic discard authority.
83
85
 
86
+ ## Explicit redundant no-PR retirement
87
+
88
+ A non-empty unregistered checkout is never adopted by sweep, preview, queue/watch, branch pruning, age, or ancestry. After the maintainer explicitly authorizes one exact redundant checkout, use the repository-owned operation from the primary checkout:
89
+
90
+ ```bash
91
+ node scripts/governance/local-worktree-cleanup.mjs retire-redundant \
92
+ --repo D:/Git/a1 \
93
+ --path D:/Git/a1/.worktrees/redundant-task \
94
+ --confirm-redundant
95
+ ```
96
+
97
+ The command requires an exact canonical, unlocked, non-current Git worktree on a normal topic branch; no cleanup registration; no pull request in any state for that branch; no remote topic ref; no unique commit beyond freshly fetched `origin/develop`; and no staged, unstaged, untracked, hidden-index, unknown ignored, nested-repository, submodule, or other protected content. Central-policy generated content is inspected and purged normally. Under the mutation lock the command revalidates every gate, journals the captured filesystem/HEAD/ref identity, removes the checkout non-forcibly, and compare-and-deletes only the unchanged local ref. It never removes a remote ref or enables broad cleanup authority.
98
+
99
+ A repeated exact confirmed invocation resumes a partial journal or reports `already-retired`. A branch with any pull request remains owned by `complete`/sweep or explicit closed-unmerged `discard`; an open, dirty, remote-backed, locally advanced, registered, locked, detached, protected, replaced, or ambiguous checkout remains retained. Agents never substitute manual deletion when this command blocks.
100
+
84
101
  ## Preview first
85
102
 
86
103
  From a checkout containing the reviewed tooling:
@@ -90,7 +107,7 @@ node scripts/governance/local-worktree-cleanup.mjs preview --repo D:/Git/a1
90
107
  node scripts/governance/local-worktree-cleanup.mjs status --repo D:/Git/a1
91
108
  ```
92
109
 
93
- `--repo` is the **primary** worktree, not a task worktree. Preview reads live evidence but changes no worktrees, refs, ownership state, or retry checkpoints. Status is local-only. Existing folders are reported `unmanaged` and are never adopted by their name, missing upstream, or ancestry; preview reports a folder that an execution pass would remove as an empty leftover with `empty-directory` (see below) but deletes nothing. Neither command enables cleanup.
110
+ `--repo` is the **primary** worktree, not a task worktree. Preview reads live evidence but changes no worktrees, refs, ownership state, or retry checkpoints. Status is local-only. Existing folders are reported `unmanaged` and are never adopted by preview or sweep from their name, missing upstream, or ancestry; only a separate exact `retire-redundant --confirm-redundant` invocation can evaluate the narrowly defined no-PR shape above. Preview reports a folder that an execution pass would remove as an empty leftover with `empty-directory` (see below) but deletes nothing. Neither command enables cleanup.
94
111
 
95
112
  Remote reads use `GH_TOKEN`/`GITHUB_TOKEN`, otherwise existing `gh auth token --hostname github.com` authentication. Do not put tokens in command arguments, source files, reports, or PR comments. Missing/expired private-repository authentication blocks evidence checks.
96
113
 
@@ -178,7 +195,7 @@ State, journals, stop controls, and execution reports live in `<git-common-dir>/
178
195
  - `unmanaged`: no local registration; no automatic adoption. Reason `empty-directory-recent` marks an all-empty folder still inside its ten-minute grace, and in preview `empty-directory` marks one an execution pass would remove.
179
196
  - `removed`: worktree and eligible local-ref operations were verified.
180
197
  - `already-absent`: a completed journal's path/ref are still absent.
181
- - `retired`: evidence was unverifiable but nothing remained to delete and the PR is merged; the journal is complete with `retired-nothing-left`.
198
+ - `retired`: either evidence was unverifiable but nothing remained to delete and the merged PR registration completed with `retired-nothing-left`, or an exact confirmed `retire-redundant` operation safely removed its no-PR checkout and local ref.
182
199
  - `forgotten`: the maintainer explicitly closed an all-absent entry with `forget`.
183
200
  - `partial`: a destructive step began but all cleanup could not be verified; the same command resumes it.
184
201
  - `deferred`: a bounded pass or concurrent mutation owner prevented evaluation.
@@ -55,6 +55,7 @@ Use equivalent values in bare A1 and the Pi comparison profile. Exercise both a
55
55
  - [ ] `/settings`: selected cursor, label and value accent; unselected values muted; descriptions and hints dim; search uses `> ` with inverse cursor; scalar menus, numeric controls, warning-parts dialog, deferred notice, failed write, section spacing, clipping, and hidden-entry absence match their pinned semantic roles.
56
56
  - [ ] Transcript: toggle images and image width, thinking level/visibility, Mermaid mode, output padding, cache notices, warnings, auto-compaction, queue modes, command autocomplete, provider timeout/retry/error, and changelog collapse. Existing and streaming blocks must re-render without focus, selection, scroll, or queued-work loss.
57
57
  - [ ] Trust startup: from an undecided project, compare selected Trust/Do not trust rows, arrow navigation, Enter, Escape/Ctrl+C, clearing, cursor state, and restoration. No project extension/theme/prompt/skill may run before selection, and a fail-closed diagnostic must appear once on the restored parent rather than above a blank fullscreen frame.
58
+ - [ ] Stable release note: with a built matching stable fixture from an explicitly approved draft GitHub Release snapshot and a fresh A1 profile, verify that exact note opens once after trust/other startup modals, fills the existing `What's New` screen, renders the Pi-style `## [version] - YYYY-MM-DD` heading and categorized `###` sections, scrolls by keys/wheel/rail, resizes, and closes with Escape. Relaunch to verify it stays closed, then use `/changelog` to verify version-labeled packaged history puts the latest A1 release at the top and the oldest at the bottom. A preview fixture must not auto-open or write acknowledgement state; `a1 pi` must retain Pi's oldest-first in-feed changelog so its latest release remains nearest the bottom.
58
59
  - [ ] Terminal lifecycle: toggle hardware cursor, clear-on-shrink, and terminal progress; resize smaller/larger; open/close selectors; select and copy transcript text; verify no duplicate rows, stale OSC progress, leaked mouse mode, misplaced cursor, or broken parent input.
59
60
  - [ ] Images: in Kitty or iTerm2 verify inline width and clipping; in Windows Terminal verify the textual fallback and absence of image protocol bytes without hiding `showImages`.
60
61
  - [ ] Bare A1 quit (`/quit` and the second `Ctrl+C`): the configured quit effect plays over the last frame on the alternate screen, the terminal is restored once, and the parent shows only its earlier scrollback plus the dim `To resume this session:` hint. No frame rows, transcript rows, editor box, or footer may remain. With `/settings` → Quit → Effect set to `off`, the leave is immediate and the parent output is identical.
@@ -19,7 +19,7 @@ Version-1 and version-2 deliveries and their existing comments, acceptance PRs,
19
19
 
20
20
  ### Complete-regression evidence ordering
21
21
 
22
- PR-attached Full regression is selected only for a repair that the trusted triage created from a failed Full regression: base policy verifies the immutable `openspec-ci` App author, generated candidate identity, and `regression-provenance.json`. Human-authored lookalikes, publishing or validation-authority changes, labels, Release-only repairs, and successful-run persistent-overrun candidates retain bounded ordinary validation. Generated repair drafts run no Development test suites, including after implementation begins. Finish substantive implementation tasks, focused local evidence, pre-finalization observations, and known-gap disposition before marking ready. The ready active head defers testing while trusted finalization publishes the candidate; the finalized head then receives all four native lanes as new full evidence, required by `Development validation required` alongside the existing gates.
22
+ PR-attached Full regression is selected only for a repair that the trusted triage created from a failed Full regression: base policy verifies the immutable `openspec-ci` App author, generated candidate identity, and `regression-provenance.json`. Human-authored lookalikes, publishing or validation-authority changes, labels, Publish-only repairs, and successful-run persistent-overrun candidates retain bounded ordinary validation. Generated repair drafts run no Development test suites, including after implementation begins. Finish substantive implementation tasks, focused local evidence, pre-finalization observations, and known-gap disposition before marking ready. The ready active head defers testing while trusted finalization publishes the candidate; the finalized head then receives all four native lanes as new full evidence, required by `Development validation required` alongside the existing gates.
23
23
 
24
24
  The final exact-head run is a handoff gate, not a task requiring a future run ID in committed `design.md`. Keep final head/run/selection identity in Actions outcomes and the maintainer handoff; do not invalidate successful evidence with an extra recording commit. Changed code, acceptance/body metadata, selection labels, or target baseline requires fresh evidence. A selected PR success removes the additional mandatory Full regression dispatch, but a standalone/manual run never substitutes for selected PR checks. Before deployment, existing separate-dispatch obligations remain. Neither PR validation nor manual regression proves numbered-package nightly publication recovery.
25
25
 
@@ -0,0 +1,47 @@
1
+ ## [0.2.2] - 2026-09-30
2
+
3
+ ### Breaking Changes
4
+
5
+ - publish from the native Publish release button ([#629](https://github.com/timurproko/a1/pull/629))
6
+
7
+ ### New Features
8
+
9
+ - review changelog before publish ([#613](https://github.com/timurproko/a1/pull/613))
10
+ - review notes in draft release ([#617](https://github.com/timurproko/a1/pull/617))
11
+ - configure prompt image limit ([#622](https://github.com/timurproko/a1/pull/622))
12
+ - refresh ready PRs after merges ([#625](https://github.com/timurproko/a1/pull/625))
13
+ - refresh a draft bound to an older develop in place ([#635](https://github.com/timurproko/a1/pull/635))
14
+ - show live validation jobs while waiting ([#637](https://github.com/timurproko/a1/pull/637))
15
+ - keep one draft per stable version ([#638](https://github.com/timurproko/a1/pull/638))
16
+ - delete a release tag left behind by a deleted Release ([#640](https://github.com/timurproko/a1/pull/640))
17
+ - announce newer A1 releases on startup ([#643](https://github.com/timurproko/a1/pull/643))
18
+
19
+ ### Changed
20
+
21
+ - rename publisher workflow ([#612](https://github.com/timurproko/a1/pull/612))
22
+ - Update README.md ([#614](https://github.com/timurproko/a1/pull/614))
23
+ - Update README.md ([#616](https://github.com/timurproko/a1/pull/616))
24
+ - Update README.md ([#618](https://github.com/timurproko/a1/pull/618))
25
+ - use npm x for installer commands ([#620](https://github.com/timurproko/a1/pull/620))
26
+ - Streamline stable release handoff ([#627](https://github.com/timurproko/a1/pull/627))
27
+ - shard Windows full regression ([#630](https://github.com/timurproko/a1/pull/630))
28
+ - acknowledge candidate release note before resume launches ([#633](https://github.com/timurproko/a1/pull/633))
29
+ - run the upstream sync at 03:23 Central European time ([#641](https://github.com/timurproko/a1/pull/641))
30
+
31
+ ### Fixed
32
+
33
+ - retire blocked worktrees safely ([#610](https://github.com/timurproko/a1/pull/610))
34
+ - approve publication from Actions ([#619](https://github.com/timurproko/a1/pull/619))
35
+ - keep queued chips unbroken ([#621](https://github.com/timurproko/a1/pull/621))
36
+ - retain pinned Pi runtime root ([#624](https://github.com/timurproko/a1/pull/624))
37
+ - repair the 2026-09-29 full regression failure ([#626](https://github.com/timurproko/a1/pull/626))
38
+ - repair the 2026-09-29-1 publish failure ([#628](https://github.com/timurproko/a1/pull/628))
39
+ - wait for candidate validation and authorize dispatch wrappers ([#631](https://github.com/timurproko/a1/pull/631))
40
+ - keep full-lanes directory in Windows lane artifacts ([#632](https://github.com/timurproko/a1/pull/632))
41
+ - report preparation failures from the default runtime ([#634](https://github.com/timurproko/a1/pull/634))
42
+ - keep the version tag when refreshing a draft ([#636](https://github.com/timurproko/a1/pull/636))
43
+ - capture the stable version before checking the Release id ([#639](https://github.com/timurproko/a1/pull/639))
44
+ - full changelog range, candidate-validated publish, and npm trust preflight ([#644](https://github.com/timurproko/a1/pull/644))
45
+ - repair the 2026-09-30 full regression failure ([#645](https://github.com/timurproko/a1/pull/645))
46
+ - repair the 2026-09-30-2 publish failure ([#646](https://github.com/timurproko/a1/pull/646))
47
+ - stop the trust dialog flashing the terminal ([#647](https://github.com/timurproko/a1/pull/647))
@@ -26,7 +26,7 @@ npm run test:release # release gates; publication authority is unc
26
26
 
27
27
  `test:pr-core` is not a replacement for `test:fast`: CI combines it with directly changed and coarse-owner tests from the exact impact selection. Selected resource-sensitive tests run independently on an isolated Windows runner. Selected package, startup, rendering, Pi, compatibility, and platform owners also run independently after their actual prerequisites.
28
28
 
29
- Conservative Development retains every pull-request owner but does not schedule exhaustive owners. The complete regression implementation runs inside a PR only when base policy verifies an `openspec-ci` App-created repair, its generated candidate identity, and a failed Full regression source in `regression-provenance.json`. Publishing/prerequisite/validation-authority impact, shared inputs, unknown paths, labels, Release-only repairs, and successful-run persistent-overrun candidates retain bounded ordinary validation. Planning-only generated repair drafts stay exempt; eligible implementation drafts get feedback without integration authority. The selected exact-head evidence must include Windows Node 22/24, Linux Node 24, and macOS Node 24. Full regression and nightly/stable release retain both cadence classes and the same coverage through the shared implementation. The real three-release `update-predecessor` exact-package oracle is exhaustive; deterministic predecessor command, fixture, materialization, warmup, package, and update contracts remain PR-eligible. Preview and release continue to consume exact candidate bytes under their channel-specific contracts. A standalone manual Full regression remains useful for diagnosis or an unselected candidate, but never replaces automatically selected current-PR evidence. The generated ownership ledger command is:
29
+ Conservative Development retains every pull-request owner but does not schedule exhaustive owners. The complete regression implementation runs inside a PR only when base policy verifies an `openspec-ci` App-created repair, its generated candidate identity, and a failed Full regression source in `regression-provenance.json`. Publishing/prerequisite/validation-authority impact, shared inputs, unknown paths, labels, Publish-only repairs, and successful-run persistent-overrun candidates retain bounded ordinary validation. Planning-only generated repair drafts stay exempt; eligible implementation drafts get feedback without integration authority. The selected exact-head evidence must include Windows Node 22/24, Linux Node 24, and macOS Node 24. Full regression and nightly/stable release retain both cadence classes and the same coverage through the shared implementation. The real three-release `update-predecessor` exact-package oracle is exhaustive; deterministic predecessor command, fixture, materialization, warmup, package, and update contracts remain PR-eligible. Preview and release continue to consume exact candidate bytes under their channel-specific contracts. A standalone manual Full regression remains useful for diagnosis or an unselected candidate, but never replaces automatically selected current-PR evidence. The generated ownership ledger command is:
30
30
 
31
31
  ```bash
32
32
  node scripts/release/generate-validation-ownership-ledger.mjs --output .artifacts/validation/ownership-ledger.json
@@ -34,6 +34,16 @@ node scripts/release/generate-validation-ownership-ledger.mjs --output .artifact
34
34
 
35
35
  The `terminal-host` owner is CI-only. A change under `native/terminal-host/` or to its run scripts selects the Windows x64 **Native terminal host (Windows)** job, which builds the crate with pinned Rust and Zig 0.15.2, runs `npm run test:terminal-host`, and uploads the debug executable. Local Windows builds fail in `build.rs` unless `TERMINAL_HOST_LOCAL_BUILD=1` is set, because Zig's package fetch unpacks test data that workstation antivirus quarantines along with the installed process guardian. See [`native/terminal-host/README.md`](../native/terminal-host/README.md).
36
36
 
37
+ ## Windows Full regression shards
38
+
39
+ Standalone and PR-attached Full regression run each Windows runtime (Node 22 and Node 24) as four hosted-runner shards derived from the one canonical `full-release` plan: `core` (command gates and the bounded-parallel ordinary remainder), `resource` (the serial resource-sensitive invocation with its unchanged explicit bound), `rendering` (the serial isolated rendering invocation), and `package` (packing, the shared exact-package installation, Defender-backed first-attempt startup before package contracts, package smoke, update timing, and the exhaustive published-predecessor invocation). Each shard checks out, installs, builds, and records its own build receipt; only the package shard packs and installs the candidate. Linux, macOS, local `npm run test:full`, and publication validation keep one sequential complete plan.
40
+
41
+ ```
42
+ node scripts/release/run-validation-tier.mjs --full-shard <core|resource|rendering|package> --result <path>
43
+ ```
44
+
45
+ `partitionFullRegressionPlan` assigns every canonical command and Vitest invocation to exactly one shard and rejects unknown or duplicate work; the build is the only per-shard prerequisite. Each shard result carries its shard identity, assigned work, and the canonical-plan digest. A per-runtime collector job reconstructs one ordinary `a1-validation-outcomes-v1` result only when all four current-run shards for the exact source, runtime, run, attempt, and plan passed and each reported exactly its assigned work; the reconstructed result then binds the unchanged `windows-2025-node22` or `windows-2025-node24` lane, and the required aggregate still demands exactly four lanes. The collector's summary reports each shard's time and the elapsed span across overlapping shards. Nightly triage maps a failed shard's owners to the canonical Windows lane and names the shard job, and it rejects more than one startup evidence file for a lane.
46
+
37
47
  ## Failed-job reruns and attempt evidence
38
48
 
39
49
  Every modular outcome, content-free job envelope, and uploaded artifact name is qualified by `github.run_attempt`. Authority remains bound to the workflow run ID, exact head, complete selection identity, logical job, and platform/runtime target.
@@ -71,8 +81,8 @@ The exact-package startup gate always measures both profiles and all three launc
71
81
 
72
82
  | Value | Where | Effect |
73
83
  | --- | --- | --- |
74
- | `record` | Full regression, nightly and development publication (`release.yml` with `mode != 'stable'`), and the pull-request `startup` group in `ci.yml` | Keeps the measurement, appends the violation to the evidence, emits a `::warning::` annotation, renders the run-summary table, and lets the run succeed. |
75
- | `fail` | Stable publication | Throws the same message as before and blocks publication. |
84
+ | `record` | Full regression, nightly and development publication (`publish.yml` on channel `next`), and the pull-request `startup` group in `ci.yml` | Keeps the measurement, appends the violation to the evidence, emits a `::warning::` annotation, renders the run-summary table, and lets the run succeed. |
85
+ | `fail` | Stable candidate validation (`publish.yml` on channel `latest`), whose validated bytes stable publication adopts | Throws the same message as before, so the draft cannot be published from that run. |
76
86
 
77
87
  Any absent, empty, or unrecognized value means `fail`, so a local run and a misspelled channel both keep enforcing. A launch that records no input-ready frame fails in either mode, because that is a functional failure rather than a timing observation.
78
88
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Standalone terminal workspace for supervised native and managed agents",
5
5
  "type": "module",
6
6
  "privateLaunchContract": "neutral-launch-v1",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "scripts": {
25
25
  "clean": "node scripts/clean.mjs",
26
- "build": "node scripts/development/check-environment.mjs && npm run clean && tsc -p tsconfig.build.json && node scripts/pi/build-pi-settings-metadata.mjs && node scripts/pi/build-startup-public.mjs && node scripts/development/build-process-guardian.mjs && node scripts/release/generate-runtime-payload-inventory.mjs",
26
+ "build": "node scripts/development/check-environment.mjs && npm run clean && tsc -p tsconfig.build.json && node scripts/release/generate-release-notes-resource.mjs && node scripts/pi/build-pi-settings-metadata.mjs && node scripts/pi/build-startup-public.mjs && node scripts/development/build-process-guardian.mjs && node scripts/release/generate-runtime-payload-inventory.mjs",
27
27
  "build:process-guardian": "node scripts/development/build-process-guardian.mjs",
28
28
  "typecheck": "tsgo -p tsconfig.json --noEmit && tsgo -p tsconfig.bin.json",
29
29
  "check:architecture": "node scripts/governance/check-architecture.mjs && node scripts/governance/check-product-identity-boundaries.mjs && node scripts/governance/check-package-identity.mjs && node scripts/governance/check-pinned-pi-source-ledger.mjs && node scripts/governance/check-terminal-host-provenance.mjs",
@@ -58,7 +58,7 @@
58
58
  "proof:terminal-host": "node scripts/development/run-terminal-host.mjs",
59
59
  "start": "npm run build && node scripts/development/dev-launch.mjs",
60
60
  "start:pi": "npm run build && node scripts/development/dev-launch.mjs pi",
61
- "prepack": "node scripts/release/prepack-gate.mjs",
61
+ "prepack": "node scripts/release/validate-packaged-release-note.mjs && node scripts/release/prepack-gate.mjs",
62
62
  "prepublishOnly": "npm run test:release",
63
63
  "prepare": "npm run build",
64
64
  "typecheck:bin": "tsgo -p tsconfig.bin.json"