@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.
- package/dist/app/session-shell/session-shell-root.d.ts +2 -0
- package/dist/app/session-shell/session-shell-root.js +1 -1
- package/dist/app/session-shell/session-shell.js +1 -0
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.js +7 -4
- package/dist/native/darwin-arm64/a1_session_lock.node +0 -0
- package/dist/native/darwin-arm64/manifest.json +2 -2
- package/dist/native/darwin-arm64/process-guardian +0 -0
- package/dist/native/darwin-arm64/terminal-host +0 -0
- package/dist/native/darwin-arm64/terminal-host.manifest.json +6 -6
- package/dist/native/darwin-x64/a1_session_lock.node +0 -0
- package/dist/native/darwin-x64/manifest.json +3 -3
- package/dist/native/darwin-x64/process-guardian +0 -0
- package/dist/native/darwin-x64/terminal-host +0 -0
- package/dist/native/darwin-x64/terminal-host.manifest.json +5 -5
- package/dist/native/linux-x64/a1_session_lock.node +0 -0
- package/dist/native/linux-x64/manifest.json +2 -2
- package/dist/native/linux-x64/process-guardian +0 -0
- package/dist/native/linux-x64/terminal-host +0 -0
- package/dist/native/linux-x64/terminal-host.manifest.json +6 -6
- package/dist/native/win32-x64/a1_session_lock.node +0 -0
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/native/win32-x64/terminal-host.exe +0 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +4 -4
- package/docs/openspec-archive-automation.md +15 -3
- 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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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) {
|
|
Binary file
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"platform": "darwin",
|
|
6
6
|
"architecture": "arm64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-10-
|
|
8
|
+
"builtAt": "2026-10-16T04:40:04.241Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "47e9052599983a6bb0078ce6203ba18d71bec0b7b94e6a49019d11d46c3fbeca",
|
|
12
12
|
"size": 410368
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
Binary file
|
|
Binary file
|
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
"architecture": "arm64",
|
|
8
8
|
"target": "aarch64-apple-darwin",
|
|
9
9
|
"capability": "supported",
|
|
10
|
-
"builtAt": "2026-10-
|
|
10
|
+
"builtAt": "2026-10-16T04:43:05.642Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "terminal-host",
|
|
13
|
-
"sha256": "
|
|
14
|
-
"size":
|
|
13
|
+
"sha256": "3771b1f4f03de8bb088d8a3cb22dce123b3376b9365804cc819fe100aedec51f",
|
|
14
|
+
"size": 4836800
|
|
15
15
|
},
|
|
16
16
|
"sessionLock": {
|
|
17
17
|
"filename": "a1_session_lock.node",
|
|
18
|
-
"sha256": "
|
|
19
|
-
"size":
|
|
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.
|
|
35
|
+
"rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
|
|
36
36
|
"features": {
|
|
37
37
|
"executable": [],
|
|
38
38
|
"sessionLock": [
|
|
Binary file
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"platform": "darwin",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-10-
|
|
8
|
+
"builtAt": "2026-10-16T04:40:50.831Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
|
-
"sha256": "
|
|
12
|
-
"size":
|
|
11
|
+
"sha256": "ccc1272de81b06efa5e590a88dbafe30726a0fe33e0808025a6602236e5d2855",
|
|
12
|
+
"size": 394776
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
15
15
|
"language": "Rust",
|
|
Binary file
|
|
Binary file
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
"architecture": "x64",
|
|
8
8
|
"target": "x86_64-apple-darwin",
|
|
9
9
|
"capability": "supported",
|
|
10
|
-
"builtAt": "2026-10-
|
|
10
|
+
"builtAt": "2026-10-16T04:49:00.861Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "terminal-host",
|
|
13
|
-
"sha256": "
|
|
14
|
-
"size":
|
|
13
|
+
"sha256": "272f4effb0134cbb17c89e0dda86c3c7bb4fed73e423613663bc8c5c0936381f",
|
|
14
|
+
"size": 5266656
|
|
15
15
|
},
|
|
16
16
|
"sessionLock": {
|
|
17
17
|
"filename": "a1_session_lock.node",
|
|
18
|
-
"sha256": "
|
|
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.
|
|
35
|
+
"rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
|
|
36
36
|
"features": {
|
|
37
37
|
"executable": [],
|
|
38
38
|
"sessionLock": [
|
|
Binary file
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"platform": "linux",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-10-
|
|
8
|
+
"builtAt": "2026-10-16T04:39:33.511Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "94a96fa9d5178a1949d05c6d6cc9504f3030cd49a096cd9db20dd29860ea5884",
|
|
12
12
|
"size": 411760
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
Binary file
|
|
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-
|
|
10
|
+
"builtAt": "2026-10-16T04:42:14.245Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "terminal-host",
|
|
13
|
-
"sha256": "
|
|
14
|
-
"size":
|
|
13
|
+
"sha256": "d8b29e901f2fe58f41baa9e1d7cba8d5b57b9a3feb7de286347d92ced978c186",
|
|
14
|
+
"size": 5826128
|
|
15
15
|
},
|
|
16
16
|
"sessionLock": {
|
|
17
17
|
"filename": "a1_session_lock.node",
|
|
18
|
-
"sha256": "
|
|
19
|
-
"size":
|
|
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.
|
|
35
|
+
"rustVersion": "rustc 1.99.1 (58cf8f9c3 2026-10-13)",
|
|
36
36
|
"features": {
|
|
37
37
|
"executable": [],
|
|
38
38
|
"sessionLock": [
|
|
Binary file
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"platform": "win32",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-10-
|
|
8
|
+
"builtAt": "2026-10-16T04:40:17.804Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian.exe",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "f4a05632945373022648d190e30504d546c9fc6000269caa1c9bc71dcec6a565",
|
|
12
12
|
"size": 288256
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
Binary file
|
|
Binary file
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
"architecture": "x64",
|
|
8
8
|
"target": "x86_64-pc-windows-msvc",
|
|
9
9
|
"capability": "supported",
|
|
10
|
-
"builtAt": "2026-10-
|
|
10
|
+
"builtAt": "2026-10-16T04:45:12.553Z",
|
|
11
11
|
"artifact": {
|
|
12
12
|
"filename": "terminal-host.exe",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "54bce17829832c1b51ff0a917fe6e194a7a2723475011ed252613b40d5573e72",
|
|
14
14
|
"size": 5114368
|
|
15
15
|
},
|
|
16
16
|
"sessionLock": {
|
|
17
17
|
"filename": "a1_session_lock.node",
|
|
18
|
-
"sha256": "
|
|
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.
|
|
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