aimship 0.1.0-preview.15 → 0.1.0-preview.17
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/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/docs/cli.md +16 -12
- package/docs/guide.md +16 -10
- package/docs/guide.zh-CN.md +16 -12
- package/lib/approvals.mjs +13 -7
- package/lib/cli.mjs +7 -7
- package/lib/delivery.mjs +19 -4
- package/lib/documents.mjs +7 -7
- package/lib/language.mjs +2 -2
- package/lib/state.mjs +16 -16
- package/lib/view.mjs +9 -6
- package/package.json +1 -1
- package/skills/aimship/SKILL.md +7 -7
- package/skills/aimship/references/artifact-map.json +1 -1
- package/skills/aimship/references/core.md +19 -11
- package/skills/aimship/references/document-patterns.md +4 -4
- package/skills/aimship/references/document-review.md +14 -6
- package/skills/aimship/references/recovery.md +3 -3
- package/skills/aimship/references/sources-and-changes.md +4 -4
- package/skills/aimship/references/stages/contract.md +1 -1
- package/skills/aimship/references/stages/diagnose.md +1 -1
- package/skills/aimship/references/stages/plan.md +1 -1
- package/skills/aimship/references/stages/prototype.md +3 -1
- package/skills/aimship/references/stages/requirements.md +4 -2
- package/skills/aimship/references/stages/tech-design.md +7 -1
- package/skills/aimship/references/stages/test-design.md +1 -1
- package/skills/aimship/references/templates/tech-design.md +6 -6
package/README.md
CHANGED
|
@@ -36,14 +36,14 @@ Choose `codex`, `cursor` or `claude-code`. To connect several tools, repeat the
|
|
|
36
36
|
npx aimship@preview install --host codex --host claude-code
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
The npx package prompt confirms downloading and running the package; `install` performs the Aimship installation or upgrade. `@preview` selects the published preview channel; an exact published version, such as `@0.1.0-preview.
|
|
39
|
+
The npx package prompt confirms downloading and running the package; `install` performs the Aimship installation or upgrade. `@preview` selects the published preview channel; an exact published version, such as `@0.1.0-preview.17`, can be used instead. The preview channel is experimental and does not imply a stable release.
|
|
40
40
|
|
|
41
41
|
### A specific version or local package
|
|
42
42
|
|
|
43
43
|
To install an exact published version, for example:
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
|
-
npx aimship@0.1.0-preview.
|
|
46
|
+
npx aimship@0.1.0-preview.17 install --host codex
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
If you already have an Aimship `.tgz` package, replace `VERSION` with its actual version and run from the directory containing it:
|
|
@@ -82,7 +82,7 @@ npx aimship@preview install
|
|
|
82
82
|
|
|
83
83
|
After upgrading, we recommend restarting your AI tool and opening a new session, then activating Aimship to reload the updated rules. Existing sessions may still retain older rules.
|
|
84
84
|
|
|
85
|
-
Installation and upgrades use the same `install` command. Existing tool registrations, configuration, custom content and deliveries are retained. The installer reports previous/target versions, results and conflicts; no background updater or resident process runs. To upgrade to a specific version, for example, run `npx aimship@0.1.0-preview.
|
|
85
|
+
Installation and upgrades use the same `install` command. Existing tool registrations, configuration, custom content and deliveries are retained. The installer reports previous/target versions, results and conflicts; no background updater or resident process runs. To upgrade to a specific version, for example, run `npx aimship@0.1.0-preview.17 install`. Existing installations do not need `--host` or `--data-root` repeated.
|
|
86
86
|
|
|
87
87
|
<a id="add-a-host"></a>
|
|
88
88
|
<a id="add-an-ai-development-tool"></a>
|
package/README.zh-CN.md
CHANGED
|
@@ -36,14 +36,14 @@ AI 工具可选 `codex`、`cursor` 或 `claude-code`。连接多个 AI 工具时
|
|
|
36
36
|
npx aimship@preview install --host codex --host claude-code
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
npx 的获取包提示只确认下载并运行该包;执行 `install` 才会安装或升级 Aimship。`@preview` 表示已发布的预览通道,也可以替换为明确版本号,例如 `@0.1.0-preview.
|
|
39
|
+
npx 的获取包提示只确认下载并运行该包;执行 `install` 才会安装或升级 Aimship。`@preview` 表示已发布的预览通道,也可以替换为明确版本号,例如 `@0.1.0-preview.17`。预览通道用于实验性版本,不代表稳定版。
|
|
40
40
|
|
|
41
41
|
### 指定版本或本地包
|
|
42
42
|
|
|
43
43
|
安装指定的已发布版本,例如:
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
|
-
npx aimship@0.1.0-preview.
|
|
46
|
+
npx aimship@0.1.0-preview.17 install --host codex
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
如果已有 Aimship 的 `.tgz` 安装包,将 `VERSION` 替换为实际版本号,在包所在目录执行:
|
|
@@ -82,7 +82,7 @@ npx aimship@preview install
|
|
|
82
82
|
|
|
83
83
|
升级完成后,建议重启 AI 工具并新建会话,再启用 Aimship,以便重新加载更新后的规则。已有会话可能仍保留旧规则。
|
|
84
84
|
|
|
85
|
-
安装和升级使用同一个 `install` 命令。已有 AI 工具登记、配置、自定义内容和交付资料都会保留。安装器报告旧/目标版本、结果及冲突;没有后台自动升级或常驻进程。更新到指定版本时,例如运行 `npx aimship@0.1.0-preview.
|
|
85
|
+
安装和升级使用同一个 `install` 命令。已有 AI 工具登记、配置、自定义内容和交付资料都会保留。安装器报告旧/目标版本、结果及冲突;没有后台自动升级或常驻进程。更新到指定版本时,例如运行 `npx aimship@0.1.0-preview.17 install`。已有安装无需重复填写 `--host` 或 `--data-root`。
|
|
86
86
|
|
|
87
87
|
<a id="添加宿主"></a>
|
|
88
88
|
<a id="添加-ai-开发工具"></a>
|
package/docs/cli.md
CHANGED
|
@@ -8,22 +8,24 @@ Commands emit JSON. Errors include code/message/recovery and use a nonzero exit.
|
|
|
8
8
|
|
|
9
9
|
Default initialization must use a distinct delivery directory under the bound dataRoot; the root itself is not a delivery. The current project or supplied-material directory is not an explicit location choice. A different user-selected directory requires init input `storage: {"mode":"explicit","decisionRef":"source/location-decision.md"}` with a nonempty readable local record of that choice. The tool validates evidence access, not the truth of the decision. Do not supply dataRoot in input. No access means report the intended location and stop saving, without falling back elsewhere. Existing deliveries outside the root remain readable and recoverable.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The first successful init receipt includes a neutral directory reminder; updates and resumes do not repeat it.
|
|
12
|
+
|
|
13
|
+
Before init, save nonempty initialization notes including the original commission in `.aimship/init.md`. A concrete request needs no PRD, code or known technical conditions yet. No templates are automatically created. Minimal input:
|
|
12
14
|
|
|
13
15
|
```json
|
|
14
16
|
{
|
|
15
17
|
"language":"en",
|
|
16
|
-
"goal": {"summary":"Export the currently filtered orders"
|
|
17
|
-
"goalRef":"
|
|
18
|
+
"goal": {"summary":"Export the currently filtered orders"},
|
|
19
|
+
"goalRef":".aimship/init.md",
|
|
18
20
|
"documentPolicy":{"authority":null,"interaction":null,"prototypeCovered":null,"interface":null,"databases":null},
|
|
19
21
|
"documents":[],
|
|
20
|
-
"stageRuns":[{"id":"requirements-1","stage":"requirements","scope":"Order export","progress":"active","inputRefs":["
|
|
22
|
+
"stageRuns":[{"id":"requirements-1","stage":"requirements","scope":"Order export","progress":"active","inputRefs":[".aimship/init.md"],"outputRefs":[]}],
|
|
21
23
|
"currentRun":"requirements-1",
|
|
22
|
-
"next":{"action":"Clarify export fields and acceptance criteria","inputRefs":["
|
|
24
|
+
"next":{"action":"Clarify export fields and acceptance criteria","inputRefs":[".aimship/init.md"]}
|
|
23
25
|
}
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
language and goal.summary are required in new input; absent endpoint defaults to
|
|
28
|
+
language and goal.summary are required in new input; an absent or null endpoint defaults to implementation, review, independent verification and delivery acceptance in the saved language, goalRef to .aimship/init.md, documents to [], and documentPolicy fields to null. Known facts may be supplied. Use `language: "zh-CN"` or `"en"`: explicit language preference takes precedence, otherwise use the delivery conversation language. This setting persists through update/render/resume and guides new formal documents; preserve original input, existing documents, filenames and machine identifiers. An explicit language update changes subsequent generated display, not existing document text. For artifact conditions, 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.
|
|
27
29
|
|
|
28
30
|
```sh
|
|
29
31
|
node '<stable-launcher>' bind
|
|
@@ -32,9 +34,9 @@ node '<fixed-cli>' init '<delivery-dir>' --rules-version '<bound-version>' --inp
|
|
|
32
34
|
|
|
33
35
|
init uses schema 4, 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 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.
|
|
34
36
|
|
|
35
|
-
`documentPolicy.authority`: null while the requirement authority is undecided; authored → prd.md; adopted → the registered retained PRD file in source/ (mode
|
|
37
|
+
`documentPolicy.authority`: null while the requirement authority is undecided; authored → prd.md; adopted → the registered retained PRD file in source/ (mode input); editable → an explicitly authorized existing PRD. All three use kind prd and goalRef points to its actual path. `interaction`, `prototypeCovered`, `interface` (none/http/other) and target `databases` IDs record artifact conditions. They do not select a preset route. Prototype coverage is descriptive; a prototype is optional unless selected in stageRuns, in which case its completion and applicable input check or AI-output approval remain required. Register the first real PRD 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 work can be active without the draft; done requires it. Design requires adopted, checked input requirements or approved AI-authored 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.
|
|
36
38
|
|
|
37
|
-
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, 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 ordinary Markdown headings. 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.
|
|
39
|
+
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, 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 ordinary Markdown headings. Modes: new for AI-authored files, reused for existing reviewable outputs, input for unchanged supplied PRD/prototype. Input basisRef preserves the actual user request to deliver from that material; mere file existence is insufficient. Inputs need a current self-check and become adopted, without an approved record. An unresolved question uses next.questionRef pointing to an existing concrete question/options/impact; the current run stays blocked. Clear it with null after resolving the question. No new approval is recorded for that clarification. 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.
|
|
38
40
|
|
|
39
41
|
## Update and inspect
|
|
40
42
|
|
|
@@ -59,7 +61,7 @@ Read/check/resume are read-only. They return view diagnostics and changed regist
|
|
|
59
61
|
|
|
60
62
|
## State and view recovery
|
|
61
63
|
|
|
62
|
-
State writes are atomic per file and keep `.aimship/state.previous.json`. Across formal documents/state/status there is no transaction. First persist unfinished intent, edit and inspect documents, then save state. Managed document digests detect some external changes, never semantic equivalence.
|
|
64
|
+
State writes are atomic per file and keep `.aimship/state.previous.json`. Across formal documents/state/status there is no transaction. First persist unfinished intent, edit and inspect documents, then save state. Managed document digests detect some external changes, never semantic equivalence. Initialization notes can be maintained and saved normally; changes to business requirements still belong in the formal authority/change log and follow its review rules. Preserve the original commission within the notes.
|
|
63
65
|
|
|
64
66
|
A write returns the actual state revision and `writeResult: {stateSaved:true,revision,view}`. If view status is protected/error, the JSON is already saved. Do not replay the business patch; explicitly repair:
|
|
65
67
|
|
|
@@ -87,11 +89,13 @@ Each record has `{id, kind, document, version, digest, sourceRef, summary}`. Kin
|
|
|
87
89
|
|
|
88
90
|
`read`, `check`, and `resume` return `review.documents` with current `path`, `version`, `digest`, `selfCheck`, `approval` and status. First append a self-check of those exact bytes; after presenting the document and receiving explicit approval, append an approved record binding the same version/digest and the actual user message. Questions, silence, and “show the result” cannot be recorded as approval. A hash/source reference validates the record's content basis, **not user identity or authenticity**. Never synthesize a real approval to make an update pass.
|
|
89
91
|
|
|
92
|
+
Nonblocking questions remain in their formal document with impact and resolution timing. Use `next.questionRef` only for a current blocker; approving a document does not resolve every question.
|
|
93
|
+
|
|
90
94
|
Production `progress: done` may be saved while approval is pending. Starting/completing dependent runs is blocked until prerequisite completion and document approval are current. Runs default to depending on their predecessor; explicit `dependsOn: [preceding-run-ids]` supports recorded independent branches, while input/output producers and earlier selected development prerequisites also apply. The initial applicable development order is requirements, technical design, interface/SQL, test-design, plan, implement. Unselected stages are not created. Contract can produce only SQL when no interface change applies; technical design no longer requires SQL files before completion.
|
|
91
95
|
|
|
92
96
|
For new `plan.md` and `testing.md`, fingerprints cover the content before the ordinary headings mapped to `execution` and `runs` respectively. Append implementation and RUN/conclusion evidence after those boundaries. Reused formats and other documents use whole-file content; remote/binary or linked-asset semantic inspection still belongs to the host/Agent. `done`, matching hashes and structural checks do not prove semantic quality.
|
|
93
97
|
|
|
94
|
-
When the PRD authority path changes, retain the prior registered file as kind source (mode reused), register one current prd, and preserve the old result reference in the requirement run. Use the real goal decision and an open CHG for
|
|
98
|
+
When the PRD authority path changes, retain the prior registered file as kind source (mode reused), register one current prd, and preserve the old result reference in the requirement run. Use the real goal decision and an open CHG for a change to approved requirements or adopted inputs; affected input checks and AI-output reviews must be reassessed before dependent work continues. This changes current material, not historical approval records.
|
|
95
99
|
|
|
96
100
|
A material change needs an open CHG with impact/decision evidence, a revised document version, a new self-check and explicit reapproval. Old review records remain. Affected producer/dependent runs become `needs-review`; update currentRun/next to the re-review stop and restore applicability after evidence-backed rechecking in dependency order. Independent branches are preserved. An `editorial` record carries a prior approval only after a same-version self-check explains a formatting/typo change and references its previous digest; it is not a new user approval. Do not hide changed design in excluded result sections. Final `outcome.acceptance` stays independent.
|
|
97
101
|
|
|
@@ -99,7 +103,7 @@ See the [Agent review workflow](../skills/aimship/references/document-review.md)
|
|
|
99
103
|
|
|
100
104
|
## Standard completeness and session suggestions
|
|
101
105
|
|
|
102
|
-
New state defaults to `deliveryPolicy: {version: 1}`. The standard main sequence is requirements/acceptance, technical and applicable contract/interaction artifacts, cases, plan, implementation with batch review, overall review, verification, handoff/acceptance. Do not present stageRuns as an arbitrary menu of core stages. Preserve existing materials and inspect them before adoption;
|
|
106
|
+
New state defaults to `deliveryPolicy: {version: 1}`. The standard main sequence is requirements/acceptance, technical and applicable contract/interaction artifacts, cases, plan, implementation with batch review, overall review, verification, handoff/acceptance. Do not present stageRuns as an arbitrary menu of core stages. Preserve existing materials and inspect them before adoption. Mode input records supplied PRD/prototype with actual adoption intent and a current self-check; it is not an approved AI output.
|
|
103
107
|
|
|
104
108
|
An explicit limited-scope decision (including no cases and testing) is referenced by `deliveryPolicy.partialRef` in existing PRD/change material. Such a scope may reach `outcome.goal: met` and have a real acceptance decision, but derived `completion.status` remains `partial-scope`, never `standard-complete`. Adding/changing/removing this basis needs a new goal.decisionRef, preserving goal history; set partialRef to null to restore standard scope. Standard goal completion checks recorded stages/approvals, passing batch and overall review, passing independent verification, handoff and resolvable evidence; standard-complete additionally requires recorded acceptance. These checks cannot prove actual execution or semantic quality. Failed or omitted checks must never be labeled passed.
|
|
105
109
|
|
|
@@ -107,7 +111,7 @@ Independent review, verify-only work or limited handoff can omit standard upstre
|
|
|
107
111
|
|
|
108
112
|
Reviews identify their actual implementation coverage with `reviewOf: [implementationRunId, ...]`; overall review has `overall: true`. For a single batch one review may explicitly cover both. An unresolved failed review prevents standard completion even if an earlier overall review passed. A passing repair review or retest may list the superseded review/RUN result references in its existing `historyResultRefs`, preserving old failures; the Agent must verify that it actually resolves or covers them on current objects. Verification must follow the applicable overall review. Merely setting a link is not semantic evidence.
|
|
109
113
|
|
|
110
|
-
`run.sessionGroup` remains advisory context, not permission to cross stages. Each stage finishes its work/self-check, saves artifacts and stops: `session.action` is await-review for required approval or await-continue for a completed stage awaiting continuation; `stop` and `suggestNewSession` make that advice explicit.
|
|
114
|
+
`run.sessionGroup` remains advisory context, not permission to cross stages. Each stage finishes its work/self-check, saves artifacts and stops: `session.action` is await-review for required approval or await-continue for a completed stage awaiting continuation; `stop` and `suggestNewSession` make that advice explicit. `suggestNewSession` is true only at major work boundaries: requirements to design, design/applicable contracts to test design, plan to implementation, batch review to the next batch/overall review, and overall review to independent verification. Pending review remains the current task; a suggestion never skips it. Approval and continuation may be expressed together. This is agent interaction guidance, not interception of general-purpose tools or a new approval for non-review stages. `read/check/resume` and `writeResult.session` use the same rule. Unconfirmed saves return reconcile-save with no continuation; repair the view at the saved revision without replaying approval. Pending review never becomes approval through resume or “continue”.
|
|
111
115
|
|
|
112
116
|
`read` and `resume` accept optional `--delivery-id <known-id>` to reject a wrong directory binding. A directory remains required; no implicit latest-delivery lookup exists. Resume is read-only and inspects actual state, approval/content versions, references and view diagnostics; old prompts grant no approval. The Agent must additionally inspect relevant complete formal documents, actual artifacts and unfinished effects before acting.
|
|
113
117
|
|
package/docs/guide.md
CHANGED
|
@@ -47,7 +47,7 @@ The delivery directory contains these materials:
|
|
|
47
47
|
~/Aimship/ # Materials root
|
|
48
48
|
└── 20261027-login-signup/ # Example delivery directory
|
|
49
49
|
├── status.md # Current work, pending reviews, next action
|
|
50
|
-
├──
|
|
50
|
+
├── .aimship/init.md # Initialization context for the AI
|
|
51
51
|
├── prd.md # Requirements and acceptance criteria
|
|
52
52
|
├── prototype/index.html # Page interaction prototype
|
|
53
53
|
├── tech-design.md # Technical design
|
|
@@ -76,7 +76,7 @@ Materials develop gradually and are kept as needed. Search readable REQ, AC and
|
|
|
76
76
|
|
|
77
77
|
Follow sign-up and login from requirements to acceptance. **This is fictional practice; wording and business choices need not be copied.** The example later supplies a project and isolated test database, with prototype review after requirements and before technical design. Actual prototype placement follows the delivery's needs.
|
|
78
78
|
|
|
79
|
-
Use one Aimship entry within a session; no invocation is needed at every stage. After completing and self-checking a stage, the AI saves its results, reports the stop and pauses. A new session is recommended, not
|
|
79
|
+
Use one Aimship entry within a session; no invocation is needed at every stage. After completing and self-checking a stage, the AI saves its results, reports the stop and pauses. A new session is recommended at major work transitions, not after every stop. AI-authored or substantively revised reviewable documents await approval; questions affecting current work await clarification; other completed stages await continuation. You may say “approved, continue” once. Work within a stage stays continuous.
|
|
80
80
|
|
|
81
81
|
<a id="11-prepare-a-workspace"></a>
|
|
82
82
|
<a id="12-activate-aimship-and-describe-the-request"></a>
|
|
@@ -96,13 +96,15 @@ Use one Aimship entry within a session; no invocation is needed at every stage.
|
|
|
96
96
|
|
|
97
97
|
**User actions:** Explicitly request Aimship and state the goal. For example:
|
|
98
98
|
|
|
99
|
-
> Use Aimship for username/password sign-up, login, logout and a home page requiring login. Complete development and local verification
|
|
99
|
+
> Use Aimship for username/password sign-up, login, logout and a home page requiring login. Complete development and local verification; I will supply code later.
|
|
100
100
|
|
|
101
101
|
For existing prototypes, PRDs or other documents, supply their original locations; originals stay in place and you need not copy them manually. Following the source rules, the AI retains copies of the formally adopted versions and necessary dependencies under this delivery's `source/` and records the adoption basis in the existing source record. Materials consulted only as background need not be copied in full. Before later revisions, identify the editable artifact; new versions do not overwrite earlier evidence.
|
|
102
102
|
|
|
103
103
|
**AI processing:** Determines the delivery directory and checks access, preserves the request, creates or resumes the delivery, and reports the actual saved directory, current work and next action. It starts requirement intake on the standard sequence without a full-delivery/design-only/init-only choice; explicit limits or pauses are respected. If access is unavailable, it asks you to add that directory or grant access; it does not relocate the delivery into the workspace.
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
The standard endpoint is implementation, review, independent verification and delivery acceptance; no extra scope choice is needed. On initialization, the AI reminds you to add the actual delivery directory to your current project/workspace, ignoring the reminder if already added.
|
|
106
|
+
|
|
107
|
+
**Outputs:** `.aimship/init.md` keeps the original commission, material locations and initialization context for the AI; `status.md` shows the full stage sequence and statuses, current position, pending documents, blocking questions and next action. For a new delivery, the AI saves your preferred language, or otherwise the language of the current conversation. Status and new documents use that language; filenames, IDs, original sources and existing documents remain unchanged.
|
|
106
108
|
|
|
107
109
|
<a id="14-read-the-document-and-give-a-decision"></a>
|
|
108
110
|
<a id="15-continue-after-approval"></a>
|
|
@@ -124,7 +126,7 @@ For existing prototypes, PRDs or other documents, supply their original location
|
|
|
124
126
|
- No PRD/prototype: describe features and expected behavior, such as “Usernames must be unique; after logout, the home page must require login again.”
|
|
125
127
|
- Existing materials: provide the PRD/prototype location, version and adopted scope. Say what is available even if it is incomplete.
|
|
126
128
|
|
|
127
|
-
|
|
129
|
+
When you provide a complete applicable PRD/prototype and ask to deliver from it, the AI adopts it unchanged without asking you to review the source again. Source copies and management records do not require individual review. Clarification is needed only for specific questions affecting progress. Review requirements or prototypes the AI writes, narrows or substantively changes: check scope, acceptance criteria and page behavior, then approve or give feedback. Valid approval of the current output content is reused.
|
|
128
130
|
|
|
129
131
|
**AI processing:** Adopts a complete applicable PRD without rewriting or renumbering. For partial adoption, it writes this iteration’s PRD with sources, inclusions, exclusions and acceptance, retaining source IDs where possible. Without a PRD, discussion produces one. Prototypes are optional; adequate existing ones are reused. It self-checks, confirms and saves each selected document, preserving originals.
|
|
130
132
|
|
|
@@ -230,7 +232,7 @@ The AI rechecks access to the same delivery directory, reads its state and confi
|
|
|
230
232
|
|
|
231
233
|
**AI processing:** Summarizes results and remaining work, and records your actual acceptance decision. Complete delivery needs evidence of required document approvals, batch/overall review, independent verification and final acceptance.
|
|
232
234
|
|
|
233
|
-
**Outputs:** `handoff.md` provides result locations, usage, verification conclusions and
|
|
235
|
+
**Outputs:** `handoff.md` provides result locations, usage, verification conclusions and integration status. Earlier document approvals do not replace final acceptance.
|
|
234
236
|
|
|
235
237
|
<a id="guide-sessions"></a>
|
|
236
238
|
|
|
@@ -254,7 +256,11 @@ The AI rechecks access to the same delivery directory, reads its state and confi
|
|
|
254
256
|
|
|
255
257
|
### 2.1 When to switch sessions
|
|
256
258
|
|
|
257
|
-
|
|
259
|
+
Consider a new session after requirements before technical design, after design and applicable contracts before test design, after the plan before implementation, after each batch and its review, and after overall review before independent verification. Combine coinciding boundaries. Resume pending review before advancing; directory creation and small steps within a stage need no session change.
|
|
260
|
+
|
|
261
|
+
Review open questions with their document, including impact, recommendation and when an answer is needed. Nonblocking questions can remain open; document approval does not answer every question.
|
|
262
|
+
|
|
263
|
+
At each completed stage, follow the stop in `status.md`: approve or give feedback on pending documents, or ask to continue completed work. Changing sessions is optional; “continue” does not approve a pending document. The page prioritizes current actions and shows future stages as not started, not current defects.
|
|
258
264
|
|
|
259
265
|
See the [new-session example](#guide-session-example). Keep one writing session per delivery. Trusted records can locate it directly; missing or ambiguous matches prompt clarification. The saved delivery language carries over. If switching before the first save, carry the unsaved request, intended location and pending operations.
|
|
260
266
|
|
|
@@ -289,7 +295,7 @@ Manual progress-page edits are preserved first; conflicts need coordination. Do
|
|
|
289
295
|
|
|
290
296
|
### 3.1 Existing materials or discussion
|
|
291
297
|
|
|
292
|
-
Provide the PRD, prototype or screenshot locations, versions and scope to use. The AI checks them as described in [Confirm requirements](#guide-requirements). A complete applicable PRD is adopted directly; partial adoption produces an iteration PRD without changing the original. Explicitly request edits to the original if needed.
|
|
298
|
+
Provide the PRD, prototype or screenshot locations, versions and scope to use. The AI checks them as described in [Confirm requirements](#guide-requirements). A complete applicable PRD is adopted directly; partial adoption produces an iteration PRD without changing the original. Explicitly request edits to the original if needed. File presence alone does not establish intent to use it. A clear request to deliver from unchanged supplied material establishes adoption, without a repeated source review; review AI-written changes instead.
|
|
293
299
|
|
|
294
300
|
For prior discussion, say “Use Aimship to continue the requirements we just discussed.” The AI organizes visible requests, decisions and open questions. Supply history it cannot see; suggestions are not approvals.
|
|
295
301
|
|
|
@@ -304,9 +310,9 @@ For prior discussion, say “Use Aimship to continue the requirements we just di
|
|
|
304
310
|
|
|
305
311
|
### 3.2 Change approved content
|
|
306
312
|
|
|
307
|
-
Explain what changes, why, and what stays the same; identify any documents you edited yourself. The AI records important changes in `change-log.md
|
|
313
|
+
Explain what changes, why, and what stays the same; identify any documents you edited yourself. The AI records important changes in `change-log.md`. Newly supplied unchanged inputs are checked and adopted; affected AI outputs are resubmitted for review before dependent work continues. Unaffected work, earlier approvals and test history remain.
|
|
308
314
|
|
|
309
|
-
|
|
315
|
+
Maintain initialization details normally, preserving the original commission in `.aimship/init.md`; record new requirements in the PRD and change log. Typos and formatting need no full re-review. Small fixes can continue the same delivery; a new goal or major redesign gets a separate delivery linked to the original.
|
|
310
316
|
|
|
311
317
|
<a id="guide-limits"></a>
|
|
312
318
|
<a id="27-stop-at-a-limited-goal"></a>
|
package/docs/guide.zh-CN.md
CHANGED
|
@@ -46,8 +46,8 @@ AI 工具项目空间
|
|
|
46
46
|
```text
|
|
47
47
|
~/Aimship/ # 资料根目录
|
|
48
48
|
└── 20261027-login-signup/ # 示例交付目录
|
|
49
|
-
├── status.md #
|
|
50
|
-
├──
|
|
49
|
+
├── status.md # 完整阶段进度、待审材料、下一步
|
|
50
|
+
├── .aimship/init.md # AI 接续所需的初始化约定
|
|
51
51
|
├── prd.md # 需求与验收标准
|
|
52
52
|
├── prototype/index.html # 页面交互原型
|
|
53
53
|
├── tech-design.md # 技术方案
|
|
@@ -76,7 +76,7 @@ AI 工具项目空间
|
|
|
76
76
|
|
|
77
77
|
以登录注册功能演示从需求到验收。**这是虚构实践参考,措辞和业务方案无需照抄。** 本例稍后提供工程和隔离测试数据库,约定需求后确认原型,再做技术设计;实际原型安排按交付需要确定。
|
|
78
78
|
|
|
79
|
-
同一会话沿用一个 Aimship 入口,无需逐阶段调用。每阶段完成并自检后,AI
|
|
79
|
+
同一会话沿用一个 Aimship 入口,无需逐阶段调用。每阶段完成并自检后,AI 保存成果、说明停点并停下。主要工作切换时建议新会话,也可原会话继续。AI 新产出或实质修改的需审文档等待批准,影响当前推进的问题等待确认,其他已完成阶段等待继续;可以一次说“通过并继续”。阶段内部不逐小步暂停。
|
|
80
80
|
|
|
81
81
|
<a id="11-准备工作位置"></a>
|
|
82
82
|
<a id="12-启用-aimship-并说明需求"></a>
|
|
@@ -96,13 +96,13 @@ AI 工具项目空间
|
|
|
96
96
|
|
|
97
97
|
**用户操作**:明确使用 Aimship,并说明目标。例如:
|
|
98
98
|
|
|
99
|
-
> 使用 Aimship
|
|
99
|
+
> 使用 Aimship,做用户名密码注册、登录、退出和登录后首页。完成开发与本地验证;代码稍后提供。
|
|
100
100
|
|
|
101
101
|
已有原型、PRD 或其他文档时,提供原位置即可,原件保留,用户无需手动复制。AI 按来源规则将正式采用的版本及必要依赖资源留存为本次交付 `source/` 中的副本,并在已有来源记录中注明采用依据;仅作背景参考的材料无需全量复制。后续修改先明确编辑对象,新版不覆盖旧依据。
|
|
102
102
|
|
|
103
|
-
**AI
|
|
103
|
+
**AI 处理**:确定交付目录并核对访问,保留诉求,建立或续接交付,告知实际保存目录、当前工作和下一步,并提醒将交付目录添加到当前项目/工作空间,已添加则忽略;默认按主流程承接需求,不先让你选择完整交付、仅设计或仅初始化。标准终点为实现、评审、独立验证和交付验收,无需再选择交付范围。你主动要求暂停或限定范围时按要求处理。若无法访问,提示你添加该原目录或授权;不会改存到项目空间。
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
**输出产物**:`.aimship/init.md` 为 AI 保留原始委托、材料位置及初始化约定;`status.md` 展示整个交付的阶段顺序、各阶段状态、当前位置、待审文档、影响推进的问题和下一步。新建交付时,AI 优先按明确偏好,否则按当前交流语言保存本次交付语言;状态和新文档沿用,文件名、编号、来源原文及已有文档不变。
|
|
106
106
|
|
|
107
107
|
<a id="14-阅读文档并给出结论"></a>
|
|
108
108
|
<a id="15-批准后继续推进"></a>
|
|
@@ -124,7 +124,7 @@ AI 工具项目空间
|
|
|
124
124
|
- 没有 PRD/原型:说明功能和预期行为,如“用户名不能重复,退出后再进首页必须登录”。
|
|
125
125
|
- 已有材料:给出 PRD/原型的位置、版本和本次采用范围;只有部分材料也直接说明。
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
你明确提供完整适用的 PRD/原型并要求据此交付时,AI 原样接纳,不要求重审原文;来源副本和管理记录也不逐份送审。只有存在影响推进的具体疑问才请你确认。需要你审核的是 AI 新写、裁剪或实质修改的需求与原型:查看范围、验收标准和页面行为,明确通过或反馈。已有当前内容的有效批准直接沿用。
|
|
128
128
|
|
|
129
129
|
**AI 处理**:完整适用的 PRD 直接采用,不重写或重新编号;仅采用部分时编写本次 PRD,写清来源、纳入、排除及验收,尽量沿用原编号;没有 PRD 时讨论后生成。原型可选,已有原型充分则复用。逐份自检、确认并保存,原件保留。
|
|
130
130
|
|
|
@@ -230,7 +230,7 @@ AI 重新核对同一交付目录的访问,读取状态并确认下一步技
|
|
|
230
230
|
|
|
231
231
|
**AI 处理**:汇总成果与遗留事项,记录你的实际验收决定。完整交付需有必要文档批准、批内及整体 review、独立验证和最终验收依据。
|
|
232
232
|
|
|
233
|
-
**输出产物**:`handoff.md`
|
|
233
|
+
**输出产物**:`handoff.md` 提供成果位置、用法、验证结论和集成状态。先前文档批准不替代最终验收。
|
|
234
234
|
|
|
235
235
|
<a id="guide-sessions"></a>
|
|
236
236
|
|
|
@@ -254,7 +254,11 @@ AI 重新核对同一交付目录的访问,读取状态并确认下一步技
|
|
|
254
254
|
|
|
255
255
|
### 2.1 何时换会话
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
文档中的待确认问题随文档一起审阅,注明影响、建议和最晚解决节点。不影响下一步的问题可以留待后续;文档通过不等于其中所有疑问都已有答案。
|
|
258
|
+
|
|
259
|
+
每阶段完成后按 `status.md` 的停点处理:AI 产出待审则批准或反馈,有具体疑问则回答问题,已完成则要求继续。无需每次都换会话;“继续”不替代待审材料的批准。进度页先展示当前操作,尚未开始的后续阶段不会当作当前缺项。
|
|
260
|
+
|
|
261
|
+
建议在需求完成进入技术设计、设计及适用契约完成进入测试、计划完成进入实施、每批实施及审查完成、整体审查完成进入独立验证时换会话。重合的节点只提示一次;待审时先接续审核,单独创建目录或阶段内的小步骤不需要换窗。
|
|
258
262
|
|
|
259
263
|
新会话操作见[演示中的续接示例](#guide-session-example)。同一交付只保留一个写入会话;可信记录可直接定位,找不到或有多个候选才询问。交付语言沿用已保存设置。首次保存前就要切换时,携带未保存诉求、计划位置及未完成操作。
|
|
260
264
|
|
|
@@ -289,7 +293,7 @@ AI 重新核对同一交付目录的访问,读取状态并确认下一步技
|
|
|
289
293
|
|
|
290
294
|
### 3.1 已有资料或讨论
|
|
291
295
|
|
|
292
|
-
提供 PRD、原型或截图的位置、版本和本次使用范围,AI 按[确认需求](#guide-requirements)核对。完整适用的 PRD 直接采用;部分采用形成迭代 PRD
|
|
296
|
+
提供 PRD、原型或截图的位置、版本和本次使用范围,AI 按[确认需求](#guide-requirements)核对。完整适用的 PRD 直接采用;部分采用形成迭代 PRD,原件不改。若要修改原件,请明确说明。文件存在本身不等于采用意图。你明确要求据此交付时,原样材料作为输入接纳,无需重复审核;AI 新写或实质修改的文档再正常送审。
|
|
293
297
|
|
|
294
298
|
已有讨论可说:“使用 Aimship 继续刚才讨论的需求。”AI 整理可见的诉求、决定和待确认问题;看不到的历史请补充,建议不算批准。
|
|
295
299
|
|
|
@@ -304,9 +308,9 @@ AI 重新核对同一交付目录的访问,读取状态并确认下一步技
|
|
|
304
308
|
|
|
305
309
|
### 3.2 修改已批准内容
|
|
306
310
|
|
|
307
|
-
说明改什么、为什么改、哪些保持不变;自行改过文档时指出文件。AI 在 `change-log.md`
|
|
311
|
+
说明改什么、为什么改、哪些保持不变;自行改过文档时指出文件。AI 在 `change-log.md` 记录重要变化。新提供的原样材料重新核对并记录采用;受影响的 AI 产出重新送审,相关工作审核通过后继续。未受影响的工作、旧批准和测试历史保留。
|
|
308
312
|
|
|
309
|
-
|
|
313
|
+
初始化约定可以正常维护;原始委托保留在 `.aimship/init.md`,新诉求写入需求文档和变更记录。错字或排版无需全部重审。交付后的小修可继续原交付;新目标或大幅重设计另建交付,并注明与原交付的关系。
|
|
310
314
|
|
|
311
315
|
<a id="guide-limits"></a>
|
|
312
316
|
<a id="27-只做到部分目标"></a>
|
package/lib/approvals.mjs
CHANGED
|
@@ -103,7 +103,10 @@ export async function reviewStatus(directory, state) {
|
|
|
103
103
|
let digest = null;
|
|
104
104
|
try { digest = await reviewFingerprint(directory, state, doc); } catch { /* Missing input remains blocked. */ }
|
|
105
105
|
const { approved, checked, latest } = decisionFor(state, doc, digest);
|
|
106
|
-
|
|
106
|
+
let inputBasis=false;
|
|
107
|
+
if(doc.mode==='input') { try { await evidence(directory,state,doc.basisRef); inputBasis=true; } catch { /* The adoption request must be readable. */ } }
|
|
108
|
+
const status=!digest ? 'unavailable' : (checked && evidenceIssues.includes(checked.id)) || (approved && evidenceIssues.includes(approved.id)) ? 'evidence-changed' : doc.mode==='input' && !inputBasis ? 'input-basis-required' : latest?.kind==='changes-requested' ? 'changes-requested' : latest?.kind==='self-check' && latest.result==='failed' ? 'self-check-failed' : doc.mode==='input' ? checked?'adopted':'self-check-required' : approved?'approved':checked?'pending':'self-check-required';
|
|
109
|
+
documents.push({ path: doc.path, version: doc.version, digest, selfCheck: checked?.id ?? null, approval: doc.mode==='input'?null:approved?.id ?? null, input:doc.mode==='input', status });
|
|
107
110
|
}
|
|
108
111
|
let limitedScope=false;
|
|
109
112
|
if(state.deliveryPolicy?.partialRef) {
|
|
@@ -147,10 +150,10 @@ export async function reviewStatus(directory, state) {
|
|
|
147
150
|
if (run.stage === 'implement' && state.stageRuns.some(r=>r.stage==='prototype')) needs.push('prototype');
|
|
148
151
|
for (const kind of needs) {
|
|
149
152
|
const inputs = (state.documents ?? []).filter(d=>d.kind === kind);
|
|
150
|
-
if (!inputs.length || inputs.some(d
|
|
153
|
+
if (!inputs.length || inputs.some(d=>!['approved','adopted'].includes(documents.find(r=>r.path===d.path)?.status))) blockedBy.push(`approval:${kind}`);
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
|
-
const waiting = required.filter(file => documents.find(d => d.path === file)?.status
|
|
156
|
+
const waiting = required.filter(file => !['approved','adopted'].includes(documents.find(d => d.path === file)?.status));
|
|
154
157
|
const ready = run.progress === 'done' && !['needs-review','unknown'].includes(run.applicability) && !blockedBy.length && !waiting.length && (!spec?.humanReview || required.length > 0);
|
|
155
158
|
const releaseReady = ready && (run.stage !== 'review' || run.result === 'passed');
|
|
156
159
|
runs.push({ id: run.id, stage: run.stage, progress: run.progress, applicability: run.applicability, documents: required, waiting, dependsOn, blockedBy, ready, releaseReady });
|
|
@@ -167,7 +170,7 @@ export async function reviewStatus(directory, state) {
|
|
|
167
170
|
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 })));
|
|
168
171
|
const nextRun = runs.find(r => !r.ready);
|
|
169
172
|
const nextStage = current ? runs[runs.indexOf(current) + 1]?.stage ?? null : nextRun?.stage ?? null;
|
|
170
|
-
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.releaseReady) && current.progress !== 'blocked' && !['needs-review','unknown'].includes(current.applicability) : !pending.length && !runs.some(r=>r.progress==='blocked' || (r.progress === 'done' && !r.releaseReady) || (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.' };
|
|
173
|
+
return { compatibility: 'current', documents, runs, pending, evidenceIssues, currentRun: current?.id ?? null, nextRun: nextRun?.id ?? null, nextStage, canProceed: !state.next.questionRef && (current ? !current.blockedBy.length && !(current.progress === 'done' && !current.releaseReady) && current.progress !== 'blocked' && !['needs-review','unknown'].includes(current.applicability) : !pending.length && !runs.some(r=>r.progress==='blocked' || (r.progress === 'done' && !r.releaseReady) || (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.' };
|
|
171
174
|
}
|
|
172
175
|
async function evidence(directory, state, ref) {
|
|
173
176
|
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.');
|
|
@@ -181,6 +184,8 @@ async function evidence(directory, state, ref) {
|
|
|
181
184
|
export async function enforceReviews(directory, state, previous) {
|
|
182
185
|
validateReviewState(state);
|
|
183
186
|
if (state.reviewPolicy !== 1) reject('Invalid review policy.');
|
|
187
|
+
for(const doc of state.documents.filter(d=>d.mode==='input')) await evidence(directory,state,doc.basisRef);
|
|
188
|
+
if(state.next.questionRef) await evidence(directory,state,state.next.questionRef);
|
|
184
189
|
const oldHistory = previous?.reviewHistory ?? [];
|
|
185
190
|
const previousPrd=previous?.documents.find(d=>d.kind==='prd'), currentPrd=state.documents.find(d=>d.kind==='prd');
|
|
186
191
|
const replacedPrd=previousPrd && currentPrd && previousPrd.path!==currentPrd.path;
|
|
@@ -188,13 +193,14 @@ export async function enforceReviews(directory, state, previous) {
|
|
|
188
193
|
const retained=state.documents.some(d=>d.path===old.path && (d.kind===old.kind || (replacedPrd && old===previousPrd && d.kind==='source' && d.mode==='reused')));
|
|
189
194
|
if(oldHistory.some(r=>r.document===old.path) && !retained)reject(`Preserve reviewed document registration ${old.path}.`);
|
|
190
195
|
}
|
|
191
|
-
const revisedApprovedPrd=replacedPrd && oldHistory.some(r=>r.document===previousPrd.path && ['approved','editorial'].includes(r.kind));
|
|
196
|
+
const revisedApprovedPrd=replacedPrd && oldHistory.some(r=>r.document===previousPrd.path && (['approved','editorial'].includes(r.kind) || (previousPrd.mode==='input' && r.kind==='self-check' && r.result==='passed')));
|
|
192
197
|
if(revisedApprovedPrd && !state.openChanges.some(c=>c.status==='open'))reject('Record the requirement authority change and impact in an open CHG.');
|
|
193
198
|
if (state.reviewHistory.length < oldHistory.length || !oldHistory.every((r, i) => isDeepStrictEqual(r, state.reviewHistory[i]))) reject('Preserve review history unchanged and in order.');
|
|
194
199
|
const prefix = { ...state, reviewHistory: [...oldHistory] };
|
|
195
200
|
for (const r of state.reviewHistory.slice(oldHistory.length)) {
|
|
196
201
|
const doc = state.documents.find(d => d.path === r.document);
|
|
197
202
|
if (!doc || r.version !== doc.version || r.digest !== await reviewFingerprint(directory, state, doc)) reject(`${r.id}: review must bind the current registered document version and content.`);
|
|
203
|
+
if(doc.mode==='input' && ['approved','editorial'].includes(r.kind)) reject('Supplied inputs use their adoption basis and self-check, not a fabricated document approval.');
|
|
198
204
|
const prior = decisionFor(prefix, doc, r.digest);
|
|
199
205
|
if (r.kind === 'approved' && !prior.checked) reject(`${r.id}: self-check the same content before recording approval.`);
|
|
200
206
|
if (r.kind === 'editorial' && (!prior.checked || !decisionFor(prefix, doc, r.previousDigest).approved)) reject(`${r.id}: editorial reconciliation needs a self-check and the previous approval at the same version.`);
|
|
@@ -214,7 +220,7 @@ export async function enforceReviews(directory, state, previous) {
|
|
|
214
220
|
const affected = new Set(revisedApprovedPrd ? status.runs.filter(r=>r.stage==='requirements' && r.progress!=='planned').map(r=>r.id) : []);
|
|
215
221
|
for (const doc of state.documents) {
|
|
216
222
|
const oldDoc = previous?.documents?.find(d => d.path === doc.path);
|
|
217
|
-
const latest = oldHistory.filter(r => r.document === doc.path && ['approved','editorial'].includes(r.kind)).at(-1);
|
|
223
|
+
const latest = oldHistory.filter(r => r.document === doc.path && (['approved','editorial'].includes(r.kind) || (oldDoc?.mode==='input' && r.kind==='self-check' && r.result==='passed'))).at(-1);
|
|
218
224
|
const now = status.documents.find(d => d.path === doc.path);
|
|
219
225
|
if (!oldDoc || !latest || !now) continue;
|
|
220
226
|
const changed = latest.digest !== now.digest || latest.version !== doc.version;
|
|
@@ -222,7 +228,7 @@ export async function enforceReviews(directory, state, previous) {
|
|
|
222
228
|
const requested = state.reviewHistory.slice(oldHistory.length).some(r=>r.document===doc.path && (r.kind==='changes-requested' || (r.kind==='self-check' && r.result==='failed')));
|
|
223
229
|
if ((!changed && !requested) || editorial) continue;
|
|
224
230
|
if (changed && !state.openChanges.some(c => c.status === 'open')) reject(`${doc.path}: record the material change and impact in an open CHG, or self-check an editorial reconciliation.`);
|
|
225
|
-
if (changed && now.status
|
|
231
|
+
if (changed && ['approved','adopted'].includes(now.status) && doc.version === latest.version) reject(`${doc.path}: a material revision needs a new document version; use editorial only for unchanged meaning.`);
|
|
226
232
|
for (const r of status.runs.filter(r => r.documents.includes(doc.path) && r.progress !== 'planned')) affected.add(r.id);
|
|
227
233
|
}
|
|
228
234
|
for (const r of status.runs) if (r.dependsOn.some(id => affected.has(id))) affected.add(r.id);
|
package/lib/cli.mjs
CHANGED
|
@@ -16,7 +16,7 @@ const HELP = {
|
|
|
16
16
|
scan: 'scan <material-root>. Read immediate delivery directories at .aimship/state.json, deduplicate IDs and report conflicts or invalid records. No global search or write.',
|
|
17
17
|
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.',
|
|
18
18
|
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.',
|
|
19
|
-
init: 'init <dir> --input <json-file|-> --rules-version <version>. Create state once; input requires goal.summary, language (en or zh-CN) and saved
|
|
19
|
+
init: 'init <dir> --input <json-file|-> --rules-version <version>. Create state once; input requires goal.summary, language (en or zh-CN) and saved .aimship/init.md; directory must be a child of bound dataRoot unless storage has an explicit local decisionRef; endpoint defaults to standard delivery; artifact conditions may remain null (unknown). Does not create templates.',
|
|
20
20
|
read: 'read <dir> [--rules-version <version>] [--delivery-id <known-id>]. Read current delivery state without executing work.',
|
|
21
21
|
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.',
|
|
22
22
|
check: 'check <dir> [--rules-version <version>] [--all]. Check structure and current input references (or every registered reference). Checks ordinary Markdown sections and searchable numbers in new local Markdown; reused and unsupported fragments are explicitly not checked. Does not prove semantics, remote access or validation results.',
|
|
@@ -30,7 +30,7 @@ const HELP = {
|
|
|
30
30
|
schemaVersion: SCHEMA_VERSION,
|
|
31
31
|
documentReview: {reviewPolicy:1, reviewHistory:'Append-only {id,kind,document,version,digest,sourceRef,summary}. self-check requires result: passed|failed; approved requires decision: explicit-approval; editorial requires previousDigest. Read review.documents for current digests. Tools validate records, not user identity. See docs/cli.md#document-review-protocol.'},
|
|
32
32
|
deliveryPolicy: 'New states default to {version:1}; partialRef identifies an explicitly limited scope, null restores standard scope with a new goal decision. Completion is derived separately from goal/acceptance.',
|
|
33
|
-
sessions: 'run.sessionGroup is an advisory context group, auto-filled for new runs; reviewOf names implementation runs and overall:true identifies overall review. read/check/resume expose session/completion. Completed stages return stop with await-review or await-continue, even within one group; suggestNewSession is advisory. Failed view saving returns reconcile-save. No new approval or automatic execution.',
|
|
33
|
+
sessions: 'run.sessionGroup is an advisory context group, auto-filled for new runs; reviewOf names implementation runs and overall:true identifies overall review. read/check/resume expose session/completion. Supplied PRD/prototype mode input uses the actual request basisRef and self-check, not human approval. next.questionRef identifies a concrete question on a blocked stage (clear with null). Completed stages return stop with await-review, await-clarification or await-continue, even within one group; suggestNewSession is advisory. Failed view saving returns reconcile-save. No new approval or automatic execution.',
|
|
34
34
|
stages: STAGES,
|
|
35
35
|
progress: ['planned', 'active', 'blocked', 'done'],
|
|
36
36
|
result: ['passed', 'failed', 'not-run', 'unknown', 'mixed'],
|
|
@@ -40,7 +40,7 @@ const HELP = {
|
|
|
40
40
|
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}.',
|
|
41
41
|
topLevel: {
|
|
42
42
|
managed: 'schemaVersion, revision, deliveryId, rulesVersion, createdAt, updatedAt, goalHistory, documentDigests, writeResult. Do not supply these in init/update.',
|
|
43
|
-
requiredInit: 'language: en|zh-CN and goal: {summary, endpoint?}; save
|
|
43
|
+
requiredInit: 'language: en|zh-CN and goal: {summary, endpoint?}; save nonempty initialization notes in .aimship/init.md before init. Defaults: endpoint standard delivery, goalRef .aimship/init.md, empty documents, and null documentPolicy conditions/authority. Register PRD and switch goalRef when drafted; no empty templates.',
|
|
44
44
|
language: 'en or zh-CN from explicit user preference, otherwise this delivery conversation. Required in current state; retained on update/render/resume.',
|
|
45
45
|
storage: 'Init-only {mode: explicit, decisionRef: delivery-relative-readable-file} for a user-selected location. Otherwise a strict child of configured dataRoot. Returned dataRoot is managed; ordinary workspace/material location is not a choice.',
|
|
46
46
|
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.',
|
|
@@ -54,13 +54,13 @@ const HELP = {
|
|
|
54
54
|
},
|
|
55
55
|
minimalInit: {
|
|
56
56
|
language: 'en',
|
|
57
|
-
goal: { summary: 'Export the currently filtered orders'
|
|
58
|
-
goalRef: '
|
|
57
|
+
goal: { summary: 'Export the currently filtered orders' },
|
|
58
|
+
goalRef: '.aimship/init.md',
|
|
59
59
|
documentPolicy: {authority:null,interaction:null,prototypeCovered:null,interface:null,databases:null},
|
|
60
60
|
documents: [],
|
|
61
|
-
stageRuns: [{ id: 'requirements-1', stage: 'requirements', scope: 'Clarify order export', progress: 'active', inputRefs: ['
|
|
61
|
+
stageRuns: [{ id: 'requirements-1', stage: 'requirements', scope: 'Clarify order export', progress: 'active', inputRefs: ['.aimship/init.md'], outputRefs: [] }],
|
|
62
62
|
currentRun: 'requirements-1',
|
|
63
|
-
next: { action: 'Clarify export fields and acceptance criteria', inputRefs: ['
|
|
63
|
+
next: { action: 'Clarify export fields and acceptance criteria', inputRefs: ['.aimship/init.md'] }
|
|
64
64
|
},
|
|
65
65
|
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.'
|
|
66
66
|
}
|
package/lib/delivery.mjs
CHANGED
|
@@ -66,6 +66,18 @@ export function suggestedNextStage(state) {
|
|
|
66
66
|
const contracts=(state.documentPolicy.interface!=null && state.documentPolicy.interface!=='none') || state.documentPolicy.databases?.length;
|
|
67
67
|
return ({frame:'requirements',requirements:'tech-design',prototype:'tech-design','tech-design':contracts?'contract':'test-design',contract:'test-design','test-design':'plan',plan:'implement',implement:'review',review:current.overall?'verify':'review',verify:'handoff'})[current.stage]??null;
|
|
68
68
|
}
|
|
69
|
+
function majorSessionBoundary(state,current) {
|
|
70
|
+
if (!current || current.progress !== 'done') return false;
|
|
71
|
+
const next=suggestedNextStage(state);
|
|
72
|
+
if (!next) return false;
|
|
73
|
+
if (['requirements','prototype'].includes(current.stage)) return next==='tech-design';
|
|
74
|
+
if (['tech-design','contract'].includes(current.stage)) return next==='test-design';
|
|
75
|
+
if (current.stage==='plan') return next==='implement';
|
|
76
|
+
if (current.stage==='review' && current.result==='passed') {
|
|
77
|
+
return current.overall ? next==='verify' : !!current.reviewOf?.length && ['implement','review'].includes(next);
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
69
81
|
export function sessionAdvice(directory,state,review,{saved=true}={}) {
|
|
70
82
|
const groups=[];
|
|
71
83
|
for (const r of state.stageRuns) {
|
|
@@ -81,12 +93,15 @@ export function sessionAdvice(directory,state,review,{saved=true}={}) {
|
|
|
81
93
|
const endAction=concluded?'finished':(current??last)?.stage==='handoff'?'assess-outcome':'await-continue';
|
|
82
94
|
let action='continue-current';
|
|
83
95
|
if (!saved) action='reconcile-save';
|
|
84
|
-
else if(
|
|
96
|
+
else if(state.next.questionRef) action='await-clarification';
|
|
97
|
+
else if(pending) action=review.pending.some(p=>!review.documents.find(d=>d.path===p.document)?.input)?'await-review':'resolve-current';
|
|
85
98
|
else if(!current && state.stageRuns.length && review.runs.every(r=>r.ready)) action=concluded?endAction:review.runs.some(r=>r.releaseReady===false)?'resolve-current':endAction;
|
|
86
99
|
else if(current && ((!status?.resolvedBy && (['failed','mixed','unknown','not-run'].includes(current.result) || (current.stage==='review' && current.progress==='done' && !status?.releaseReady))) || current.progress==='blocked' || ['needs-review','unknown'].includes(current.applicability))) action=concluded && !next?'finished':'resolve-current';
|
|
87
100
|
else if(status?.ready) action=!next?endAction:next.progress!=='planned'?'inspect-existing-work':'await-continue';
|
|
88
101
|
if (saved && !pending && state.deliveryPolicy?.version === 1 && status?.ready && next && review.runs.find(r=>r.id===next.id)?.blockedBy.length) action='resolve-current';
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
const suggestNewSession=['await-review','await-continue'].includes(action) && majorSessionBoundary(state,current);
|
|
103
|
+
let instruction=action==='await-clarification'?text(state,'Please answer the question listed below so this work can continue.','请回答下一步所列的具体问题,以便继续当前工作。'):action==='await-continue'?text(state,'This stage is saved. Say “continue” when ready.','本阶段已保存。准备好后可说“继续”。'):action==='assess-outcome'?text(state,'Review the handoff against the agreed goal and record the actual goal conclusion and acceptance; completed handoff alone does not end the delivery.','请对照约定目标审阅交付材料,记录实际目标结论和用户接受结果;完成交付文档不等于交付已结束。'):null;
|
|
104
|
+
if(suggestNewSession) instruction=[instruction,action==='await-review'?text(state,'A new session is recommended to review this document; you can also review it here.','建议新开会话审阅本份文档,也可留在这里审核。'):text(state,'A new session is recommended for the next work; you can also continue here.','建议新开会话接续下一步,也可留在这里继续。')].filter(Boolean).join(' ');
|
|
105
|
+
const continuation=['reconcile-save','await-review','await-clarification','assess-outcome','finished'].includes(action)?null:text(state,`Use Aimship to continue delivery ${JSON.stringify(path.resolve(directory))}; first read its current state and relevant formal documents, then continue the recorded work.${instruction?' '+instruction:''}`,`使用 Aimship 继续交付「${path.resolve(directory)}」,先读取当前状态和相关正式文档再接续。${instruction??''}`);
|
|
106
|
+
return {action,stop:!['continue-current','inspect-existing-work'].includes(action),suggestNewSession,currentRun:current?.id??null,nextRun:next?.id??null,groups,continuation,instruction,advisory:true,note:text(state,'A session boundary is not a blocker or approval. Continue here when requested. Resolve the delivery identity, current approvals and unfinished effects on every resume; this text grants no approval.','会话边界不是阻塞或批准。用户要求时可在当前会话继续。每次续接都需核对交付身份、当前审批和未完成事项;本提示不授予权限。')};
|
|
92
107
|
}
|
package/lib/documents.mjs
CHANGED
|
@@ -131,13 +131,13 @@ export async function inspectDocuments(directory, state) {
|
|
|
131
131
|
const find = kind => docs.find(d => d.kind === (kind === 'requirement' ? requirementKind : kind));
|
|
132
132
|
if (state.schemaVersion === 4) {
|
|
133
133
|
try {
|
|
134
|
-
const request = await safeRead(directory,state,'
|
|
135
|
-
if (!request?.trim()) issues.push('Missing or empty
|
|
136
|
-
else digests['
|
|
137
|
-
} catch { issues.push('Cannot read
|
|
134
|
+
const request = await safeRead(directory,state,'.aimship/init.md');
|
|
135
|
+
if (!request?.trim()) issues.push('Missing or empty .aimship/init.md.');
|
|
136
|
+
else digests['.aimship/init.md'] = hash(request);
|
|
137
|
+
} catch { issues.push('Cannot read .aimship/init.md inside this delivery.'); }
|
|
138
138
|
}
|
|
139
139
|
const preparing = state.schemaVersion === 4 && !find('requirement');
|
|
140
|
-
if (preparing && state.goalRef !== '
|
|
140
|
+
if (preparing && state.goalRef !== '.aimship/init.md') issues.push('Before requirements exist, goalRef must point to .aimship/init.md.');
|
|
141
141
|
if (!preparing && !find('requirement')) issues.push(`Register ${requirementKind} as the requirement entry.`);
|
|
142
142
|
if (!preparing && policy.authority === null) issues.push('Select the requirement authority when registering PRD.');
|
|
143
143
|
if (find('requirement') && state.goalRef.split('#')[0]!==find('requirement').path) issues.push('goalRef must point to the registered requirement authority.');
|
|
@@ -155,12 +155,12 @@ export async function inspectDocuments(directory, state) {
|
|
|
155
155
|
if (text === null) { unchecked.push(`${doc.path}: remote or unavailable repository; inspect adopted version using host tools (${doc.basisRef ?? 'missing basisRef'}).`); continue; }
|
|
156
156
|
digests[doc.path] = hash(text);
|
|
157
157
|
if (!text.trim()) issues.push(`${doc.path}: empty document.`);
|
|
158
|
-
if (doc.mode
|
|
158
|
+
if (doc.mode !== 'new') {
|
|
159
159
|
// Reuse is a current input option, not a historical document protocol.
|
|
160
160
|
// Read ordinary IDs from the explicitly registered requirement authority;
|
|
161
161
|
// do not impose our outline or infer that arbitrary source formats passed.
|
|
162
162
|
if (doc === find('requirement') && /\.md$/i.test(doc.path)) defs.push(...definitions(text,doc.path));
|
|
163
|
-
unchecked.push(`${doc.path}: reused format/content;
|
|
163
|
+
unchecked.push(`${doc.path}: reused format/content; recorded basis ${doc.basisRef}.`); continue;
|
|
164
164
|
}
|
|
165
165
|
if (spec) {
|
|
166
166
|
const records=sections(text,spec); let previous=-1;
|