@aviaratech/ai-delivery 0.3.23 → 0.3.24

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 (112) hide show
  1. package/CONTRIBUTING.md +9 -0
  2. package/README.md +56 -447
  3. package/dist/agent.d.ts +5 -11
  4. package/dist/agent.js +4 -8
  5. package/dist/agent.js.map +1 -1
  6. package/dist/cli.js +12 -107
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config/deliveryConfig.d.ts +44 -55
  9. package/dist/config/deliveryConfig.js +85 -88
  10. package/dist/config/deliveryConfig.js.map +1 -1
  11. package/dist/config/deliveryConfig.test.js +13 -5
  12. package/dist/config/deliveryConfig.test.js.map +1 -1
  13. package/dist/delivery/common.js +7 -2
  14. package/dist/delivery/common.js.map +1 -1
  15. package/dist/delivery/delivery.test.js +2 -3
  16. package/dist/delivery/delivery.test.js.map +1 -1
  17. package/dist/delivery/index.d.ts +0 -6
  18. package/dist/delivery/index.js +0 -3
  19. package/dist/delivery/index.js.map +1 -1
  20. package/dist/delivery/legacy.d.ts +8 -0
  21. package/dist/delivery/legacy.js +5 -0
  22. package/dist/delivery/legacy.js.map +1 -0
  23. package/dist/delivery/policy.js +2 -13
  24. package/dist/delivery/policy.js.map +1 -1
  25. package/dist/directoryIndependent.test.d.ts +1 -0
  26. package/dist/directoryIndependent.test.js +262 -0
  27. package/dist/directoryIndependent.test.js.map +1 -0
  28. package/dist/dispatch.d.ts +29 -3
  29. package/dist/dispatch.js +160 -457
  30. package/dist/dispatch.js.map +1 -1
  31. package/dist/genericCompatibility.test.js +0 -35
  32. package/dist/genericCompatibility.test.js.map +1 -1
  33. package/dist/git.js +10 -3
  34. package/dist/git.js.map +1 -1
  35. package/dist/gitProcess.d.ts +6 -0
  36. package/dist/gitProcess.js +56 -0
  37. package/dist/gitProcess.js.map +1 -0
  38. package/dist/github/discovery.d.ts +1 -0
  39. package/dist/github/discovery.js +1 -1
  40. package/dist/github/discovery.js.map +1 -1
  41. package/dist/github/discovery.test.js +25 -20
  42. package/dist/github/discovery.test.js.map +1 -1
  43. package/dist/github/nativeIssueMetadata.d.ts +2 -2
  44. package/dist/github/nativeIssueMetadata.js.map +1 -1
  45. package/dist/github/projectDelivery.d.ts +1 -1
  46. package/dist/github/projectDelivery.js.map +1 -1
  47. package/dist/github/repo.d.ts +7 -1
  48. package/dist/github/repo.js +58 -2
  49. package/dist/github/repo.js.map +1 -1
  50. package/dist/issue.d.ts +11 -6
  51. package/dist/issue.js +136 -319
  52. package/dist/issue.js.map +1 -1
  53. package/dist/issueJournal.d.ts +1 -1
  54. package/dist/lifecycle.test.js +40 -7371
  55. package/dist/lifecycle.test.js.map +1 -1
  56. package/dist/logger.js +4 -4
  57. package/dist/logger.js.map +1 -1
  58. package/dist/mcp/tools.d.ts +26 -42
  59. package/dist/mcp/tools.js +33 -42
  60. package/dist/mcp/tools.js.map +1 -1
  61. package/dist/pluginInstaller.d.ts +1 -1
  62. package/dist/pluginPackaging.test.js +129 -0
  63. package/dist/pluginPackaging.test.js.map +1 -1
  64. package/dist/pr.d.ts +66 -114
  65. package/dist/pr.js +288 -1108
  66. package/dist/pr.js.map +1 -1
  67. package/dist/pr.test.js +295 -237
  68. package/dist/pr.test.js.map +1 -1
  69. package/dist/releaseReconciliation.test.d.ts +1 -0
  70. package/dist/releaseReconciliation.test.js +314 -0
  71. package/dist/releaseReconciliation.test.js.map +1 -0
  72. package/dist/review.d.ts +37 -7
  73. package/dist/review.js +106 -45
  74. package/dist/review.js.map +1 -1
  75. package/dist/review.test.js +30 -71
  76. package/dist/review.test.js.map +1 -1
  77. package/dist/services/agentReadinessService.d.ts +1 -1
  78. package/dist/services/agentReadinessService.js +2 -0
  79. package/dist/services/agentReadinessService.js.map +1 -1
  80. package/dist/services/deliveryAdmission.d.ts +4 -4
  81. package/dist/services/deliveryAdmission.js.map +1 -1
  82. package/dist/setup.test.js +10 -5
  83. package/dist/setup.test.js.map +1 -1
  84. package/dist/start.test.d.ts +1 -0
  85. package/dist/start.test.js +72 -0
  86. package/dist/start.test.js.map +1 -0
  87. package/dist/stdoutRegression.test.d.ts +1 -0
  88. package/dist/stdoutRegression.test.js +326 -0
  89. package/dist/stdoutRegression.test.js.map +1 -0
  90. package/dist/verification.d.ts +1 -27
  91. package/dist/verification.js +5 -1332
  92. package/dist/verification.js.map +1 -1
  93. package/dist/worktree.d.ts +1 -31
  94. package/dist/worktree.js +5 -200
  95. package/dist/worktree.js.map +1 -1
  96. package/dist/worktreeTransition.d.ts +1 -1
  97. package/dist/worktreeTransition.js +10 -5
  98. package/dist/worktreeTransition.js.map +1 -1
  99. package/dist/worktreeTransition.test.js +2 -3
  100. package/dist/worktreeTransition.test.js.map +1 -1
  101. package/package.json +1 -1
  102. package/plugins/ai-delivery/.claude-plugin/plugin.json +2 -2
  103. package/plugins/ai-delivery/README.md +3 -3
  104. package/plugins/ai-delivery/plugin.json +1 -1
  105. package/plugins/ai-delivery/runtime/dist/cli.js +50 -59
  106. package/plugins/ai-delivery/runtime/package.json +1 -1
  107. package/plugins/ai-delivery/skills/intake-create/SKILL.md +1 -1
  108. package/plugins/ai-delivery/skills/pr-handoff/SKILL.md +14 -21
  109. package/plugins/ai-delivery/skills/worktree-lifecycle/SKILL.md +12 -23
  110. package/dist/services/deliveryRecordService.d.ts +0 -47
  111. package/dist/services/deliveryRecordService.js +0 -199
  112. package/dist/services/deliveryRecordService.js.map +0 -1
package/CONTRIBUTING.md CHANGED
@@ -69,6 +69,15 @@ after publication, including a failed or ambiguous publish command, and never
69
69
  automatically retries publication. Read the registry before any explicit retry.
70
70
  Metadata presence alone does not verify a provenance signature or source identity.
71
71
 
