@timurproko/a1 0.2.7-dev.772 → 0.2.7-dev.779

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 (29) hide show
  1. package/dist/app/session-shell/session-shell-root.d.ts +2 -0
  2. package/dist/app/session-shell/session-shell-root.js +1 -1
  3. package/dist/app/session-shell/session-shell.js +1 -0
  4. package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
  5. package/dist/integrations/pi/components/shell-footer-status.js +2 -2
  6. package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
  7. package/dist/integrations/pi/components/upstream/components/session-footer.js +7 -4
  8. package/dist/native/darwin-arm64/a1_session_lock.node +0 -0
  9. package/dist/native/darwin-arm64/manifest.json +2 -2
  10. package/dist/native/darwin-arm64/process-guardian +0 -0
  11. package/dist/native/darwin-arm64/terminal-host +0 -0
  12. package/dist/native/darwin-arm64/terminal-host.manifest.json +6 -6
  13. package/dist/native/darwin-x64/a1_session_lock.node +0 -0
  14. package/dist/native/darwin-x64/manifest.json +3 -3
  15. package/dist/native/darwin-x64/process-guardian +0 -0
  16. package/dist/native/darwin-x64/terminal-host +0 -0
  17. package/dist/native/darwin-x64/terminal-host.manifest.json +5 -5
  18. package/dist/native/linux-x64/a1_session_lock.node +0 -0
  19. package/dist/native/linux-x64/manifest.json +2 -2
  20. package/dist/native/linux-x64/process-guardian +0 -0
  21. package/dist/native/linux-x64/terminal-host +0 -0
  22. package/dist/native/linux-x64/terminal-host.manifest.json +6 -6
  23. package/dist/native/win32-x64/a1_session_lock.node +0 -0
  24. package/dist/native/win32-x64/manifest.json +2 -2
  25. package/dist/native/win32-x64/process-guardian.exe +0 -0
  26. package/dist/native/win32-x64/terminal-host.exe +0 -0
  27. package/dist/native/win32-x64/terminal-host.manifest.json +4 -4
  28. package/docs/openspec-archive-automation.md +15 -3
  29. package/package.json +1 -1
@@ -217,6 +217,8 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
217
217
  readonly keybindings?: PiKeybindingsHost;
218
218
  readonly promptImageLimit?: () => number;
219
219
  readonly skillsPresentation?: () => "collapse" | "expand";
220
+ /** A resident tab chip already shows the session name, so its footer omits the duplicate. */
221
+ readonly footerSessionName?: boolean;
220
222
  }, startup?: PiShellHeaderOptions, agentDir?: string, extensionRenderers?: OwnedUiTranscriptRendererPort, sessionLayout?: "pinned" | "custom-viewport", imageAssets?: PiShellImageAssetResolver);
221
223
  setEditorPaddingX(padding: number): void;
222
224
  setAutocompleteMaxVisible(maxVisible: number): void;
@@ -119,7 +119,7 @@ export class OwnedUiSessionShellRoot {
119
119
  frame: progressStatusFrame,
120
120
  }, handlers);
121
121
  this.#status.setProgressPresentation(this.#customViewport ? "custom-viewport" : "pinned");
