sillyspec 3.31.0 → 3.32.1
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/.claude/skills/sillyspec-auto/SKILL.md +1 -1
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +2 -2
- package/.claude/skills/sillyspec-commit/SKILL.md +1 -1
- package/.claude/skills/sillyspec-flow/SKILL.md +10 -6
- package/.claude/skills/sillyspec-quick/SKILL.md +105 -7
- package/.zcodeignore +66 -0
- package/AGENTS.md +16 -16
- package/assets/command-cards/flow.md +9 -3
- package/assets/command-cards/run-quick.md +4 -1
- package/package.json +2 -2
- package/src/agent-session-log.js +27 -5
- package/src/config-schema.js +21 -0
- package/src/datetime.js +51 -0
- package/src/db.js +10 -3
- package/src/decision-distill.js +21 -12
- package/src/design-facts.js +46 -6
- package/src/flow-draft.js +468 -95
- package/src/flow-parity.js +199 -5
- package/src/flow-review.js +136 -6
- package/src/flow.js +786 -145
- package/src/foreign-declared.js +75 -3
- package/src/fr-index.js +148 -162
- package/src/git-helper.js +16 -3
- package/src/hooks/worktree-guard.js +16 -5
- package/src/hunk-attribution.js +28 -5
- package/src/index.js +186 -19
- package/src/knowledge-classify.js +3 -1
- package/src/knowledge-digest.js +55 -26
- package/src/knowledge-match.js +135 -7
- package/src/knowledge-stats.js +105 -4
- package/src/knowledge-vector.js +160 -0
- package/src/machine-interface.js +90 -2
- package/src/module-impact.js +22 -1
- package/src/modules.js +9 -0
- package/src/progress/change-registry.js +20 -0
- package/src/progress/stage-machine.js +4 -7
- package/src/progress.js +8 -1
- package/src/quicklog.js +20 -0
- package/src/redomain.js +23 -7
- package/src/route-hindsight.js +276 -0
- package/src/run/archive-distill.js +3 -1
- package/src/run/command.js +65 -12
- package/src/run/complete-handlers.js +219 -5
- package/src/run/complete.js +99 -22
- package/src/run/gate-snapshot.js +15 -0
- package/src/run/gates.js +60 -4
- package/src/run/prompt.js +159 -31
- package/src/run/quick-audit.js +66 -7
- package/src/run/shared.js +6 -11
- package/src/run/stage.js +5 -1
- package/src/run/verify-quality-scan.js +84 -0
- package/src/scan-facts.js +2 -1
- package/src/scope-audit.js +138 -5
- package/src/sentinel-assertions.js +67 -16
- package/src/stage-contract-engine.js +4 -1
- package/src/stage-contract-spec.js +103 -4
- package/src/stage-contract.js +55 -7
- package/src/stages/brainstorm.js +27 -14
- package/src/stages/knowledge.js +4 -3
- package/src/stages/plan-postcheck.js +98 -3
- package/src/stages/plan.js +22 -2
- package/src/stages/quick.js +1 -1
- package/src/stages/verify.js +2 -1
- package/src/task-review.js +1 -1
- package/src/task-tick.js +121 -0
- package/src/taskcard-frontmatter.js +31 -0
- package/src/ui-visual.js +43 -8
- package/src/verify-postcheck.js +518 -38
- package/src/verify-probes.js +216 -5
- package/src/watcher.js +1067 -1031
- package/src/worktree-apply.js +9 -1
- package/src/worktree.js +21 -6
- package/templates/agents-instruction.md +15 -15
- package/templates/prompts/taskcard-rules.md +1 -0
package/src/worktree-apply.js
CHANGED
|
@@ -21,7 +21,7 @@ import { getCrossWorktreeMeta, cleanupCrossWorktrees } from './worktree-cross.js
|
|
|
21
21
|
import { parseFileChangeList, parseFileChangeListDetailed, pathMatches } from './change-list.js';
|
|
22
22
|
import { parseAllowedPaths, parseRepo } from './stages/plan-postcheck.js';
|
|
23
23
|
import { git, gitQuiet, safeGit, unquoteGitPath } from './git-helper.js';
|
|
24
|
-
import { resolveLatestExecuteRunId, resolveLatestExecuteRunIdWithTasks, readReview, normalizeRepoKey } from './task-review.js';
|
|
24
|
+
import { resolveLatestExecuteRunId, resolveLatestExecuteRunIdWithTasks, readReview, readExecuteRunChangeStamp, normalizeRepoKey } from './task-review.js';
|
|
25
25
|
import { collectActiveQuickGuardFiles } from './quicklog.js';
|
|
26
26
|
import { appendWriteAudit, WRITE_AUDIT_FILE_CAP } from './write-audit.js';
|
|
27
27
|
import { detectCommittedDrift, formatCommittedDriftWarning } from './run/concurrent-detect.js';
|
|
@@ -861,6 +861,14 @@ export function collectReviewDeclaredFiles(projectRoot, changeName, opts = {}) {
|
|
|
861
861
|
|| join(projectRoot, '.sillyspec', '.runtime');
|
|
862
862
|
const runId = resolveLatestExecuteRunIdWithTasks({ runtimeRoot, changeName });
|
|
863
863
|
if (!runId) return byRepo;
|
|
864
|
+
// 归属戳门控(2026-10-05-review-declared-unstamped-gate):resolver 无戳命中时回退拿
|
|
865
|
+
// mtime 最新的无主 run——从未跑过 execute 的变更会误挂无关历史 run 的 review 声明
|
|
866
|
+
// (实证:14 个 8 月无戳 run 文件误报「review 声明了越权文件」)。review changedFiles 是
|
|
867
|
+
// reviewer 对该 run 实际改动的经验证陈述,信任不跨 run 迁移——无戳即无法证明归属本变更,
|
|
868
|
+
// 声明面空集(fail-closed:少一份放松面;本变更 run 真丢戳时 apply 收紧报 violations,
|
|
869
|
+
// 补 design 清单/allowed_paths 即过)。resolver 本体不动——无主回退服务 task-done 等
|
|
870
|
+
// marker 漂移恢复场景。
|
|
871
|
+
if (readExecuteRunChangeStamp(runtimeRoot, runId) !== changeName) return byRepo;
|
|
864
872
|
const runTasksDir = join(runtimeRoot, 'execute-runs', runId, 'tasks');
|
|
865
873
|
if (!existsSync(runTasksDir)) return byRepo;
|
|
866
874
|
for (const taskId of readdirSync(runTasksDir)) {
|
package/src/worktree.js
CHANGED
|
@@ -1232,8 +1232,12 @@ export class WorktreeManager {
|
|
|
1232
1232
|
const meta = parseJSON(readFileSync(metaPath, 'utf8'));
|
|
1233
1233
|
if (!meta) continue;
|
|
1234
1234
|
results.push({
|
|
1235
|
-
|
|
1236
|
-
|
|
1235
|
+
// 缺字段 meta 读侧归一化(2026-10-05-wt-list-resilience):注册表目录名恒由
|
|
1236
|
+
// create() 以 validateChangeName 过的变更名创建,是缺 changeName 件(e2e/旧版
|
|
1237
|
+
// 写入形态残留)的权威事实;branch 缺失展示 '-'。消费端(CLI list 渲染的
|
|
1238
|
+
// i.changeName.length、doctor 孤儿匹配的 metaNames)都要求 string。
|
|
1239
|
+
changeName: typeof meta.changeName === 'string' && meta.changeName ? meta.changeName : entry.name,
|
|
1240
|
+
branch: typeof meta.branch === 'string' && meta.branch ? meta.branch : '-',
|
|
1237
1241
|
baseHash: meta.baseHash,
|
|
1238
1242
|
baseBranch: meta.baseBranch,
|
|
1239
1243
|
createdAt: meta.createdAt,
|
|
@@ -1295,11 +1299,22 @@ export class WorktreeManager {
|
|
|
1295
1299
|
visit(runsDir);
|
|
1296
1300
|
if (candidates.size === 0) return [];
|
|
1297
1301
|
const refs = [];
|
|
1302
|
+
// 双探针(2026-10-05-branch-ref-anchor-scope):worktree 分支自带全部主仓历史,单探针
|
|
1303
|
+
// 「hash 是分支祖先或自身」会把旧 review.json 对历史主仓 commit 的引用全部误中(实证:
|
|
1304
|
+
// 56 个无关历史引用触发锚定打 tag)。锚定只护「分支独有」commit——删分支 ref 后真正会
|
|
1305
|
+
// 悬空的只有 baseline checkpoint/task commit;主仓 HEAD 可达的历史 commit 恒可达,不计入。
|
|
1306
|
+
// 探针二对象显式主仓根(_resolveMainRepoRoot)——native-worktree 复用路径下 cwd 是
|
|
1307
|
+
// worktree、其 HEAD 即分支自身,按 cwd 探会「永不锚定」fail-open。
|
|
1308
|
+
const mainRoot = this._resolveMainRepoRoot();
|
|
1298
1309
|
for (const [hash, paths] of candidates) {
|
|
1299
|
-
// merge-base --is-ancestor
|
|
1300
|
-
//
|
|
1301
|
-
|
|
1302
|
-
if (
|
|
1310
|
+
// 探针一(语义不变):merge-base --is-ancestor 祖先或自身 → exit 0 输出空串(gitQuiet
|
|
1311
|
+
// 返回 ''≠null);非祖先 → exit 1 → null;未知/畸形 hash → 报错非零 → null(不在分支
|
|
1312
|
+
// 内,语义正确——非真实对象无可悬空链)
|
|
1313
|
+
if (gitQuiet(this.cwd, ['merge-base', '--is-ancestor', hash, branch]) === null) continue;
|
|
1314
|
+
// 探针二(新增):主仓 HEAD 祖先或自身 → ''≠null → 不计入(删分支后仍可达);探针失败
|
|
1315
|
+
// (null)按「不在主仓可达」处理即计入——fail-closed 宁误锚不误删
|
|
1316
|
+
if (gitQuiet(mainRoot, ['merge-base', '--is-ancestor', hash, 'HEAD']) !== null) continue;
|
|
1317
|
+
refs.push(...paths);
|
|
1303
1318
|
}
|
|
1304
1319
|
return [...new Set(refs)];
|
|
1305
1320
|
}
|
|
@@ -6,26 +6,25 @@
|
|
|
6
6
|
## 选道(动手前先对号入座)
|
|
7
7
|
| 需求形态 | 走法 |
|
|
8
8
|
|---|---|
|
|
9
|
-
| 需求已含决策(改什么、成功标准说得清) | **轻量变更(默认快道)**:`flow start` → 直接干活 → `flow done
|
|
10
|
-
| 需求不清晰 / 需要方案探索 | 头脑风暴预段:`run brainstorm --change <名>` → 完成后 `flow start --change <名>`
|
|
11
|
-
| 大改动:跨模块取舍 /
|
|
12
|
-
| 代码已先写好(倒推收尾) |
|
|
9
|
+
| 需求已含决策(改什么、成功标准说得清) | **轻量变更(默认快道)**:`flow start` → 直接干活 → `flow done`(2 次协议调用;操作细节见 `/sillyspec:flow` skill 与 flow start 输出) |
|
|
10
|
+
| 需求不清晰 / 需要方案探索 | 头脑风暴预段:`run brainstorm --change <名>` → 完成后 `flow start --change <名>` 收编续跑(design 以头脑风暴版为准) |
|
|
11
|
+
| 大改动:跨模块取舍 / Wave 计划编排 / 多阶段治理 / 设计期人机对抗 | 完整流程五阶段:`run brainstorm → plan → execute → verify → archive`(每阶段一次渲染 + 一次 --done 收口;细节见各阶段 skill 与 CLI 输出) |
|
|
12
|
+
| 代码已先写好(倒推收尾) | 不回头补流程装样子:`flow start --change <YYYY-MM-DD-名> --input` 按下方过门格式写(动机=已做改动的描述,成功标准=已验证达标的行为)→ `flow done` 一步收口 |
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
`--input` 过门格式(轻量道首次调用即过,勿靠报错学;引号内换行合法,下例可照抄):
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
```bash
|
|
17
|
+
sillyspec flow start --change <YYYY-MM-DD-名> --input "<动机与背景>
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
成功标准:
|
|
20
|
+
- <可验证标准>"
|
|
21
|
+
```
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
选道看流程形态需求,不看技术关键词——风险面由收口评审按证据(承诺词/diff 原语/盲维作答)判定。轻量→完整转道是用户决策:须征得用户同意并带 `--upgrade-thick`(同意门留痕,无 flag 拒跑);轻量变更实测失败自动升厚。
|
|
23
24
|
|
|
24
|
-
##
|
|
25
|
-
-
|
|
26
|
-
- 跨会话交接:`sillyspec handoff --change
|
|
27
|
-
- 变更列表 / 状态:`sillyspec status`
|
|
28
|
-
- 自检修复:`sillyspec doctor`
|
|
25
|
+
## 恢复与查看
|
|
26
|
+
- 轻量变更恢复:重跑 `sillyspec flow start --change <名>`(输出恢复简报)或 `flow status --change <名>`;完整流程恢复:`run <stage> --change <名>` 续跑。不直接 commit 半成品
|
|
27
|
+
- 跨会话交接:`sillyspec handoff --change <名>`;变更列表:`sillyspec status`;自检修复:`sillyspec doctor`
|
|
29
28
|
- 知识库:`sillyspec knowledge search "<关键词>"`(命中知识 CLI 会自动注入 prompt,勿自行重复检索)
|
|
30
29
|
|
|
31
30
|
## 核心规则
|
|
@@ -41,3 +40,4 @@ start 之后:按提示填 design.md 四节 AGENT 槽(做法/接口契约/边
|
|
|
41
40
|
10. **会话启动先立身份**:`export SILLYSPEC_SESSION_ID=<唯一标识>`(如 agent 名+任务名)——多会话并行时 change 所有权判定(apply / cleanup / 归档对他会话活跃变更的接管拒绝)依赖此标识;缺省降级为 `anon@<主机名>` 机器级标识(只拦他机,同机并行不设防)。部分 harness 的 shell 状态不持久(env 随命令丢失),此时接管类命令每条显式带 flag:`sillyspec worktree apply <change> --session <唯一标识>`(`--session` 优先级高于 env)。
|
|
42
41
|
11. **禁止目录级 git add / git add -A**(多会话共享仓):目录级暂存会夹带并行会话的进行中文件甚至误删已提交文件。提交一律用显式 pathspec,且 **add 与 commit 用同一份清单**:`git commit -m "..." -- 文件1 文件2`——带 pathspec 的 commit 只提交这些路径,他侧已 staged 的条目既不被带走、也原样留给对方;裸 `git commit` 提交的是整个共享暂存区,他会话 add 过的文件会被一并扫入。核对暂存面固定用 `git diff --cached --name-only` 全量读取,禁用过滤式核对(过滤正是致盲原因);核对与提交分开两条命令执行,不得链在同一命令里(链行没有拦截点)。安装了 commit-guard hook 的仓会对超声明面的 staged 文件警告(只警告不阻断)。
|
|
43
42
|
12. **不奉承用户**,禁止"你说得对"类话术,直接给结论、依据、方案。
|
|
43
|
+
13. **边干边勾(任务进度唯一源=变更的 tasks.md)**:完成一个任务单元(实现到位 + 相关测试跑绿)当场勾对应格——`sillyspec task tick --change <名> --task task-NN`(即时回显进度与下一任务)或直接 Edit 翻格 `- [ ]`→`- [x]`,勿攒到收口一把勾。harness 自带的 TodoWrite 类工具是会话内便利面,不替代 tasks.md——平台进度投影、收口哨兵、断点恢复只读 tasks.md。
|
|
@@ -33,3 +33,4 @@ TaskCard 格式规则(必须严格遵守):
|
|
|
33
33
|
- allowed_paths 非空(至少一个真实源文件路径;回归类 task 无源码改动时填被验证的关键入口文件)
|
|
34
34
|
- acceptance 与 verify 都在 frontmatter 内(漏写会被 plan-postcheck 报「缺少验收标准」/「缺少验证步骤」)
|
|
35
35
|
- **生成方式**:由主 agent 一次性 `sillyspec taskcard <change-name> --all` 预生成全部安全骨架(LF 行尾 + frontmatter 必闭合 + 九个硬校验字段齐全 + author/created_at 自动填;幂等,已存在跳过)。**子代理不要并行跑 taskcard CLI**(2026-08-25 实证撞进度库 SQLite 锁),只往骨架里填语义内容(LF 行尾 + frontmatter 必闭合 + 九个硬校验字段齐全 + author/created_at 自动填),再往骨架里填语义内容——**勿用 Write tool 整文件手写**(CRLF / 漏闭合 `---` / 漏字段的根源,postcheck 报错大多由此来);已存在的卡命令会跳过不覆盖,局部修改用 Edit 定点改
|
|
36
|
+
- **填完即自检**:`sillyspec taskcard <change-name> --validate`——plan 门禁同源规则的零成本快照(frontmatter YAML 合法性含中文分诊/必要字段/占位符/target_files 形态),报错即门禁报错,修复后重跑至通过再推进(免 Step 4 门禁批量报错返工)
|