72
+ Expected version/archive 404s, missing provenance metadata or package-index entries,
73
+ and a lagging stable `latest` tag receive paced read-only reconciliation for up to
74
+ five minutes inside the existing ten-minute publish job. Requests retain a
75
+ 30-second limit, shortened to the remaining reconciliation allowance, with bounded
76
+ response bodies and pending-state output. Conflicting evidence, a newer `latest`
77
+ tag and authentication/service errors fail immediately. Exhausted reconciliation
78
+ or an ambiguous publish result requires read-only qualification of the original
79
+ invocation; it never triggers another publication or retag.
80
+
72
81
  Any packaged-file edit, including this guide, changes the release candidate.
73
82
  Preserve previously accepted archives as evidence and independently qualify a
74
83
  new exact source/archive before dispatching; never substitute it silently.
package/README.md CHANGED
@@ -1,204 +1,78 @@
1
1
  # ai-delivery
2
2
 
3
- Generic GitHub issue and pull request delivery with Git/GitHub discovery and a source-controlled `RepositoryDeliveryPolicy@1` module. Routing overrides are optional. The package provides one `ai-delivery` CLI, one stdio MCP server, and a self-contained plugin root in `plugins/ai-delivery`. The packaged root includes portable `plugin.json` / `mcp.json`, Claude-compatible manifests, the three delivery skills, a built stdio launcher and bundled dependency notices. Hosts can copy the root into their native cache without resolving a parent npm installation or running an installation build.
3
+ GitHub issue and pull request delivery through a CLI, a stdio MCP server and a self-contained Codex/Claude Code plugin. Explicit repository calls work from any directory. The runtime reads operator-owned JSON and GitHub metadata; it never imports a consuming repository's policy or runs its checks. Run contributor checks and prepare worktrees through the host's normal tools.
4
4
 
5
- The package contains no repository-specific policy, credential, model, or deployment configuration. A consuming repository owns its issue taxonomy, author and reviewer credentials, native Project fields, delivery stages, and phase constraints. The runtime refuses an untracked override file or a missing or untracked policy module. Credentials and delivery policy remain explicit.
5
+ ## Installation and runtime
6
6
 
7
- ## Availability and installation
8
-
9
- Install the versioned package from npm or a reviewed package archive. The
10
- consuming repository must run its own configuration and runtime-admission
11
- procedure before any lifecycle write.
12
-
13
- The selected CLI, MCP server and verification controller use Node 24.21.0 and
14
- npm 11.19.0. The public library exports also support Node 26.2.0 consumers.
15
- Package checks run the Node 24 controller against actual npm-packed Node 26
16
- consumers, including filesystem fixture contention, reader and link rejection,
17
- success/failure teardown, cancellation, leaked fixtures and positive byte limits.
18
- For package development, set `AI_DELIVERY_NODE26_EXECUTABLE` to the absolute
19
- Node 26.2.0 executable before `npm run checks`; CI retains that executable while
20
- selecting Node 24 for the canonical commands.
7
+ Use Node 24.21.0 and npm 11.19.0 for the CLI, MCP server and contributor checks. Public library consumers also support Node 26.2.0. Set `AI_DELIVERY_NODE26_EXECUTABLE` to that actual executable for contributor checks. Install a qualified published version or reviewed archive, then use the [plugin guide](plugins/ai-delivery/README.md) for native installation.
21
8
 
22
9
  ```sh
23
- node --version # 24.21.0
24
- npm --version # 11.19.0
25
- npm install --save-dev @aviaratech/ai-delivery@0.3.4
26
- npx ai-delivery --help
27
- npx ai-delivery --repo-root /absolute/path/to/consumer --identity configured-author info --issue 17
28
- npx ai-delivery --repo-root /absolute/path/to/consumer --identity configured-author mcp:serve
10
+ ai-delivery --repo example/widget info --issue 17
11
+ ai-delivery mcp:serve
29
12
  ```
30
13
 
31
- `info` is a read. `verify`, PR publication, formal review submission and finish
32
- are lifecycle writes. The CLI and MCP server enforce the same admission and
33
- identity rules. The [plugin guide](plugins/ai-delivery/README.md) covers host
34
- installation.
35
-
36
- ## Configure a consuming repository
37
-
38
- Keep the repository's delivery policy in `ai-delivery.policy.mjs` at its Git
39
- root. Its default export remains `RepositoryDeliveryPolicy@1`, implementing
40
- `classifyExactRange` and `validateBoundary` with the repository's actual required
41
- checks, stages, risk and publication/merge constraints. There is no permissive
42
- default policy. Add a named `deliverySettings` export for explicit authentication
43
- roles and command settings:
44
-
45
- ```js
46
- export const deliverySettings = {
47
- roles: {
48
- author: {
49
- identity: 'delivery-author',
50
- credentialEnv: {
51
- appId: 'DELIVERY_AUTHOR_APP_ID',
52
- installationId: 'DELIVERY_AUTHOR_INSTALLATION_ID',
53
- privateKeyPath: 'DELIVERY_AUTHOR_KEY_PATH',
54
- },
55
- },
56
- reviewer: {
57
- identity: 'delivery-reviewer',
58
- credentialEnv: {
59
- appId: 'DELIVERY_REVIEWER_APP_ID',
60
- installationId: 'DELIVERY_REVIEWER_INSTALLATION_ID',
61
- privateKeyPath: 'DELIVERY_REVIEWER_KEY_PATH',
62
- },
63
- },
64
- },
65
- commandPolicy: {
66
- checks: { format: 'REQUIRED', gitClean: 'REQUIRED', lint: 'REQUIRED', test: 'REQUIRED', typecheck: 'REQUIRED' },
67
- timeoutsMs: { lint: 60000, test: 60000, typecheck: 60000 },
68
- },
69
- };
70
- // Retain the default RepositoryDeliveryPolicy@1 export with real stage commands.
71
- ```
14
+ ## User configuration
72
15
 
73
- No JSON file is needed when discovery is unambiguous. The resolver reads the
74
- checkout's single GitHub remote, verifies its repository identity with GitHub,
75
- and discovers repository issue types and inherited organization issue fields.
76
- The standard field names are `Points`, `Priority` and `Status`, with workflow
77
- options `Todo`, `In Progress`, `Blocked` and `Done`. Points and Priority must be
78
- native organization single-select issue fields bound into the Project; unrelated
79
- Project-owned fields are rejected. This release supports github.com organization
80
- repositories, matching the existing native metadata contract.
81
-
82
- The default Project is the one compatible open Project linked to that repository
83
- and visible to the configured discovery identity. All pages are read before
84
- selection. Zero or multiple compatible Projects require an explicit choice.
85
- API failures, null/partial results, and an unwritable compatible Project fail
86
- without falling back to another destination. No Project is inferred from issue
87
- history, its name, or organization-wide availability. GitHub's Project-to-default-
88
- repository setting does not define a repository's default Project. Linked
89
- Projects must belong to the repository organization.
90
-
91
- For exceptions, commit a small `ai-delivery.config.json`, for example:
16
+ Create `~/.config/aviaratech-ai/ai-delivery.json`, or set `AI_DELIVERY_CONFIG` to an absolute operator-owned JSON path. Required settings are `schemaVersion`, `roles.author`, `roles.reviewer`, `project`, and `checkoutRoots`; validation errors name the missing setting. A consuming repository needs no ai-delivery files.
92
17
 
