aimship 0.1.0-preview.10 → 0.1.0-preview.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -14,10 +14,17 @@ Use GitHub Issues for bugs and feature suggestions. Provide the version, host de
14
14
 
15
15
  ## Documentation
16
16
 
17
- The English/Chinese README introduces the software delivery workflow, its value and outputs, and owns installation, upgrades, host management, version/health queries and uninstallation. The Guide owns the annotated delivery directory and document overview, and explains usage by scenario: starting from an idea, adopting materials, changing existing code, reading results, changing requirements, continuing and completing delivery. Avoid generic prompt tutorials; a contextual continuation entry belongs in the Guide. Keep detailed artifact, stage and identifier rules in the bilingual [Guide appendix](docs/guide.md#document-details). Keep both languages equivalent. Put source development and isolated validation procedures here, and agent/tool details in the [CLI protocol](docs/cli.md). Old installation/example URLs retain short compatibility pointers rather than duplicate command instructions.
17
+ The English/Chinese README introduces the software delivery workflow, its value and outputs, gives the explicit first-use entry and expected receipt, and owns installation, upgrades, host management, version/health queries and uninstallation. The Guide owns the annotated delivery directory and document overview, and explains usage by scenario: starting without a requirements document, adopting materials, changing existing code, reading results, changing requirements, continuing and completing delivery. Avoid generic prompt tutorials; a contextual continuation entry belongs in the Guide. Keep stage mappings and document/identifier rules in the [shared agent references](skills/aimship/references/document-patterns.md); the Guide provides a brief explanation of traceability and retains user-facing [SQL and engineering version guidance](docs/guide.md#document-details). Keep both languages equivalent. Put source development and isolated validation procedures here, and agent/tool details in the [CLI protocol](docs/cli.md). Old installation/example URLs retain short compatibility pointers rather than duplicate command instructions.
18
18
 
19
19
  Validate public links and the shared stage/template mapping with `npm run check:docs`. Treat [artifact-map.json](skills/aimship/references/artifact-map.json) and the [document rules](skills/aimship/references/document-patterns.md) as the mapping to check against; update user-facing explanations when that mapping changes.
20
20
 
21
+ <a id="local-source-trial"></a>
22
+ ## Local source trial without installation
23
+
24
+ To try unreleased initialization changes, open a session with access to the checkout and a separate disposable materials directory. Explicitly ask to use the checkout's `skills/aimship/SKILL.md`, read its core, and run `node bin/aimship.mjs bind` from this package root. Verify the returned releaseRoot/corePath/cliPath all point into that checkout and schemaVersion is 3; a version string alone is insufficient when local code retains the published version. Then provide a concrete synthetic request, the trial materials path, and the desired stop. Do not load the installed launcher or run install.
25
+
26
+ In the next session, explicitly request that same source Skill and bind again, then provide the original delivery directory and ask to resume. Check its saved deliveryId, revision, review status and next action. This exercises source rules and local tooling without replacing global entries. Whether a specific host automatically discovers a checkout Skill is separate and must be tested rather than promised. Check `test/initialization.test.mjs` for deterministic initialization, interruption, old-format and approval-bypass regressions; their synthetic decisions are not real AI-host evidence.
27
+
21
28
  <a id="isolated-installation-check"></a>
22
29
  ## Isolated installation lifecycle check
23
30
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [中文](README.zh-CN.md) · [Guide](docs/guide.md)
4
4
 
5
- **A software delivery workflow for AI tools, connecting requirements, design, implementation, review and verification.**
5
+ **Aimship is a software delivery workflow for AI tools, connecting requirements, design, implementation, review and verification.**
6
6
 
7
7
  For developers responsible for delivering a requirement. You provide the goal, existing materials and code locations. Aimship helps the agent turn them into a clear scope, a reasoned design, an implementation plan and verified results. It connects these stages so that you can follow the work, understand key decisions and assess what has actually been delivered.
8
8
 
@@ -22,7 +22,7 @@ Documents and state are saved throughout the work, keeping progress, decisions a
22
22
  <a id="install"></a>
23
23
  ## Installation
24
24
 
25
- Requires **Node.js 22+ and npm**. Command examples use a POSIX shell.
25
+ Requires **Node.js 22+ and npm**.
26
26
 
27
27
  ### Published preview
28
28
 
@@ -59,13 +59,19 @@ Choose one installation method. No global npm installation, administrator privil
59
59
  The default delivery material root is `~/Aimship/`. On the first installation, use `--data-root` to choose another location:
60
60
 
61
61
  ```sh
62
- npx aimship@preview install --host codex --data-root "$HOME/MyDeliveries"
62
+ npx aimship@preview install --host codex --data-root "./MyDeliveries"
63
63
  ```
64
64
 
65
- This sets the default material location for new deliveries. It is not a code repository location and does not move existing materials. Later installations retain the configuration; no per-project installation is needed.
65
+ The example uses a `MyDeliveries` folder under the current working directory; you can replace it with an absolute path to your preferred location. This sets the default material location for new deliveries. It is not a code repository location and does not move existing materials. Later installations retain the configuration; no per-project installation is needed.
66
66
 
67
67
  After installation, follow the [Guide](docs/guide.md#hosts) to select Aimship in your tool. AI tool integrations are experimental: actual Skill discovery and continuation across AI tools still need validation.
68
68
 
69
+ ## Start a delivery
70
+
71
+ Explicitly select Aimship in your AI tool, or ask it to **use Aimship** for a concrete request. For example: “Use Aimship to deliver an export of the currently filtered orders. First clarify the fields; code will be prepared later.” A PRD, code repository and settled technical conditions are not required. A product name alone prompts a short clarification first.
72
+
73
+ The agent preserves your request, helps you make the materials location accessible, and creates or resumes one delivery. Its receipt shows the actual saved directory, `status.md`, current work and next step. Opening a project or mentioning the name in passing does not activate Aimship. In a new session, explicitly use Aimship again and identify the same delivery; see the [Guide](docs/guide.md#start). Source edits do not update an installed Skill; contributors can use the [local source trial](CONTRIBUTING.md#local-source-trial).
74
+
69
75
  <a id="update"></a>
70
76
  <a id="update-or-stop-using-aimship"></a>
71
77
  <a id="upgrades-and-host-management"></a>
@@ -145,7 +151,7 @@ Full uninstall retains delivery materials, user code, custom files and necessary
145
151
  ## Documentation and contributions
146
152
 
147
153
  <a id="use-cases-and-examples"></a>
148
- The **[Guide](docs/guide.md)** explains how to start work, review documents, inspect results, handle changes and resume. Artifact and traceability details are also in the Guide; [CONTRIBUTING](CONTRIBUTING.md) covers development and isolated validation; the [CLI protocol](docs/cli.md) serves agents and tool developers.
154
+ The [Guide](docs/guide.md) explains how to start a delivery, review documents, inspect results, handle requirement changes and continue work. [Contributing](CONTRIBUTING.md) covers development and isolated validation; the [CLI protocol](docs/cli.md) serves agents and tool developers.
149
155
 
150
156
  Aimship is in preview, with ongoing improvements to the workflow, usability and compatibility. Share problems and suggestions from actual use through [GitHub Issues](https://github.com/clsx/aimship/issues); read the contribution guide before contributing to development.
151
157
 
package/README.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) · [使用指南](docs/guide.zh-CN.md)
4
4
 
5
- **面向 AI 工具的软件交付流程,贯通需求、设计、实施、审核与验证。**
5
+ **Aimship 是面向 AI 工具的软件交付流程,贯通需求、设计、实施、审核与验证。**
6
6
 
7
7
  面向有开发基础、对一项需求交付负责的开发者。你提供目标、已有资料和代码位置,Aimship 帮助 Agent 将需求整理为清晰的范围、有依据的设计、可执行的计划和经过验证的成果,并衔接各阶段的工作,让你能了解推进过程、理解关键决定、判断实际交付结果。
8
8
 
@@ -22,7 +22,7 @@
22
22
  <a id="install"></a>
23
23
  ## 安装
24
24
 
25
- 需要 **Node.js 22+ 和 npm**。以下命令使用 POSIX shell 写法。
25
+ 需要 **Node.js 22+ 和 npm**。
26
26
 
27
27
  ### 安装已发布的预览版
28
28
 
@@ -59,13 +59,19 @@ npx --offline file:./aimship-VERSION.tgz install --host codex
59
59
  默认交付资料根目录为 `~/Aimship/`。首次安装时,可以用 `--data-root` 指定其他位置:
60
60
 
61
61
  ```sh
62
- npx aimship@preview install --host codex --data-root "$HOME/MyDeliveries"
62
+ npx aimship@preview install --host codex --data-root "./MyDeliveries"
63
63
  ```
64
64
 
65
- 此选项设置后续新交付的默认资料位置,不是代码仓库位置,也不会搬迁已有资料。后续安装保留已有配置;无需逐项目安装。
65
+ 示例使用当前执行目录下的 `MyDeliveries` 文件夹,也可以替换为所需位置的绝对路径。此选项设置后续新交付的默认资料位置,不是代码仓库位置,也不会搬迁已有资料。后续安装保留已有配置;无需逐项目安装。
66
66
 
67
67
  安装后,按[使用指南](docs/guide.zh-CN.md#hosts)在 AI 工具中选择 Aimship。AI 工具集成仍处于实验阶段,真实 Skill 发现和跨工具接续仍需验证。
68
68
 
69
+ ## 开始一次交付
70
+
71
+ 在 AI 工具中明确选择 Aimship,或明确要求**使用 Aimship** 处理具体诉求。例如:“使用 Aimship 交付按当前筛选条件导出订单的功能,先确认导出字段,代码稍后准备。”不要求先有 PRD、代码仓库或明确的技术条件。只有产品名称时,Agent 会先简短澄清实际问题。
72
+
73
+ Agent 保留原始诉求,引导准备资料位置的访问条件,然后创建或续接同一次交付。回执会说明实际保存目录、`status.md`、当前工作和下一步。打开项目空间或偶然提到名称不会启用 Aimship。新会话仍需明确使用 Aimship 并定位原交付,详见[指南](docs/guide.zh-CN.md#start)。源码修改不会更新已安装的 Skill;贡献者可按[本地源码体验](CONTRIBUTING.md#local-source-trial)加载。
74
+
69
75
  <a id="update"></a>
70
76
  <a id="update-or-stop-using-aimship"></a>
71
77
  <a id="升级与宿主管理"></a>
@@ -145,7 +151,7 @@ npx aimship@preview uninstall
145
151
  ## 文档与贡献
146
152
 
147
153
  <a id="适用场景与示例"></a>
148
- **[使用指南](docs/guide.zh-CN.md)**说明如何开始需求、审核文档、查看成果、处理变更和接续。产物与追溯细则也在指南中;[CONTRIBUTING](CONTRIBUTING.md)说明开发和隔离验证;[CLI 协议](docs/cli.md)供 Agent 和工具开发者查阅。
154
+ [使用指南](docs/guide.zh-CN.md)介绍如何开始交付、审核文档、查看成果、处理需求变更和继续工作。[贡献指南](CONTRIBUTING.md)说明开发和隔离验证;[CLI 协议](docs/cli.md)供 Agent 和工具开发者查阅。
149
155
 
150
156
  Aimship 目前处于预览阶段,流程、使用体验和兼容性仍在完善。欢迎通过 [GitHub Issues](https://github.com/clsx/aimship/issues)反馈实际使用中遇到的问题和改进建议;参与开发请先阅读贡献指南。
151
157
 
package/docs/cli.md CHANGED
@@ -6,27 +6,30 @@ Commands emit JSON. Errors include code/message/recovery and use a nonzero exit.
6
6
 
7
7
  `bind` returns fixed CLI/core/stage paths, version and configured data root. Keep that binding for the session. Installation does not create deliveries.
8
8
 
9
- Before init, save `source/request.md` and the PRD/Scope draft from the [templates](../skills/aimship/references/document-patterns.md). No templates are automatically created. Example input:
9
+ Before init, save the nonempty original input in `source/request.md`. A concrete request needs no PRD, code or known technical conditions yet. No templates are automatically created. Minimal input:
10
10
 
11
11
  ```json
12
12
  {
13
- "goal": {"summary":"Define the selected design", "endpoint":"Design handoff"},
14
- "goalRef":"prd.md",
15
- "documentPolicy":{"authority":"authored","interaction":false,"prototypeCovered":false,"interface":"none","databases":[]},
16
- "documents":[{"kind":"prd","path":"prd.md","mode":"new","version":"1"}],
17
- "stageRuns":[],
18
- "next":{"action":"Draft the agreed design","inputRefs":["prd.md"]}
13
+ "goal": {"summary":"Export the currently filtered orders", "endpoint":null},
14
+ "goalRef":"source/request.md",
15
+ "documentPolicy":{"authority":null,"interaction":null,"prototypeCovered":null,"interface":null,"databases":null},
16
+ "documents":[],
17
+ "stageRuns":[{"id":"requirements-1","stage":"requirements","scope":"Order export","progress":"active","inputRefs":["source/request.md"],"outputRefs":[]}],
18
+ "currentRun":"requirements-1",
19
+ "next":{"action":"Clarify export fields and acceptance criteria","inputRefs":["source/request.md"]}
19
20
  }
20
21
  ```
21
22
 
23
+ Only goal.summary is required in the input; absent endpoint defaults to null, goalRef to source/request.md, documents to [], and documentPolicy fields to null. Known facts may be supplied. Null means unknown, while false/none/[] mean explicitly not applicable. The CLI validates saved structure, not whether the user's request is concrete or authorized; the Agent must establish that before creating records.
24
+
22
25
  ```sh
23
26
  node '<stable-launcher>' bind
24
27
  node '<fixed-cli>' init '<delivery-dir>' --rules-version '<bound-version>' --input '<init.json>'
25
28
  ```
26
29
 
27
- init allocates deliveryId and revision 0, creates `.aimship/state.json`, and generates `status.md`. Add that ID to the document information at the next save point. Identity/version/timestamps, documentDigests, identityHistory, retiredIdentities and legacyRunIds are managed; never supply them in a patch. `writeResult` is return metadata, not state input.
30
+ init uses schema 3, allocates deliveryId and revision 0, creates `.aimship/state.json`, and generates `status.md`. Add that ID to the document information at the next save point. Identity/version/timestamps, documentDigests, identityHistory, retiredIdentities and legacyRunIds are managed; never supply them in a patch. `writeResult` is return metadata, not state input. Its receipt contains actual identity, directory/state/status paths, bound version, current stage and next action; statusPath is null when view repair is needed. Verify the saved files before presenting the user receipt. Repeated init returns ALREADY_EXISTS; read/resume the same delivery and render a missing view instead of replaying creation.
28
31
 
29
- `documentPolicy.authority`: authored → prd.md; adopted → scope.md; editable → an explicitly authorized existing PRD containing this commission's complete scope/authorization/endpoint. `legacy` is migration-only. `interaction`, `prototypeCovered`, `interface` (none/http/other) and target `databases` IDs record artifact conditions. They do not select a preset route.
32
+ `documentPolicy.authority`: null while the requirement authority is undecided; authored → prd.md; adopted → scope.md; editable → an explicitly authorized existing PRD containing this commission's complete scope/authorization/endpoint. `legacy` is migration-only. `interaction`, `prototypeCovered`, `interface` (none/http/other) and target `databases` IDs record artifact conditions. They do not select a preset route. Register the first real PRD/Scope and switch goalRef in the same update; this reference-only transition does not need a fabricated goal decision. Actual goal/endpoint changes still require goal.decisionRef. Early frame/requirements/scope work can be active without the draft; done requires it. Design requires approved requirements and an agreed endpoint, but may analyze unknown technical conditions. Resolve those conditions before completing design or starting dependent contract/cases/plan/implementation. Required document approvals remain checked even when producer runs are absent; existing stage ordering and review semantics are unchanged.
30
33
 
31
34
  Register documents as `{kind,path,mode,version,assetRefs?}`. List local/repository prototype images, scripts and other review-relevant assets in assetRefs so their bytes participate in the document fingerprint; the Agent must identify the complete asset set. Kinds: prd, scope, tech-design, plan, testing, review, diagnosis, handoff, change-log, prototype, contract, sql, source. New formal Markdown follows the artifact map's root filename and ordered anchors. Reused files additionally need `basisRef` recording location/version/coverage/gaps and editability; unsupported content is explicitly not checked. New HTML prototype is prototype/index.html; register other agreed formats. HTTP contracts use openapi.yaml unless reused. SQL filenames follow database count. Source files are immutable adopted versions by workflow, not OS access controls.
32
35
 
@@ -66,7 +69,7 @@ The delivery identity, view digest and state revision are stored in `.aimship/vi
66
69
 
67
70
  ## Explicit migration and rule adoption
68
71
 
69
- Schema 1 root state remains readable; normal updates/adopt require migration first. Unknown schemas stay read-only. To migrate one selected old delivery, record a compatibility assessment and original/new artifact mapping:
72
+ Schema 3 is used for new deliveries; older tools treat it as unknown/read-only. Existing schema 2 continues without automatic conversion, and its recorded history is preserved. Schema 1 root state remains readable; normal updates/adopt require migration first. Unknown schemas stay read-only. To migrate one selected old delivery, record a compatibility assessment and original/new artifact mapping:
70
73
 
71
74
  ```sh
72
75
  node '<new-fixed-cli>' migrate '<delivery-dir>' --revision '<old-revision>' --rules-version '<new-version>' --input '<assessment.json>'
package/docs/guide.md CHANGED
@@ -7,7 +7,7 @@ This guide explains what to provide, how the agent proceeds and where to find re
7
7
  <a id="install"></a>
8
8
  If Aimship is not installed yet, start with the README's [installation instructions](../README.md#install).
9
9
 
10
- [Select Aimship](#hosts) · [Start from your situation](#start) · [Proceed and review](#review) · [Progress and results](#results) · [Changing requirements](#changes) · [Sessions and continuation](#continue) · [Parallel work](#parallel) · [Complete delivery](#completion) · [Usage problems](#troubleshoot)
10
+ [Select Aimship](#hosts) · [Start in different scenarios](#start) · [Proceed and review](#review) · [Progress and results](#results) · [Changing requirements](#changes) · [Sessions and continuation](#continue) · [Parallel work](#parallel) · [Complete delivery](#completion) · [Usage problems](#troubleshoot)
11
11
 
12
12
  <a id="hosts"></a>
13
13
  <a id="1-select-aimship-in-your-host"></a>
@@ -27,14 +27,25 @@ Each tool needs its own login, available model and access to delivery materials
27
27
  AI tool integrations are experimental: actual Skill discovery, directory access and continuation across AI tools remain unverified. Healthy installation files do not prove that a tool loaded the Skill. Codex and Cursor share an entry, and compatible tools may discover entries in other locations; inspect paths and versions if duplicates appear, preserving unrelated or customized content. See the official [Cursor documentation](https://cursor.com/docs/skills) and [Codex skill locations](https://learn.chatgpt.com/docs/build-skills) for tool behavior.
28
28
 
29
29
  <a id="start"></a>
30
+ <a id="choose-the-requirement-authority"></a>
30
31
  <a id="describe-the-work-and-its-endpoint"></a>
31
- ## 2. Start from your current situation
32
+ ## 2. Start in different scenarios
33
+
34
+ After explicit activation, a concrete problem or intended change is enough to start. The agent preserves relevant original wording and visible discussion, checks whether this is a new or existing delivery, and reuses the current accessible workspace. If access is missing, it names the materials path and the operation you need to complete. Code can wait; a project name is not proof of access.
35
+
36
+ Initialization saves `source/request.md`, structured state and the generated `status.md`. Its receipt states what was saved, where, the bound Aimship version, code association, current work and next step. PRD/Scope is created when substantive requirements are drafted. Unknown endpoint, interaction, interface or database conditions remain unknown; “requirements first” does not mean “requirements only” or permission to implement.
37
+
38
+ To adopt an ongoing conversation, explicitly ask to use Aimship for the discussed request. The agent uses visible relevant input and identifies missing history, without asking known questions again or converting suggestions into decisions. If access preparation requires a new session before saving, take the provided unsaved context and intended location with you, then explicitly activate Aimship again.
32
39
 
33
- ### Starting with an idea
40
+ When code is ready, supply the accessible local checkout. The agent reads necessary instructions and engineering facts and associates it with the same delivery. It may read code during requirements if a conclusion depends on existing behavior. Association does not clone, move or modify code or grant implementation permission. New facts use the existing change process.
41
+
42
+ Repeated activation resumes the same identity and review stop. If a receipt is interrupted or the progress view fails, the agent checks what actually saved and repairs the missing view without recreating the delivery or overwriting materials. Ambiguous ownership is clarified. See [continuation](#continue) for the same steps in a new session; a passing mention of Aimship does not activate it.
43
+
44
+ ### Starting without a requirements document
34
45
 
35
46
  Describe the problem, who it affects, the expected change and known constraints. Include screenshots, discussion notes or references if available; a complete PRD is not required.
36
47
 
37
- The agent clarifies gaps that affect scope and acceptance, organizes requirements, and proposes the stages and execution order. After you confirm the goal and important tradeoffs, work proceeds. Requirements and acceptance criteria are usually recorded in `prd.md`; open `status.md` for current progress.
48
+ After initialization, the agent clarifies gaps in the goal, scope and acceptance criteria, organizes the requirements and acceptance criteria, and explains the work ahead. After you confirm the goal and important tradeoffs, work proceeds. Requirements and acceptance criteria are usually recorded in `prd.md`; open `status.md` for current progress.
38
49
 
39
50
  ### Working from an existing PRD, prototype or other materials
40
51
 
@@ -73,6 +84,7 @@ Authorized implementation, batch checks/repairs and retests can proceed. Review
73
84
  Start with the delivery's **`status.md`** for the current stage, pending documents, review status, blockers, next stage and artifact links. Read verification conclusions alongside the tested version, environment and evidence. Checks lacking accounts, tools or environments remain blocked or unexecuted rather than passing.
74
85
 
75
86
  <a id="delivery-structure"></a>
87
+ <a id="stage-outputs-and-content"></a>
76
88
  ### Delivery structure and documents
77
89
 
78
90
  By default, each request has its own delivery directory under `~/Aimship/`, while code stays in its existing repositories.
@@ -109,7 +121,8 @@ The tree below lists delivery artifacts and their purposes. Files follow the agr
109
121
 
110
122
  Formal documents are directly in the request folder. `source/` preserves adopted originals; `.aimship/` holds internal records. The software itself is installed separately in `~/.aimship/`.
111
123
 
112
- Filenames, outlines and identifier rules come from shared templates. Requirements and acceptance criteria link to implementation tasks, reviews and versioned test cases/results. The [document details](#document-details) explain when each artifact is produced and what it contains.
124
+ <a id="fixed-outlines-and-traceable-identifiers"></a>
125
+ The agent maintains links between requirements, acceptance criteria, implementation tasks, reviews and test results for traceability.
113
126
 
114
127
  <a id="changes"></a>
115
128
  <a id="review-verify-and-change"></a>
@@ -160,13 +173,15 @@ Aimship itself does not create sessions. After the current session confirms savi
160
173
 
161
174
  Keep one writing session per delivery. Code locations and access permissions must remain available; switching sessions cannot bypass reviews or affected-work stops. Progress stays in the same `status.md`, without copying the entire chat.
162
175
 
163
- Official CLI documentation checked on 2026-10-25 describes [`/new`](https://developers.openai.com/codex/cli/slash-commands) for Codex, [`/new-chat`](https://cursor.com/docs/cli/reference/slash-commands) for Cursor CLI, and [`/clear`](https://code.claude.com/docs/en/interactive-mode#command-history) for Claude Code to start a fresh chat/session. Check the command list of your installed CLI version; these are documentation checks, not a claim of testing each tool. They differ from simply redrawing the screen or compacting context. Save and stop the current writer first.
176
+ ### Continue after work stops unexpectedly
177
+
178
+ If the agent stops because of a lost connection, a tool exit or a canceled operation, describe what it was doing and provide any available errors. Before continuing, the agent checks actual files, saved progress and unfinished operations to establish what completed and avoid repeating writes or other actions with side effects.
164
179
 
165
- ### Handle interruptions and version changes
180
+ If a repository moved, provide its new location so the agent can verify its identity and update the association. State conflicts or progress-view problems need reconciliation or repair, not forced overwrites.
166
181
 
167
- After an unexpected interruption, have the agent check completed operations before repeating writes or other actions with side effects. If a repository moved, provide its new location so the agent can verify its identity and update the association. State conflicts or progress-view problems need reconciliation or repair, not forced overwrites.
182
+ ### Continue an existing delivery after upgrading Aimship
168
183
 
169
- After a software upgrade, an old session may retain old rules. Save work, then have the agent reconcile the current version and delivery records at a stable boundary; start a new session if context cannot refresh reliably. Older delivery formats require explicit migration, rule adoption and document reconciliation before work continues; unknown formats remain read-only. Originals and historical results are preserved without inventing work that was never performed or treating old completion records as approval. The [CLI protocol](cli.md) provides recovery details for the agent.
184
+ After upgrading Aimship, an old session may retain old rules. Save work, then have the agent reconcile the current version and delivery records at a stable boundary; start a new session if context cannot refresh reliably. Older delivery formats require explicit migration, rule adoption and document reconciliation before work continues; unknown formats remain read-only. Originals and historical results are preserved without inventing work that was never performed or treating old completion records as approval. The [CLI protocol](cli.md) provides recovery details for the agent.
170
185
 
171
186
  <a id="parallel"></a>
172
187
  <a id="work-on-two-requests-at-once"></a>
@@ -210,7 +225,7 @@ For a bug report, include the tool and Aimship versions, the operation, expected
210
225
 
211
226
  <a id="artifacts"></a>
212
227
  <a id="keep-only-useful-artifacts"></a>
213
- See the [document details](#document-details) for generation conditions, stage outputs, outlines and identifier rules. The agent maintains these as work progresses; you do not need to learn them all before starting.
228
+ See [delivery structure and documents](#delivery-structure) for file locations and purposes. For database work or engineering versions, see the [SQL and engineering versions appendix](#document-details).
214
229
 
215
230
  <a id="update"></a>
216
231
  <a id="update-or-stop-using-aimship"></a>
@@ -220,58 +235,9 @@ For software upgrades, adding tools, version queries and installation health che
220
235
  For tool disconnection or full uninstallation, see the [README](../README.md#uninstall). Source development and isolated validation belong in [Contributing](../CONTRIBUTING.md).
221
236
 
222
237
  <a id="document-details"></a>
223
- ## Appendix: document details
224
-
225
- Use the preceding sections for everyday work. This appendix covers stage outputs, SQL and traceability; file locations follow the [delivery directory](#delivery-structure).
226
-
227
- <a id="choose-the-requirement-authority"></a>
228
- See [starting work](#start) for source adoption. PRD and Scope are alternative requirement authorities, not duplicate documents to create by default.
229
-
230
- <a id="stage-outputs-and-content"></a>
231
- ### Stage outputs
232
-
233
- This is an internal responsibility/file mapping for understanding artifacts, not a menu of arbitrary stages to select. See [progress and review](#review) for the standard sequence and limited scope. Sharing plan/testing does not complete stages together, and file existence does not establish completion.
234
-
235
- | Stage | When used | Output and content |
236
- | --- | --- | --- |
237
- | `frame` | The problem or intended result needs clarification | Goal/background section of PRD/Scope: problem, outcome, non-goals and assumptions |
238
- | `requirements` | Requirements need authoring or adoption | `prd.md`: goals, scope, requirements, states, acceptance and arrangement; or `scope.md`: source adoption, scope, exclusions, decisions, acceptance and arrangement |
239
- | `scope` | Commission boundaries need explicit resolution | Update PRD scope or Scope goals/boundaries; no second requirements document |
240
- | `prototype` | Required interaction changes are not covered by existing material | New HTML at `prototype/index.html` with related assets; other agreed formats or reused entries are registered |
241
- | `diagnose` | An independent investigation is explicitly arranged | `diagnosis.md`: goal, symptoms, environment, evidence, causes, unknowns and conclusion |
242
- | `tech-design` | Technical solution needs designing | `tech-design.md`: basis, architecture, modules, data/contracts, errors, risks and requirement coverage; SQL is produced and reviewed in contract after this design is approved |
243
- | `contract` | Interfaces or database changes need formal artifacts | HTTP: `openapi.yaml` or the registered authority; agreed non-HTTP format; independent SQL per target, reviewed individually |
244
- | `test-design` | Test cases need authoring | `testing.md`: basis, environment, cases/assertions and requirement/acceptance coverage |
245
- | `plan` | Before any implementation, including one small batch | `plan.md`: basis, batches, tasks, validation approach, execution section and remaining work |
246
- | `implement` | Execute the accepted plan | Code in its repositories; actual task status, objects and deviations in the same `plan.md` |
247
- | `review` | Review a batch, the integrated result or a review-only commission | `review.md`: review basis, each review's scope/findings/resolution and conclusion |
248
- | `verify` | Execute versioned cases after the required review, or a verification-only commission | Append execution batches/RUNs, actual results/evidence, retests and conclusion to the same `testing.md` |
249
- | `handoff` | Deliver the agreed endpoint | `handoff.md`: goal, artifacts, usage, review/verification results, limits and completion/acceptance/integration outcomes |
250
-
251
238
  <a id="sql-changes-and-progress"></a>
252
- ### SQL and engineering versions
239
+ ## Appendix: SQL and engineering versions
253
240
 
254
241
  SQL identifies the target, dialect, version/schema basis and execution conditions, and links ordered statements to requirements/design. It is prepared and individually reviewed in contract after technical design approval and before test cases. A Markdown SQL snippet or migration reference does not replace this deliverable. Generating SQL does not authorize executing it or changing a repository's migration mechanism.
255
242
 
256
243
  Existing engineering HTTP contracts remain authoritative; avoid a second competing copy. Project current and target versions are recorded in PRD/Scope with their engineering source and observation basis; an unspecified version remains unspecified. `plan.md` records actual changes, while review and test results identify the exact commit/build or uncommitted content. Each repository has its own version and object references. These differ from Aimship’s rules version, state schema and save revision. The handoff records final code objects and actual merge/release status; a target version does not establish publication.
257
-
258
- <a id="fixed-outlines-and-traceable-identifiers"></a>
259
- ### Outlines and traceable identifiers
260
-
261
- New documents follow [shared templates and rules](../skills/aimship/references/document-patterns.md). Section order and stable anchors are retained; visible headings can be translated. Inapplicable sections explain why. Short tasks use the same outline, with shorter content. Unselected stages do not produce empty documents, and there is no arbitrary small-task merging.
262
-
263
- | Identifier | Meaning |
264
- | --- | --- |
265
- | `REQ-001`, `AC-001` | Requirement and acceptance criterion |
266
- | `B-001`, `TASK-001` | Implementation batch and task |
267
- | `PAGE-001`, `Q-001` | Prototype page and tracked question |
268
- | `TC-001`, `RUN-001` | Test case and actual verification run |
269
- | `REV-001`, `CHG-001` | Review and meaningful change |
270
-
271
- Each series starts at `001` and advances beyond its historical maximum, including retired items; three digits are the minimum width. An ID is never reused for a different obligation. Within a namespace and version, an identity has one effective definition; other documents reference it. Classification or layout changes retain the ID, while splits/merges create new IDs linked to the originals.
272
-
273
- References connect requirements/acceptance to design, tasks, code objects, reviews, case versions and actual runs. These relationships may be many-to-many: `REQ-001` and `TC-001` are not related merely because their numbers match. Shared rules, permissions and quality requirements receive independent identities when independently testable. External IDs retain their spelling and source/version namespace; sources without IDs receive local mappings to their original locations. Changed case meaning gets a new version; earlier failures and their case/code versions remain traceable.
274
-
275
- For example: `REQ-001 → AC-002 → TC-004@1 → RUN-003` records the explicit requirement-to-result relationship. A RUN also identifies the tested code/build and evidence; the case ID alone does not prove execution.
276
-
277
- The tools check structure, references and basic coverage. The agent must still assess whether the content and assertions actually satisfy the requirement; valid metadata alone is not proof.
@@ -7,7 +7,7 @@
7
7
  <a id="install"></a>
8
8
  尚未安装时,先阅读 README 的[安装说明](../README.zh-CN.md#install)。
9
9
 
10
- [选择 Aimship](#hosts) · [按当前情况开始](#start) · [推进与审核](#review) · [查看进度与成果](#results) · [需求变化](#changes) · [会话与续接](#continue) · [并行需求](#parallel) · [完成交付](#completion) · [使用问题](#troubleshoot)
10
+ [选择 Aimship](#hosts) · [不同场景下如何开始](#start) · [推进与审核](#review) · [查看进度与成果](#results) · [需求变化](#changes) · [会话与续接](#continue) · [并行需求](#parallel) · [完成交付](#completion) · [使用问题](#troubleshoot)
11
11
 
12
12
  <a id="hosts"></a>
13
13
  <a id="1-在宿主中选择-aimship"></a>
@@ -27,14 +27,25 @@
27
27
  AI 工具集成仍处于实验阶段,真实 Skill 发现、目录访问和跨工具接续仍待验证。安装文件健康不等于 AI 工具已加载 Skill。Codex 和 Cursor 共用入口,兼容 AI 工具也可能发现其他位置的入口;出现重复项时检查路径和版本,保留无关或定制内容。AI 工具行为可参考官方 [Cursor 文档](https://cursor.com/docs/skills)和 [Codex Skill 位置说明](https://learn.chatgpt.com/docs/build-skills)。
28
28
 
29
29
  <a id="start"></a>
30
+ <a id="需求依据与输入条件"></a>
30
31
  <a id="describe-the-work-and-its-endpoint"></a>
31
- ## 2. 按当前情况开始
32
+ ## 2. 不同场景下如何开始
33
+
34
+ 明确启用后,有具体问题或预期变化即可开始。Agent 保留相关原话和可见讨论,判断新建还是续接已有交付,复用当前可访问的工作空间。缺少访问权限时,会说明资料的具体路径和需要你完成的操作。代码可以稍后准备;项目空间名称本身不证明目录可访问。
35
+
36
+ 初始化保存 `source/request.md`、结构化状态和生成的 `status.md`。回执说明实际保存内容、位置、绑定的 Aimship 版本、代码关联情况、当前工作和下一步。PRD/Scope 在形成实质需求草稿时创建。终点、交互、接口或数据库条件未明确时保留未知;“先聊需求”不等于“只交付需求”,也不授予实施权限。
37
+
38
+ 普通讨论中途转入时,明确要求使用 Aimship 处理刚才的诉求。Agent 采用当前可见的相关输入,说明不可见历史的缺口,不重复询问已有答案,不把建议写成决定。若尚未保存就必须换会话,带上 Agent 给出的未保存上下文和计划位置,在新会话再次明确启用 Aimship。
32
39
 
33
- ### 从一个想法开始
40
+ 代码准备好后,提供可访问的本地工程位置。Agent 读取必要规范和工程事实,关联到同一次交付。需求结论依赖既有行为时,可以在需求阶段读代码。关联不会克隆、搬动或修改代码,也不授予实施权限;新事实影响原决定时沿用现有变更流程。
41
+
42
+ 重复启用会续接同一身份和审核停点。回执中断或进度页失败时,Agent 核对实际保存结果并修复缺失视图,不重建交付或覆盖资料。归属不清时才澄清。新会话按[续接说明](#continue)明确启用并定位原交付;仅碰巧提及 Aimship 不会启用它。
43
+
44
+ ### 尚未形成需求文档
34
45
 
35
46
  说明想解决的问题、使用者、期望变化和已知限制。有截图、讨论记录或参考资料时一起提供,无需先准备完整 PRD。
36
47
 
37
- Agent 会澄清影响范围和验收判断的缺口,整理需求,提出所需阶段及执行顺序。你确认目标和重要取舍后,Agent 继续推进。需求与验收标准通常记录在 `prd.md`,当前进度从 `status.md` 查看。
48
+ 初始化后,Agent 会澄清目标、范围和验收判断中的缺口,整理需求与验收标准,并说明后续工作安排。你确认目标和重要取舍后,Agent 继续推进。需求与验收标准通常记录在 `prd.md`,当前进度从 `status.md` 查看。
38
49
 
39
50
  ### 已有 PRD、原型或其他资料
40
51
 
@@ -73,6 +84,7 @@ Agent 会检查相关实现,确认需求与技术约束,安排设计、实
73
84
  从交付目录的 **`status.md`** 查看当前阶段、待审文档、审核状态、阻塞事项、下一阶段和成果入口。查看验证结论时,同时关注对应版本、环境和证据。缺少账号、工具或环境的检查会标为阻塞或未执行,不能计为通过。
74
85
 
75
86
  <a id="delivery-structure"></a>
87
+ <a id="阶段产物与内容"></a>
76
88
  ### 交付目录与文档
77
89
 
78
90
  默认每个需求在 `~/Aimship/` 下使用独立交付目录,代码保留在原仓库。
@@ -109,7 +121,8 @@ Agent 会检查相关实现,确认需求与技术约束,安排设计、实
109
121
 
110
122
  正式文档直接放在需求目录下;`source/` 保留采用的原件,`.aimship/` 保存内部记录。软件安装目录为 `~/.aimship/`,与各需求目录内的 `.aimship/` 分别管理。
111
123
 
112
- 文档名称、大纲和编号遵循统一模板。需求与验收标准关联到实施任务、审核、带版本的测试用例及执行结果。[文档细则](#document-details)进一步说明每种文档的生成条件和具体内容。
124
+ <a id="固定大纲和可追溯编号"></a>
125
+ 需求、验收标准、实施任务、审核和测试结果之间的关联由 Agent 维护,便于追溯。
113
126
 
114
127
  <a id="changes"></a>
115
128
  <a id="review-verify-and-change"></a>
@@ -160,13 +173,15 @@ Aimship 本身不创建新会话。等当前会话确认保存并停止写入后
160
173
 
161
174
  同一交付只保留一个写入会话。代码位置和访问权限仍需可用,不能因换会话绕过审核或受影响工作的停点。进度始终从同一份 `status.md` 查看,无需复制完整聊天。
162
175
 
163
- 截至 2026-10-25 核对的官方 CLI 文档:Codex 使用 [`/new`](https://developers.openai.com/codex/cli/slash-commands),Cursor CLI 使用 [`/new-chat`](https://cursor.com/docs/cli/reference/slash-commands),Claude Code 使用 [`/clear`](https://code.claude.com/docs/en/interactive-mode#command-history) 开始新的聊天/会话。以所用 CLI 版本的命令列表为准;这里是文档核对,不代表已逐一实测。这些操作不同于仅清屏或压缩上下文,使用前先保存并停止当前写入。
176
+ ### 工作意外停止后继续
177
+
178
+ 如果 Agent 因断网、工具退出或操作取消而停止工作,告诉它停止时正在处理什么,并提供已有错误信息。继续前,Agent 会核对实际文件、已保存进度及未完成操作,确认哪些操作已经完成,避免重复写入或重跑有副作用的动作。
164
179
 
165
- ### 处理中断与版本变化
180
+ 代码仓库搬迁后提供新位置,由 Agent 核对身份后更新关联。状态冲突或进度视图异常需要先协调或修复,不能强行覆盖。
166
181
 
167
- 意外中断时,让 Agent 先核对已经完成的操作,避免重复写入或重跑有副作用的动作。代码仓库搬迁后提供新位置,由 Agent 核对身份后更新关联。状态冲突或进度视图异常需要先协调或修复,不能强行覆盖。
182
+ ### 升级 Aimship 后继续已有交付
168
183
 
169
- 软件升级后,旧会话可能保留旧规则。先保存工作,再让 Agent 在稳定边界核对当前版本与交付记录;无法可靠刷新时开启新会话。旧格式交付需要明确迁移、采用规则并整理相关文档后继续,未知格式保持只读。已有原件和历史结果保留,不补造过去未执行的工作,也不将旧完成记录当作批准;恢复协议供 Agent 查阅 [CLI 文档](cli.md)。
184
+ 升级 Aimship 后,旧会话可能保留旧规则。先保存工作,再让 Agent 在稳定边界核对当前版本与交付记录;无法可靠刷新时开启新会话。旧格式交付需要明确迁移、采用规则并整理相关文档后继续,未知格式保持只读。已有原件和历史结果保留,不补造过去未执行的工作,也不将旧完成记录当作批准;恢复协议供 Agent 查阅 [CLI 文档](cli.md)。
170
185
 
171
186
  <a id="parallel"></a>
172
187
  <a id="work-on-two-requests-at-once"></a>
@@ -210,7 +225,7 @@ Agent 会分别记录目标完成、用户验收、合并和部署的实际情
210
225
 
211
226
  <a id="artifacts"></a>
212
227
  <a id="keep-only-useful-artifacts"></a>
213
- 文档生成条件、阶段产物、大纲与编号规则见[文档细则](#document-details)。这些规则由 Agent 随工作维护,无需在开始前逐项掌握。
228
+ 文件位置与用途见[交付目录与文档](#delivery-structure);涉及数据库或工程版本时,可查阅附录中的 [SQL 与工程版本说明](#document-details)。
214
229
 
215
230
  <a id="update"></a>
216
231
  <a id="update-or-stop-using-aimship"></a>
@@ -220,58 +235,9 @@ Agent 会分别记录目标完成、用户验收、合并和部署的实际情
220
235
  断开 AI 工具或完整卸载见 [README](../README.zh-CN.md#uninstall)。源码开发与隔离验证见[贡献指南](../CONTRIBUTING.md)。
221
236
 
222
237
  <a id="document-details"></a>
223
- ## 附录:文档细则
224
-
225
- 日常操作见前文;本附录用于查阅阶段产物、SQL 和追溯规则。文档位置以[交付目录](#delivery-structure)为准。
226
-
227
- <a id="需求依据与输入条件"></a>
228
- 需求采用条件见[按当前情况开始](#start)。PRD 与 Scope 是需求依据的两种选择,不默认同时编写。
229
-
230
- <a id="阶段产物与内容"></a>
231
- ### 阶段产物
232
-
233
- 下表是内部职责与文件映射,用于理解成果,不是需要用户任意勾选的流程菜单。标准顺序与阶段性范围见[推进与审核](#review)。共用 plan/testing 不代表阶段同时完成;文件存在也不等于完成。
234
-
235
- | 阶段 | 使用条件 | 产物及内容 |
236
- | --- | --- | --- |
237
- | `frame` 问题定义 | 问题或预期结果仍需澄清 | PRD/Scope 的目标与背景章节:问题、目标、非目标和假设 |
238
- | `requirements` 需求 | 需要编写或采用需求 | `prd.md`:目标、范围、需求、状态、验收和执行安排;或 `scope.md`:资料采用、本次范围、排除项、决定、验收和执行安排 |
239
- | `scope` 范围确认 | 需要明确本次委托边界 | 更新 PRD 的范围或 Scope 的目标/边界,不再新建另一份需求说明 |
240
- | `prototype` 原型 | 所需交互变化未被现有资料覆盖 | 新 HTML 使用 `prototype/index.html`,相关资源放在同目录;其他约定格式或复用入口单独登记 |
241
- | `diagnose` 调查定位 | 明确安排了独立调查 | `diagnosis.md`:目标、现象、环境、证据、原因、未知项和结论 |
242
- | `tech-design` 技术方案 | 需要设计技术实现 | `tech-design.md`:依据、架构、模块、数据/契约、异常、风险和需求覆盖;通过后在 contract 生成并审核所需 SQL |
243
- | `contract` 契约及 SQL | 接口或数据库变化需要正式产物 | HTTP 使用 `openapi.yaml` 或已登记的工程权威契约;非 HTTP 使用约定格式;每个目标库的独立 SQL 逐份审核 |
244
- | `test-design` 测试设计 | 需要编写测试用例 | `testing.md`:依据、环境、用例/断言,以及需求和验收覆盖 |
245
- | `plan` 实施计划 | 任何实施开始前,包括单个小批次 | `plan.md`:依据、批次、任务、验证安排、执行记录章节和剩余工作 |
246
- | `implement` 实施 | 执行已确定的计划 | 在代码仓库实施;同一份 `plan.md` 记录实际任务状态、代码对象和偏差 |
247
- | `review` 审核 | 审核某批、整体成果,或单独受托 review | `review.md`:审核依据、各次审核范围、发现与处理、结论 |
248
- | `verify` 验证 | 必要 review 后执行带版本用例,或单独受托验证 | 在同一份 `testing.md` 追加执行批次/RUN、实际结果、证据、重测和结论 |
249
- | `handoff` 交接 | 交付约定终点的成果 | `handoff.md`:目标、产物、使用方式、审核/验证结果、限制,以及完成/验收/集成状态 |
250
-
251
238
  <a id="sql变更和进度"></a>
252
- ### SQL 与工程版本
239
+ ## 附录:SQL 与工程版本
253
240
 
254
241
  SQL 标明目标、方言、版本/结构依据、执行条件,按顺序组织语句并关联需求和设计,在技术方案通过后的 contract 阶段、测试用例之前准备并逐份审核。Markdown 中的 SQL 片段或迁移文件引用不能替代它。生成 SQL 不代表获准执行数据库操作或修改工程迁移机制。
255
242
 
256
243
  已有工程 HTTP 契约继续作为权威来源,避免维护另一份相互冲突的副本。项目当前版本和目标版本在 PRD/Scope 中记录,并注明工程来源和观察依据;未设置版本时如实说明。`plan.md` 记录实际改动,审核与测试结果定位准确的 commit、构建或未提交内容。多仓库分别记录版本和对象引用,与 Aimship 规则版本、状态格式及保存 revision 区分。交接记录最终代码对象和真实合并/发布状态,目标版本不代表已发布版本。
257
-
258
- <a id="固定大纲和可追溯编号"></a>
259
- ### 大纲与追溯编号
260
-
261
- 新文档遵循[统一模板和规则](../skills/aimship/references/document-patterns.md),保留章节顺序和稳定锚点,可翻译展示标题。不适用章节说明原因,小需求使用相同大纲、缩短内容。未选择的阶段不生成空文档,也不按“小需求”随意合并文件。
262
-
263
- | 编号 | 含义 |
264
- | --- | --- |
265
- | `REQ-001`、`AC-001` | 需求、验收标准 |
266
- | `B-001`、`TASK-001` | 实施批次、任务 |
267
- | `PAGE-001`、`Q-001` | 原型页面、待决问题 |
268
- | `TC-001`、`RUN-001` | 测试用例、实际验证执行 |
269
- | `REV-001`、`CHG-001` | 审核、重要变更 |
270
-
271
- 各类编号从 `001` 开始,在包含已废弃条目的历史最大值后递增,三位是最小补零宽度。旧编号不用于另一项义务。同一命名空间和适用版本内,一个编号只有一处有效定义,其他文档引用该定义。分类或排版变化保留编号,拆分/合并则创建新编号并关联原编号。
272
-
273
- 需求/验收通过引用关联到设计、任务、代码对象、审核、用例版本和实际执行,允许多对多关联;不能因数字相同就认定 `REQ-001` 对应 `TC-001`。可独立测试的公共规则、权限和质量要求应具有独立身份。外部编号保留原样,并携带来源/版本命名空间;无原编号时建立指向原文位置的本地映射。用例含义改变后产生新版本,先前失败及当时的用例和代码版本仍可追溯。
274
-
275
- 例如,`REQ-001 → AC-002 → TC-004@1 → RUN-003` 表示明确的需求到结果关联。RUN 同时记录被测代码/构建及证据,仅存在用例编号不能证明已执行。
276
-
277
- 工具检查结构、引用和基础覆盖;Agent 仍需判断正文和断言是否真正满足需求。元信息合法不等于内容正确。
package/lib/approvals.mjs CHANGED
@@ -77,6 +77,24 @@ export async function reviewStatus(directory, state) {
77
77
  const prerequisites = development.includes(run.stage) ? state.stageRuns.slice(0,i).filter(r=>development.includes(r.stage) && development.indexOf(r.stage)<development.indexOf(run.stage)).map(r=>r.id) : [];
78
78
  const dependsOn = [...new Set([...declared, ...producers, ...prerequisites])];
79
79
  const blockedBy = dependsOn.filter(id => !runs.find(r => r.id === id)?.ready);
80
+ // An omitted producer run must not turn an unapproved input into permission.
81
+ // Schema 1/2 retain their historical arrangement; new initialization uses schema 3.
82
+ if (state.schemaVersion === 3) {
83
+ const needs = [];
84
+ if (['prototype','tech-design','contract','test-design','plan','implement'].includes(run.stage)) needs.push(requirement);
85
+ if (['contract','test-design','plan','implement'].includes(run.stage)) needs.push('tech-design');
86
+ if (['plan','implement'].includes(run.stage) && !state.deliveryPolicy?.partialRef) needs.push('testing');
87
+ if (run.stage === 'implement') needs.push('plan');
88
+ if (['test-design','plan','implement'].includes(run.stage)) {
89
+ if (state.documentPolicy.interface !== null && state.documentPolicy.interface !== 'none') needs.push('contract');
90
+ if (state.documentPolicy.databases?.length) needs.push('sql');
91
+ }
92
+ if (run.stage === 'implement' && state.documentPolicy.interaction && !state.documentPolicy.prototypeCovered) needs.push('prototype');
93
+ for (const kind of needs) {
94
+ const inputs = (state.documents ?? []).filter(d=>d.kind === kind);
95
+ if (!inputs.length || inputs.some(d=>documents.find(r=>r.path===d.path)?.status !== 'approved')) blockedBy.push(`approval:${kind}`);
96
+ }
97
+ }
80
98
  const waiting = required.filter(file => documents.find(d => d.path === file)?.status !== 'approved');
81
99
  const ready = run.progress === 'done' && !['needs-review','unknown'].includes(run.applicability) && !blockedBy.length && !waiting.length && (!spec?.humanReview || required.length > 0);
82
100
  runs.push({ id: run.id, stage: run.stage, progress: run.progress, applicability: run.applicability, documents: required, waiting, dependsOn, blockedBy, ready });
@@ -85,7 +103,7 @@ export async function reviewStatus(directory, state) {
85
103
  const pending = runs.filter(r => r.progress !== 'planned').flatMap(r => r.waiting.map(document => ({ run: r.id, document, status: documents.find(d => d.path === document)?.status })));
86
104
  const nextRun = runs.find(r => !r.ready);
87
105
  const nextStage = current ? runs[runs.indexOf(current) + 1]?.stage ?? null : nextRun?.stage ?? null;
88
- return { compatibility: 'current', documents, runs, pending, evidenceIssues, currentRun: current?.id ?? null, nextRun: nextRun?.id ?? null, nextStage, canProceed: current ? !current.blockedBy.length && !(current.progress === 'done' && !current.ready) && current.progress !== 'blocked' && !['needs-review','unknown'].includes(current.applicability) : !pending.length && !runs.some(r=>r.progress==='blocked' || ['needs-review','unknown'].includes(r.applicability)), identity: 'Record validation only; user identity, intent and source authenticity are not authenticated.' };
106
+ return { compatibility: 'current', documents, runs, pending, evidenceIssues, currentRun: current?.id ?? null, nextRun: nextRun?.id ?? null, nextStage, canProceed: current ? !current.blockedBy.length && !(current.progress === 'done' && !current.ready) && current.progress !== 'blocked' && !['needs-review','unknown'].includes(current.applicability) : !pending.length && !runs.some(r=>r.progress==='blocked' || (r.progress !== 'planned' && r.blockedBy.length) || ['needs-review','unknown'].includes(r.applicability)), identity: 'Record validation only; user identity, intent and source authenticity are not authenticated.' };
89
107
  }
90
108
  async function evidence(directory, state, ref) {
91
109
  if (!text(ref) || ref.includes('\\') || ref.split('#')[0].split('/').includes('..') || ref.startsWith('/') || (/^[a-zA-Z]:/.test(ref) && !ref.startsWith('repo:'))) reject('Review evidence must stay inside a registered root.');
package/lib/cli.mjs CHANGED
@@ -15,7 +15,7 @@ const HELP = {
15
15
  scan: 'scan <material-root>. Read immediate delivery directories in both layouts, deduplicate IDs and report conflicts/unknown records. No global search or write.',
16
16
  status: 'status [--home <dir>]. Read only Aimship-managed paths and fixed entries. Report registration, shared entry presence/integrity, active version, pending work and config problems. Host loading, login and access permissions remain unverified; no directories are created.',
17
17
  bind: 'Resolve active installation once. Returns immutable release/core/stage/CLI paths plus configured dataRoot, configPath and customPath. Source mode returns the default data root with null config/custom paths. No directories are created. Optional --home is for isolated testing.',
18
- init: 'init <dir> --input <json-file|-> --rules-version <version>. Create state once; input requires goal {summary, endpoint} and goalRef. Does not create templates.',
18
+ init: 'init <dir> --input <json-file|-> --rules-version <version>. Create state once; input requires goal.summary and saved source/request.md; endpoint and artifact conditions may remain null (unknown). Does not create templates.',
19
19
  read: 'read <dir> [--rules-version <version>] [--delivery-id <known-id>]. Read-only JSON access; unknown schemas remain readable.',
20
20
  update: 'update <dir> --revision <N> --rules-version <version> --input <json-file|->. Recursively merge objects; arrays replace in full. Identity/history fields are managed. null is a literal value, not deletion.',
21
21
  check: 'check <dir> [--rules-version <version>] [--all]. Check structure and current input references (or every registered reference). Checks explicit anchors/identity metadata in new local Markdown; reused and unsupported fragments are explicitly not checked. Does not prove semantics, remote access or validation results.',
@@ -41,7 +41,7 @@ const HELP = {
41
41
  references: 'delivery-relative/path#optional-fragment, repo:<registered-id>/<repo-relative-path>#fragment, or HTTP(S) URL. Local paths cannot escape their root. Repository registration: {id, path: absolute-path, role}.',
42
42
  topLevel: {
43
43
  managed: 'schemaVersion, revision, deliveryId, rulesVersion, createdAt, updatedAt, goalHistory, rulesHistory, documentDigests, identityHistory, retiredIdentities, legacyRunIds, writeResult. Do not supply these in init/update.',
44
- requiredInit: 'goal: {summary, endpoint}; goalRef: current requirements or Scope reference. Save source/request.md and the registered PRD/Scope draft before init; documentPolicy and documents are required.',
44
+ requiredInit: 'goal: {summary, endpoint?}; save a nonempty source/request.md before init. Defaults: endpoint null, goalRef source/request.md, empty documents, and null documentPolicy conditions/authority. Register PRD/Scope and switch goalRef when drafted; no empty templates.',
45
45
  stageRuns: 'Ordered array of stageInstance objects, default []. Every ID is unique; currentRun must match one of these IDs or be null. Stage types may repeat with distinct IDs.',
46
46
  currentRun: 'Instance ID or null (default). Do not invent an ID without registering its instance in stageRuns.',
47
47
  repositories: 'Array of {id, path: absolute-path, role, ...optional-version-facts}, default []. No repository is required for a design-only goal.',
@@ -52,13 +52,13 @@ const HELP = {
52
52
  closureRefs: 'Historical closure references, default []. Preserve them across reopenings.'
53
53
  },
54
54
  minimalInit: {
55
- goal: { summary: 'Repair the search empty-state message', endpoint: 'Implement, review, and verify the agreed repair' },
56
- goalRef: 'prd.md',
57
- documentPolicy: {authority:'authored',interaction:false,prototypeCovered:false,interface:'none',databases:[]},
58
- documents: [{kind:'prd',path:'prd.md',mode:'new',version:'1'}],
59
- stageRuns: [{ id: 'requirements-1', stage: 'requirements', scope: 'Search empty-state repair', progress: 'planned', inputRefs: ['prd.md'], outputRefs: [] }],
55
+ goal: { summary: 'Export the currently filtered orders', endpoint: null },
56
+ goalRef: 'source/request.md',
57
+ documentPolicy: {authority:null,interaction:null,prototypeCovered:null,interface:null,databases:null},
58
+ documents: [],
59
+ stageRuns: [{ id: 'requirements-1', stage: 'requirements', scope: 'Clarify order export', progress: 'active', inputRefs: ['source/request.md'], outputRefs: [] }],
60
60
  currentRun: 'requirements-1',
61
- next: { action: 'Draft the confirmed requirements', inputRefs: ['prd.md'] }
61
+ next: { action: 'Clarify export fields and acceptance criteria', inputRefs: ['source/request.md'] }
62
62
  },
63
63
  safety: 'Done is execution progress only. Results, applicability, goal attainment, acceptance, merge, and deployment are independent. Preserve old result references with priorResultRef/historyResultRefs. Goal revision needs a new goal.decisionRef; prior goals are retained automatically.'
64
64
  }
package/lib/delivery.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import { unknownConditions } from './documents.mjs';
2
3
  import { fail } from './io.mjs';
3
4
 
4
5
  // Additive policy: absent means historical, never inferred complete or rewritten on read.
@@ -25,6 +26,7 @@ export function arrangeSessions(state) {
25
26
  export function completionStatus(state, review, {changed=[]}={}) {
26
27
  if (state.deliveryPolicy?.version !== 1) return {status:'historical-unassessed', standardComplete:false, readyForAcceptance:false, gaps:['Historical outcomes are preserved; explicitly adopt the delivery policy after assessing evidence.']};
27
28
  const runs=state.stageRuns, gaps=[];
29
+ if (state.schemaVersion === 3 && (state.goal.endpoint === null || state.documentPolicy.authority === null || unknownConditions(state.documentPolicy).length)) gaps.push('Endpoint or artifact conditions remain unknown.');
28
30
  if(changed.length) gaps.push('Changed or missing registered documents require reconciliation.');
29
31
  const ready=r=>review.runs.find(x=>x.id===r.id)?.ready;
30
32
  const has=stage=>runs.some(r=>r.stage===stage && ready(r));
package/lib/documents.mjs CHANGED
@@ -52,8 +52,11 @@ export function definitions(text, file) {
52
52
  } catch { fail('DOCUMENT_METADATA', `Invalid definition in ${file}.`, 'Use the documented aimship:def JSON syntax.'); }
53
53
  });
54
54
  }
55
+ export function unknownConditions(policy) {
56
+ return ['interaction','interface','databases', ...(policy.interaction === false ? [] : ['prototypeCovered'])].filter(key=>policy[key] === null);
57
+ }
55
58
  export async function inspectDocuments(directory, state) {
56
- if (state.schemaVersion !== 2 || !state.documentPolicy || state.documentPolicy.authority === 'legacy') return { issues: [], unchecked: ['Legacy documents require recorded compatibility review.'], digests: {}, identities: [], nextIds: {} };
59
+ if (![2,3].includes(state.schemaVersion) || !state.documentPolicy || state.documentPolicy.authority === 'legacy') return { issues: [], unchecked: ['Legacy documents require recorded compatibility review.'], digests: {}, identities: [], nextIds: {} };
57
60
  const map = await artifactMap(), issues = [], unchecked = [], digests = {}, defs = [], documentAnchors = new Map();
58
61
  const docs = state.documents ?? [];
59
62
  const policy = state.documentPolicy;
@@ -61,9 +64,18 @@ export async function inspectDocuments(directory, state) {
61
64
  if (docs.some(d=>d.kind==='prd'&&d.mode==='new') && docs.some(d=>d.kind==='scope'&&d.mode==='new')) issues.push('Do not create competing new PRD and Scope entries.');
62
65
  const requirementKind = policy.authority === 'adopted' ? 'scope' : 'prd';
63
66
  const find = kind => docs.find(d => d.kind === (kind === 'requirement' ? requirementKind : kind));
64
- if (!await exists(path.join(directory, 'source/request.md'))) issues.push('Missing source/request.md.');
65
- if (!find('requirement')) issues.push(`Register ${requirementKind} as the requirement entry.`);
66
- if (policy.authority !== 'editable' && state.goalRef.split('#')[0] !== `${requirementKind}.md`) issues.push('goalRef must point to the selected root PRD/Scope.');
67
+ if (state.schemaVersion === 3) {
68
+ try {
69
+ const request = await safeRead(directory,state,'source/request.md');
70
+ if (!request?.trim()) issues.push('Missing or empty source/request.md.');
71
+ else digests['source/request.md'] = hash(request);
72
+ } catch { issues.push('Cannot read source/request.md inside this delivery.'); }
73
+ } else if (!await exists(path.join(directory,'source/request.md'))) issues.push('Missing source/request.md.');
74
+ const preparing = state.schemaVersion === 3 && !find('requirement');
75
+ if (preparing && state.goalRef !== 'source/request.md') issues.push('Before requirements exist, goalRef must point to source/request.md.');
76
+ if (!preparing && !find('requirement')) issues.push(`Register ${requirementKind} as the requirement entry.`);
77
+ if (!preparing && policy.authority === null) issues.push('Select the requirement authority when registering PRD/Scope.');
78
+ if (!preparing && policy.authority !== 'editable' && state.goalRef.split('#')[0] !== `${requirementKind}.md`) issues.push('goalRef must point to the selected root PRD/Scope.');
67
79
  if (find('requirement') && state.goalRef.split('#')[0]!==find('requirement').path) issues.push('goalRef must point to the registered requirement authority.');
68
80
  for (const doc of docs) {
69
81
  const spec = map.documents[doc.kind];
@@ -95,6 +107,7 @@ export async function inspectDocuments(directory, state) {
95
107
  for (const [i, run] of state.stageRuns.entries()) {
96
108
  if (!runs.includes(run) || run.progress === 'planned') continue;
97
109
  const contract = map.stages[run.stage], doc = find(contract.kind) ?? (run.stage === 'contract' && policy.interface === 'none' ? find('sql') : null);
110
+ if (!doc && preparing && ['frame','requirements','scope'].includes(run.stage) && run.progress !== 'done') continue;
98
111
  if (!doc) { issues.push(`${run.id}: missing registered ${contract.kind} artifact.`); continue; }
99
112
  if (run.stage === 'implement' && !state.stageRuns.slice(0,i).some(r => r.stage === 'plan' && r.progress === 'done')) issues.push(`${run.id}: complete plan before implementation.`);
100
113
  if (run.progress === 'done') {
@@ -109,14 +122,21 @@ export async function inspectDocuments(directory, state) {
109
122
  if (!defs.some(d=>d.file===doc.path && d.namespace==='local' && d.id.startsWith(prefix) && d.run===run.id && `${doc.path}#${d.id.toLowerCase()}-v${d.version}`===run.resultRef)) issues.push(`${run.id}: result must locate its own versioned REV/RUN definition with matching run field.`);
110
123
  }
111
124
  if (run.stage === 'contract') {
112
- for (const db of policy.databases) {
125
+ for (const db of policy.databases ?? []) {
113
126
  const file = policy.databases.length === 1 ? 'database.sql' : `database-${db}.sql`;
114
127
  if (!docs.some(d => d.kind === 'sql' && d.path === file) || !await exists(path.join(directory,file))) issues.push(`${run.id}: missing independent ${file}.`);
115
128
  }
116
129
  }
117
130
  }
118
131
  }
119
- if (state.reviewPolicy === 1 && (policy.interface !== 'none' || policy.databases.length) && runs.some(r=>['test-design','plan','implement'].includes(r.stage) && r.progress !== 'planned') && !runs.some(r=>r.stage==='contract' && r.progress==='done')) issues.push('Complete the applicable interface/SQL contract before test design, plan or implementation.');
132
+ if (state.schemaVersion === 3) {
133
+ const unknown = unknownConditions(policy);
134
+ const dependent = runs.filter(r=>r.progress !== 'planned' && !['frame','requirements','scope','diagnose'].includes(r.stage));
135
+ if (preparing && dependent.length) issues.push('Prepare and review formal requirements before dependent work.');
136
+ if (state.goal.endpoint === null && dependent.length) issues.push('Resolve the delivery endpoint before dependent work; initialization grants no further authorization.');
137
+ if (unknown.length && runs.some(r=>(r.stage === 'tech-design' && r.progress === 'done') || (['contract','test-design','plan','implement'].includes(r.stage) && r.progress !== 'planned'))) issues.push(`Resolve artifact conditions before completing design or dependent work: ${unknown.join(', ')}.`);
138
+ }
139
+ if (state.reviewPolicy === 1 && (policy.interface !== 'none' || (policy.databases?.length ?? 0)) && runs.some(r=>['test-design','plan','implement'].includes(r.stage) && r.progress !== 'planned') && !runs.some(r=>r.stage==='contract' && r.progress==='done')) issues.push('Complete the applicable interface/SQL contract before test design, plan or implementation.');
120
140
  if (policy.interface === 'http') {
121
141
  const doc=find('contract');
122
142
  if (doc?.mode === 'new' && doc.path !== 'openapi.yaml') issues.push('New HTTP contract must be openapi.yaml.');
package/lib/state.mjs CHANGED
@@ -7,7 +7,7 @@ import { savedResult, viewStatus, generateView } from './view.mjs';
7
7
  import { randomUUID } from 'node:crypto';
8
8
  import { atomicWrite, exists, fail, inside, json, noSymlinks, readJSON, withLock } from './io.mjs';
9
9
 
10
- export const SCHEMA_VERSION = 2;
10
+ export const SCHEMA_VERSION = 3;
11
11
  export const STAGES = ['frame', 'requirements', 'prototype', 'scope', 'diagnose', 'tech-design', 'contract', 'test-design', 'plan', 'implement', 'review', 'verify', 'handoff'];
12
12
  const PROGRESS = ['planned', 'active', 'blocked', 'done'];
13
13
  const RESULTS = ['passed', 'failed', 'not-run', 'unknown', 'mixed'];
@@ -28,12 +28,13 @@ function unique(items, label) { requireThat(items.every(object), `${label} entri
28
28
 
29
29
  export function validateState(state) {
30
30
  requireThat(object(state), 'State must be an object.');
31
- if (![1, SCHEMA_VERSION].includes(state.schemaVersion)) fail('UNKNOWN_SCHEMA', `Schema ${state.schemaVersion} is read-only for this tool.`, 'Preserve the file and use a compatible tool or an explicit, reviewed migration.');
32
- if (state.schemaVersion === 2) {
33
- requireThat(object(state.documentPolicy) && ['authored','adopted','editable','legacy'].includes(state.documentPolicy.authority), 'documentPolicy.authority is required.');
31
+ if (![1, 2, SCHEMA_VERSION].includes(state.schemaVersion)) fail('UNKNOWN_SCHEMA', `Schema ${state.schemaVersion} is read-only for this tool.`, 'Preserve the file and use a compatible tool or an explicit, reviewed migration.');
32
+ if (state.schemaVersion >= 2) {
33
+ requireThat(object(state.documentPolicy) && (['authored','adopted','editable','legacy'].includes(state.documentPolicy.authority) || (state.schemaVersion === 3 && state.documentPolicy.authority === null)), 'documentPolicy.authority is required.');
34
34
  if (state.documentPolicy.authority !== 'legacy') {
35
35
  const p = state.documentPolicy;
36
- requireThat(typeof p.interaction === 'boolean' && typeof p.prototypeCovered === 'boolean' && ['none','http','other'].includes(p.interface) && Array.isArray(p.databases) && p.databases.every(x => typeof x === 'string' && /^[a-z0-9][a-z0-9-]*$/.test(x)) && new Set(p.databases).size === p.databases.length, 'Invalid documentPolicy conditions.');
36
+ const unknown = value => state.schemaVersion === 3 && value === null;
37
+ requireThat((unknown(p.interaction) || typeof p.interaction === 'boolean') && (unknown(p.prototypeCovered) || typeof p.prototypeCovered === 'boolean') && (unknown(p.interface) || ['none','http','other'].includes(p.interface)) && (unknown(p.databases) || (Array.isArray(p.databases) && p.databases.every(x => typeof x === 'string' && /^[a-z0-9][a-z0-9-]*$/.test(x)) && new Set(p.databases).size === p.databases.length)), 'Invalid documentPolicy conditions.');
37
38
  requireThat(Array.isArray(state.documents), 'documents must be an array.');
38
39
  const paths = new Set();
39
40
  for (const d of state.documents) {
@@ -46,7 +47,7 @@ export function validateState(state) {
46
47
  }
47
48
  requireThat(Number.isSafeInteger(state.revision) && state.revision >= 0, 'revision must be a nonnegative integer.');
48
49
  requireThat(string(state.deliveryId) && string(state.rulesVersion), 'deliveryId and rulesVersion are required.');
49
- requireThat(object(state.goal) && string(state.goal.summary) && string(state.goal.endpoint), 'goal.summary and goal.endpoint are required.');
50
+ requireThat(object(state.goal) && string(state.goal.summary) && (string(state.goal.endpoint) || (state.schemaVersion === 3 && state.goal.endpoint === null)), 'goal.summary and goal.endpoint are required.');
50
51
  ref(state.goalRef, 'goalRef');
51
52
  if (state.compatibilityRef !== undefined) ref(state.compatibilityRef, 'compatibilityRef');
52
53
  if (state.goal.decisionRef !== undefined) ref(state.goal.decisionRef, 'goal.decisionRef');
@@ -102,8 +103,8 @@ export async function locateState(directory, writing = false) {
102
103
  export async function readState(directory) {
103
104
  const paths=await locateState(directory); const state=await readJSON(paths.statePath);
104
105
  requireThat(object(state),'State must be an object.');
105
- const layoutMismatch=(state.schemaVersion===1 && !paths.legacy)||(state.schemaVersion===2 && paths.legacy);
106
- const readOnly=paths.conflict || layoutMismatch || ![1,SCHEMA_VERSION].includes(state.schemaVersion) || (state.reviewPolicy !== undefined && state.reviewPolicy !== 1) || (state.deliveryPolicy !== undefined && state.deliveryPolicy?.version !== 1);
106
+ const layoutMismatch=(state.schemaVersion===1 && !paths.legacy)||([2,3].includes(state.schemaVersion) && paths.legacy);
107
+ const readOnly=paths.conflict || layoutMismatch || ![1,2,SCHEMA_VERSION].includes(state.schemaVersion) || (state.reviewPolicy !== undefined && state.reviewPolicy !== 1) || (state.deliveryPolicy !== undefined && state.deliveryPolicy?.version !== 1);
107
108
  if (!readOnly) validateState(state);
108
109
  const review=readOnly ? null : await reviewStatus(directory,state);
109
110
  const view=await viewStatus(directory,state), changes=await documentChanges(directory,state);
@@ -151,7 +152,9 @@ export async function initState(directory, input, rulesVersion, runtime) {
151
152
  const forbidden = ['schemaVersion', 'revision', 'deliveryId', 'rulesVersion', 'createdAt', 'updatedAt', 'goalHistory', 'rulesHistory', 'documentDigests', 'identityHistory', 'retiredIdentities', 'legacyRunIds', 'writeResult'];
152
153
  requireThat(object(input) && !forbidden.some(x => Object.hasOwn(input, x)), 'init input must not set tool-managed identity/version fields.');
153
154
  const now = new Date().toISOString();
154
- const state = { deliveryPolicy: {version:1}, reviewPolicy: 1, reviewHistory: [], cycle: 1, closureRefs: [], stageRuns: [], currentRun: null, openChanges: [], repositories: [], outcome: { goal: 'in-progress', acceptance: 'not-recorded' }, next: { action: 'Continue the confirmed arrangement.' }, ...input, schemaVersion: SCHEMA_VERSION, revision: 0, deliveryId: randomUUID(), rulesVersion, createdAt: now, updatedAt: now };
155
+ const state = { goalRef:'source/request.md', documentPolicy:{authority:null,interaction:null,prototypeCovered:null,interface:null,databases:null}, documents:[], deliveryPolicy: {version:1}, reviewPolicy: 1, reviewHistory: [], cycle: 1, closureRefs: [], stageRuns: [], currentRun: null, openChanges: [], repositories: [], outcome: { goal: 'in-progress', acceptance: 'not-recorded' }, next: { action: 'Clarify the request and prepare requirements for review.', inputRefs:['source/request.md'] }, ...input, schemaVersion: SCHEMA_VERSION, revision: 0, deliveryId: randomUUID(), rulesVersion, createdAt: now, updatedAt: now };
156
+ if (object(input.documentPolicy)) state.documentPolicy = {authority:null,interaction:null,prototypeCovered:null,interface:null,databases:null,...input.documentPolicy};
157
+ if (object(state.goal) && state.goal.endpoint === undefined) state.goal.endpoint = null;
155
158
  arrangeSessions(state); validateState(state); requireThat(state.deliveryPolicy?.version === 1, 'New deliveries require deliveryPolicy version 1.'); requireThat(state.documentPolicy.authority !== 'legacy', 'New deliveries cannot opt into legacy rules.'); await inspectForWrite(directory,state); await enforceReviews(directory,state); await enforceCompletion(directory,state); await atomicWrite(p.statePath, json(state)); return savedResult(directory,state);
156
159
  });
157
160
  }
@@ -216,7 +219,9 @@ export async function updateState(directory, patch, revision, rulesVersion, runt
216
219
  requireThat(basis.every(r=>['exists','not-checked'].includes(r.status)), 'Compatibility assessment must be accessible before policy adoption.');
217
220
  }
218
221
  arrangeSessions(next); validateState(next);
219
- if (JSON.stringify(previous.goal) !== JSON.stringify(next.goal) || previous.goalRef !== next.goalRef) {
222
+ // Registering the first formal basis is not a new user scope decision.
223
+ const formalizing = previous.schemaVersion === 3 && previous.goalRef === 'source/request.md' && !previous.documents.some(d=>['prd','scope'].includes(d.kind)) && next.documents.some(d=>['prd','scope'].includes(d.kind) && d.path === next.goalRef.split('#')[0]);
224
+ if (JSON.stringify(previous.goal) !== JSON.stringify(next.goal) || (previous.goalRef !== next.goalRef && !formalizing)) {
220
225
  requireThat(string(next.goal.decisionRef) && next.goal.decisionRef !== previous.goal.decisionRef, 'Goal revision requires a new explicit decisionRef; viewing results does not revise a goal.');
221
226
  next.goalHistory = [...(previous.goalHistory ?? []), { goal: previous.goal, goalRef: previous.goalRef, deliveryPolicy: previous.deliveryPolicy, outcome: previous.outcome, revision: previous.revision }];
222
227
  }
@@ -226,7 +231,7 @@ export async function updateState(directory, patch, revision, rulesVersion, runt
226
231
  if (previous.deliveryPolicy?.partialRef !== next.deliveryPolicy?.partialRef && previous.deliveryPolicy !== undefined) requireThat(string(next.goal.decisionRef) && next.goal.decisionRef !== previous.goal.decisionRef, 'Scope changes need a new explicit goal decision.');
227
232
  if (mode === 'update' && next.deliveryPolicy && previous.deliveryPolicy && JSON.stringify(previous.outcome)!==JSON.stringify(next.outcome)) await enforceCompletion(directory,next);
228
233
  retainHistory(previous, next); next.revision = previous.revision + 1; next.updatedAt = new Date().toISOString();
229
- validateState(next); await atomicWrite(p.backup, json(previous)); await atomicWrite(p.statePath, json(next)); return next.schemaVersion === 2 ? savedResult(directory,next) : next;
234
+ validateState(next); await atomicWrite(p.backup, json(previous)); await atomicWrite(p.statePath, json(next)); return next.schemaVersion >= 2 ? savedResult(directory,next) : next;
230
235
  });
231
236
  }
232
237
  export async function recoverState(directory, revision, rulesVersion, runtime) {
@@ -247,7 +252,7 @@ export async function recoverState(directory, revision, rulesVersion, runtime) {
247
252
  await atomicWrite(path.join(p.internal, `state.corrupt.${randomUUID()}.json`), raw);
248
253
  }
249
254
  const next = { ...backup, revision: corruptRevision + 1, updatedAt: new Date().toISOString(), recovery: { fromRevision: backup.revision, action: 'Inspect actual artifacts and unfinished effects before proceeding; nothing has been re-executed.' } };
250
- await atomicWrite(p.statePath, json(next)); return next.schemaVersion === 2 ? savedResult(directory,next) : next;
255
+ await atomicWrite(p.statePath, json(next)); return next.schemaVersion >= 2 ? savedResult(directory,next) : next;
251
256
  });
252
257
  }
253
258
  export async function checkReferences(directory, state, all = false) {
@@ -299,6 +304,7 @@ export async function checkReferences(directory, state, all = false) {
299
304
 
300
305
  async function enforceCompletion(directory,state) {
301
306
  if (state.deliveryPolicy?.version !== 1 || state.outcome.goal !== 'met') return;
307
+ if (state.schemaVersion === 3 && (state.goal.endpoint === null || state.goalRef === 'source/request.md')) fail('DELIVERY_INCOMPLETE','Initialization is not a completed delivery.','Resolve the endpoint and formal requirements before claiming completion.');
302
308
  const completion=completionStatus(state,await reviewStatus(directory,state));
303
309
  if (!state.deliveryPolicy.partialRef && !completion.readyForAcceptance) fail('DELIVERY_INCOMPLETE','Standard delivery evidence is incomplete.','Keep the goal in progress, or record the explicitly limited scope without claiming standard completion.',completion);
304
310
  const refs=await checkReferences(directory,state,true);
package/lib/view.mjs CHANGED
@@ -8,7 +8,7 @@ import { resolveRef, documentChanges } from './documents.mjs';
8
8
 
9
9
  const paths = dir => ({ view: path.join(dir,'status.md'), meta: path.join(dir,'.aimship/view.json') });
10
10
  export async function viewStatus(directory, state) {
11
- if (state.schemaVersion !== 2) return { status:'legacy', recovery:'Explicitly migrate this delivery before generating its view.' };
11
+ if (![2,3].includes(state.schemaVersion)) return { status:'legacy', recovery:'Explicitly migrate this delivery before generating its view.' };
12
12
  const p=paths(directory);
13
13
  try {
14
14
  if (!await exists(p.view)) return { status:'missing', recovery:'Run render at the current revision.' };
@@ -33,7 +33,8 @@ export async function renderText(directory,state) {
33
33
  const fragment=ref.includes('#')?'#'+ref.split('#')[1]:'';
34
34
  return target ? `[${cell(ref)}](${encodeURI(target).replaceAll('(','%28').replaceAll(')','%29')}${fragment})` : cell(ref);
35
35
  };
36
- const lines=['# Delivery status','','Generated by Aimship. Edit formal documents and structured state, not this page.','', '## Goal and basis','', cell(state.goal.summary), '',`Endpoint: ${cell(state.goal.endpoint)}`,''];
36
+ const lines=['# Delivery status','','Generated by Aimship. Edit formal documents and structured state, not this page.','', '## Goal and basis','', cell(state.goal.summary), '',`Endpoint: ${cell(state.goal.endpoint ?? 'Unknown — not yet agreed')}`,''];
37
+ if (state.schemaVersion === 3) lines.push('Initialization: state saved; this page is the derived view.', `Requirements: ${state.documents.some(d=>['prd','scope'].includes(d.kind)) ? 'registered; see document review' : 'being clarified; no formal document yet'}`, `Artifact conditions: ${['interaction','prototypeCovered','interface','databases'].map(k=>`${k}=${state.documentPolicy[k] === null ? 'unknown' : JSON.stringify(state.documentPolicy[k])}`).join(', ')}`, '');
37
38
  if (await available(directory,state,state.goalRef)) lines.push(artifactLink(state.goalRef),'');
38
39
  lines.push('## Associated engineering objects','','| ID | Actual checkout/worktree | Role |','| --- | --- | --- |');
39
40
  for (const r of state.repositories) lines.push(`| ${cell(r.id)} | ${cell(r.path)} | ${cell(r.role)} |`);
@@ -76,5 +77,5 @@ export async function generateView(directory,state,preserveEdits=false) {
76
77
  }
77
78
  export async function savedResult(directory,state) {
78
79
  const view=await generateView(directory,state);
79
- return {...state,writeResult:{stateSaved:true,revision:state.revision,view,session:sessionAdvice(directory,state,await reviewStatus(directory,state),{saved:view.status==='current'})}};
80
+ return {...state,writeResult:{stateSaved:true,revision:state.revision,view,receipt:{status:view.status==='current'?'saved':'view-repair-required',deliveryId:state.deliveryId,directory:path.resolve(directory),statePath:path.join(path.resolve(directory),'.aimship/state.json'),statusPath:view.status==='current'?path.join(path.resolve(directory),'status.md'):null,rulesVersion:state.rulesVersion,currentStage:state.stageRuns.find(r=>r.id===state.currentRun)?.stage??(state.goalRef==='source/request.md'?'requirements preparation':null),nextAction:state.next.action,repositoryCount:state.repositories.length},session:sessionAdvice(directory,state,await reviewStatus(directory,state),{saved:view.status==='current'})}};
80
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimship",
3
- "version": "0.1.0-preview.10",
3
+ "version": "0.1.0-preview.11",
4
4
  "description": "Explicit, goal-driven delivery workflow for coding agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -6,11 +6,11 @@ disable-model-invocation: true
6
6
 
7
7
  # Aimship
8
8
 
9
- Activate only when the user explicitly asks to start or resume Aimship. Ordinary conversation does not create a delivery. Once activated, continue the same delivery across turns without asking the user to invoke every stage.
9
+ Activate only when the user explicitly asks to start or resume Aimship. A clear request such as “use Aimship to start/continue” is explicit activation; a passing mention of its name or opening a project is not. In each new session, explicitly activate it again. Ordinary conversation does not create a delivery. Once activated, continue the same delivery across turns without asking the user to invoke every stage.
10
10
 
11
11
  1. Run `"{{AIMSHIP_NODE}}" "{{AIMSHIP_LAUNCHER}}" bind` to resolve the installed version. Read the returned fixed-version core and CLI help. Use that fixed version's tools, carrying its rules version and the current state revision. If this is a source checkout rather than an installed entry, use `node bin/aimship.mjs bind` from the package root.
12
12
  2. Read the core at the path returned by `bind`. Resolve all supporting links below against that same fixed release, even if a cached entry mentions an older path. [The shared core](references/core.md) is the source-checkout reference. For an existing delivery, read its state and the current goal/Scope plus only the next step's required references. Do not create a replacement delivery, reset its plan, or infer a new goal from “continue”.
13
- 3. For new work, use the binding’s configured `dataRoot` unless the user supplied a delivery location; do not infer it from the code root. Preserve the original request, identify the authorized endpoint and code locations, and establish the standard development sequence and applicable artifacts; respect explicitly limited scope and record its basis without calling it standard complete delivery. After associating code scope, follow the core’s recorded-overlap check for independent deliveries. Existing explicit authorization and agreed arrangements remain valid. No answer is not acceptance. Create records only for an actual request.
13
+ 3. Follow the core's [initialization flow](references/core.md#initialization) for new work or interrupted creation. A concrete problem or intended change is enough; no PRD, code or known technical conditions are required. Preserve the original request, resolve the same delivery and access, and use the existing init only when state does not exist. Unknown endpoint/conditions remain unknown, never an inferred authorization or limited scope. Report actual save location, current work and next step. Repeated activation resumes; later code association retains the same delivery ID.
14
14
  4. Read the selected [stage reference](references/core.md#stage-references) when reaching it. Explain design choices and unresolved decisions. Follow [document review](references/document-review.md): generate, self-check, give the current document entry/status/review focus and wait; do not send a next-stage continuation prompt while review is pending. After explicit approval save and verify the record, then follow the core session interaction: continue within a group, suggest a new session at its boundary without executing the next group in that response; continuing here needs no new approval; questions, silence and viewing results do not approve. Authorized implementation/review/repair/retest can then continue.
15
15
  5. Use the core’s default session groups in existing state. At confirmed saved group boundaries give current results, next suggestion and one continuation line with the actual delivery directory; no extra prompt document. A requested full prompt is optional. On resume, uniquely verify the delivery and actual saved review/unfinished-work stop; never infer approval from the copied entry. Keep a compact binding: delivery ID, absolute delivery directory, state path, current run, rules version, and fixed core/tool paths. After compaction, reload these references if absent; do not assume the full skill survived.
16
16
 
@@ -2,14 +2,34 @@
2
2
 
3
3
  ## Start from the commission
4
4
 
5
- A delivery has one centralized material directory, a preserved original request, current requirements or adopted sources plus Scope, an endpoint, and a state record. Code stays in its existing locations. A single repository and several repositories use the same model; there is no project registration step, repository count limit, or route classification.
5
+ A delivery has one centralized material directory, a preserved original request, a state record, and current requirements or adopted sources plus Scope as they are formed. The final endpoint may initially be unknown. Code stays in its existing locations. A single repository and several repositories use the same model; there is no project registration step, repository count limit, or route classification.
6
6
 
7
- Understand the intended result, supplied evidence, authorized changes and endpoint. Record known answers instead of asking again. Clarify only gaps that affect this work, with a recommendation and its consequence. Do not promote assumptions into user decisions. A design-only commission may have no repository. A short bug fix still needs its original report, context, expected behavior, scope and acceptance criteria, with a concise prd.md using the fixed outline.
7
+ Understand the intended result, supplied evidence, authorized changes and endpoint. Record known answers instead of asking again. Clarify only gaps that affect this work, with a recommendation and its consequence. Do not promote assumptions into user decisions. A delivery may start without a repository; a design-only commission may never need one. A short bug fix still needs its original report, context, expected behavior, scope and acceptance criteria, with a concise prd.md using the fixed outline.
8
8
 
9
9
  Use the configured material root (default `~/Aimship`), with one identifiable directory per delivery. Do not create it during installation. Before creating a new directory, use the user's explicit target or check a possible existing match; ambiguous candidates need selection, not a global “latest” pointer. If access fails, retain the request and intended location in the conversation and say what has not been saved. Continue the same delivery after access is restored.
10
10
 
11
11
  Read repository instructions and existing tools for the relevant work. Record relevant pre-existing modifications and distinguish them from the delivery's changes. Do not clean a working tree, initialize Git, modify an unrelated repository, or expand write access merely to simplify the workflow.
12
12
 
13
+ <a id="initialization"></a>
14
+ ## Initialize or resume the same delivery
15
+
16
+ This flow follows explicit Aimship activation in the first and every new session. Opening a project or merely mentioning Aimship does not activate it. A concrete problem, defect, technical objective or intended change is sufficient; a complete PRD, code, technical stack and final endpoint are not prerequisites. With only a product name or broad direction, ask a focused question about the actual problem before creating records; do not invent features or a full product scope.
17
+
18
+ 1. Preserve the user's relevant wording, sources, constraints and visible discussion. Distinguish user decisions, reported facts, Agent suggestions and unknowns. Do not re-ask known answers or treat discussion as approval. Before write access exists, keep this in the conversation and say it is not saved. If a session switch is necessary before saving, provide copyable context with the intended path, original input and pending operation; it is not a new approval.
19
+ 2. Bind the actual tool/core version and use the configured dataRoot or the user's location. Inspect the explicit target or known candidates for an existing delivery, partial creation or conflicting material. Read and resume existing state, checking deliveryId when known. Do not guess a global latest delivery, create a replacement, overwrite sources, or infer ownership from a matching name. Ask only when identity/location is unresolved.
20
+ 3. Reuse the current accessible workspace. If access is missing, follow [host access](hosts.md) with the exact required materials path; the user prepares the project/access. If the target does not exist, use its accessible existing parent or explain which directory the user must create/open. No silent fallback into code, unrelated probes or global settings changes. Workspace names and “I added it” are not proof; normal reads and actual saves establish this session's access only.
21
+ 4. Save the original input in source/request.md without replacing existing material. Reuse existing CLI init to create state and its generated status.md. Before PRD/Scope exists, use goalRef source/request.md, empty documents and null for unknown endpoint and documentPolicy conditions/authority (schema 3). A requirements/frame/scope run can be active without a draft; a done result still requires its formal artifact. Do not create empty templates or mark unknown conditions false/none/[] to pass init. Use next for the concrete pending questions/work; no parallel initialization ledger.
22
+ 5. Inspect stateSaved, revision and view from the actual result. Read back the saved state and status entry before reporting complete initialization. If the view failed, preserve the ID/revision and repair it with render; do not init again. If the response was lost, read before retrying. Source-only partial creation resumes at the same intended location after checking its ownership; stale locks require confirming the writer stopped. Unknown formats remain read-only.
23
+ 6. Give a concise receipt: initialized / resumed / incomplete, recognizable delivery, actual absolute directory and readable status link (only when available), saved materials, bound version, code association and checked access, current stage/work and next action. A repository registration alone does not prove access. Do not claim original initialization facts for an old delivery. Then continue authorized requirement clarification, unless the user requested a stop.
24
+
25
+ Register the first substantive PRD/Scope, select its authority and change goalRef in the same update when drafting it. This reference transition alone does not alter the user's goal or require a fabricated approval; an actual endpoint/scope change still needs its decision source. Formal requirements and each subsequent selected reviewable document keep their existing self-check/explicit-approval stops. Unknown technical conditions can be investigated during design, but must be resolved before completing design or advancing work that depends on them. Omitting a stage record cannot bypass its input document approvals. Initialization/check/resume readiness permits only the recorded current work, not all future stages.
26
+
27
+ “Clarify requirements first” describes current work, not a requirements-only endpoint or full development permission. Use null until the actual endpoint is known, then save the real decision before dependent work. Keep known conditions when available; false/none/[] mean explicitly not applicable, not unknown. Later changes use existing impact/re-review rules.
28
+
29
+ ### Associate code when needed
30
+
31
+ Code prepared by the user can be associated later through repositories in the same state, preserving deliveryId, sources and approvals. Read relevant engineering facts during requirements when they affect current behavior or feasibility; do not force waiting until implementation. If only a remote URL is supplied, record the source and request an accessible local checkout when needed; do not clone by default. Read repository instructions, actual checkout identity, version/commit and pre-existing changes; a non-Git directory or missing version is recorded honestly. Check known overlap below. Association itself does not authorize code writes, branch changes, dependency installs or publication. New facts trigger only the necessary impact assessment; unchanged decisions remain intact.
32
+
13
33
  ## Independent deliveries and recorded overlap
14
34
 
15
35
  Several independent deliveries may progress at the same time, each with its own material directory, goal, stages and state. One writing session **per delivery** is not a product-wide single-task limit. This check is workspace preparation based on records, not a cross-session lock or scheduler.
@@ -6,6 +6,8 @@ One request has one directory. Formal documents are at its root. `source/request
6
6
 
7
7
  ## Input and output conditions
8
8
 
9
+ Initialization may start with preserved source/request.md before a PRD/Scope is formed. Do not generate an empty template for init. Register the substantive requirement draft and switch goalRef when ready; before completing requirements or dependent work, use the existing formal artifact and approval rules below. Unknown artifact conditions stay null until determined, distinct from false/none/[] (not applicable).
10
+
9
11
  Author current requirements in `prd.md`, including scope. Adopt an authoritative PRD/prototype through `scope.md`, preserving source/version/original IDs and gaps. Prior authorship does not make an adopted source editable. Only explicit maintenance of an editable authoritative PRD that completely expresses this commission's scope/authorization/endpoint permits registered reuse without another PRD/Scope. Scattered ideas/screenshots/reference cases are inputs to a PRD, not automatically authoritative requirements.
10
12
 
11
13
  Interaction changes require a prototype when existing adopted material does not cover them and that work lies within the commissioned endpoint. New HTML uses `prototype/index.html`; register other agreed formats or reused entries. No interaction change means no invented prototype. Investigation/clarification-only requirements describe that commission and leave future development undefined.
@@ -15,3 +15,7 @@ After compaction or manual switching, reload the fixed-version core, state and c
15
15
  When changing hosts, use the same delivery directory and state; do not duplicate requirements, Scope or design to establish a new session. Permissions must be granted separately in each host. Keep one writing host/session for the delivery. User-facing entry/reload and lifecycle instructions are in [the user guide](../../../docs/guide.md#hosts).
16
16
 
17
17
  When reconciling an old Aimship-created workspace, resolve relative folders against its old file location before writing the new internal file. Verify actual checkout/worktree identity. Do not move or replace a user-owned existing workspace.
18
+
19
+ For initialization, materials access is sufficient; code may be associated later. An existing accessible project should be reused. When a new target folder cannot yet be opened, guide the user to the existing parent or to create/open the intended folder, according to actual tool capabilities. Preserve unsaved input before any session switch. Recheck necessary access in the new session; a project name is not evidence of permissions. Follow the core's initialization receipt after the actual save.
20
+
21
+ For an unreleased source trial, explicitly read the checkout Skill and bind its package-root CLI. Verify releaseRoot/corePath/cliPath and schemaVersion, not just the package version: local edits may retain the published version number. Do not fall back to a cached installed Skill. Loading the source manually does not establish host automatic discovery.
@@ -27,3 +27,11 @@ Follow [document review](document-review.md) for saved review stops, approval hi
27
27
  Use the core’s session interaction. Locate the actual delivery before reading; an explicit path or trustworthy unique binding is necessary. Check deliveryId when supplied, current approval fingerprints, current inputs and unfinished side effects; never treat an old continuation prompt as authority. Pending review remains pending. A session suggestion is not a blocker; a request to continue here uses the same saved work without a new approval. No automatic sessions or clipboard actions.
28
28
 
29
29
  Older state without deliveryPolicy is historical-unassessed, not invalid. Preserve met/accepted and old evidence. Adopt active rules and explicitly add deliveryPolicy with compatibilityRef after a real scope/evidence assessment; partialRef records an actual limited commission. No inferred historical approvals, no bulk migration. Standard completion remains separately assessed. Unknown newer delivery policies are read-only.
30
+
31
+ ## Early initialization and schema 3
32
+
33
+ New initialization may have only source/request.md, .aimship/state.json and status.md; technical conditions and endpoint may be null. Missing PRD/Scope at this point is normal. Read/check/resume use the same early-state rules; do not fill placeholders or infer non-applicability to clear warnings. Register the real draft when formed and retain the existing approval stops.
34
+
35
+ If source exists but state does not, inspect the original input and ownership before completing init at that location. If state exists, resume its ID instead; init deliberately rejects duplicates. A failed view or interrupted receipt never requires a second init. Inspect state then repair only the view at the saved revision, preserving manual status edits. Do not remove locks without checking that the writer stopped.
36
+
37
+ Schema 1 retains the existing explicit migration to schema 2. Schema 2 remains supported with its recorded conditions and history, without automatic rewriting or invented first-use facts. New deliveries use schema 3 so older tools refuse unknown semantics. Normal updates preserve the schema; no bulk conversion of old deliveries is required. Unknown future formats remain read-only.