@timurproko/a1 0.2.7-dev.1245 → 0.2.7-dev.1249

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.
@@ -543,8 +543,8 @@ export class SettingsApp {
543
543
  flagDialog: entry.backend !== "a1" ? null
544
544
  : entry.id === PLUS_MENU_SETTING_ID ? new PlusMenuDialog(entry.flags)
545
545
  : entry.id === TAB_BAR_RIGHT_ITEMS_SETTING_ID ? new FlagToggleDialog(entry.flags, {
546
- title: "Right Side",
547
- description: "Choose what the right side of the tab bar shows.",
546
+ title: "Widgets",
547
+ description: "Choose which widgets the tab bar shows.",
548
548
  empty: "No items match",
549
549
  }) : null,
550
550
  filter: modelDialog === null ? null : new LineInput(""),
@@ -186,6 +186,9 @@ export class SupervisorServer {
186
186
  this.#supersededPoll = null;
187
187
  for (const client of this.#clients)
188
188
  client.destroy();
189
+ // Concurrency: disconnect reconciliation can still commit a terminal outcome after its
190
+ // bounded process wait. Settle it before retiring the endpoint and closing shared storage.
191
+ await Promise.allSettled(this.#reconciliations.values());
189
192
  await withEndpointLock(this.paths.endpointMetadataPath, async () => {
190
193
  try {
191
194
  await this.#metadataWrites.catch(() => undefined);
@@ -455,6 +458,8 @@ export class SupervisorServer {
455
458
  const existing = this.#reconciliations.get(instanceId);
456
459
  if (existing)
457
460
  return existing;
461
+ if (this.#closing)
462
+ return Promise.resolve();
458
463
  const reconciliation = this.#performReconciliation(instanceId).finally(() => this.#reconciliations.delete(instanceId));
459
464
  this.#reconciliations.set(instanceId, reconciliation);
460
465
  return reconciliation;
@@ -19,7 +19,7 @@ export function observeCompactionProgress(session, onProgress) {
19
19
  let expected = DEFAULT_EXPECTED_COMPACTION_SUMMARY_CHARS;
20
20
  let reported = null;
21
21
  const report = (percent = Math.min(MAX_STREAMING_PERCENT, Math.floor((100 * streamed) / expected))) => {
22
- if (percent === reported)
22
+ if (reported !== null && percent <= reported)
23
23
  return;
24
24
  reported = percent;
25
25
  onProgress(percent);
@@ -29,6 +29,18 @@ export function observeCompactionProgress(session, onProgress) {
29
29
  if (!active || disposed)
30
30
  return stream;
31
31
  const observed = generation;
32
+ // Concurrency: Pi resolves result() before an independent iterator receives the terminal
33
+ // event, so register first to publish 100 before Pi can emit compaction_end.
34
+ try {
35
+ void stream.result().then(result => {
36
+ if (observed !== generation || !active || disposed || result.stopReason !== "stop")
37
+ return;
38
+ report(COMPLETE_PERCENT);
39
+ }, () => undefined);
40
+ }
41
+ catch {
42
+ // Invariant: optional observation never affects the stream returned to Pi.
43
+ }
32
44
  void (async () => {
33
45
  report();
34
46
  // Invariant: observation never affects the request; a stream that cannot be iterated ends observation only.
@@ -41,10 +53,6 @@ export function observeCompactionProgress(session, onProgress) {
41
53
  report();
42
54
  }
43
55
  }
44
- // Invariant: normal exhaustion is the only observed completion boundary. The real
45
- // compaction_end event owns work-state exit; errors and stale generations never claim 100%.
46
- if (observed === generation && active && !disposed)
47
- report(COMPLETE_PERCENT);
48
56
  }
49
57
  catch {
50
58
  return;
@@ -7,7 +7,7 @@
7
7
  "platform": "darwin",
8
8
  "architecture": "arm64",
9
9
  "capability": "supported",
10
- "builtAt": "2026-11-06T08:23:55.616Z",
10
+ "builtAt": "2026-11-06T18:31:39.019Z",
11
11
  "artifact": {
12
12
  "filename": "process-guardian.node",
13
13
  "sha256": "9ab579426034c752ef8ed53a789566f5b7cfe102149d30c28f4bdb60e73107c5",
@@ -9,11 +9,11 @@
9
9
  "architecture": "arm64",
10
10
  "target": "aarch64-apple-darwin",
11
11
  "capability": "supported",
12
- "builtAt": "2026-11-06T08:27:51.656Z",
12
+ "builtAt": "2026-11-06T18:34:18.531Z",
13
13
  "artifact": {
14
14
  "filename": "terminal-host.node",
15
- "sha256": "b2548f95b9660b11b6d28fb4b35f254cde9940d9d19233517bb70507ffcf76ab",
16
- "size": 6626528
15
+ "sha256": "7dcfd045769d22ffd59f11974a7d5d490199ee67eec288e92224be4c049857d7",
16
+ "size": 6645216
17
17
  },
18
18
  "entry": {
19
19
  "filename": "dist/foundation/resident-tabs/host-entry.js",
@@ -7,7 +7,7 @@
7
7
  "platform": "darwin",
8
8
  "architecture": "x64",
9
9
  "capability": "supported",
10
- "builtAt": "2026-11-06T08:24:02.357Z",
10
+ "builtAt": "2026-11-06T18:31:46.232Z",
11
11
  "artifact": {
12
12
  "filename": "process-guardian.node",
13
13
  "sha256": "65f3a469a6faa9b578bc095e7559012775ee85e5b93cbc9451c62604f769146e",
@@ -9,11 +9,11 @@
9
9
  "architecture": "x64",
10
10
  "target": "x86_64-apple-darwin",
11
11
  "capability": "supported",
12
- "builtAt": "2026-11-06T08:31:58.733Z",
12
+ "builtAt": "2026-11-06T18:37:01.604Z",
13
13
  "artifact": {
14
14
  "filename": "terminal-host.node",
15
- "sha256": "cd1103472889d53e2e039cf7673b2fe6e9e0937234591b1202234d0c1c357d2a",
16
- "size": 7226904
15
+ "sha256": "691f821e9a4d2da71866dbe09742909d8f8c46fc330bdb917e8b81de2fa83450",
16
+ "size": 7249568
17
17
  },
18
18
  "entry": {
19
19
  "filename": "dist/foundation/resident-tabs/host-entry.js",
@@ -7,7 +7,7 @@
7
7
  "platform": "linux",
8
8
  "architecture": "x64",
9
9
  "capability": "supported",
10
- "builtAt": "2026-11-06T08:23:51.242Z",
10
+ "builtAt": "2026-11-06T18:26:24.402Z",
11
11
  "artifact": {
12
12
  "filename": "process-guardian.node",
13
13
  "sha256": "64232d4c827bb7f69c14612986f9b6780a0593d8842cd039a411b6bfe29cd5da",
@@ -9,11 +9,11 @@
9
9
  "architecture": "x64",
10
10
  "target": "x86_64-unknown-linux-gnu",
11
11
  "capability": "supported",
12
- "builtAt": "2026-11-06T08:26:29.024Z",
12
+ "builtAt": "2026-11-06T18:28:48.745Z",
13
13
  "artifact": {
14
14
  "filename": "terminal-host.node",
15
- "sha256": "f5abfe9464780c9acdf85dfbf8a0f194bf0355188ab23feaa09cb7df84363088",
16
- "size": 8010960
15
+ "sha256": "70f658de12b148666d0414e8a0fd0d8a10844d7a0ee6e2b11c2013477f4db91f",
16
+ "size": 8033296
17
17
  },
18
18
  "entry": {
19
19
  "filename": "dist/foundation/resident-tabs/host-entry.js",
@@ -7,10 +7,10 @@
7
7
  "platform": "win32",
8
8
  "architecture": "x64",
9
9
  "capability": "supported",
10
- "builtAt": "2026-11-06T08:24:41.351Z",
10
+ "builtAt": "2026-11-06T18:27:06.362Z",
11
11
  "artifact": {
12
12
  "filename": "process-guardian.node",
13
- "sha256": "dab6b6aed5ab24435d7814fc5099f26707486ee187551ff1dfd939679682f32b",
13
+ "sha256": "e8f4a87276da9375c998d9cdb28c2ed5d4ed857089001c338a689bb045d75dad",
14
14
  "size": 414208
15
15
  },
16
16
  "provenance": {
@@ -9,11 +9,11 @@
9
9
  "architecture": "x64",
10
10
  "target": "x86_64-pc-windows-msvc",
11
11
  "capability": "supported",
12
- "builtAt": "2026-11-06T08:29:00.280Z",
12
+ "builtAt": "2026-11-06T18:29:48.572Z",
13
13
  "artifact": {
14
14
  "filename": "terminal-host.node",
15
- "sha256": "00dc90f70d76ff36418a301d36dd406d143a6bf1da6b56e24ae5341b4e0c7d8e",
16
- "size": 7131136
15
+ "sha256": "712c6ed93b1d9fa307a6e12045222c1cbf34be1044360d1a0070d694bdfe2f55",
16
+ "size": 7155712
17
17
  },
18
18
  "entry": {
19
19
  "filename": "dist/foundation/resident-tabs/host-entry.js",
@@ -230,7 +230,7 @@ export declare const OWNED_SETTING_DECLARATIONS: Readonly<{
230
230
  }>;
231
231
  readonly tabBarRightItems: Readonly<{
232
232
  id: "tabBarRightItems";
233
- label: "Right side";
233
+ label: "Widgets";
234
234
  section: Readonly<{
235
235
  id: "tabs";
236
236
  title: "Tab Bar";
@@ -177,7 +177,7 @@ export const OWNED_SETTING_DECLARATIONS = Object.freeze({
177
177
  }),
178
178
  tabBarRightItems: Object.freeze({
179
179
  id: "tabBarRightItems",
180
- label: "Right side",
180
+ label: "Widgets",
181
181
  section: TABS_SECTION,
182
182
  description: "Choose whether the tab bar's right side shows the executing Version, Time, both, or neither.",
183
183
  application: "live",
@@ -95,31 +95,37 @@ Build output mirrors the production namespaces directly under ignored `dist/`, w
95
95
 
96
96
  Every task worktree must be created at `{working-dir}/.worktrees/<task-id>`, where `{working-dir}` is the agent session's initial working directory. The `.worktrees` directory is inside that working directory, not beside it. For working directory `D:/Git/a1`, `D:/Git/a1/.worktrees/<task-id>` is correct and `D:/Git/a1-<task-id>` is forbidden.
97
97
 
98
- From the initial working directory, run `a1 session worktrees` to inspect cooperative live ownership before selecting an existing checkout. A `busy` or `unverifiable` worktree is unavailable. An `available` checkout may be reused only when its exact branch, OpenSpec change, and pull request match the requested stream and atomic `a1 session link-worktree <absolute-worktree>` succeeds; names, similar files, recency, cleanliness, and ancestry are not ownership evidence. Otherwise create a fresh task branch/worktree, link it from the owning A1 session, and continue to address it explicitly:
99
-
100
- ```sh
101
- a1 session worktrees
102
- git fetch origin develop
103
- git worktree add -b <type>/<short-description> .worktrees/<task-id> origin/develop
104
- a1 session link-worktree <absolute-worktree>
105
- git -C .worktrees/<task-id> status
106
- ```
98
+ ### Common Git workflow
99
+
100
+ External agents use ordinary Git without an A1 installation, runtime, or session link. Keep primary on `develop`, run the bounded cleanup sweep and relay its `lines`, then inspect `git worktree list --porcelain` from primary. Inventory is read-only and advisory; it is not atomic editing exclusion or permission to adopt a checkout.
107
101
 
108
- Claude Code sessions have no A1 shell-tool session, so they link with Claude Code's `EnterWorktree` tool by task name. The tracked `.claude/settings.json` wires a `WorktreeCreate` hook, `scripts/governance/claude-worktree-create.mjs`, that creates `.worktrees/<task-id>` detached at fresh `origin/develop`, or returns it when it is already registered, so Claude Code anchors the session there without an approval prompt. The agent then creates the task branch inside it:
102
+ For a new delivery, create a unique absent task path and a new topic branch from freshly fetched `origin/develop`, unless the maintainer selected another base. For example, with primary at `D:/Git/a1` and unused task/branch names:
109
103
 
110
- ```sh
111
- git -C .worktrees/<task-id> switch -c <type>/<short-description>
104
+ ```bash
105
+ cd /d/Git/a1 && git fetch origin develop && git worktree add -b feature/example-task .worktrees/example-task origin/develop && git -C .worktrees/example-task rev-parse --show-toplevel --git-common-dir && git -C .worktrees/example-task status --short --branch
112
106
  ```
113
107
 
114
- Passing an absolute `path` to `EnterWorktree` is reserved for a worktree created by hand, from the primary checkout, before any shell command in that session; Claude Code otherwise keeps its shell tools anchored to the primary checkout and refuses their commands. The matching `WorktreeRemove` hook declines removal, so sessions leave with `ExitWorktree` `keep` and worktrees are removed only by the cleanup tool.
108
+ Successful creation by this session establishes provenance for that fresh checkout. Before planning, implementation, test, or delivery-documentation edits, verify the exact canonical root, common Git repository, intended branch, and working-tree state. Relative Git directory results must resolve to the primary repository's common directory. A path/branch collision never permits force creation, overwriting, or adoption of the existing checkout. A context mismatch means stop edits and report the blocker; never fall back to task edits in primary.
109
+
110
+ ### Resume and ownership
111
+
112
+ Reuse an existing checkout only when its exact branch, OpenSpec change, and PR match the requested stream and continuing ownership or explicit handoff from the prior owner or maintainer is established without conflicting ownership evidence. Names, similar files, recency, cleanliness, and ancestry are not ownership evidence. Inspect Git worktree locks and the cleanup journal's `status`; claim any released cleanup registration through the [cleanup ownership protocol](../local-worktree-cleanup.md#resume-or-recover-ownership) before editing. An owned registration requires matching owner authority. Neither an unregistered path nor a successful cleanup claim proves that no other editor is using it.
113
+
114
+ Known live editing claims, foreign cleanup ownership, Git locks, and unverifiable handoffs block reuse. Stop edits and report the blocker, or use a safe fresh worktree without overriding, recovering, unlocking, unlinking, or waiting out another owner. Preserve the existing delivery's branch/history/PR: do not force a branch checked out elsewhere or create a replacement PR to evade ownership. If the same stream cannot safely continue, report that concrete blocker.
115
+
116
+ Repeat exact-context and ownership verification when resuming or switching streams. Handoffs name the absolute worktree, branch, change, PR, and whether editing ownership is being handed over. This is cooperative coordination, not enforcement against arbitrary external editors. Missing A1 integration alone never blocks external agents and is not evidence of a conflicting owner.
117
+
118
+ ### Environment-specific adapters
119
+
120
+ Inside an active A1 shell-tool session only, run `a1 session worktrees` and `a1 session link-worktree <absolute-worktree>` before edits to acquire the runtime's editing claim and footer association. An `available` result still needs atomic linking; a `busy` or `unverifiable` owner, failed association, lost race, or different returned path blocks edits there. A failed stream switch preserves the prior association. External agents use the common Git workflow instead of fabricating runtime identities or starting A1 just to satisfy repository policy.
115
121
 
116
- Inventory is read-only and advisory because another runtime may win a later race. A successful link response confirming the exact canonical worktree is required before planning, implementation, test, or delivery-documentation edits. If inventory or linking fails, reports a live/unverifiable owner, loses a race, or confirms another path, stop task edits and report the blocker; use a separate fresh worktree rather than overriding, unlinking, or recovering that owner. A session resuming an existing delivery or switching streams atomically claims and links the exact worktree before editing it.
122
+ A stale Git registration elsewhere whose directory is missing and whose row is `prunable` may be pruned before retrying inventory; this does not permit removing a live checkout. Mutation-gate corruption and transient A1 startup-registration failures have a separate [worktree-link recovery procedure](../worktree-link-recovery.md). Recovery never overrides a live or unverifiable editing claim.
117
123
 
118
- Mutation-gate corruption and transient startup-registration failures have a separate [worktree-link recovery procedure](../worktree-link-recovery.md). Automatic recovery never overrides a live or unverifiable editing claim; ambiguous legacy gates remain protected.
124
+ Claude Code uses its established `EnterWorktree` tool by task name. The tracked `.claude/settings.json` wires `scripts/governance/claude-worktree-create.mjs` to create `.worktrees/<task-id>` detached at fresh `origin/develop`, or return an already registered path. The agent must still establish ownership before reusing that path and create the topic branch in a new detached worktree before editing. Passing an absolute `path` to `EnterWorktree` is reserved for a worktree created by hand, from primary before any shell command in that session. The matching `WorktreeRemove` hook declines removal: leave with `ExitWorktree` `keep` and use only the guarded cleanup tool for removal. Other agents do not need these tools or hooks.
119
125
 
120
- The link acquires a cooperative live-session editing claim and switches bare A1's footer repository context and pull-request discovery. It does not change process or tool cwd, create a Git worktree lock, or register, release, or authorize cleanup. Clean unlink/disposal releases live editing authority; a crashed owner becomes reusable only after exact process death is verified. Repository commands therefore keep an explicit worktree path. The primary worktree stays on `develop` for integration and must not be used for task edits. Do not edit, adopt, move, or remove another session's worktree.
126
+ A1 linking acquires a cooperative live-session editing claim and switches footer repository/PR discovery; an existing draft PR is not required when linking first succeeds. Clean unlink/disposal releases that runtime claim; a crashed A1 owner becomes reusable only after exact process death is verified. Runtime association does not change process or tool cwd, create a Git lock, or register, release, or authorize cleanup. Context verification and editing handoff also grant no acceptance, finalization, merge, deletion, or cleanup authority. Repository commands therefore keep an explicit worktree path. The primary worktree stays on `develop` for integration and must not be used for task edits. Do not edit, adopt, move, or remove another session's worktree.
121
127
 
122
- An agent that directly chooses a transient file path for a PR/comment body, command payload, captured output, temporary patch/diff, or ad hoc log must place it beneath the linked worktree's exact `.artifacts/` root, never the primary checkout, another worktree, OS temp, home/desktop, or a sibling path. Such scratch remains ignored, unstaged, uncommitted, disposable, non-authoritative, and secret-free. This repository path rule does not relocate storage internally selected by tools, product runtime code, or hermetic tests.
128
+ An agent that directly chooses a transient file path for a PR/comment body, command payload, captured output, temporary patch/diff, or ad hoc log must place it beneath the verified task worktree's exact `.artifacts/` root, never the primary checkout, another worktree, OS temp, home/desktop, or a sibling path. Such scratch remains ignored, unstaged, uncommitted, disposable, non-authoritative, and secret-free. This repository path rule does not relocate storage internally selected by tools, product runtime code, or hermetic tests.
123
129
 
124
130
  ## Documentation and comments
125
131
 
@@ -40,7 +40,7 @@ Source builds require Rust/Cargo 1.85 or newer; `rust-toolchain.toml` pins the e
40
40
 
41
41
  `npm run build` compiles `native/process-guardian` as the host platform's Node-API 9 addon, places `process-guardian.node` under `dist/native/<platform>-<architecture>/`, loads it to observe its version identity, and writes the v2 integrity manifest. It also builds the current platform's release-profile `terminal-host.node`, whose v2 manifest binds the addon, `dist/foundation/resident-tabs/host-entry.js`, and notices, so the ordinary `npm run build && ./scripts/dev` handoff exercises resident tabs without deployment. On Windows the normal build reuses a compatible ignored terminal-library cache or downloads the newest compatible library from the current branch or a successful CI run belonging to a pull request already merged into `develop`, then links it under the crate's manifest verification; it never silently invokes the quarantined Zig package fetch. An unavailable or mismatched prerequisite fails the build instead of leaving a nominally successful single-agent-only tree. The npm `prepare` lifecycle and validation preflight use the explicit core build because selected native lanes assemble and certify terminal hosts separately.
42
42
 
43
- Preview and stable candidate workflows build the addons on isolated Windows, Linux, and macOS arm64 runners, cross-compile the macOS x64 addons on the arm64 runner with `--target x86_64-apple-darwin`, and assemble all targets before packing. Those release runners retain their explicit `npm run build:terminal-host` step and pinned Zig input rather than consuming a workstation cache. Cross-compiled artifacts record a Mach-O architecture check when they cannot be loaded on the producing runner. Supported native code is always loaded by Node; an absent, incompatible, or unsupported addon fails before runtime startup rather than falling back to PID-only cleanup. The process-guardian addon inherits terminal handles but transports no terminal bytes. Its separate Node-hosted exit watcher restores terminal state after guardian failure, subject to the documented node-wide-kill gap. See [`process-guardian-provenance.md`](process-guardian-provenance.md), [`terminal-host-provenance.md`](terminal-host-provenance.md), and [`resident-tabs.md`](resident-tabs.md).
43
+ Preview and stable candidate workflows build the addons on isolated Windows, Linux, and macOS arm64 runners, cross-compile the macOS x64 addons on the arm64 runner with `--target x86_64-apple-darwin`, and assemble all targets before packing. Those release runners retain their explicit `npm run build:terminal-host` step and pinned Zig input rather than consuming a workstation cache; Development validation lanes may instead restore a CI-built release addon from an exact-input cache and re-verify it (see [`../ci-release-runbook.md`](../ci-release-runbook.md)). Cross-compiled artifacts record a Mach-O architecture check when they cannot be loaded on the producing runner. Supported native code is always loaded by Node; an absent, incompatible, or unsupported addon fails before runtime startup rather than falling back to PID-only cleanup. The process-guardian addon inherits terminal handles but transports no terminal bytes. Its separate Node-hosted exit watcher restores terminal state after guardian failure, subject to the documented node-wide-kill gap. See [`process-guardian-provenance.md`](process-guardian-provenance.md), [`terminal-host-provenance.md`](terminal-host-provenance.md), and [`resident-tabs.md`](resident-tabs.md).
44
44
 
45
45
  ## Gates
46
46
 
@@ -103,6 +103,8 @@ The real three-release `update-predecessor` scenario is exhaustive because its f
103
103
 
104
104
  Development outcomes report each owner/scope invocation separately while sharing authenticated build/package preparation. The aggregate reports setup, scope, job, aggregate-processing, total runner, and runner-critical-path durations. The acceptance targets are at most eight minutes of runner critical path and five minutes for one PR-required scope; an over-target result remains unmet without retries, timeout increases, workload reduction, or mutable installation caches. Hosted queue time is reported separately when available and is not counted as test execution.
105
105
 
106
+ Candidate-packing Development lanes restore the release `terminal-host.node`, its manifest, and its third-party notices from an exact-input `actions/cache` entry keyed by the native tree, `rust-toolchain.toml`, the provenance configuration, the build scripts, the pinned Zig version, and the runner image. On a hit the lane skips the Rust toolchain, Zig, and `cargo` build steps, re-records the manifest's `host-entry.js` digest from the current TypeScript build (`build-terminal-host.mjs --reuse`), and still runs `verify-native-artifacts.mjs --local` before the build receipt; any tampered or mismatched restored file fails the lane instead of rebuilding. A miss builds as before and saves the result. This is build-output reuse with a complete input key, not a mutable installation cache, and publication lanes keep building in-run. Before this reuse, each `packs_candidate` lane spent 2.6 to 3.4 minutes on the release build, and a resident-tabs pull request repeated it in four lanes. Likewise the Linux terminal-host lane caches the `cargo-fuzz 0.13.2` binary by version and nightly date instead of compiling it each run, and the three terminal-host partition jobs run only their `role_integration` slice, so the crate's unit tests execute once per target per run rather than four times.
107
+
106
108
  Inspect local committed and worktree impact without running tests:
107
109
 
108
110
  ```sh
@@ -184,6 +184,10 @@ After a low-level release, request a pass from the stable checkout if queue clea
184
184
 
185
185
  ## Resume or recover ownership
186
186
 
187
+ This protocol works for external agents without an A1 installation, runtime, or session link. First verify the exact delivery branch, change, and PR plus continuing editing ownership or explicit handoff under the [worktree protocol](architecture/project-structure.md#development-worktrees). Inspect Git locks and this tool's `status` from the primary checkout. A familiar path, clean status, or missing A1 runtime is not evidence of another editor's absence. Known live editing claims, foreign cleanup ownership, Git locks, and unverifiable handoffs block reuse.
188
+
189
+ For a worktree with no cleanup registration, this tool supplies no ownership claim: a fresh checkout created by this session or verified continuing ownership/explicit handoff establishes editing provenance. Do not register with fabricated PR identities or create a cleanup claim solely to simulate an A1 link. For a released registration, the atomic claim below is mandatory before editing; an already-owned registration requires matching owner authority. A failed claim never authorizes recovery or takeover. A successful cleanup claim prevents cleanup but does not prove exclusive editing ownership, and an A1 runtime link does not claim the cleanup journal. Both remain cooperative, independent safeguards.
190
+
187
191
  Before resuming a released worktree, acquire it:
188
192
 
189
193
  ```bash
@@ -6,6 +6,14 @@ Unrelated standalone documentation remains separate: a non-draft unassociated PR
6
6
 
7
7
  Version-1 and version-2 deliveries and their existing comments, acceptance PRs, archive PRs, receipts, retries, and bounded catch-up remain supported under [Legacy delivery](#legacy-delivery). Do not silently convert an in-flight legacy delivery.
8
8
 
9
+ ## Worktree context across agent environments
10
+
11
+ External agents use ordinary Git worktrees without an A1 installation, runtime, or session link. Follow the [development worktree protocol](architecture/project-structure.md#development-worktrees): keep primary on `develop`, run the cleanup sweep, inspect Git inventory, and verify the exact task root, common repository, branch, and state before edits. A fresh worktree created by the session establishes its provenance. An existing delivery needs continuing ownership or explicit handoff plus the exact branch, change, and PR; inventory and a clean checkout alone grant nothing.
12
+
13
+ Use A1 inventory/linking only inside an active A1 shell-tool session, and Claude Code's established worktree hooks in that environment. Missing A1 integration alone does not block an external agent. A known live owner, Git lock, conflicting cleanup owner, or unverifiable handoff still blocks reuse. Claim any released cleanup registration through the [cleanup ownership protocol](local-worktree-cleanup.md#resume-or-recover-ownership) before editing. Neither a runtime link nor a cleanup claim proves the absence of arbitrary external editors; coordination remains cooperative.
14
+
15
+ Repeat context and ownership verification on resume or stream changes, preserve the delivery's branch/history/PR, and keep every command explicitly scoped to its worktree. Handoffs name the absolute worktree path, branch, change, PR, and whether editing ownership is being handed over. An editing handoff does not register, release, or authorize cleanup and grants no integration authority. The lifecycle below applies equally to all agent environments.
16
+
9
17
  ## Version-3 lifecycle
10
18
 
11
19
  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 one or more unchecked, outcome-sized task items under `## Implementation`, with no fixed maximum. Each item names a delivered code outcome. Omit generic process tasks; run, verify, validate, evidence, or manual-test items; 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.
@@ -94,11 +102,11 @@ Keep acceptance absent during proposal review so unfinished intent is not mistak
94
102
 
95
103
  ## Agent scratch files
96
104
 
97
- When an agent chooses a path for a transient repository-delivery file—such as a PR/comment body, command payload, captured output, temporary patch/diff, or ad hoc log—it must use a purpose-specific descendant of the exact `.artifacts/` root in the worktree that owns the operation. A linked delivery uses its linked task worktree, not the primary checkout, another worktree, the operating-system temporary directory, home/desktop, or a sibling path. Address the worktree path explicitly because session linking does not change tool cwd.
105
+ When an agent chooses a path for a transient repository-delivery file—such as a PR/comment body, command payload, captured output, temporary patch/diff, or ad hoc log—it must use a purpose-specific descendant of the exact `.artifacts/` root in the worktree that owns the operation. Use the verified task worktree, not the primary checkout, another worktree, the operating-system temporary directory, home/desktop, or a sibling path. Address the worktree path explicitly; context verification and optional runtime association do not change tool cwd.
98
106
 
99
107
  Keep these files ignored, unstaged, uncommitted, disposable, non-authoritative, and free of credentials or other prohibited sensitive data. Required durable evidence belongs in its declared tracked OpenSpec location. This rule governs paths selected by the agent; it does not relocate temporary storage internally selected by Git, GitHub CLI, OpenSpec, language/package tooling, product runtime code, test frameworks, or hermetic fixtures.
100
108
 
101
- For example, create `.artifacts/agent/pr-body.md` in the linked worktree before passing it to `gh pr create --body-file` or `gh pr edit --body-file`. The exact `.artifacts/` root remains subject to the existing guarded generated-content cleanup policy; this guidance does not authorize deletion outside that root or through unsafe filesystem boundaries.
109
+ For example, create `.artifacts/agent/pr-body.md` in the verified task worktree before passing it to `gh pr create --body-file` or `gh pr edit --body-file`. The exact `.artifacts/` root remains subject to the existing guarded generated-content cleanup policy; this guidance does not authorize deletion outside that root or through unsafe filesystem boundaries.
102
110
 
103
111
  ## Version-3 implementation metadata
104
112
 
@@ -190,7 +198,7 @@ If an unassociated implementation has already integrated, do not edit its merged
190
198
 
191
199
  ## Finalization command
192
200
 
193
- The local command remains available for inspection or when a developer prefers to finalize before the automatic ready transition; the workflow then verifies the head and pushes nothing. It has inspection mode by default and an explicit `--write` mode. It never commits, pushes, edits GitHub, marks a PR ready, or merges. Run from the linked worktree and use an ignored artifact body file so the operation can update exact version-3 paths without mutating remote PR state:
201
+ The local command remains available for inspection or when a developer prefers to finalize before the automatic ready transition; the workflow then verifies the head and pushes nothing. It has inspection mode by default and an explicit `--write` mode. It never commits, pushes, edits GitHub, marks a PR ready, or merges. Run from the verified task worktree and use an ignored artifact body file so the operation can update exact version-3 paths without mutating remote PR state:
194
202
 
195
203
  ```bash
196
204
  git fetch origin develop
@@ -52,7 +52,9 @@ node scripts/release/generate-validation-ownership-ledger.mjs --output .artifact
52
52
 
53
53
  Containment-selected modular jobs build and test the debug `process-guardian.node` addon for their exact platform, export `A1_PROCESS_GUARDIAN_PATH` to that file, and run the launch-owner integration fixtures as Node processes. The tests exercise the real addon-held Windows job or Unix process group, addon-backed identity and terminal operations, and the Node exit watcher; no fixture invokes a process-guardian executable. The Windows startup lane keeps Defender real-time protection enabled while packaged startup loads the release addon.
54
54
 
55
- The `terminal-host` owner is CI-only. A change under `native/terminal-host/` or to its run scripts selects, per platform (Windows x64, Linux x64, macOS arm64), one **Native terminal host** job and three **Native terminal host tests** partition jobs. The partition jobs each build the test profile and run one third of the serialized `role_integration` suite (`run-terminal-host-probe.mjs --partition <i>/3`, partitioned by sorted test name read from the suite's source); the feature-gated `role-host` binary stands in only for the fixed role grammar inside Rust integration tests and is never packaged. The build-and-probe job runs `npm run test:terminal-host` with the role suite skipped (`TERMINAL_HOST_PARTITION=none`), building `terminal-host.node` with Rust, Node-API 9, and Zig 0.15.2 for the lane's exact target and baseline CPU model. It loads the addon for its version and non-interactive probes, verifies the shared session-writer lock export, and uploads the debug addon and frozen protocol manifest; Linux also runs bounded decoder fuzzing.
55
+ The `terminal-host` owner is CI-only. A change under `native/terminal-host/` or to its run scripts selects, per platform (Windows x64, Linux x64, macOS arm64), one **Native terminal host** job and three **Native terminal host tests** partition jobs. The partition jobs each build the test profile and run one third of the serialized `role_integration` suite (`run-terminal-host-probe.mjs --partition <i>/3`, partitioned by sorted test name read from the suite's source) and nothing else; the crate's unit tests run once, in the build-and-probe job, rather than once per partition. The feature-gated `role-host` binary stands in only for the fixed role grammar inside Rust integration tests and is never packaged. The build-and-probe job runs `npm run test:terminal-host` with the role suite skipped (`TERMINAL_HOST_PARTITION=none`), which runs the `--lib --bins` unit tests and the `release_isolation` integration test, building `terminal-host.node` with Rust, Node-API 9, and Zig 0.15.2 for the lane's exact target and baseline CPU model. It loads the addon for its version and non-interactive probes, verifies the shared session-writer lock export, and uploads the debug addon and frozen protocol manifest; Linux also runs bounded decoder fuzzing with a `cargo-fuzz` binary restored from an exact version-and-nightly cache when one exists.
56
+
57
+ Candidate-packing lanes need the release terminal host but not its toolchain when an exact-input cache entry exists: they restore the addon, manifest, and notices, re-record the manifest's `host-entry.js` digest from the current build with `build-terminal-host.mjs --reuse`, and verify the result with `verify-native-artifacts.mjs --local` before recording the build receipt. See the Development cadence section of [`ci-release-runbook.md`](ci-release-runbook.md).
56
58
 
57
59
  The protected aggregate requires every partition of every selected platform, keyed by `partition` in the outcome authority and job envelope. Because the role suite no longer warms the resident launch paths in the build-and-probe job, its certification step runs one unmeasured `measure-resident-tabs.mjs` pass before the measured pass whose budgets are unchanged. Fidelity, latency, chaos, and certification start roles as `process.execPath dist/foundation/resident-tabs/host-entry.js` with `A1_TERMINAL_HOST_PATH` naming the addon. Windows cleanup identifies those Node-hosted residents by command line; it never kills every `node.exe` by image name. Locally, `npm run test:terminal-host` without a partition is unchanged and runs everything in one process. 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. Native lanes also publish the terminal library they linked; a local build can link it instead of running Zig (see Local native iteration in [`architecture/resident-tabs.md`](architecture/resident-tabs.md)), which is development evidence only and never replaces selected CI. `TERMINAL_HOST_CONTRACTS_ONLY=1` is a library-only diagnostic and cannot substitute for selected CI. See [`native/terminal-host/README.md`](../native/terminal-host/README.md).
58
60
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1",
3
- "version": "0.2.7-dev.1245",
3
+ "version": "0.2.7-dev.1249",
4
4
  "description": "Standalone terminal workspace for supervised native and managed agents",
5
5
  "type": "module",
6
6
  "privateLaunchContract": "neutral-launch-v1",
@@ -126,7 +126,7 @@
126
126
  "@mariozechner/clipboard": "^0.3.9"
127
127
  },
128
128
  "publication": {
129
- "source": "fc4a2588e22b6d90034465d80d7923c8fede91d8",
130
- "pullRequest": 870
129
+ "source": "fdbfddae64dfff5140ae471515eace2208be9246",
130
+ "pullRequest": 872
131
131
  }
132
132
  }