93
18
  ```json
94
19
  {
95
- "schemaVersion": "ai-delivery.config@2",
96
- "remote": "upstream",
20
+ "schemaVersion": "ai-delivery.user@1",
21
+ "roles": {
22
+ "author": {
23
+ "identity": "host-author",
24
+ "authSource": "personal",
25
+ "credentialEnv": { "token": "DELIVERY_AUTHOR_TOKEN" }
26
+ },
27
+ "reviewer": {
28
+ "identity": "delivery-reviewer",
29
+ "credentialEnv": {
30
+ "appId": "DELIVERY_REVIEWER_APP_ID",
31
+ "installationId": "DELIVERY_REVIEWER_INSTALLATION_ID",
32
+ "privateKeyPath": "DELIVERY_REVIEWER_KEY_PATH"
33
+ }
34
+ }
35
+ },
97
36
  "project": 7,
98
- "policy": { "module": "./scripts/delivery-policy.mjs" }
37
+ "checkoutRoots": ["/absolute/path/to/clones"]
99
38
  }
100
39
  ```
101
40
 
102
- Every field is optional. Multiple remotes require `remote`; a GitHub fork also
103
- requires an explicit remote choice. `repository`, when present, is an assertion
104
- against that remote. `project` explicitly selects an organization Project number
105
- and takes precedence over linked-project discovery. `pointsField`,
106
- `priorityField`, `statusField`, and `statuses` (all four `todo`, `inProgress`,
107
- `blocked`, `done` names) express custom meanings without copying GitHub IDs or
108
- option catalogs. Optional `issueTypes` restricts the discovered enabled types;
109
- unavailable types are refused. IDs, titles and available choices remain GitHub
110
- facts. Unknown keys and legacy full-config files are refused.
111
-
112
- Worktree bases, verification, PR fetches and cleanup all use the selected remote's
113
- tracking refs. Fetch that remote and set its remote HEAD before delivery when its
114
- default branch is not `main`; delivery never falls back to another remote or a
115
- local branch to establish its base.
116
-
117
- For App roles, set environment variables for the App ID, installation ID and absolute
118
- private-key path. Secret values and keys stay outside Git. The author App needs
119
- Contents, Issues, organization Projects and Pull requests write permissions plus
120
- read access to repository issue types and fields. Discovery uses that author
121
- identity; review operations still use the distinct reviewer App (Contents read
122
- and Pull requests write suffice to submit a review). For that App's approval to
123
- satisfy a required-review rule, configure Contents write as well. Contents write
124
- also grants the App real code-write capability; grant it only when that review
125
- route is intended. Accept the App's new permissions on its installation and
126
- obtain fresh installation credentials before relying on the changed grant.
127
- Existing App author configurations remain valid.
128
-
129
- To use the host user's GitHub identity for publication, replace only the author
130
- role in `deliverySettings`:
131
-
132
- ```js
133
- author: {
134
- identity: 'host-author',
135
- authSource: 'personal',
136
- credentialEnv: { token: 'DELIVERY_AUTHOR_TOKEN' },
137
- },
138
- ```
139
-
140
- Set `DELIVERY_AUTHOR_TOKEN` outside source control to a token for the intended
141
- user. The runtime reads only that named variable for this route, uses the same
142
- token for Git HTTP push and GitHub API calls, and verifies the user login. It
143
- does not use an ambient `gh` session or another environment token. The legacy
144
- `--identity personal --personal-auth` override remains explicit for development
145
- and `config:resolve`; configure the personal author role above for complete PR
146
- delivery with matching review artifacts and policy evidence.
41
+ An App author uses the same `credentialEnv` shape as the reviewer. Roles and credential environment names must be distinct. Credential values and private keys remain outside source control. A configured personal author uses only its named token variable. The optional `--identity` or `AI_DELIVERY_IDENTITY` override must select the command's configured role; neither is needed for normal operation. The explicit legacy `--identity personal --personal-auth` override is limited to development access diagnosis under an App author configuration; publication requires the configured author.
147
42
 
148
- | Route | Package behavior | Native required approval |
149
- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
150
- | Configured personal author + reviewer App | One App submits the exact-head independent review. | With Contents write accepted on the App installation, confirm that GitHub counts it; an eligible independent human may still need to approve if another rule blocks it. |
151
- | Author App + reviewer App | Existing separate App roles keep their credential and review bindings. | With Contents write accepted on the reviewer App installation, confirm that GitHub counts its approval. |
152
- | Author App + eligible human reviewer | A valid GitHub route for a repository that requires human approval; the current package still needs its configured reviewer App for the formal artifact receipt. | The human reviews and approves in GitHub. |
43
+ The explicit organization Project number selects a compatible writable Project. Optional `pointsField`, `priorityField`, `statusField`, four `statuses` names (`todo`, `inProgress`, `blocked`, `done`), and `issueTypes` customize discovered metadata. Defaults are Points, Priority, Status and Todo/In Progress/Blocked/Done. IDs, option catalogs and issue types come from GitHub. This runtime supports github.com organization repositories and native organization single-select Points/Priority fields bound into the selected Project.
153
44
 
154
- GitHub requires qualifying approvals under [branch protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches) and [rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets). Pull requests write permits submitting a review; it does not grant repository write access for a required approval. When a required-approval rule is visible and the reviewer App's effective Contents grant is read-only, `pr:create --dry-run` reports `approvalEligibility: insufficient-permission` before publication. Unknown grants or rules remain `unknown`. The post-review readback reports `submittedReviewAuthorCanPushToRepository` when GitHub exposes it for the exact submitted review. Neither an App's scopes nor a submitted `APPROVED` review proves that it counted. The live PR `reviewDecision` is the required-review readback; it does not attribute a counted approval to one actor. Recheck it on the current head before merge.
45
+ Every remote MCP tool accepts `repo: "owner/name"`; the CLI uses global `--repo`. Without a selector, the launch checkout's `origin` supplies the destination. Explicit remote calls never probe launch-directory Git or checkoutRoots. One MCP server can switch A → B → A without restart. Tool and server selectors that disagree are refused.
155
46
 
156
- The local Git commit author is metadata. The selected author token authenticates
157
- the push and PR creation; `issue_pr_info.authorLogin` confirms the actual PR
158
- author. The independent artifact records its reviewer identity and effective
159
- model, while the submitted review receipt records the GitHub actor. Keep these
160
- identities separate when diagnosing a blocked PR.
47
+ Local runtime setup and legacy transition calls select a matching `origin` per invocation. A matching current checkout wins; otherwise `checkoutRoots` may contain exact clone roots or parents whose immediate directories contain clones. Duplicate physical matches are collapsed. Zero or multiple matches refuse with a specific diagnostic; use `--repo-root` to select the intended matching clone. Git probes disable repository hooks, filters, fsmonitor and external diff/text conversion. Remote delivery never performs a checkout, push, or worktree mutation.
161
48
 
