aimship 0.1.0-preview.19 → 0.1.0-preview.21
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 +3 -3
- package/README.md +6 -4
- package/README.zh-CN.md +6 -4
- package/docs/cli.md +41 -12
- package/docs/examples.md +4 -0
- package/docs/guide.md +16 -12
- package/docs/guide.zh-CN.md +16 -12
- package/lib/approvals.mjs +47 -126
- package/lib/cli.mjs +10 -7
- package/lib/delivery.mjs +39 -37
- package/lib/documents.mjs +9 -7
- package/lib/domains.mjs +123 -0
- package/lib/execution.mjs +17 -0
- package/lib/language.mjs +2 -1
- package/lib/operations.mjs +30 -0
- package/lib/projections.mjs +73 -0
- package/lib/protocol.mjs +5 -5
- package/lib/state.mjs +30 -11
- package/lib/view.mjs +160 -92
- package/package.json +2 -2
- package/skills/aimship/SKILL.md +2 -2
- package/skills/aimship/references/core.md +21 -7
- package/skills/aimship/references/document-patterns.md +16 -2
- package/skills/aimship/references/document-review.md +2 -2
- package/skills/aimship/references/recovery.md +4 -4
- package/skills/aimship/references/review-method.md +7 -0
- package/skills/aimship/references/reviews/batch.md +21 -0
- package/skills/aimship/references/reviews/overall.md +21 -0
- package/skills/aimship/references/reviews/recheck.md +21 -0
- package/skills/aimship/references/routing.md +16 -0
- package/skills/aimship/references/sources-and-changes.md +1 -1
- package/skills/aimship/references/stages/contract.md +12 -14
- package/skills/aimship/references/stages/diagnose.md +12 -14
- package/skills/aimship/references/stages/frame.md +11 -11
- package/skills/aimship/references/stages/handoff.md +12 -12
- package/skills/aimship/references/stages/implement.md +14 -14
- package/skills/aimship/references/stages/plan.md +10 -12
- package/skills/aimship/references/stages/prototype.md +10 -14
- package/skills/aimship/references/stages/requirements.md +10 -14
- package/skills/aimship/references/stages/review.md +14 -16
- package/skills/aimship/references/stages/tech-design.md +15 -17
- package/skills/aimship/references/stages/test-design.md +10 -12
- package/skills/aimship/references/stages/verify.md +13 -13
- package/skills/aimship/references/templates/change-log.md +2 -2
- package/skills/aimship/references/templates/diagnosis.md +7 -7
- package/skills/aimship/references/templates/handoff.md +6 -6
- package/skills/aimship/references/templates/plan.md +13 -7
- package/skills/aimship/references/templates/prd.md +7 -7
- package/skills/aimship/references/templates/review.md +11 -6
- package/skills/aimship/references/templates/tech-design.md +7 -7
- package/skills/aimship/references/templates/testing.md +14 -8
package/lib/view.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { text, displayValue } from './language.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import {phaseOf,phaseOrder} from './domains.mjs';
|
|
3
|
+
import {generatedKinds,generatedArea,initialGeneratedBody,projectionText} from './projections.mjs';
|
|
4
|
+
import { completionStatus, sessionAdvice } from './delivery.mjs';
|
|
3
5
|
import fs from 'node:fs/promises';
|
|
4
6
|
import { reviewStatus } from './approvals.mjs';
|
|
5
7
|
import path from 'node:path';
|
|
@@ -8,18 +10,36 @@ import { atomicWrite, exists, hash, json, readJSON, noSymlinks } from './io.mjs'
|
|
|
8
10
|
import { resolveRef, documentChanges } from './documents.mjs';
|
|
9
11
|
|
|
10
12
|
const paths = dir => ({ view: path.join(dir,'status.md'), meta: path.join(dir,'.aimship/view.json') });
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
async function metadata(directory){
|
|
14
|
+
const p=paths(directory);await noSymlinks(p.meta);return await exists(p.meta)?readJSON(p.meta):null;
|
|
15
|
+
}
|
|
16
|
+
const recovery=state=>text(state,'Render at the current revision; do not replay the saved business update. Preserve modified generated content before rebuilding.','按当前修订重新生成;不要重放已保存的业务更新。重建前保留改动过的生成内容。');
|
|
17
|
+
async function inspectStatus(directory,state,meta){
|
|
18
|
+
const p=paths(directory);await noSymlinks(p.view);
|
|
19
|
+
if(!await exists(p.view))return {path:'status.md',status:'missing'};
|
|
20
|
+
const raw=await fs.readFile(p.view,'utf8');
|
|
21
|
+
if(!meta||meta.deliveryId!==state.deliveryId||hash(raw)!==meta.hash)return {path:'status.md',status:'modified'};
|
|
22
|
+
return {path:'status.md',status:meta.revision===state.revision?'current':'stale',revision:meta.revision};
|
|
23
|
+
}
|
|
24
|
+
async function inspectProjection(directory,state,doc,meta){
|
|
25
|
+
await noSymlinks(path.join(directory,doc.path));
|
|
26
|
+
if(!await exists(path.join(directory,doc.path)))return {path:doc.path,status:'missing',reason:'DOCUMENT_MISSING'};
|
|
27
|
+
const raw=await fs.readFile(path.join(directory,doc.path),'utf8'),area=generatedArea(raw,doc.kind);
|
|
28
|
+
if(area.count!==1)return {path:doc.path,status:'error',reason:area.reason??(area.count?'DUPLICATE_GENERATED_SECTION':'GENERATED_SECTION_MISSING')};
|
|
29
|
+
const record=meta?.deliveryId===state.deliveryId?meta.artifacts?.[doc.path]:null;
|
|
30
|
+
if(!record)return {path:doc.path,status:initialGeneratedBody(area.body)?'missing':'modified'};
|
|
31
|
+
if(record.hash!==hash(area.body))return {path:doc.path,status:'modified'};
|
|
32
|
+
return {path:doc.path,status:record.revision===state.revision?'current':'stale',revision:record.revision};
|
|
33
|
+
}
|
|
34
|
+
const projectionDocs=state=>state.documents.filter(d=>d.mode==='new'&&generatedKinds.includes(d.kind));
|
|
35
|
+
const aggregate=items=>['error','modified','missing','stale'].find(s=>items.some(x=>x.status===s))??'current';
|
|
36
|
+
export async function viewStatus(directory,state){
|
|
37
|
+
try{
|
|
38
|
+
const meta=await metadata(directory),statusView=await inspectStatus(directory,state,meta),artifacts=[];
|
|
39
|
+
for(const doc of projectionDocs(state))artifacts.push(await inspectProjection(directory,state,doc,meta));
|
|
40
|
+
const status=aggregate([statusView,...artifacts]);
|
|
41
|
+
return {status,revision:meta?.revision,statusView,artifacts,recovery:status==='current'?null:recovery(state)};
|
|
42
|
+
}catch(error){return {status:'error',reason:error.code??error.message,recovery:recovery(state)};}
|
|
23
43
|
}
|
|
24
44
|
const cell = x => String(x ?? 'not recorded').replaceAll('|','\\|').replaceAll('\n',' ');
|
|
25
45
|
const link = ref => `[${ref.replaceAll('[','\\[').replaceAll(']','\\]')}](${ref.split('#')[0].replaceAll(' ','%20').replaceAll('(','%28').replaceAll(')','%29')})`;
|
|
@@ -27,82 +47,96 @@ async function available(directory,state,ref) {
|
|
|
27
47
|
if (/^https?:\/\//.test(ref)) return true;
|
|
28
48
|
const p=resolveRef(directory,state,ref); return p && await exists(p);
|
|
29
49
|
}
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
// One responsibility per main-stage row; internal review and repair facts stay
|
|
51
|
+
// in the relevant batch view.
|
|
52
|
+
const batchReview=(_state,r)=>r.stage==='review'&&r.reviewScope==='batch';
|
|
53
|
+
export function derivedNextAction(state,review,{changed=[]}={}){
|
|
54
|
+
const t=(en,zh)=>text(state,en,zh),model=review.execution;
|
|
55
|
+
if(state.next.questionRef)return t('Resolve the recorded question before its dependent work.','先解决已记录问题,再推进依赖它的工作。');
|
|
56
|
+
if(changed.length||review.evidenceIssues.length)return t('Reconcile the changed material or review evidence.','核对变化的资料或审核依据。');
|
|
57
|
+
if(review.pending.length)return t('Review or correct the current document content.','审核或修订当前文档内容。');
|
|
58
|
+
const current=state.stageRuns.find(r=>r.id===state.currentRun),s=review.runs.find(r=>r.id===current?.id);
|
|
59
|
+
if(current&&(s?.blockedBy.length||current.progress==='blocked'||['needs-review','unknown'].includes(current.applicability)))return t('Resolve the current dependency or affected scope.','处理当前依赖或受影响范围。');
|
|
60
|
+
if(state.deliveryPolicy.partialRef){
|
|
61
|
+
if(current?.stage==='review'&&['failed','mixed','unknown'].includes(current.result)&&!s?.resolvedBy)return t('Resolve the cited review within the agreed limited scope.','在约定限定范围内处理所引审查。');
|
|
62
|
+
return s?.ready?t('Stop at the saved scope boundary and assess the result against the agreed limited goal.','在已保存的范围边界停止,对照约定限定目标核对结果。'):t('Complete the current agreed limited scope and its recorded dependencies.','完成当前约定限定范围及其已记录依赖。');
|
|
63
|
+
}
|
|
64
|
+
if(model.batches.some(b=>b.status==='needs-repair'))return t('Repair and recheck the affected batch within its authorized scope.','在已授权范围内修复并复查受影响批次。');
|
|
65
|
+
if(model.batches.some(b=>b.status==='await-review'))return t('Complete this batch review and authorized repairs before its batch stop.','完成本批审查及授权内修复,再在批次边界停止。');
|
|
66
|
+
if(current?.stage==='review'&&['failed','mixed','unknown'].includes(current.result)&&!s?.resolvedBy)return t('Resolve the cited review and recheck its actual scope.','处理所引审查,并按实际范围复查。');
|
|
67
|
+
if(model.batches.length&&model.batches.every(b=>b.status==='complete')){
|
|
68
|
+
if(!model.overall)return t('Summarize implementation and stop. Start the existing overall review in a new session, or here when explicitly requested.','汇总实施结果后停止;建议新会话执行已有整体审查,明确要求时可在当前会话继续。');
|
|
69
|
+
if(model.verification.coverage.some(c=>['failed','mixed'].includes(c.result)))return t('Resolve the cited verification failures and retest their actual coverage after the necessary repair review.','处理所引验证失败,在必要的修复审查后按实际覆盖重测。');
|
|
70
|
+
if(!model.verification.passed)return t('Prepare the actual test environment and perform separate formal verification; inspect the current coverage below.','准备实际测试环境并独立正式验证;核对下方当前覆盖。');
|
|
71
|
+
if(!state.stageRuns.some(r=>r.stage==='handoff'&&review.runs.find(x=>x.id===r.id)?.ready))return t('Prepare the handoff from the current review and verification results.','依据当前审查和验证结果准备交接。');
|
|
72
|
+
return state.outcome.acceptance==='accepted'?t('Assess the recorded delivery conclusion.','核对已记录的交付结论。'):t('Review the handoff and record the actual user acceptance.','审核交接并记录实际用户验收。');
|
|
73
|
+
}
|
|
74
|
+
if(current?.stage==='review'&¤t.reviewScope==='batch'&&s?.releaseReady)return t('This batch is complete. Stop before starting the next authorized batch.','本批已完成;在开始下一授权批次前停止。');
|
|
75
|
+
if(current?.stage==='plan'&&s?.releaseReady)return t('The plan is approved. Start only the agreed implementation batch.','计划已批准;只开始约定的实施批次。');
|
|
76
|
+
if(current?.stage==='implement')return t('Finish this authorized batch and its batch review; stop before the next batch.','完成当前授权批次及批审,在下一批前停止。');
|
|
77
|
+
return t('Continue the current agreed stage after its required review or continuation.','在所需审核或继续指令后接续当前约定阶段。');
|
|
45
78
|
}
|
|
46
|
-
export async function renderText(directory,state) {
|
|
79
|
+
export async function renderText(directory,state,snapshot) {
|
|
47
80
|
const t=(en,zh)=>text(state,en,zh), v=x=>cell(displayValue(state,x));
|
|
48
81
|
const artifactLink=ref=>ref.startsWith('repo:')
|
|
49
82
|
? `[${cell(ref.split('#')[0])}](${encodeURI(resolveRef(directory,state,ref)).replaceAll('(','%28').replaceAll(')','%29')})`
|
|
50
83
|
: link(ref.split('#')[0]);
|
|
51
|
-
const review=await reviewStatus(directory,state), changed=await documentChanges(directory,state);
|
|
84
|
+
const review=snapshot?.review??await reviewStatus(directory,state), changed=snapshot?.changed??await documentChanges(directory,state);
|
|
52
85
|
const completion=completionStatus(state,review,{changed}), session=sessionAdvice(directory,state,review);
|
|
53
86
|
const current=state.stageRuns.find(r=>r.id===state.currentRun) ?? state.stageRuns.at(-1);
|
|
54
87
|
const currentReview=review.runs.find(r=>r.id===current?.id);
|
|
55
88
|
const humanDocs=review.documents.filter(d=>currentReview?.documents.includes(d.path));
|
|
56
89
|
const failed=r=>['failed','mixed'].includes(r.result);
|
|
57
90
|
const progress=r=> {
|
|
58
|
-
const check=review.runs.find(x=>x.id===r.id);
|
|
91
|
+
const check=review.runs.find(x=>x.id===r.id), resolved=check?.resolvedBy;
|
|
59
92
|
if(r.progress==='planned')return t('Not started','尚未开始');
|
|
60
93
|
if(r.id===state.currentRun && state.next.questionRef)return t('Awaiting clarification','待确认具体问题');
|
|
61
94
|
if(r.progress==='blocked' || check?.blockedBy.length || ['needs-review','unknown'].includes(r.applicability))return t('Needs attention','需要处理');
|
|
62
|
-
if(failed(r) && !
|
|
63
|
-
if(r.result==='unknown' && !
|
|
64
|
-
if(r.result==='not-run' && !
|
|
65
|
-
if(r.stage==='review' && r.progress==='done' && !r.result && !
|
|
95
|
+
if(failed(r) && !resolved)return t('Result needs resolution','结果待处理');
|
|
96
|
+
if(r.result==='unknown' && !resolved)return t('Result not yet known','结果尚未确定');
|
|
97
|
+
if(r.result==='not-run' && !resolved)return t('Not run','未执行');
|
|
98
|
+
if(r.stage==='review' && r.progress==='done' && !r.result && !resolved)return t('Review result not recorded','审查结果未记录');
|
|
66
99
|
if(check?.documents.some(file=>['self-check-failed','changes-requested','evidence-changed','unavailable'].includes(review.documents.find(d=>d.path===file)?.status)))return t('Needs revision or checking','需要修改或核对');
|
|
67
100
|
if(r.progress==='done' && check?.waiting.length)return check.waiting.every(file=>review.documents.find(d=>d.path===file)?.input)?t('Input check pending','输入材料待核对'):t('Document prepared; awaiting review','文档已完成,待审核');
|
|
68
101
|
if(r.progress==='done' && check?.documents.length && check.documents.every(file=>review.documents.find(d=>d.path===file)?.status==='adopted'))return t('Provided material adopted','已采用现有材料');
|
|
69
102
|
return r.progress==='done'?t('Completed','已完成'):t('In progress','进行中');
|
|
70
103
|
};
|
|
71
|
-
const
|
|
104
|
+
const standaloneReview=!!state.deliveryPolicy.partialRef&&!review.execution.batches.length;
|
|
105
|
+
const phaseName=stage=>stage==='review' && !standaloneReview?t('Overall review','整体审查'):v(stage);
|
|
72
106
|
const runName=r=>batchReview(state,r)?t('implement · Batch review','实施 · 批次审查'):phaseName(r.stage);
|
|
73
107
|
const phaseProgress=stage=> {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const attention=runs.filter(pending);
|
|
79
|
-
if(attention.length)return progress(attention.find(r=>r.id===state.currentRun)??attention.at(-1));
|
|
80
|
-
if(runs.some(r=>r.progress==='planned'))return t('In progress','进行中');
|
|
81
|
-
if(stage==='implement') {
|
|
82
|
-
const batches=state.stageRuns.filter(r=>r.stage==='implement');
|
|
83
|
-
const covered=batches.filter(b=>state.stageRuns.some(r=>r.stage==='review' && r.reviewOf?.includes(b.id) && state.stageRuns.indexOf(r)>state.stageRuns.indexOf(b) && review.runs.find(x=>x.id===r.id)?.releaseReady && r.result==='passed')).length;
|
|
84
|
-
return covered===batches.length?t(`Recorded batches completed: ${batches.length}; batch reviews passed`,`已记录批次完成 ${batches.length};批次审查通过`):t(`Recorded batches completed: ${batches.length}; batch review pending`,`已记录批次完成 ${batches.length};待批次审查`);
|
|
85
|
-
}
|
|
86
|
-
// A previous overall conclusion cannot cover later implementation work.
|
|
87
|
-
if(stage==='review' && state.stageRuns.some(r=>r.stage==='implement')) {
|
|
88
|
-
const batches=state.stageRuns.filter(r=>r.stage==='implement');
|
|
89
|
-
if(!runs.some(r=>r.overall===true && batches.every(b=>r.reviewOf?.includes(b.id) && state.stageRuns.indexOf(r)>state.stageRuns.indexOf(b))))return t('Review required for current batches','当前批次待整体审查');
|
|
108
|
+
const runs=state.stageRuns.filter(r=>phaseOf(r)===stage&&!review.runs.find(x=>x.id===r.id)?.resolvedBy);
|
|
109
|
+
if(stage==='implement'&&review.execution.batches.length){
|
|
110
|
+
const batches=review.execution.batches,complete=batches.filter(b=>b.status==='complete').length;
|
|
111
|
+
return t(`Business batches complete: ${complete}/${batches.length}`,`业务批次完成 ${complete}/${batches.length}`)+(batches.some(b=>['needs-repair','needs-review','blocked'].includes(b.status))?t('; needs attention',';需要处理'):'');
|
|
90
112
|
}
|
|
113
|
+
if(stage==='review'&&review.execution.overall)return t('Completed','已完成');
|
|
114
|
+
if(stage==='verify'&&review.execution.verification.passed)return t('Completed','已完成');
|
|
115
|
+
if(!runs.length||runs.every(r=>r.progress==='planned'))return stage==='contract'&&(state.documentPolicy.interface===null||state.documentPolicy.databases===null)?t('Applicability to be determined during design','待技术设计确认是否适用'):t('Not started','尚未开始');
|
|
116
|
+
if(stage==='verify')return t('Coverage incomplete; see current testing results','覆盖尚未完成;见当前测试结果');
|
|
117
|
+
const pending=runs.filter(r=>r.progress!=='planned'&&!review.runs.find(x=>x.id===r.id)?.releaseReady);
|
|
118
|
+
if(pending.length)return progress(pending.find(r=>r.id===state.currentRun)??pending.at(-1));
|
|
119
|
+
if(runs.some(r=>r.progress==='planned'))return t('In progress','进行中');
|
|
120
|
+
if(stage==='review'&&!standaloneReview)return t('Review required for current implementation','当前实施待整体审查');
|
|
91
121
|
return runs.every(r=>progress(r)===t('Provided material adopted','已采用现有材料'))?t('Provided material adopted','已采用现有材料'):t('Completed','已完成');
|
|
92
122
|
};
|
|
123
|
+
const kinds={frame:['prd'],requirements:['prd'],prototype:['prototype'],diagnose:['diagnosis'],'tech-design':['tech-design'],contract:['contract','sql'],'test-design':['testing'],plan:['plan'],implement:['plan'],review:['review'],verify:['testing'],handoff:['handoff']};
|
|
124
|
+
const stageFiles=new Set();
|
|
125
|
+
for(const stage of phaseOrder(state)){
|
|
126
|
+
for(const doc of state.documents.filter(d=>kinds[stage]?.includes(d.kind)))if(await available(directory,state,doc.path))stageFiles.add(doc.path);
|
|
127
|
+
for(const ref of state.stageRuns.filter(r=>r.stage==='contract'&&stage==='contract').flatMap(r=>r.outputRefs)){const file=ref.split('#')[0];if(file&&!file.includes('/')&&await available(directory,state,file))stageFiles.add(file);}
|
|
128
|
+
}
|
|
129
|
+
// Registered formal entries also appear in adopted-material navigation when
|
|
130
|
+
// no selected main-stage row owns them. Do not link those twice above it.
|
|
131
|
+
for(const doc of state.documents)if(!doc.path.startsWith('.aimship/')&&await available(directory,state,doc.path))stageFiles.add(doc.path);
|
|
132
|
+
const workRefs=[...new Set(state.next.inputRefs??[])].filter(ref=>ref!=='.aimship/init.md'&&!stageFiles.has(ref.split('#')[0]));
|
|
93
133
|
const lines=[t('# Delivery progress','# 交付进度'),'',cell(state.goal.summary),'',t('## Current stage and your next action','## 当前阶段与用户操作'),''];
|
|
94
134
|
lines.push(`${t('Current stage','当前阶段')}: ${current?runName(current):v('requirements preparation')}${current?' · '+progress(current):''}`);
|
|
95
135
|
for(const d of humanDocs)lines.push(`- ${artifactLink(d.path)} ${cell(d.version)} · ${d.selfCheck?t('Self-check recorded as passed','自检记录通过'):t('Self-check pending','待自检')} · ${v(d.status)}`);
|
|
96
|
-
lines.push('',`${t('Next action','下一步')}: ${cell(state
|
|
136
|
+
lines.push('',`${t('Next action','下一步')}: ${cell(derivedNextAction(state,review,{changed}))}`);
|
|
137
|
+
if(workRefs.length)lines.push('',`${t('Work references','待办依据')}: ${workRefs.map(artifactLink).join('; ')}`);
|
|
97
138
|
if(session.action==='await-review')lines.push('',t('Review the document above and approve it or give feedback.','请查看上方文档,通过或反馈修改。'));
|
|
98
139
|
if(state.next.questionRef)lines.push('',`${t('Question and impact','问题与影响')}: ${artifactLink(state.next.questionRef)}`);
|
|
99
|
-
if(session.instruction)lines.push('',cell(session.instruction));
|
|
100
|
-
const next=suggestedNextStage(state);
|
|
101
|
-
if(next && current?.progress==='done' && !['resolve-current','finished','assess-outcome'].includes(session.action)) {
|
|
102
|
-
const scheduled=state.stageRuns[state.stageRuns.indexOf(current)+1];
|
|
103
|
-
const label=scheduled?runName(scheduled):next==='review'?(current.stage==='implement'?t('implement · Batch review','实施 · 批次审查'):t('Overall review','整体审查')):phaseName(next);
|
|
104
|
-
lines.push('',`${t('After this stop','当前停点处理后')}: ${label}${session.action==='await-review'?t(' (after approval)','(批准后)'):''}`);
|
|
105
|
-
}
|
|
106
140
|
const problems=[];
|
|
107
141
|
if(current && current.progress!=='planned') {
|
|
108
142
|
if(current.progress==='blocked')problems.push(cell(current.scope));
|
|
@@ -115,8 +149,26 @@ export async function renderText(directory,state) {
|
|
|
115
149
|
for(const c of state.openChanges.filter(c=>c.status==='open'))problems.push(`${t('Open change','待处理变更')}: ${artifactLink(c.ref)}`);
|
|
116
150
|
if(review.evidenceIssues.length)problems.push(t('Recorded review evidence needs checking.','已记录的审核依据需要核对。'));
|
|
117
151
|
if(problems.length)lines.push('',t('## Items to resolve','## 当前待处理事项'),'',...problems.map(p=>'- '+p));
|
|
118
|
-
|
|
119
|
-
|
|
152
|
+
const refs=new Map(), used=new Set();
|
|
153
|
+
const names={testing:t('Test cases and results','用例与结果'),sql:'SQL',prd:t('Requirements','需求依据'),source:t('Source material','来源材料'),prototype:t('Prototype','原型')};
|
|
154
|
+
for(const d of state.documents)if(!d.path.startsWith('.aimship/'))refs.set(d.path,`${names[d.kind]??v(d.kind)} · ${cell(d.version)}`);
|
|
155
|
+
for(const ref of state.stageRuns.filter(r=>r.stage==='contract').flatMap(r=>r.outputRefs)) {
|
|
156
|
+
const file=ref.split('#')[0];
|
|
157
|
+
if(file && !file.includes('/') && !refs.has(file))refs.set(file,t('Additional contract','补充契约'));
|
|
158
|
+
}
|
|
159
|
+
const artifacts=async stage=> {
|
|
160
|
+
const entries=new Map();
|
|
161
|
+
for(const d of state.documents.filter(d=>kinds[stage]?.includes(d.kind)))entries.set(d.path,d.path);
|
|
162
|
+
const runs=state.stageRuns.filter(r=>phaseOf(r)===stage && !review.runs.find(x=>x.id===r.id)?.resolvedBy);
|
|
163
|
+
for(const ref of runs.flatMap(r=>r.outputRefs))if(refs.has(ref.split('#')[0]))entries.set(ref.split('#')[0],ref);
|
|
164
|
+
const latest=runs.findLast(r=>r.progress==='done' && r.resultRef);
|
|
165
|
+
if(latest && refs.has(latest.resultRef.split('#')[0]))entries.set(latest.resultRef.split('#')[0],latest.resultRef);
|
|
166
|
+
const links=[];
|
|
167
|
+
for(const [file,ref] of entries)if(await available(directory,state,file)){used.add(file);links.push(artifactLink(file)+(ref.includes('#')?' · '+cell(ref.split('#')[1]):''));}
|
|
168
|
+
return links.join('; ') || t('Not yet recorded','尚未记录');
|
|
169
|
+
};
|
|
170
|
+
lines.push('',t('## Delivery progress','## 整体进度'),'',t('| Stage | Artifact or result | Status |','| 阶段 | 成果 | 状态 |'),'| --- | --- | --- |');
|
|
171
|
+
for(const stage of phaseOrder(state))lines.push(`| ${phaseName(stage)} | ${await artifacts(stage)} | ${phaseProgress(stage)} |`);
|
|
120
172
|
lines.push('',`${t('Delivery conclusion','交付结论')}: ${v(completion.status)}`);
|
|
121
173
|
// Full completion diagnostics matter at handoff, not as a list of early-stage defects.
|
|
122
174
|
if(current?.stage==='handoff' || state.outcome.goal==='met')lines.push(...completion.gaps.map(g=>'- '+cell(g)));
|
|
@@ -125,41 +177,57 @@ export async function renderText(directory,state) {
|
|
|
125
177
|
if(state.outcome.deploymentRef)lines.push(`${t('Deployment record','部署记录')}: ${artifactLink(state.outcome.deploymentRef)}`);
|
|
126
178
|
lines.push('',t('## Goal and adopted materials','## 目标与采用材料'),'',`${t('Endpoint','交付终点')}: ${cell(state.goal.endpoint??t('To be confirmed','待确认'))}`);
|
|
127
179
|
if(state.documentPolicy.interface===null || state.documentPolicy.databases===null)lines.push('',t('Interface/database applicability will be determined during technical design.','接口/数据库适用性待技术设计确认。'));
|
|
128
|
-
const refs
|
|
129
|
-
const names={testing:t('Test cases and results','用例与结果'),sql:'SQL',prd:t('Requirements','需求依据'),source:t('Source material','来源材料'),prototype:t('Prototype','原型')};
|
|
130
|
-
for(const d of state.documents)if(!d.path.startsWith('.aimship/'))refs.set(d.path,`${names[d.kind]??v(d.kind)} · ${cell(d.version)}`);
|
|
131
|
-
// Contract stages may have supplementary formal formats (for example RPC).
|
|
132
|
-
// Root outputs are artifact entries, not approval claims; evidence stays under .aimship/.
|
|
133
|
-
for(const ref of state.stageRuns.filter(r=>r.stage==='contract').flatMap(r=>r.outputRefs)) {
|
|
134
|
-
const file=ref.split('#')[0];
|
|
135
|
-
if(file && !file.includes('/') && !refs.has(file))refs.set(file,t('Additional contract','补充契约'));
|
|
136
|
-
}
|
|
137
|
-
for(const [ref,role] of refs)if(await available(directory,state,ref))lines.push(`- ${role}: ${artifactLink(ref)}`);
|
|
138
|
-
lines.push('',t('## Continue this delivery','## 接续本次交付'),'',`${t('Delivery directory','交付目录')}: ${cell(path.resolve(directory))}`,'',t('You can continue here, or start a new session with “Use Aimship to continue this delivery” and this directory. The AI reads the saved state and materials and resumes the current stop.','可在当前会话继续;新会话请说“使用 Aimship 继续本次交付”并提供此目录。AI 会读取已保存状态和材料,接续本页停点。'));
|
|
180
|
+
for(const [ref,role] of refs)if(!used.has(ref) && await available(directory,state,ref))lines.push(`- ${role}: ${artifactLink(ref)}`);
|
|
139
181
|
if(state.repositories.length) {
|
|
140
182
|
lines.push('',t('## Associated engineering','## 关联工程'),'',t('| Object | Location | Role |','| 工程 | 位置 | 用途 |'),'| --- | --- | --- |');
|
|
141
183
|
for(const r of state.repositories)lines.push(`| ${cell(r.id)} | ${cell(r.path)} | ${cell(r.role)} |`);
|
|
142
184
|
}
|
|
143
|
-
lines.push('',t('## Saved information','## 保存信息'),'',`${t('Delivery','交付')}: ${state.deliveryId}`,`${t('State revision','状态修订')}: ${state.revision}`,`${t('Rules','规则版本')}: ${state.rulesVersion}`,`${t('State saved','状态保存时间')}: ${state.updatedAt}`,'',t('Generated from saved state and document checks. Update the formal records, not this page. Recorded results are not independent proof of execution.','由保存状态和文档检查生成;请更新正式记录,不手改本页。记录结果不等于独立验证了实际执行。'),'');
|
|
185
|
+
lines.push('',t('## Saved information','## 保存信息'),'',`${t('Delivery directory','交付目录')}: ${cell(path.resolve(directory))}`,`${t('Delivery','交付')}: ${state.deliveryId}`,`${t('State revision','状态修订')}: ${state.revision}`,`${t('Rules','规则版本')}: ${state.rulesVersion}`,`${t('State saved','状态保存时间')}: ${state.updatedAt}`,'',t('Generated from saved state and document checks. Update the formal records, not this page. Recorded results are not independent proof of execution.','由保存状态和文档检查生成;请更新正式记录,不手改本页。记录结果不等于独立验证了实际执行。'),'');
|
|
144
186
|
return lines.join('\n');
|
|
145
187
|
}
|
|
146
|
-
export async function generateView(directory,state,preserveEdits=false)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
188
|
+
export async function generateView(directory,state,preserveEdits=false){
|
|
189
|
+
const p=paths(directory),results=[],metaBase={deliveryId:state.deliveryId,artifacts:{}};
|
|
190
|
+
let meta;
|
|
191
|
+
try{meta=await metadata(directory);}catch(error){
|
|
192
|
+
if(!preserveEdits||error.code!=='INVALID_JSON')return {status:'error',reason:error.code??error.message,recovery:recovery(state)};
|
|
193
|
+
try{await noSymlinks(p.meta);await atomicWrite(path.join(directory,'.aimship',`view-metadata-edits-${randomUUID()}.json`),await fs.readFile(p.meta));meta=null;}catch(cause){return {status:'error',reason:cause.code??cause.message,recovery:recovery(state)};}
|
|
194
|
+
}
|
|
195
|
+
if(meta?.deliveryId===state.deliveryId)Object.assign(metaBase,meta,{artifacts:{...meta.artifacts}});
|
|
196
|
+
const review=await reviewStatus(directory,state),changed=await documentChanges(directory,state),snapshot={review,changed};
|
|
197
|
+
async function preserve(file,raw,label){const target=path.join(directory,'.aimship',`${label}-edits-${randomUUID()}.md`);await atomicWrite(target,raw);return target;}
|
|
198
|
+
let statusView;
|
|
199
|
+
try{
|
|
200
|
+
const diagnostic=await inspectStatus(directory,state,meta);let preservedPath;
|
|
201
|
+
if(diagnostic.status==='modified'){
|
|
202
|
+
if(!preserveEdits)statusView={...diagnostic,status:'protected'};
|
|
203
|
+
else preservedPath=await preserve(p.view,await fs.readFile(p.view),'status');
|
|
204
|
+
}
|
|
205
|
+
if(!statusView){const body=await renderText(directory,state,snapshot);await atomicWrite(p.view,body);metaBase.hash=hash(body);metaBase.revision=state.revision;statusView={path:'status.md',status:'current',revision:state.revision,...(preservedPath?{preservedPath}:{})};}
|
|
206
|
+
}catch(error){statusView={path:'status.md',status:'error',reason:error.code??error.message};}
|
|
207
|
+
for(const doc of projectionDocs(state)){
|
|
208
|
+
try{
|
|
209
|
+
const diagnostic=await inspectProjection(directory,state,doc,meta),file=path.join(directory,doc.path);
|
|
210
|
+
if(diagnostic.status==='error'||diagnostic.reason==='DOCUMENT_MISSING'){results.push(diagnostic);continue;}
|
|
211
|
+
const raw=await fs.readFile(file,'utf8'),area=generatedArea(raw,doc.kind),body=projectionText(state,review,doc.kind);let preservedPath;
|
|
212
|
+
if(body===area.body){metaBase.artifacts[doc.path]={hash:hash(body),revision:state.revision};results.push({path:doc.path,status:'current',revision:state.revision});continue;}
|
|
213
|
+
// A sourceDigest pins the entire source file, including its generated area.
|
|
214
|
+
// Never change that evidence, even when asked to preserve manual view edits.
|
|
215
|
+
if(state.reviewHistory.some(r=>r.sourceDigest&&r.sourceRef.split('#')[0]===doc.path)){results.push({path:doc.path,status:'protected',reason:'APPROVAL_EVIDENCE_SOURCE'});continue;}
|
|
216
|
+
if(diagnostic.status==='modified'){
|
|
217
|
+
if(!preserveEdits){results.push({...diagnostic,status:'protected'});continue;}
|
|
218
|
+
preservedPath=await preserve(file,raw,doc.kind);
|
|
219
|
+
}
|
|
220
|
+
if(await fs.readFile(file,'utf8')!==raw){results.push({path:doc.path,status:'protected',reason:'CONTENT_CHANGED_DURING_RENDER'});continue;}
|
|
221
|
+
await atomicWrite(file,raw.slice(0,area.bodyStart)+body+raw.slice(area.end));
|
|
222
|
+
metaBase.artifacts[doc.path]={hash:hash(body),revision:state.revision};
|
|
223
|
+
results.push({path:doc.path,status:'current',revision:state.revision,...(preservedPath?{preservedPath}:{})});
|
|
224
|
+
}catch(error){results.push({path:doc.path,status:'error',reason:error.code??error.message});}
|
|
225
|
+
}
|
|
226
|
+
try{await atomicWrite(p.meta,json(metaBase));}catch(error){return {status:'error',reason:error.code??error.message,statusView,artifacts:results,recovery:recovery(state)};}
|
|
227
|
+
const failed=[statusView,...results].filter(r=>r.status!=='current'),status=failed.some(r=>r.status==='error')?'error':failed.length?'protected':'current';
|
|
228
|
+
return {status,revision:state.revision,statusView,artifacts:results,...(failed.length?{recovery:recovery(state)}:{})};
|
|
161
229
|
}
|
|
162
|
-
export async function savedResult(directory,state,{initialized=false}={})
|
|
163
|
-
|
|
164
|
-
|
|
230
|
+
export async function savedResult(directory,state,{initialized=false}={}){
|
|
231
|
+
const view=await generateView(directory,state),review=await reviewStatus(directory,state);
|
|
232
|
+
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.statusView?.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==='.aimship/init.md'?'requirements preparation':null),nextAction:derivedNextAction(state,review),repositoryCount:state.repositories.length,...(initialized?{workspaceHint:text(state,`Add ${path.resolve(directory)} to your current project/workspace; ignore this if already added.`,`请将「${path.resolve(directory)}」添加到当前项目/工作空间;已添加则忽略。`)}:{})},session:sessionAdvice(directory,state,review,{saved:view.status==='current'})}};
|
|
165
233
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aimship",
|
|
3
|
-
"version": "0.1.0-preview.
|
|
3
|
+
"version": "0.1.0-preview.21",
|
|
4
4
|
"description": "Explicit, goal-driven delivery workflow for coding agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -43,6 +43,6 @@
|
|
|
43
43
|
},
|
|
44
44
|
"homepage": "https://github.com/clsx/aimship#readme",
|
|
45
45
|
"aimship": {
|
|
46
|
-
"protocolVersion":
|
|
46
|
+
"protocolVersion": 2
|
|
47
47
|
}
|
|
48
48
|
}
|
package/skills/aimship/SKILL.md
CHANGED
|
@@ -10,8 +10,8 @@ Activate only when the user explicitly asks to start or resume Aimship. A clear
|
|
|
10
10
|
|
|
11
11
|
1. Run `"{{AIMSHIP_NODE}}" "{{AIMSHIP_LAUNCHER}}" bind`, then read the returned fixed-version [core](references/core.md) and CLI help. Use that release's tools and references. In a source checkout, run `node bin/aimship.mjs bind` from its package root.
|
|
12
12
|
2. Locate the same delivery and read its state, initialization notes and current materials. For new work, follow [initialization](references/core.md#initialization): preserve the commission in `.aimship/init.md`, use a separate directory under the bound dataRoot, and save the actual language and scope. A concrete request is enough; code and a PRD can come later. Resume existing work rather than initialize it again.
|
|
13
|
-
3.
|
|
14
|
-
4.
|
|
13
|
+
3. Use [routing](references/routing.md) to determine this turn's stage, actual scope and user-visible stop from the request and saved state. Load the selected [stage contract](references/core.md#stage-references), not every stage. Each has inputs, goal/scope, actions, outputs/result and completion/stop. Shared approval, change, source and recovery rules remain in their common references.
|
|
14
|
+
4. Execute that work unit within the commission. One implementation batch includes local checks, batch review and authorized repair/recheck; keep separate internal runs but do not ask for continuation between them. Stop at batch closure, a real dependency, a required document review, or the selected overall-review/verification boundary. After the last batch, save its implementation summary and recommend a new session for the existing overall review; continue it here only with explicit authorization. A request for overall review alone does not authorize full testing. Save actual content approval before dependent work; approval and continuation may be expressed together.
|
|
15
15
|
5. Report the saved directory, materials and next action using the core's User-facing updates guidance. On initialization, remind the user once to add the actual directory to the current project/workspace, ignoring the reminder if already added. On resume, preserve the delivery ID, current stop, language and fixed rule/tool paths; reload these if context is lost.
|
|
16
16
|
|
|
17
17
|
|
|
@@ -26,7 +26,7 @@ This flow follows explicit Aimship activation in the first and every new session
|
|
|
26
26
|
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.
|
|
27
27
|
2. Bind the actual tool/core version and keep its returned dataRoot. Inspect the intended delivery folder or known candidates for existing state, partial creation or conflicting material. Read and resume existing state, checking deliveryId when known, including older deliveries outside today’s configured root. For a new location explicitly chosen by the user, preserve that actual decision in a nonempty local file within the delivery and supply `storage: {mode: "explicit", decisionRef: "<delivery-relative file>"}` to init; the reference is a file path without a fragment. Never invent the decision or override the tool’s dataRoot to make a path pass. Otherwise use a separate folder under the bound dataRoot. Ask only when identity/location is unresolved; do not create a replacement or infer ownership from a matching name.
|
|
28
28
|
3. Reuse the current workspace’s access to the intended materials path without changing that path. If access is missing, follow [AI tool access](hosts.md) with the exact required path; the user adds the original directory or grants the needed access. If the target does not exist, use its accessible existing parent to create it as part of saving this delivery, or explain which directory the user must create/open. No silent fallback into the workspace, unrelated probe files or global settings changes. Workspace names and “I added it” are not proof: normal reads establish read access only; actual saves establish write access for that operation. Do not report saved work before the result confirms it.
|
|
29
|
-
4. Write concise initialization notes in .aimship/init.md: the original commission in its own words, language, supplied material locations, adopted copies, explicit user limits and the delivery endpoint. Distinguish the user’s words from your summary. Keep stable context here, current progress in state/status and business changes in formal requirements; date any necessary initialization-time observation so it cannot be mistaken for current execution. Do not duplicate the general workflow or conversation history. Set `language` to `zh-CN` or `en`: an explicit user preference takes precedence, otherwise use the language of this conversation. The Agent saves this delivery setting in init; it is not an installation setting or a command the user must learn. Use init to create state and its generated status.md. An omitted or null endpoint defaults to standard delivery; provide an actual narrower endpoint when the user limits the work. Before PRD exists, use goalRef .aimship/init.md, empty documents and null for unknown documentPolicy conditions/authority (schema
|
|
29
|
+
4. Write concise initialization notes in .aimship/init.md: the original commission in its own words, language, supplied material locations, adopted copies, explicit user limits and the delivery endpoint. Distinguish the user’s words from your summary. Keep stable context here, current progress in state/status and business changes in formal requirements; date any necessary initialization-time observation so it cannot be mistaken for current execution. Do not duplicate the general workflow or conversation history. Set `language` to `zh-CN` or `en`: an explicit user preference takes precedence, otherwise use the language of this conversation. The Agent saves this delivery setting in init; it is not an installation setting or a command the user must learn. Use init to create state and its generated status.md. An omitted or null endpoint defaults to standard delivery; provide an actual narrower endpoint when the user limits the work. Before PRD exists, use goalRef .aimship/init.md, empty documents and null for unknown documentPolicy conditions/authority (schema 5). A requirements/frame 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.
|
|
30
30
|
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.
|
|
31
31
|
6. Give a concise receipt: initialized / resumed / incomplete, recognizable delivery, actual absolute directory and readable status link (only when available), saved materials, bound version, saved language, 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. Separate existing materials retained or copied from documents newly authored or revised and delivery records newly created. Report “unchanged” only when supported by the actual operations and source evidence. For a complete unchanged supplied PRD with clear intent to deliver from it, report input adoption without requesting repeated source approval; clarify only actual uncertainties. On first initialization, add one neutral reminder with the actual directory: add it to the current project/workspace, ignoring this if already added. No tool-specific instructions or membership check are needed. Then continue authorized requirement clarification, unless the user requested a stop.
|
|
32
32
|
|
|
@@ -71,7 +71,7 @@ Standard development order: PRD → technical design → interface/SQL → test
|
|
|
71
71
|
|
|
72
72
|
### Standard completeness and limited scope
|
|
73
73
|
|
|
74
|
-
New deliveries use `deliveryPolicy: {version: 1}`. `outcome.goal` describes the agreed scope and `outcome.acceptance` the actual user decision; neither alone means standard complete delivery. The tool reports a separate derived completion assessment. Standard completion requires reviewed requirements/design/cases/plan and applicable artifacts, completed implementation with passing batch and overall review, passing independent verification, handoff and explicit final acceptance. Record review coverage with reviewOf implementation IDs and
|
|
74
|
+
New deliveries use `deliveryPolicy: {version: 1}`. `outcome.goal` describes the agreed scope and `outcome.acceptance` the actual user decision; neither alone means standard complete delivery. The tool reports a separate derived completion assessment. Standard completion requires reviewed requirements/design/cases/plan and applicable artifacts, completed implementation with passing batch and overall review, passing independent verification, handoff and explicit final acceptance. Register approved business batches separately from execution runs. Record review coverage with reviewOf implementation IDs and explicit reviewScope: batch or overall; repairs keep the business batch identity when applicable. Records validate structure/evidence references, not truth or user identity; inspect actual results and coverage.
|
|
75
75
|
|
|
76
76
|
If the user explicitly excludes cases and testing (or limits the commission to an earlier endpoint), explain the consequence once, preserve that scope decision in existing PRD/change records, and register `deliveryPolicy.partialRef`. Do not quietly add the excluded work or repeatedly persuade the user. Finish the authorized work and hand off the untested or otherwise limited result, recording omitted work and remaining limits. Its agreed scope can be met and accepted, but its completion assessment stays partial-scope, never standard-complete or verified. No special external-testing mode or extra documents are needed. Existing implementation/approval dependencies still apply. Scope changes preserve the earlier goal/decision/history; started runs are not erased to manufacture completion.
|
|
77
77
|
|
|
@@ -79,7 +79,7 @@ Current completion claims require the recorded scope, approvals and actual resul
|
|
|
79
79
|
|
|
80
80
|
## Stage references
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
Use [routing](routing.md) to select the current work unit, then read its stage contract. Do not load all stages on every turn. Review dispatch selects a batch, overall or recheck contract; modules are instructions, not separate user commands, agents or isolated contexts.
|
|
83
83
|
|
|
84
84
|
| Responsibility | Read when | Reference |
|
|
85
85
|
| --- | --- | --- |
|
|
@@ -98,9 +98,19 @@ Read the reference for the current responsibility, not all stage references on e
|
|
|
98
98
|
|
|
99
99
|
Each run records its scope, required inputs, results and progress. A result may be a section in a shared document. A `done` run records completed work, not human approval. Adopted user input is distinct from reviewed AI output. Proceed when required AI-output approvals or adopted-input checks match current content, this run's requirements are met, the next inputs exist, authorization covers it and no relevant unresolved issue blocks it. An issue blocks only dependent work; changing the order to continue other work is still an explicit plan change.
|
|
100
100
|
|
|
101
|
+
## Project context and decisions
|
|
102
|
+
|
|
103
|
+
Use the relevant current implementation, interfaces, database structures and applicable repository conventions to understand this change. Investigation, design, contract/SQL, implementation and review reuse that context according to their responsibilities. Existing code is evidence, not a requirement to copy it or repair unrelated historical debt. Read the applicable parts of available instructions; when none exist, use the current code/contracts and user requirements and proceed. Do not require a new conventions/context document or whole-project compliance proof.
|
|
104
|
+
|
|
105
|
+
Investigate facts accessible through the code, documents and tools instead of turning that work into questions for the user. Present only substantive business, authorization or design decisions with their impact, recommendation and dependent work. Hold the work that needs that answer; nonblocking details can remain for later investigation or verification. A design review need not resolve every future execution condition, but must disclose gaps that affect the decision or correctness of the next work.
|
|
106
|
+
|
|
101
107
|
## Implementation and evidence
|
|
102
108
|
|
|
103
|
-
|
|
109
|
+
Complete one authorized implementation work unit (implement → necessary development checks → automatic batch review → authorized repair/recheck), save and report its closure, then stop before the next batch. Compile/type checks and local tests are development self-checks, not code review or formal verification; choose them for the actual change rather than requiring a full suite after every batch. Planned tests can be written with implementation; writing them does not mean they passed. Keep brief development checks and existing evidence references in plan execution.
|
|
110
|
+
|
|
111
|
+
After the last batch and its review are complete, summarize implementation and remaining work, save and stop. Recommend a new session for the existing overall-review responsibility; do not start it automatically. Explicit authorization to continue overall review in the current session permits that path, without a special phrase, session proof or extra approval record. This also applies to a single business batch: its batch review does not replace overall review. Overall review examines the combined current object and stops before formal verification. A review request alone does not commission execution of the test plan.
|
|
112
|
+
|
|
113
|
+
After passing overall review, hand over the reviewed object, agreed environment preparation and formal verification scope. Use the actual project conditions: where testing requires a deployed test environment, it must be ready for that execution; local units or other agreed checks need no deployment. Aimship does not initiate deployment or add a deployment stage. Formal RUN records and optional coverage-based groups belong to testing execution. Groups follow coverage and conditions, not development batches; retests are new RUNs, not new business batches.
|
|
104
114
|
|
|
105
115
|
For standard delivery, registering review/verify/handoff as active or done requires their actual predecessors even when dependsOn or inputRefs are empty: review identifies completed implementation objects (an overall review covers all preceding batches), verification follows a passing overall review and resolved preceding reviews, and handoff follows passing verification or an evidenced passing rerun. Draft documents and planned work may be saved earlier. Independent review, verification or limited handoff requires the existing deliveryPolicy.partialRef to point to readable local evidence of the explicitly limited commission; an empty dependency list is not such authorization. Existing declared dependencies and document approvals still apply. These are state-tool checks, not interception of general-purpose file, test or deployment tools.
|
|
106
116
|
|
|
@@ -110,13 +120,17 @@ Each conclusion identifies who/what produced it, date, object/version, scope, ba
|
|
|
110
120
|
|
|
111
121
|
Execution progress (`planned`, `active`, `blocked`, `done`) is separate from pass/fail/not-run/unknown, current applicability, goal achievement and user acceptance. A finished failed verification is still failed. Review is not runtime testing. Neither the presence of a report nor successful tool exit proves the goal.
|
|
112
122
|
|
|
123
|
+
### Conditional host delegation
|
|
124
|
+
|
|
125
|
+
Use the host's existing subagent capability when there are independent work blocks and the benefit exceeds coordination cost. Small work, shared-write conflicts or hosts without that capability proceed serially. Do not split frontend/backend automatically. Give each delegated block the relevant approved design/contracts, project context, scope and nonoverlapping write boundary. The main agent gathers required results, checks integration and completes the batch review, then records the delivery facts through the same state tool. Actual delegation is evidenced by host tool activity, not role-played summaries. Delegation adds no delivery stage, business batch, scheduling store, host plugin or proof gate, and does not make results inherently correct.
|
|
126
|
+
|
|
113
127
|
## State and stopping
|
|
114
128
|
|
|
115
129
|
Use the installed tool's documented state protocol. Read the current revision before a write and provide the expected revision; never bypass a conflict by blindly increasing it. State stores summaries and references, not copies of requirements or test reports. Persist the unfinished intent before changing multiple documents, then verify the artifacts before recording completion. No cross-file transaction is promised.
|
|
116
130
|
|
|
117
131
|
Important semantic changes retain historical review and test facts, mark affected conclusions for review and update the current editable authority. Do not overwrite external adopted sources. See [sources and change flow](sources-and-changes.md).
|
|
118
132
|
|
|
119
|
-
At each
|
|
133
|
+
At each user-visible work-unit boundary, save the completed work and self-check, show its artifacts, actual stop and next action, then stop. Implementation and batch review save separate runs as internal checkpoints in one authorized batch work unit; continue its review/repair before the batch stop. A real permission, scope, approval or technical dependency can stop that work earlier. Existing sessionGroup is contextual grouping, not authorization. Overall review and formal verification remain distinct stops. Recommend a new session at the major boundaries below without requiring one; no session approval record or changed-session-ID proof.
|
|
120
134
|
|
|
121
135
|
Recommend switching after requirements are ready for technical design, after design and applicable contracts before test design, after the plan before implementation, after an implementation batch and its review, and after overall review before independent verification. Combine coinciding boundaries. Directory creation alone, individual documents inside a design group, test design before planning, and implementation before its batch review do not need another suggestion. For a pending document at a major boundary, recommend resuming its review, not starting the next stage. A failed review stays with its repairs.
|
|
122
136
|
|
|
@@ -124,7 +138,7 @@ For a reviewable draft, show only its current stage/status, document entry and r
|
|
|
124
138
|
|
|
125
139
|
After explicit approval, in one handling of the message: preserve the actual decision source and exact reviewed version; update approval, current run and next work together as appropriate; inspect the returned saved revision and view result (reread when uncertain); then report the saved outcome and next suggestion. Do not ask the user separately to approve saving or the prompt. If state saving failed, do not claim success; if state saved but the view failed, repair the view at that revision without replaying the approval. Only give the handoff entry once the save is confirmed.
|
|
126
140
|
|
|
127
|
-
After a
|
|
141
|
+
After a user-visible work unit is saved, wait for explicit approval where document review is required, or for continuation where it is not. An approval may include “continue”; record it and proceed without a second confirmation. Approval without a continuation request leaves a saved boundary. Never treat “continue” alone as document approval. Ordinary continuation in this session needs no session permission; starting overall review after implementation still follows the explicit scope authorization above. Stage-internal work and authorized repair remain continuous; failures lead to repair/re-review rather than mechanical advancement. At final handoff do not invent a next-session task.
|
|
128
142
|
|
|
129
143
|
At a recommended session boundary or when the user requests continuation help, give current status, artifact and next suggestion, followed by one line in the saved delivery language using the actual absolute directory: “Use Aimship to continue delivery <actual directory>; first read the current state and relevant formal documents, then continue the recorded work.” In Chinese: “使用 Aimship 继续交付「实际目录」,先读取当前状态和相关正式文档再接续。” Do not output placeholders or long prompts at every stage. Full tasks, inputs, deliverable requirements, review stops and unresolved matters stay in existing state/formal documents/rules, not a new prompt or handoff file. A complete prompt may be generated when requested, without an arbitrary length limit.
|
|
130
144
|
|
|
@@ -136,4 +150,4 @@ Small corrections within the original goal can reopen the same delivery: preserv
|
|
|
136
150
|
|
|
137
151
|
## Formal artifacts and generated status
|
|
138
152
|
|
|
139
|
-
Read [document patterns](document-patterns.md) when establishing or revising the arrangement. All new formal documents use its fixed outlines and [artifact map](artifact-map.json). Schema
|
|
153
|
+
Read [document patterns](document-patterns.md) when establishing or revising the arrangement. All new formal documents use its fixed outlines and [artifact map](artifact-map.json). Schema 5 / delivery protocol 2 uses ordinary Markdown and searchable business numbers. Preserve the saved language; do not translate original materials. State holds the control facts for batches, runs, reviews, verification coverage and acceptance. Submit domain operations through the current CLI, not replacement control arrays. status.md and the finite generated sections of plan/testing/review derive from those same facts. AI maintains approved definitions, explanations, detailed REV/RUN records and evidence; do not hand-maintain a second progress table. read/check/resume are read-only; inspect view and document-change warnings, and use explicit render to repair a stale/missing view. Preserve edits before rebuilding; never infer a business decision from hand-edited display text. After partial view failure use the saved revision, not a repeated business update.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Delivery documents and traceability
|
|
2
2
|
|
|
3
|
-
[artifact-map.json](artifact-map.json) is the shared mapping for stages, templates and checks. Use [templates](templates/prd.md) for newly authored documents; preserve the ordinary section headings and their order, write visible headings and body in the saved delivery language, and explain inapplicable sections. Use the English or Chinese headings listed in the artifact map; numbered
|
|
3
|
+
[artifact-map.json](artifact-map.json) is the shared mapping for stages, templates and checks. Use [templates](templates/prd.md) for newly authored documents; preserve the ordinary section headings and their order, write visible headings and body in the saved delivery language, and explain inapplicable sections. Use the English or Chinese headings listed in the artifact map; new AI-authored formal Markdown uses an unnumbered document title and numbered body headings (1, 1.1, 1.1.1). This is writing guidance, not another validation gate. Preserve supplied PRDs/prototypes, OpenAPI, SQL and machine files; do not renumber old documents automatically. Pure editorial reconciliation follows the existing approval protocol, while substantive changes still require review. Keep business IDs and file paths unchanged. Original sources and existing documents are not automatically translated when the language changes. Templates are drafting guidance, not empty artifacts to generate for every delivery.
|
|
4
4
|
|
|
5
5
|
One request has one directory. New deliveries default to separate folders under the bound dataRoot; formal documents are at the delivery folder’s root, not at dataRoot or the current project merely because materials already exist there. `.aimship/init.md` holds the original commission and stable initialization context; adopted external versions stay in `source/` without overwriting. Follow [source retention and editing boundaries](sources-and-changes.md#location-and-version-discipline) for originals, necessary resources and subsequent versions. State, recovery copies, necessary evidence and generated AI-tool configuration belong under `.aimship/`. Generated `status.md` presents stable main stages, current review/questions, next work and registered formal artifacts. Implementation includes batch reviews; overall review is separate. Batches, repairs and repeated runs stay in the state history rather than creating more main-stage rows. No default INDEX, duplicate stage ledger, docs/sql hierarchy, transcript or full export. A requested export is a dated object/version snapshot, never an editing authority.
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ Use one registered PRD as the requirement authority. If an existing PRD fully fi
|
|
|
12
12
|
|
|
13
13
|
A prototype is optional according to the work. Reuse adequate supplied material; create a prototype only when it helps clarify the agreed interaction and is selected for this delivery. Otherwise describe behavior in the PRD/design. A selected prototype needs its current input check when supplied unchanged, or its document approval when AI-authored or substantively revised, before implementation. New HTML uses `prototype/index.html`; other agreed formats may be registered.
|
|
14
14
|
|
|
15
|
-
`test-design` precedes `plan` in standard delivery; both reviewable documents need explicit approval. If the user explicitly excludes cases/testing, record the limited scope once and do not generate empty testing artifacts or call the result standard complete delivery. `plan` must finish before first implementation, even one small batch. `plan.md`
|
|
15
|
+
`test-design` precedes `plan` in standard delivery; both reviewable documents need explicit approval. If the user explicitly excludes cases/testing, record the limited scope once and do not generate empty testing artifacts or call the result standard complete delivery. `plan` must finish before first implementation, even one small batch. `plan.md` retains approved goals, dependencies and TASK/B definitions in its design sections. Register those batches and record execution/review facts through the state tool. Its finite generated execution section is the one current batch progress table; AI maintains necessary dated execution notes, object references, deviations and blockers outside it. Do not duplicate machine state per TASK or copy the full task table into status. `testing.md` keeps cases/coverage in its design part and detailed formal RUN/retests in execution; its finite generated summary shows current effective coverage/results. `review.md` retains detailed REV findings/repairs/rechecks, while its finite generated section shows current review results. All views consume the same saved facts; none is a second editable state ledger. Brief development checks stay in plan execution with evidence references; retests are new RUNs in the same verification scope, not new development batches; verification follows overall review. Updating execution/current results does not reapprove unchanged design. Verify-only may register existing cases with version/coverage, without claiming test-design occurred. Review-only does not require implementation/tests. No arbitrary small-task merging, `implementation.md`, `test-plan.md`, `verification.md`, or `results.md` for new work.
|
|
16
16
|
|
|
17
17
|
Use `tech-design.md`. HTTP changes use `openapi.yaml` or the registered engineering authority; no extra contract wrapper. Non-HTTP formats are explicitly registered. Database changes require independent `database.sql` (one target) or `database-<id>.sql` per target in contract, after technical-design approval and before test cases. Technical design records the data approach and SQL plan without requiring finished SQL. SQL headers identify target/dialect/version/schema basis/conditions; ordered sections cite requirements/design. Never substitute a Markdown block or migration reference, or execute/change migration mechanisms without authorization.
|
|
18
18
|
|
|
@@ -49,3 +49,17 @@ Register `documentPolicy` and `documents` per [CLI](../../../docs/cli.md). Draft
|
|
|
49
49
|
Save unfinished intent, update formal documents, inspect them, then revision-check state. A matching status revision does not prove documents unchanged. Read/check/resume diagnose only. A saved state with a failed view must be repaired using render at the returned revision, never replayed. Preserve hand-edited status before rebuilding and interpret intent against existing authority; it cannot confer acceptance or publishing permission.
|
|
50
50
|
|
|
51
51
|
Preserve the fixed outlines and identity rules during [document review](document-review.md). Plan/testing design approval excludes their later execution/result sections; keep actual execution there.
|
|
52
|
+
|
|
53
|
+
### Finite generated sections
|
|
54
|
+
|
|
55
|
+
New native plan/testing/review documents reserve these visible H3 sections from their templates, using the saved delivery language:
|
|
56
|
+
|
|
57
|
+
| Document | English heading | Chinese heading |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| plan | 5.1 Current batch progress (generated) | 5.1 当前批次进度(由状态生成) |
|
|
60
|
+
| testing | 5.1 Current verification (generated) | 5.1 当前验证结果(由状态生成) |
|
|
61
|
+
| review | 1.1 Current review (generated) | 1.1 当前审查结论(由状态生成) |
|
|
62
|
+
|
|
63
|
+
Keep the next AI-maintained subsection at the same heading level so the boundary is explicit. The tool owns only the generated H3 body up to the next same/higher heading, not the document or approved definitions. Draft it empty or with the template placeholder; submit facts through the CLI and let render update it. Detailed case expectations, findings, implementation notes, RUN/REV history and evidence remain AI-maintained. Do not move definitions into these sections or hand-edit a displayed result to advance work.
|
|
64
|
+
|
|
65
|
+
A missing/duplicate section or modified generated body is a view issue, not permission to guess an old table or rewrite the document. Inspect the exact diagnostic and preserve edits before explicitly rebuilding. A view repair uses the saved revision without replaying facts. Source evidence bound to a decision remains immutable; generated refresh must not rewrite that approval basis.
|
|
@@ -25,10 +25,10 @@ New state has `reviewPolicy: 1` and append-only `reviewHistory`. Use the [CLI re
|
|
|
25
25
|
|
|
26
26
|
For new plan/testing templates, approval covers content before the ordinary execution headings mapped to `execution`/`runs` respectively. Subsequent task execution and RUN/conclusion records belong in their later sections; moving changed design into result sections to evade review is forbidden. Other documents and reused formats use the whole registered file. For prototype assets and remotely adopted formats, preserve a readable local fixed-version review basis that identifies every relevant asset/version; report binary/remote inspection limits. Register local/repository linked assets in documents[].assetRefs to bind their bytes; the Agent must check that this set is complete. Do not claim entry-file hashing alone verifies all linked assets.
|
|
27
27
|
|
|
28
|
-
Stage runs
|
|
28
|
+
Stage runs retain their actual order and explicit relationships. Design responsibilities follow the selected development sequence; engineering work uses registered batch dependencies, reviewOf coverage and current reviewed/tested objects rather than an automatic dependency on the immediately preceding execution. `dependsOn` can record additional preceding dependencies. Record the reason for changing an arrangement. A pending AI-output review or unresolved input question holds dependent work; it does not authorize unrelated work outside the commission. `status.md` shows the current stage, pending document, review status and recorded next stage. While review is pending, chat presents only the current document/status and review focus; give the next-work suggestion after approval has been saved and checked. `resume` preserves the same stop and never automatically turns a question or old `done` into approval.
|
|
29
29
|
|
|
30
30
|
## Changes and old states
|
|
31
31
|
|
|
32
|
-
Use existing CHG records to explain semantic changes, affected requirements/documents/runs and the real decision source. Change the document version, keep old approvals and necessary old meaning/evidence, mark affected producer/dependent runs `needs-review`, and return to the corresponding document stage. An old approval cannot release new content. For a revised supplied input, record the actual updated adoption basis and check the new content without inventing approval; AI-authored or substantively rewritten outputs require renewed approval. Then recheck affected downstream work in dependency order and restore applicability with evidence; never clear every result or reset unaffected branches. Update `currentRun`/`next` to the actual re-review stop. Tools cannot infer all semantic dependencies: Agent impact analysis remains necessary.
|
|
32
|
+
Use existing CHG records to explain semantic changes, affected requirements/documents/runs and the real decision source. Submit their impactRef and affectedRefs so the core can mark the actual dependent batch/review/coverage facts for reassessment. Change the document version, keep old approvals and necessary old meaning/evidence, mark affected producer/dependent runs `needs-review`, and return to the corresponding document stage. An old approval cannot release new content. For a revised supplied input, record the actual updated adoption basis and check the new content without inventing approval; AI-authored or substantively rewritten outputs require renewed approval. Then recheck affected downstream work in dependency order and restore applicability with evidence; never clear every result or reset unaffected branches. Update `currentRun`/`next` to the actual re-review stop. Tools cannot infer all semantic dependencies: Agent impact analysis remains necessary.
|
|
33
33
|
|
|
34
34
|
For a formatting/typo-only adjustment to an approved output, self-check the new digest and append an `editorial` reconciliation that cites the previous approved digest and explains why meaning is unchanged. It carries the old approval without fabricating a new user decision. No full downstream re-review is needed. A changed requirement, case expectation or design choice is never editorial.
|