122
- this.#footer = createPiShellFooter(this.#viewWithExtensionStatuses(view), cwd, this.#customViewport ? "a1" : "pi", () => this.#footerLevel);
122
+ this.#footer = createPiShellFooter(this.#viewWithExtensionStatuses(view), cwd, this.#customViewport ? "a1" : "pi", () => this.#footerLevel, handlers.footerSessionName ?? true);
123
123
  this.editor = createPiShellEditor({
124
124
  ...handlers,
125
125
  keybindingProfile: this.#customViewport ? "a1" : "pi",
@@ -188,6 +188,7 @@ export class OwnedUiSessionPresenter {
188
188
  replacementSurfaceActive: !this.root.usesDefaultInputSurface(),
189
189
  }),
190
190
  enableDockInputReuse: inputPresentation?.viewportReuse !== false,
191
+ footerSessionName: this.#residentTabOptions === undefined,
191
192
  persistentHistory: this.#customViewport && promptHistory !== undefined,
192
193
  ...(promptHistory === undefined ? {} : { historyEditor: promptHistory.editor }),
193
194
  onSubmit: text => { void this.submit(text).catch(() => this.#reportSubmissionError()); },
@@ -4,5 +4,5 @@ import { type PiShellViewComponentPort, type PiShellStatusPort, type PiShellProg
4
4
  export declare function createPiShellHeader(options?: PiShellHeaderOptions): PiShellHeaderPort;
5
5
  export declare function createPiShellLoadedResources(resources: readonly PiShellResourceEntry[], initialExpanded?: boolean): PiShellLoadedResourcesPort;
6
6
  export declare function createPiShellStatus(view: OwnedUiSessionViewModel, progressStatus: PiShellProgressStatusPresentation, runtime?: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellStatusPort;
7
- export declare function createPiShellFooter(view: OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", showLevel?: () => boolean): PiShellViewComponentPort;
7
+ export declare function createPiShellFooter(view: OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", showLevel?: () => boolean, showSessionName?: boolean): PiShellViewComponentPort;
8
8
  export declare function createPiQueuedInputStatus(submissions: readonly string[], presentation?: "pinned" | "custom-viewport", getKeybindings?: () => KeybindingsConfig): PiShellQueuedInputPort;
@@ -136,9 +136,9 @@ export function createPiShellStatus(view, progressStatus, runtime) {
136
136
  },
137
137
  };
138
138
  }
139
- export function createPiShellFooter(view, cwd, profile = "pi", showLevel = () => true) {
139
+ export function createPiShellFooter(view, cwd, profile = "pi", showLevel = () => true, showSessionName = true) {
140
140
  ensureTheme();
141
- const footer = new SessionFooter(() => view, cwd, profile, showLevel);
141
+ const footer = new SessionFooter(() => view, cwd, profile, showLevel, showSessionName);
142
142
  return {
143
143
  render: width => footer.render(width),
144
144
  invalidate: () => footer.invalidate(),
@@ -5,7 +5,8 @@ export declare class SessionFooter implements Component {
5
5
  private readonly cwd;
6
6
  private readonly profile;
7
7
  private readonly show;
8
- constructor(getView: () => OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", show?: () => boolean);
8
+ private readonly showSessionName;
9
+ constructor(getView: () => OwnedUiSessionViewModel, cwd: string, profile?: "pi" | "a1", show?: () => boolean, showSessionName?: boolean);
9
10
  invalidate(): void;
10
11
  dispose(): void;
11
12
  render(width: number): string[];
@@ -5,8 +5,9 @@
5
5
  * preserves the latest physical route for virtual models; an explicit bare-A1 profile colors the
6
6
  * thinking-level name, renders its repository-context path, and reserves its linked pull-request badge
7
7
  * before path truncation while preserving the remaining footer layout and formatting; replacement
8
- * surfaces may suppress a thinking level they already present.
9
- * Deviations: owned-status-level-color, owned-pull-request-badge.
8
+ * surfaces may suppress a thinking level they already present; a resident tab whose chip already shows
9
+ * the session name may suppress its path-row suffix.
10
+ * Deviations: owned-status-level-color, owned-pull-request-badge, owned-resident-session-name.
10
11
  */
11
12
  import { isAbsolute, relative, resolve, sep } from "node:path";
12
13
  import { hyperlink, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
@@ -16,11 +17,13 @@ export class SessionFooter {
16
17
  cwd;
17
18
  profile;
18
19
  show;
19
- constructor(getView, cwd, profile = "pi", show = () => true) {
20
+ showSessionName;
21
+ constructor(getView, cwd, profile = "pi", show = () => true, showSessionName = true) {
20
22
  this.getView = getView;
21
23
  this.cwd = cwd;
22
24
  this.profile = profile;
23
25
  this.show = show;
26
+ this.showSessionName = showSessionName;
24
27
  }
25
28
  invalidate() { }
26
29
  dispose() { }
@@ -42,7 +45,7 @@ export class SessionFooter {
42
45
  const branch = view.status.footer?.branch;
43
46
  if (branch)
44
47
  pwd = `${pwd} (${branch})`;
45
- const sessionName = view.status.footer?.sessionName;
48
+ const sessionName = this.showSessionName ? view.status.footer?.sessionName : null;
46
49
  const pullRequest = this.profile === "a1" ? view.status.footer?.pullRequest : null;
47
50
  let pathRow;
48
51
  if (pullRequest === undefined || pullRequest === null) {
@@ -5,10 +5,10 @@
5
5
  "platform": "darwin",
6
6
  "architecture": "arm64",
7
7
  "capability": "supported",
8
- "builtAt": "2026-10-15T16:36:26.826Z",
8
+ "builtAt": "2026-10-16T04:40:04.241Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian",
11
- "sha256": "51b0b2dc1c9ae577f2586c4217066929278726c2c15308d9144eb6f538e118ff",
11
+ "sha256": "47e9052599983a6bb0078ce6203ba18d71bec0b7b94e6a49019d11d46c3fbeca",
12
12
  "size": 410368
13
13
  },
14
14
  "provenance": {
@@ -7,16 +7,16 @@
7
7
  "architecture": "arm64",
8
8
  "target": "aarch64-apple-darwin",
9
9
  "capability": "supported",
10
- "builtAt": "2026-10-15T16:39:33.704Z",
10
+ "builtAt": "2026-10-16T04:43:05.642Z",
11
11
  "artifact": {
12
12
  "filename": "terminal-host",
13
- "sha256": "e0f72a7f9a551af66c802b0ef65b52fc920cee58faaf0929d341e13a0d845a7d",
14
- "size": 4836832
13
+ "sha256": "3771b1f4f03de8bb088d8a3cb22dce123b3376b9365804cc819fe100aedec51f",
14
+ "size": 4836800
15
15
  },
16
16
  "sessionLock": {
17
17
  "filename": "a1_session_lock.node",
18
- "sha256": "3a03c55e8b87ff89c99f65aeb9702a04e0df0ea4e31f914ffb18c2cea8d46689",
19
- "size": 561136
18
+ "sha256": "c29d67f9b5935bc26817940573cecbc72668730fc9c54b9d766f2daf5d81b1b7",
19
+ "size": 561184
20
20
  },
21
21
  "notices": {
22
22
  "filename": "terminal-host-THIRD-PARTY-NOTICES.txt",
@@ -32,7 +32,7 @@
32
32
  "zigTarget": "aarch64-macos",
33
33
  "zigCpu": "baseline",
34
34
  "zigVersion": "0.15.2",
35
- "rustVersion": "rustc 1.99.0 (b940084d7 2026-09-28)",
35
+ "rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
36
36
  "features": {
37
37
  "executable": [],
38
38
  "sessionLock": [
@@ -5,11 +5,11 @@
5
5
  "platform": "darwin",
6
6
  "architecture": "x64",
7
7
  "capability": "supported",
8
- "builtAt": "2026-10-15T16:36:43.786Z",
8
+ "builtAt": "2026-10-16T04:40:50.831Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian",
11
- "sha256": "6bdc3493816e4ca2ad7ce6a266910318728e71f7925aaf996dc29967e8287022",
12
- "size": 394768
11
+ "sha256": "ccc1272de81b06efa5e590a88dbafe30726a0fe33e0808025a6602236e5d2855",
12
+ "size": 394776
13
13
  },
14
14
  "provenance": {
15
15
  "language": "Rust",
@@ -7,15 +7,15 @@
7
7
  "architecture": "x64",
8
8
  "target": "x86_64-apple-darwin",
9
9
  "capability": "supported",
10
- "builtAt": "2026-10-15T16:44:16.738Z",
10
+ "builtAt": "2026-10-16T04:49:00.861Z",
11
11
  "artifact": {
12
12
  "filename": "terminal-host",
13
- "sha256": "11e26f2bfd5206e2d180ba707768ac3ee1ddf27f9ff5c306955857f118cf6d24",
14
- "size": 5268160
13
+ "sha256": "272f4effb0134cbb17c89e0dda86c3c7bb4fed73e423613663bc8c5c0936381f",
14
+ "size": 5266656
15
15
  },
16
16
  "sessionLock": {
17
17
  "filename": "a1_session_lock.node",
18
- "sha256": "d65b8281607d8f7001bb4eb1a2edd4b66b65a80c619bbbfe96bafec213f6aff0",
18
+ "sha256": "1ebe7f865f9a4ca58c4ed5b30e2693e018071458a657707fb4177f03eae63096",
19
19
  "size": 516336
20
20
  },
21
21
  "notices": {
@@ -32,7 +32,7 @@
32
32
  "zigTarget": "x86_64-macos",
33
33
  "zigCpu": "baseline",
34
34
  "zigVersion": "0.15.2",
35
- "rustVersion": "rustc 1.99.0 (b940084d7 2026-09-28)",
35
+ "rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
36
36
  "features": {
37
37
  "executable": [],
38
38
  "sessionLock": [
@@ -5,10 +5,10 @@
5
5
  "platform": "linux",
6
6
  "architecture": "x64",
7
7
  "capability": "supported",
8
- "builtAt": "2026-10-15T16:36:14.387Z",
8
+ "builtAt": "2026-10-16T04:39:33.511Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian",
11
- "sha256": "ef62679e83bc1fad3d38f9f21675d9256f08d20e67fd4791571032115ca1b0e9",
11
+ "sha256": "94a96fa9d5178a1949d05c6d6cc9504f3030cd49a096cd9db20dd29860ea5884",
12
12
  "size": 411760
13
13
  },
14
14
  "provenance": {
Binary file
@@ -7,16 +7,16 @@
7
7
  "architecture": "x64",
8
8
  "target": "x86_64-unknown-linux-gnu",
9
9
  "capability": "supported",
10
- "builtAt": "2026-10-15T16:38:59.443Z",
10
+ "builtAt": "2026-10-16T04:42:14.245Z",
11
11
  "artifact": {
12
12
  "filename": "terminal-host",
13
- "sha256": "ac5d16c19f1fd731fd5a1d71fb1e70885d6b74fd4600124552431ef6156451a6",
14
- "size": 5829424
13
+ "sha256": "d8b29e901f2fe58f41baa9e1d7cba8d5b57b9a3feb7de286347d92ced978c186",
14
+ "size": 5826128
15
15
  },
16
16
  "sessionLock": {
17
17
  "filename": "a1_session_lock.node",
18
- "sha256": "355c40b6135027f1194bac2653022f9e6f74c0f964a235347c582bf3678c0581",
19
- "size": 721704
18
+ "sha256": "ee9dc35a1a77092268d1c0460197fb7c8cf11fee28c4a643274090566706ccf8",
19
+ "size": 721776
20
20
  },
21
21
  "notices": {
22
22
  "filename": "terminal-host-THIRD-PARTY-NOTICES.txt",
@@ -32,7 +32,7 @@
32
32
  "zigTarget": "x86_64-linux-gnu",
33
33
  "zigCpu": "baseline",
34
34
  "zigVersion": "0.15.2",
35
- "rustVersion": "rustc 1.99.0 (b940084d7 2026-09-28)",
35
+ "rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
36
36
  "features": {
37
37
  "executable": [],
38
38
  "sessionLock": [
@@ -5,10 +5,10 @@
5
5
  "platform": "win32",
6
6
  "architecture": "x64",
7
7
  "capability": "supported",
8
- "builtAt": "2026-10-15T16:39:57.275Z",
8
+ "builtAt": "2026-10-16T04:40:17.804Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian.exe",
11
- "sha256": "ba1fb340de0461f227244c40090b84232e849dfc2bb4888f16701a115579c7eb",
11
+ "sha256": "f4a05632945373022648d190e30504d546c9fc6000269caa1c9bc71dcec6a565",
12
12
  "size": 288256
13
13
  },
14
14
  "provenance": {
@@ -7,15 +7,15 @@
7
7
  "architecture": "x64",
8
8
  "target": "x86_64-pc-windows-msvc",
9
9
  "capability": "supported",
10
- "builtAt": "2026-10-15T16:41:35.484Z",
10
+ "builtAt": "2026-10-16T04:45:12.553Z",
11
11
  "artifact": {
12
12
  "filename": "terminal-host.exe",
13
- "sha256": "cbcda1f0a7234ac3a2938fbedecaa71e93c0a9b18bfcc52afb434fc5c8c3e038",
13
+ "sha256": "54bce17829832c1b51ff0a917fe6e194a7a2723475011ed252613b40d5573e72",
14
14
  "size": 5114368
15
15
  },
16
16
  "sessionLock": {
17
17
  "filename": "a1_session_lock.node",
18
- "sha256": "9eb9f269336acd2955640c1044df2bcfceabbe43bdbc441f2b41e08072ffbd29",
18
+ "sha256": "f3e6feb29394ca216150f2f606c150802112e2de0c90801aaabe5ecb343c6a4a",
19
19
  "size": 1996288
20
20
  },
21
21
  "notices": {
@@ -32,7 +32,7 @@
32
32
  "zigTarget": "x86_64-windows-msvc",
33
33
  "zigCpu": "baseline",
34
34
  "zigVersion": "0.15.2",
35
- "rustVersion": "rustc 1.99.0 (b940084d7 2026-09-28)",
35
+ "rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
36
36
  "features": {
37
37
  "executable": [],
38
38
  "sessionLock": [
@@ -11,8 +11,8 @@ Version-1 and version-2 deliveries and their existing comments, acceptance PRs,
11
11
  1. **Draft plan:** create one normally named branch/PR such as `feature/...`, `fix/...`, or `chore/...`. Start the body with `## Proposal`, use it for one or two sentences of intent, and follow it with two to ten unchecked, outcome-sized task items under `## Implementation`. Omit generic process tasks, quoted phase lines, and routine validation command lists, and keep machine linkage under final collapsed `Automation`. Keep it draft and include only planning artifacts until the maintainer approves the plan and explicitly requests implementation.
12
12
  2. **Same-PR implementation:** continue after explicit approval in the same worktree, branch, history, draft PR, and phase-free body. Check an Implementation item as soon as its associated implementation, focused pre-ready evidence, and detailed task bookkeeping are complete; an ordinary progress edit changes only `[ ]` to `[x]` and is not deferred until handoff. Adding, removing, reordering, or rewriting an item is a scope refinement requiring explicit approval and coherent planning updates, with affected scope left unchecked. Reconcile approved refinements before corresponding code edits.
13
13
  3. **Complete evidence:** finish implementation, required pre-ready tests/evidence, substantive tasks, and explicit known-gap disposition. CI success is later objective evidence, not acceptance, and GitHub check counts are not Implementation task progress.
14
- 4. **Plain acceptance list:** before checking the final item, keep the body phase-free and add final `## Acceptance` with one to ten concise implementation-specific behavior-and-result bullets. Do not use checkboxes, generic review/CI/approval/archive statements, URLs, mentions, or automated-test inventory.
15
- 5. **Automatic readiness and finalization:** reconcile and push current `origin/develop`, then check the final item. That checkbox update completes the agent-owned implementation job; agents never mark implementation PRs ready themselves. Trusted automation revalidates the exact fully complete version-3 task-list snapshot and all pre-finalization inputs, marks the PR ready, and then conservatively synchronizes all deltas, moves the active change into its dated archive, stages the conditional acceptance manifest, commits that to the same branch with the archive App identity, and writes the emitted paths into the body's implementation fence. It never checks tasks or infers completion. Running the [finalization command](#finalization-command) locally first is optional and yields the same bytes.
14
+ 4. **Plain acceptance list:** before checking the final item, keep the body phase-free and add final `## Acceptance` with one to ten concise implementation-specific behavior-and-result bullets. Do not use checkboxes, generic review/CI/approval/archive statements, angle-bracket placeholders or HTML, URLs, mentions, or automated-test inventory.
15
+ 5. **Automatic readiness and finalization:** reconcile and push current `origin/develop`, run the [delivery body check](#delivery-body-check) on the intended final body, then check the final item. That checkbox update completes the agent-owned implementation job; agents never mark implementation PRs ready themselves. Trusted automation revalidates the exact fully complete version-3 task-list snapshot and all pre-finalization inputs, marks the PR ready, and then conservatively synchronizes all deltas, moves the active change into its dated archive, stages the conditional acceptance manifest, commits that to the same branch with the archive App identity, and writes the emitted paths into the body's implementation fence. It never checks tasks or infers completion. Running the [finalization command](#finalization-command) locally first is optional and yields the same bytes.
16
16
  6. **Validate:** one normal exact-head workflow validates the finalized head: implementation, synchronized specs, archive, manifest, tasks/evidence, exact PR-body list, and every selected product/governance scope before emitting the stable protected aggregate. A new commit or acceptance-list change re-finalizes automatically when needed and requires full renewed validation; no lifecycle body edit or second workflow run is required.
17
17
  7. **Maintainer integration accepts:** after reviewing the finalized candidate, an authorized human either manually merges the exact validated head after the stable protected aggregate succeeds or personally enables GitHub native auto-merge for that unchanged head so protected integration waits for the aggregate. That human action means the listed scenarios are accepted. Agents, Apps, bots, merge queue, automation-owned implementation arms, and documentation integration remain forbidden. A changed head, acceptance list, or finalization invalidates the earlier arm and requires the maintainer to choose again.
18
18
  8. **Verify and clean:** trusted post-merge policy derives `Archived` and reports `accepted-and-archived` from committed bytes and immutable GitHub provenance without editing the accepted PR body. It publishes no lifecycle branch or PR. Shared exact-head remote cleanup may delete the unchanged topic ref; local cleanup remains separately ownership-controlled: the agent parks the worktree with `handoff` at step 7, and the next session's `sweep` removes it once the merge, archive, and remote-ref evidence verify (see [local cleanup](local-worktree-cleanup.md)).
@@ -141,13 +141,25 @@ Use plain bullets:
141
141
  - Finalized specs and archive match the implementation.
142
142
  ```
143
143
 
144
+ Each Implementation and Acceptance item is one line of 20 to 300 bytes. It must not contain angle-bracket text such as `<job>` or other HTML, URLs, or `@` mentions, and Acceptance items must not be checkboxes. Write a concrete example instead of a placeholder, such as `Develop / Build process guardian`.
145
+
146
+ ### Delivery body check
147
+
148
+ Before checking the final Implementation item, write the intended final body to an ignored artifact file and run the same body validators that trusted promotion uses:
149
+
150
+ ```bash
151
+ node scripts/governance/check-delivery-body.mjs --body-file .artifacts/agent/pr-body.md --final
152
+ ```
153
+
154
+ `--final` validates the body as if every Implementation item were checked, so it can run before the last marker changes. `--pr <n>` reads the current pull request body instead. A defect exits 1 and prints the same `draft-<code>` reason the finalization run would report. The check covers association, Implementation, layout, and Acceptance only; detailed tasks, evidence, and target state remain covered by the [finalization command](#finalization-command) inspection mode.
155
+
144
156
  The committed conditional manifest contains the same ordered text. Trusted policy validates membership but never checks or edits it and never claims that the scenarios passed. The authorized maintainer's manual merge or personal native auto-merge arm for the unchanged exact head is the acceptance decision; no acceptance comment, checkbox edit, review-approval requirement, JSON edit, acceptance PR, archive PR, or later command is needed.
145
157
 
146
158
  If the body list changes, candidate validation reruns and compares it with the committed manifest. If the head changes, all prior exact-head CI is stale. If only the body changes to disagree with the manifest, integration remains blocked until the list and committed candidate agree again. No lifecycle body edit is needed after green CI.
147
159
 
148
160
  ## Automated finalization
149
161
 
150
- The `OpenSpec finalization` workflow (`.github/workflows/openspec-finalization.yml`) runs on `pull_request_target` for `opened`, `synchronize`, `ready_for_review`, `reopened`, and `edited` events targeting `develop`, one event at a time per PR. It checks out default-branch policy, installs the pinned tooling without hooks, and runs `scripts/governance/publish-openspec-finalization.mjs --pr <n>`; the PR head enters that process only as the `openspec/` tree the pinned OpenSpec engine reads. An all-checked version-3 task-list draft with valid Acceptance and complete detailed pre-finalization inputs is re-read as one exact snapshot and marked ready; no content is changed, and incomplete, malformed, legacy, unassociated, forked, or raced drafts remain draft with a stable reason. Closed PRs are skipped. For a ready version-3 candidate the workflow reconciles the head to its finalized form:
162
+ The `OpenSpec finalization` workflow (`.github/workflows/openspec-finalization.yml`) runs on `pull_request_target` for `opened`, `synchronize`, `ready_for_review`, `reopened`, and `edited` events targeting `develop`, one event at a time per PR. It checks out default-branch policy, installs the pinned tooling without hooks, and runs `scripts/governance/publish-openspec-finalization.mjs --pr <n>`; the PR head enters that process only as the `openspec/` tree the pinned OpenSpec engine reads. An all-checked version-3 task-list draft with valid Acceptance and complete detailed pre-finalization inputs is re-read as one exact snapshot and marked ready; no content is changed, and incomplete, malformed, legacy, unassociated, forked, or raced drafts remain draft with a stable reason. A draft with any unchecked item is skipped quietly. A draft whose every task-list item is checked but whose promotion is refused for a body, task, evidence, or other content defect fails the run with an `OpenSpec finalization` error annotation naming the `draft-<code>` reason, so the stall shows as a red check instead of a green skip. Closed PRs are skipped. For a ready version-3 candidate the workflow reconciles the head to its finalized form:
151
163
 
152
164
  - **Active and current:** ordinary finalization with today's UTC date; one `docs(openspec): finalize <change>` commit.
153
165
  - **Finalized, valid, and current:** nothing is pushed; the run reports `already-finalized`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1",
3
- "version": "0.2.7-dev.772",
3
+ "version": "0.2.7-dev.779",
4
4
  "description": "Standalone terminal workspace for supervised native and managed agents",
5
5
  "type": "module",
6
6
  "privateLaunchContract": "neutral-launch-v1",