162
- Inspect the delivery access route before development and before issuing a new
163
- runtime admission:
49
+ ## GitHub-gated lifecycle
164
50
 
165
51
  ```sh
166
- npx ai-delivery --repo-root /absolute/path/to/consumer --identity host-author config:resolve
167
- # For the explicit development override under an App author policy:
168
- npx ai-delivery --repo-root /absolute/path/to/consumer --identity personal --personal-auth config:resolve
52
+ ai-delivery --repo example/widget config:resolve
53
+ ai-delivery --repo example/widget ready:check --issue 17
54
+ ai-delivery --repo example/widget start --issue 17
55
+ # Prepare a host-owned worktree, implement, run repository checks, commit and push.
56
+ ai-delivery --repo example/widget pr:create --issue 17 --body-file ./pr-body.md --dry-run
57
+ ai-delivery --repo example/widget pr:create --issue 17 --body-file ./pr-body.md
58
+ # Obtain an independent review of the exact remote PR head and diff.
59
+ ai-delivery --repo example/widget pr:review --issue 17 --pr 23 --artifact ./review-artifact.json
60
+ ai-delivery --repo example/widget pr:create --issue 17 --ready
61
+ ai-delivery --repo example/widget pr:checks --pr 23
62
+ ai-delivery --repo example/widget finish --issue 17 --pr 23 --reviewed-head <reviewed-sha>
169
63
  ```
170
64
 
171
- This read returns `routing` (repository, Project/field/option identities and
172
- selection source), `configDigest`, effective author and reviewer actors,
173
- credential sources, reviewer repository read access, and available branch-rule
174
- evidence. A partial or unknown rule view stays labeled unknown; it does not
175
- require broader administrator access. Resolve a same-actor error, missing
176
- configured credential or reviewer repository-access mismatch before development.
177
- `develop`/`issue_develop`, starts that prepare worktrees, and
178
- `worktree:create`/`issue_worktree_create` also run this existing access preflight
179
- before preparing work. A new start with
180
- `develop: true` checks it before creating the issue. Plain issue creation and
181
- readiness checks retain their existing behavior. Access preflight does not issue
182
- or refresh runtime admission, and does not prove that an approval will count.
183
- The development override still checks the independent reviewer route; publication
184
- requires the configured author credential.
185
- Before publication, use `pr:create --issue 17 --dry-run` to inspect the current
186
- route again. After `issue_pr_review`, inspect its
187
- `reviewState` and `pr:checks`. If GitHub still reports `REVIEW_REQUIRED`, inspect
188
- the active rule and obtain a qualifying independent approval; repeating the
189
- same App review cannot resolve that state. CLI and MCP use the same asynchronous
190
- `loadDeliveryConfig` resolver. `issue_create` and `issue_info` also expose the
191
- resolved routing. An MCP server stays bound to its startup checkout; use separate
192
- bindings or explicit CLI checkout selection for multiple repositories.
193
-
194
- Public runtime setup has two explicit operations: `runtime:stage` and
195
- `runtime:admit` (MCP: `runtime_stage` and `runtime_admit`; API:
196
- `stageRuntime` and `admitRuntime` from `@aviaratech/ai-delivery/agent`). Both
197
- require the clean primary consumer checkout, its expected Git HEAD, the actual
198
- `loadDeliveryConfig` digest, an explicit configured author identity and separate
199
- operation authority. The authenticated author and distinct reviewer App must
200
- pass the existing repository-access preflight. Unknown rule visibility or
201
- approval eligibility remains unknown; setup does not establish counted approval.
65
+ `start` creates or reuses a GitHub-linked branch from the repository's default branch. It can create a tracking issue first, or resume a known partially created issue with `--resume-created`; recovery returns the exact known issue and safe arguments without creating another issue. Hosts own local worktree preparation and cleanup. PR creation accepts any non-empty body, appends the issue closing reference when absent, and reuses the matching remote branch/PR. Merged completion uses GitHub issue association even after branch deletion. Existing repository labels are accepted; an unknown label is refused before issue mutation.
66
+
67
+ For a new issue, `start --request-id <stable-id>` records inert retry markers in its body. Retry the same request after an unknown response; matching remote state is recovered, while conflicting intent or duplicate matches refuse. Without an explicit ID, identical tracking inputs share a deterministic retry identity. Supply a new ID for a separate issue with identical inputs. A retry search beyond 2,000 issues refuses and asks for the known issue number. `pr:create --head <branch>` selects an existing linked branch when an issue has several.
68
+
69
+ Formal review requires a validated independent artifact and the configured reviewer App. The artifact binds author/reviewer identities, exact commit/tree and complete changed-path digest. The review body retains the full artifact and its digest so merge can verify the original binding even if GitHub remaps a review's commit ID after a rebase. A matching remote review is reused; conflicting actor, head, state or duplicate artifact markers refuse. Submission reads back the exact review ID and artifact. Reviews containing only a historical marker require a fresh review. Its new `ai-delivery.github-review@1` receipt is separate from historical local-evidence receipts. CLI `--artifact` reads a UTF-8 JSON file; MCP takes its JSON content.
70
+
71
+ An App approval does not prove that GitHub counted it. `pr:checks` exposes the live required-review decision. Merge requires one independent exact-head App review, its current readback, satisfied GitHub review requirements, no unresolved native blockers, and fresh CLEAN eligibility at the reviewed head and current base. BLOCKED, BEHIND, DIRTY, UNSTABLE, unknown state or moved head/base refuses. The server merge mutation includes the reviewed SHA. Finish confirms the intended PR merged before closing its issue, and retries from remote readback without local receipts.
72
+
73
+ The removed `develop`, `verify`, `pr:checkout`, worktree creation/cleanup and local velocity record commands are no longer public CLI/MCP workflows. Preserve existing consumer checks, controller admissions and historical custody records. Their original schemas, digest identities, writer locks and operational closure rules remain separate. The legacy transition commands remain exposed, but this runtime cannot reproduce their historical repository-policy configuration binding: CLI/MCP inspection and apply refuse without executing policy or converting records. Complete those transitions with the original controller. Explicit runtime stage/admit remain supported.
74
+
75
+ ## Standalone plugin and explicit runtime setup
202
76
 
203
77
  Manage the native plugin with an explicit package version:
204
78
 
@@ -222,9 +96,7 @@ Every command supports `--dry-run` and `--json`. Dry-run reports the target
222
96
  without fetching an archive, running a native command, or writing configuration.
223
97
  Doctor reports managed installation and source integrity, skills, and a direct
224
98
  stdio startup check of the selected bundled MCP server. Restart the native host
225
- after changing a plugin so it reloads that selection. Installing a plugin does
226
- not admit a consumer repository: use the explicit setup operations below before
227
- a lifecycle write.
99
+ after changing a plugin so it reloads that selection. Installing a plugin does not admit a consumer controller. Ordinary remote GitHub delivery uses user configuration; explicit controller staging and admission remain separate operations.
228
100
 
229
101
  First read `config:resolve` with the configured author, then stage a reviewed
230
102
  local archive using its independently accepted SHA-256 and package version:
@@ -294,276 +166,13 @@ same stage to reconcile. Conflicting third-party bytes are preserved. The
294
166
  consuming installer's reviewed host activation and rollback determine when this
295
167
  final write occurs.
296
168
 
297
- The resolver's `configDigest` includes policy/settings source, validated
298
- effective roles and checks, optional overrides and discovered routing;
299
- **do not substitute a JSON-file hash**. Drift invalidates admission and
300
- verification receipts. Ordinary lifecycle operations never refresh admission
301
- implicitly, and candidate issue configuration is never activated by setup.
302
-
303
- To migrate from 0.1: move `roles` and `commandPolicy` into the existing policy's
304
- `deliverySettings` export; replace the old JSON with only necessary overrides
305
- (or remove it when using the default policy filename); await `loadDeliveryConfig`
306
- in installer integrations; review the resolved destination and reissue capability-2
307
- admission using its digest. Do not upgrade old receipts into approvals. Existing
308
- rows in `.issue-cli/worktrees.json` remain with their original runtime unless
309
- they already have an exact `ai-delivery.worktree-owner@1` witness. Installing this
310
- package never adopts or switches an active legacy writer.
311
-
312
- Legacy worktree transitions are explicit and separate from installation. Use
313
- `worktree:transition:inspect` (`issue_worktree_transition_inspect`) with the issue
314
- and purpose `active-resume` or `merged-cleanup`. Inspection reads the canonical
315
- row, clean source, native PR lineage, original evidence and writer inventory. It
316
- returns an exact plan or specific closure gaps without writing ownership or
317
- running the retained producer.
318
-
319
- The supported operational closure family is the retained official public
320
- `@aviaratech/ai-delivery@0.3.5` archive and installed bytes, its private
321
- `ai-delivery.runtime-admission@2`, producer-bound `ai-delivery.run@3`, and
322
- `ai-delivery.verification-writer@1` on supported POSIX hosts. Supply
323
- `--retained-admission` and `--retained-archive`. Operative `issue-cli`
324
- verification-stages v1/v2, unknown process ownership, external resource families
325
- or incomplete inventory refuse apply. Historical producer identity may remain
326
- `UNKNOWN`; its original schemas, bytes, failed diagnostics and accounting are
327
- preserved without becoming current verification, review or retirement authority.
328
-
329
- The configured authenticated personal operator must publish the returned whole
330
- relinquishment body as a native comment on the terminal PR, or on the issue for
331
- active resume. The distinct configured reviewer App must independently accept
332
- the same complete plan and relinquishment comment ID through a native exact-body
333
- acceptance comment. A caller-authored local receipt does not supply this
334
- authority. Changed/deleted comments, wrong actors or subjects, and an authenticated
335
- exact relinquishment revocation invalidate acceptance. These comments have their
336
- own acceptance semantics; they do not count as a GitHub PR review.
337
- The bodies bind the complete saved plan and inventory by their recomputed IDs;
338
- the operator and reviewer must inspect that complete plan before accepting it.
339
-
340
- Save the returned `plan` object, then call `worktree:transition:apply`
341
- (`issue_worktree_transition_apply`) with `--plan`, `--plan-id`,
342
- `--relinquishment-comment`, `--acceptance-comment`, and
343
- `--authorize-transition`. Apply preserves immutable original copies and records
344
- intent before ownership changes. Repeat the same plan and authority IDs after
345
- interruption; pending intent blocks ordinary resume, verification, publication,
346
- review, merge and re-registration. Active resume requires fresh current
347
- verification and review. Terminal transition witnesses permanently restrict
348
- ordinary source operations.
349
-
350
- When a ready issue remains open after a prerequisite PR merges, `develop` or
351
- `issue_develop` can continue its existing worktree under the same preparing owner.
352
- It requires the clean original branch and exact prior verified publication,
353
- merge intent and native merged-PR lineage. Continuation preserves the ownership
354
- witness and all prior receipts, clears the prior PR from the active registry row,
355
- and resumes Project synchronization idempotently. Commit the continuation changes
356
- before verification; the already-merged HEAD cannot produce replacement evidence.
357
- A closed issue, different owner, stale lineage or pending/terminal transition is
358
- refused. Source holds and runtime admission remain in force.
359
-
360
- A clean committed descendant can also continue when the configured personal
361
- author is the authenticated native author of the prior merged PR. The historical
362
- preparing label remains evidence. `develop` first saves an exact private plan and
363
- refuses to change custody until the native issue contains the complete operator
364
- authority body and independent configured reviewer-App acceptance. The saved
365
- templates bind the current source, configuration, installed runtime admission,
366
- original row, historical receipts and new owner. Set the acceptance template's `authorityCommentId` to the operator
367
- comment's native ID. The operator attests that all other launchers and writers
368
- are quiescent and remain excluded through recovery. The existing writer slot
369
- must be absent; this flow never recovers or terminates an unknown writer.
370
-
371
- For this committed-descendant case only, a complete empty native closing-issue
372
- connection may instead bind an explicit `Refs #<issue>` reference, with optional
373
- explanatory text, to complete native issue-timeline cross-reference evidence for
374
- the same PR, repository and authenticated historical author before the merge. The PR body alone is
375
- insufficient. Missing, incomplete or mismatched native evidence is refused;
376
- other worktree transition purposes retain their closing-issue requirement.
377
-
378
- Repeat `develop` or existing-issue `start` after interruption. Recovery checks
379
- the same pinned native comments, revocation, original bytes and exact original
380
- or replacement row before completing. Other mutations, including metadata
381
- resume, remain fenced while intent is pending. Completion retains the old
382
- witness and receipts, creates a distinct owner witness when identity changes,
383
- and permits fresh verification of the descendant and later ordinary commits.
384
- Historical approval supplies no current verification, review or hold release.
385
-
386
- Native issue metadata updates may target a legacy registered issue without
387
- adopting its worktree. The authenticated author and admitted runtime still apply,
388
- and canonical registry/schema, duplicate-owner and complete transition checks
389
- remain mandatory. Metadata updates preserve source, registry, ownership witnesses
390
- and delivery receipts; source lifecycle operations still require attested custody.
391
-
392
- Terminal disposition defaults to `retain`, preserving source and all holds.
393
- Supply native retained-hold comment IDs with `--retained-holds`. `remove` requires
394
- an independently accepted personal assertion that no holds remain, exact native
395
- merged-result lineage and the existing non-force clean-source cleanup proof.
396
- Source delivery never releases a hold, retires a legacy protocol, changes a host
397
- launcher or admits a shared runtime. Transition artifacts remain under the
398
- existing private Git `ai-delivery/worktree-owners` evidence directory; no second
399
- worktree registry is introduced.
400
-
401
- `verify` classifies a clean Git base/head range, runs only the stages selected by the repository policy, and persists content-addressed private checkpoints under the Git common directory. It reuses compatible complete stages and rejects corrupt or stale inputs. Selected stage commands run asynchronously without a total-duration deadline. Bounded JSON status lines on stderr show the current stage and command, completed/reused/remaining stage and command counts, elapsed time, captured output bytes, executed-command throughput, command age and time since completed work. They appear when a command starts and every five seconds while it runs; bounded resource observations are reported at each sample. A quiet command remains cancellable and diagnosable from its age and unchanged completion counts. Process activity and output do not establish useful progress; only complete receipts and the exact-source aggregate are checkpoints.
402
-
403
- For independent component reuse, export `schemaVersion: "RepositoryDeliveryPolicy@2"` from the existing policy. Each selected stage supplies both its ordered `semanticInputKeys` and matching explicit `semanticInputs`, for example:
404
-
405
- ```js
406
- {
407
- id: "unit",
408
- commands: [{ label: "unit", argv: ["npm", "run", "test:unit"] }],
409
- dependsOn: [],
410
- resourceClass: "focused_node",
411
- semanticInputKeys: ["unit-source"],
412
- semanticInputs: [{ key: "unit-source", digest: unitSourceDigest }],
413
- }
414
- ```
415
-
416
- The classifier owns the digest values and must include every relevant source, configuration, schema, dependency and input artifact for that stage. The runtime never derives component values from key names. Version 2 stage inputs also bind the selected commands and dependencies, policy/configuration bytes, policy producer, installed runner code and resolved dependency manifests, runtime environment, worktree identity, upstream receipt IDs and selected attestation artifacts. Unchanged compatible stages can survive an unrelated Git commit; a changed component invalidates its stage and dependents. Every final aggregate binds the current exact classification and verifies all selected stage proofs. `RepositoryDeliveryPolicy@1` remains supported with its original whole-range reuse contract; its receipts are never upgraded into component evidence. Classification, stage input, receipt and aggregate version 2 evidence uses separate stage/aggregate storage. Immutable command output remains content addressed.
169
+ The new resolver digest binds user settings, validated roles and discovered routing. Historical policy/configuration digests are not rewritten or relabeled as new bindings. Setup preserves source, archive, installed-byte and prior-admission compare-and-swap checks; a mismatched historical binding requires its original controller. No private runtime is activated by ordinary issue or PR calls.
417
170
 
418
- Verification holds one file lease per worktree and durably records its writer and observed command process identities. A second writer in the same worktree is rejected before execution. Separate worktrees can overlap, including at the same head, with separate stage inputs and mutable manifests. Callers must first qualify their commands' CPU, memory, disk, I/O and shared-file/service requirements; a resource class alone grants no shared-resource exclusivity. The runtime adds no global executor cap. On retry after writer interruption, it refuses live or unknown ownership and reconciles only the recorded command group and observed descendants before reusing compatible completed stages. A launch interrupted before command identity was recorded requires explicit reconciliation. Process identity observation is required on supported POSIX hosts; unavailable or ambiguous observation fails closed.
171
+ Legacy transitions remain explicit preservation operations. Inspection returns exact closure gaps for unsupported bindings. Applying a supported plan still requires its immutable inventory, authenticated native personal-operator relinquishment and independent configured App acceptance, exact plan/comment IDs, writer quiescence and runtime admission. Installing this package does not adopt legacy custody or release retained holds.
419
172
 
420
- The `--admit` flag explicitly admits additional resource classes for execution. Compatible complete stages are reused only after their existing stage, artifact, command-output and applicable resource proofs are fully validated, without admitting execution of those classes. Missing or incompatible proof requires the current invocation's admission for the actual stage class before any command runs; corrupt proof remains a hard failure. This permits serial `source_only`, `model`, then `postgres_docker` invocations to reuse prior completed stages while admitting only the next class to execute. Publication creates a draft PR only after exact-head verification; a high-risk policy also requires a prepublication review artifact. Ready promotion and merge require a submitted formal review. Merge checks live blockers, checks, base/head coordinates, and the policy boundary. Repositories may require an exact base/head lease for merge.
421
-
422
- For a bounded run, pass `--max-aggregate-rss-bytes`, `--min-free-disk-bytes`, and optionally `--max-new-output-bytes` with one or more `--output-root` paths to `verify`. `issue_verify` accepts the same values in `resourceBounds`. RSS is sampled across the observed child process tree, including observed detached descendants; free disk is checked before commands and during execution on the worktree and declared output filesystems. Positive file-size growth is sampled under the declared roots, with previously measured completed stages carried across a resume. The caller must declare every output root relevant to its allowance; aliases must resolve within those roots. The roots are relative to the issue worktree unless absolute. Unix-domain IPC sockets inside declared roots are observed as endpoints with zero regular-file payload bytes and remain counted toward the scan entry limit. Regular-file growth in every root is still measured; FIFOs and device entries remain unsupported. Output growth is separate from the 8 MiB captured stdout/stderr limit. Resource limits are opt in and do not impose a total runtime deadline.
423
-
424
- During a running command, a previously validated, unchanged alias may temporarily lose its physical target during a rebuild. The observer checks its current identity and target ancestry, reports the path and errno, and still completes a fresh scan of all physical files in every declared root. It never substitutes an incomplete scan or an earlier byte count. A missing target does not impose a build deadline when complete output accounting remains available. Unvalidated aliases that prevent a complete scan retain the one-second observation-stall window, starting after the first failed scan rather than before it. Cancellation, RSS and disk checks continue. Baseline and final scans remain strict; permanent broken links, cycles, escaping aliases and changed identities fail closed. Failed commands retain captured stdout/stderr in the existing private content-addressed command-output store, with its digest, actual exit status and first/last filesystem observation in the failure diagnostic. Output still buffered inside a killed child is unavailable to the runner.
425
-
426
- Real filesystem-negative tests can use `withVerificationFilesystemFixture` from `@aviaratech/ai-delivery` (or its `agent` export):
427
-
428
- ```js
429
- import { withVerificationFilesystemFixture } from '@aviaratech/ai-delivery';
430
-
431
- await withVerificationFilesystemFixture(async () => {
432
- // Create the real negative fixture inside a declared output root.
433
- try {
434
- // Assert the actual reader rejects it without blocking.
435
- } finally {
436
- // Remove every negative fixture before returning or throwing.
437
- }
438
- });
439
- ```
173
+ ## CLI and MCP contract
440
174
 
441
- Bounded verification supplies an inherited, run-owned filesystem coordination capability. The helper serializes the fixture's lifetime against strict scans of every declared root; nested verification and runtime setup join the same boundary. Without an inherited observer the helper runs its callback normally. Malformed, foreign or stale capabilities fail closed. The callback must contain only the negative test and its teardown, and must not start verification while holding the fixture. A queued scan takes priority over new fixtures. RSS, disk, captured-log limits and cancellation continue while the scan waits; waiting observations do not claim a new filesystem measurement. A fixture that fails to release a waiting scan within five seconds is a stalled reader/teardown failure: the command is terminated through the existing identity-checked cleanup, without stealing the live fixture lease. This is an operation-specific observation-stall bound, not a verification runtime limit. Successful commands and fully cached resumes receive fresh strict scans; ordinary or leaked unsupported entries still fail. Abrupt termination can prevent callback teardown; leaked fixtures remain visible and fail subsequent verification. After existing writer recovery confirms command quiescence, only validated abandoned control metadata from that worktree is retired. No output roots, unsupported file kinds or regular-file byte growth are exempted.
442
-
443
- Bounded stage checkpoints bind the limits and sampled observations. Older unmeasured stages and stages with different limits rerun. Current manifests use `ai-delivery.run@3`, bind the worktree and producer, and live under `runs@2/<worktree-digest>/<head>.json`. Bounded manifests also record limits, sample count, and sampled RSS, output, and disk extrema. Historical run versions 1 and 2 remain historical and are available for merged-issue recovery; current publication requires current-producer verification. `processCoverage: "observed-processes-only"` means a passing aggregate is not proof that every detached descendant was drained. A descendant that detaches and closes inherited pipes between samples can evade observation; a pipe holder that prevents command closure fails with unverified cleanup and no checkpoint. Output roots must be canonical and nonoverlapping. Resolvable aliases such as npm `.bin` links may point only within the declared roots; aliases are not traversed or counted twice, and growth of their physical targets remains measured. Escaping, broken and cyclic links fail closed. Output baselines are retained across retries, including failed stages. They are range scoped: a changed baseline regenerates the measured stage proof. Consumers must confirm their command graph remains observable and declare all relevant output roots; this contract does not assert ownership of undeclared output locations or other concurrent writers.
444
-
445
- A reviewed policy transition can be verified and published before activating
446
- its new configuration. For `verify`, issue-bound PR operations, and `finish`,
447
- invoke from the primary checkout or the exact registered issue checkout. The
448
- dispatcher selects that issue's witnessed, clean source for operation policy,
449
- configuration and author/reviewer roles. Runtime admission continues to bind
450
- the unchanged primary controller configuration and installed CLI/MCP bytes.
451
- Controller metadata discovery uses the configured source author; a review
452
- operation still authenticates independently as the configured reviewer App.
453
- Both contexts must select the same repository and share its Git common
454
- directory. Tracking and worktree preparation continue to use their caller's
455
- configuration and admission.
456
-
457
- Use the candidate's configured identities and obtain fresh verification and,
458
- when required, prepublication review for its exact base, head, tree and
459
- configuration. Formal review and ready promotion recheck that candidate
460
- configuration against the verified classification. Source drift, a changed
461
- remote base, missing ownership or
462
- unadmitted controller bytes/configuration reject the operation. The selected
463
- author credential makes the normal push and PR; formal review, counted approval
464
- and exact-head merge checks remain required. Publication does not activate the
465
- candidate configuration or rewrite runtime admission. After merge, the
466
- consumer's supported installation/admission process owns that transition.
467
- If cleanup has removed the checkout or registry row, merge/finish recovery uses
468
- the admitted primary context and retained terminal receipts with remote
469
- readback; it does not reconstruct source configuration or issue another merge.
470
-
471
- For recovery, inspect the original issue/PR, worktree registry and exact source
472
- head before retrying. A `created-not-started` response includes `safeResume`
473
- arguments; use those arguments unchanged to resume the known issue. `verify`
474
- reuses compatible stage checkpoints after interruption. If code, config, policy,
475
- the selected stage inputs or a checkpoint changes, regenerate the affected
476
- proof. A stopped or failed publish/finish must be read back before retrying;
477
- never infer completion from a timed-out command. Task assignment and model
478
- routing belong to a separate orchestrator, not this CLI.
479
-
480
- ## Bounded issue source phases
481
-
482
- The root and `@aviaratech/ai-delivery/agent` exports provide
483
- `withIssueSourcePhase(input, async context => { ... })` for an expressly
484
- authorized source graph in an existing registered issue worktree. The input
485
- binds its exact row and ownership witness, configured authenticated author,
486
- admitted executing SDK, primary controller HEAD/configuration, and separate
487
- candidate HEAD/index/dirty files/configuration. Declare frozen caller and input
488
- artifact digests, resolved command executables/argv/cwd, effective environment
489
- digest and overrides, completion artifacts, disjoint output roots and fixed
490
- RSS/output/disk bounds. Environment values stay in memory; records contain its
491
- digest. The selected SDK's producer commit and the consumer controller HEAD
492
- are separate identities.
493
-
494
- `identity` selects the configured authenticated author. Historical worktree
495
- custody may name a different principal: the exact canonical row digest and
496
- ownership witness remain bound and unchanged throughout the phase. The receipt
497
- binds that row separately from its authenticated actor; entering a source phase
498
- does not transfer custody or alias those principals.
499
-
500
- Inside the callback, prepare owned metadata and `await context.run(index)` for
501
- every command, in order, once. The context exposes read-only source,
502
- controller, authenticated actor and input identities. It permits one active
503
- command and expires when the callback settles. An unawaited command cancels
504
- the phase and triggers identity-bound descendant cleanup. This is a trusted
505
- cooperative callback: use its AbortSignal and issue all subprocesses through
506
- `run`. JavaScript is not sandboxed. Source must preserve the exact initial
507
- snapshot or produce the one declared commit with its exact parent/tree and
508
- clean postconditions. Normal commit hooks remain enabled.
509
-
510
- For a declared candidate policy change, set the optional
511
- `source.effect.configDigest` on `commitOnce` to the final resolved candidate
512
- configuration digest. `source.configDigest` binds the initial configuration;
513
- the final digest applies only to the exact declared clean child commit. Resolve
514
- both digests through the SDK's configuration loader; a policy file hash is not
515
- a resolved configuration digest. Omitting the final digest requires the initial
516
- configuration throughout and preserves existing record identities. `preserve`
517
- does not accept a final digest. The controller configuration remains fixed.
518
-
519
- The existing writer fence is published before lengthy validation/scans. The
520
- same runner accounts for the controller and owned descendants, captured logs,
521
- callback output and SDK metadata under one original cumulative physical
522
- baseline. New command calls cannot replace the graph, environment, roots or
523
- allocation. Cancellation and lock compromise cancel owned work; process
524
- cleanup, output accounting, writer release and lock release failures remain
525
- distinct. Completion is sealed only after accounting and confirmed release.
526
- The shared writer admission check continues to exclude other worktree writers
527
- while this source-phase record is unsealed, including the release-to-seal interval.
528
-
529
- The finite private `ai-delivery.source-phase@1` record is stored beneath the
530
- Git common directory's `ai-delivery/receipts/source-phase@1`, keyed by worktree
531
- and complete input digests. A compatible completed record can be returned
532
- without entering the callback or replaying commands after validating source,
533
- producer, admission and artifacts. A terminal `failed-quiescent` or
534
- `rejected-before-work` attempt can be followed only by an expressly authorized
535
- new input naming its exact predecessor phaseId/recordId, original baselineId
536
- when present, and authorization digest in `reconciliation`. Retain original
537
- source/runtime/input and allocation bindings and all output/bootstrap charges;
538
- corrected rejected inputs supply no reusable proof. Intermediate command
539
- results are never replay checkpoints. A missing or mistyped predecessor can be
540
- corrected without discarding its rejected record: validated retention edges
541
- carry every rejected sibling's bootstrap charge, separately from the requested
542
- reconciliation and any reusable source/runtime proof. Every attempt inherits
543
- the retained original allocation and charges prior attempts before checking
544
- work authorization. Rejected requests cannot enlarge that allocation or change
545
- its roots. Exhaustion remains unresolved and refuses another record or writer
546
- claim. Interrupted intent, uncertain commits,
547
- changed frozen inputs or unconfirmed release remain unresolved and refuse a
548
- new attempt; the API supplies no previous-process recovery or force-unblock.
549
-
550
- Its receipt proves this bounded operation only. Canonical verification,
551
- independent acceptance, scientific holds and receiving runtime selection keep
552
- their existing owners and checks.
553
-
554
- ## Compatibility contract
555
-
556
- The MCP input and result contract is `ai-delivery.mcp@1`, exported as `AI_DELIVERY_MCP_CONTRACT_VERSION`. Existing `issue_*` tools remain available, with typed `issue_comment`, `issue_list` and `issue_search` added. Each tool rejects unknown fields at the request boundary. `issue_create` accepts a title with optional body, Issue Type, Points, Priority, taxonomy labels, milestone, parent and blockers; it returns `{body, created: {number, title, url}, routing}`. A linked parent is read back and cleared of Points. `issue_start({issueNumber})` always checks readiness and prepares that existing issue; `develop` gates only preparation of a newly created issue. New starts default to 2 Points. `resumeCreated` requires `issueNumber` and an explicit `develop` boolean and never creates a second issue; `develop: false` recovers creation-only registration and journaling. Immediate creation and development preflights readiness before creation and returns `ai-delivery.issue-start-registration@1` with `status: "started"` or a `created-not-started` failure and exact `safeResume` arguments. The CLI prints that recovery JSON and exits nonzero for `created-not-started`. Scratch starts derive safe names from the request or title and return the branch and worktree path. `repo` on create, start and ready check, or global CLI `--repo`, must match the repository selected by the checkout's validated Git remote; a mismatch fails before a GitHub call.
557
-
558
- `issue_list` and `issue_search` return a bounded GitHub page with `{issues, page, perPage, nextPage}`. Both accept state, labels, parent issue, Issue Type, Project status, updated-since timestamp, page and per-page filters. Search requires literal text in `query`; list accepts it optionally. Text containing quotes, backslashes or newlines is rejected so search cannot replace the selected repository. Search fails on incomplete results or more than GitHub's 1,000-result window; narrow the query. Parent and Project filters apply to the fetched page, so an empty `issues` array can still have a `nextPage`. Continue until `nextPage` is null. Results include number, title, state, labels, Issue Type, parent, all native blockers, Project status, URL, update time and organization issue `fields` keyed by their actual names, including custom Points/Priority names and configured Effort/date fields. Unset fields are null. Field, option, relationship and Project item IDs stay internal. CLI `list` and `search` use these same tools.
559
-
560
- `issue_update` returns authoritative issue readback and synchronizes configured Project status from live native blockers. Closed issues and Done items remain Done; removing the last unresolved blocker returns to Todo. To park execution while retaining a worktree, use `ai-delivery update --issue 17 --park` or `issue_update({issueNumber: 17, park: true})`; status becomes Todo, or Blocked while native blockers remain. Unrelated metadata edits preserve parked presentation. Resume explicitly with `develop`/`issue_develop` or an existing-issue start, which still requires readiness; worktree presence never establishes active execution. `issue_info` returns current native metadata, parent, blockers, Project state and registered worktree; `issue_ready_check` returns deterministic admission and reasons; `issue_develop` and `issue_worktree_create` return registered worktree rows. `issue_verify` returns classification, aggregate, manifest and publication evidence IDs, plus the sampled resource summary when limits were supplied. `issue_pr_create` returns the PR number, URL and bound publication evidence ID, plus route evidence or the live review state on ready promotion; `issue_pr_info` returns number, state, exact head/base, draft flag, author login and URL. `issue_pr_review` returns an exact-head submitted review receipt and live required-review state, `issue_pr_merge` a durable merge receipt, and `issue_finish` returns the merge SHA and successful issue/cleanup readback. CLI and MCP call the same owners for these tools.
561
-
562
- `issue_update({issueNumber: 17, title: "New title", body: "New body", preserveHistory: true})` posts the complete previous title and body in a collapsed comment and confirms that comment before rewriting. HTML escaping preserves the prior text, whitespace and line endings. The result includes `historyComment` with its id, URL, exact body and retry status. Unchanged title/body adds no comment. An oversized complete history or failed comment readback prevents the rewrite; concurrent content edits detected after preservation also fail and require retrying against the current content. GitHub does not provide an atomic title/body compare-and-set, so edits made after that final read can still race with the update. CLI uses `--preserve-history`.
563
-
564
- Closing with `issue_update({issueNumber: 17, state: "closed", closeReason: "duplicate", supersededBy: 18})` validates the same-repository superseding issue, records the requested reason and supersession through the canonical comment writer, then reads back GitHub's native closure. Reasons are `completed`, `not_planned` and `duplicate`; `supersededBy` is optional and defaults the reason to `completed` when no reason is supplied. Duplicate closure also sets and verifies the native duplicate relationship. The result includes `closure` with native state, `closeReason`, repository-qualified `duplicateOf`, recorded `supersededBy` and the authoritative `comment` readback. Closure details require `state: "closed"`. Exact retries reuse the authored comment; a different reason or duplicate target on an already closed issue fails, because GitHub ignores reason changes without a state transition. Reopen explicitly before changing those native closure details. Comments record intent and remain available if a later mutation fails. CLI uses `--state closed --close-reason duplicate --superseded-by 18`.
565
-
566
- The CLI also exposes native relationship reads (`parent`, `subissues`, `blockers`), registry reads and clean registered PR/standalone cleanup (`worktrees:list`, `worktrees:status`, `worktrees:cleanup`), and PR reads and exact-head selected-author checkout (`pr:list`, `pr:checks`, `pr:checkout`). `pr:checks` includes GitHub's current review decision. A cleaned PR worktree can be reopened when its retained branch still matches the remote head. `migrate:legacy-issues --input-file` produces an offline `ai-delivery.legacy-issue-migration@1` plan without live writes. `metrics velocity --json` reads completed local delivery records and returns `ai-delivery.velocity-report@1` with buckets for configured Points; unknown blocker and review measurements remain null. `finish` can confirm completion after a lost response by matching the exact merge receipts, delivery record and live issue/Project state. Installing the package never migrates active runtime state automatically.
175
+ The remote contract is `ai-delivery.mcp@2`. CLI and MCP call the same owners. Issue listing/search preserve native filters, pagination, literal search boundaries and repository-qualified relationships. Issue updates preserve typed journals, history-before-rewrite and native reasoned closure. `issue_info.worktree` is null. Offline `migrate:legacy-issues --input-file` remains a read-only plan. Public exports expose remote delivery, metadata, digest utilities and explicit setup; removed executable policy/stage/evidence APIs are not exported.
567
176
 
568
177
  ## Typed issue journals
569
178