sillyspec 3.29.4 → 3.30.0
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 +54 -54
- 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 +57 -0
- package/.claude/skills/sillyspec-quick/SKILL.md +18 -116
- package/AGENTS.md +38 -20
- package/SKILL.md +9 -3
- package/assets/command-cards/flow.md +32 -0
- package/assets/command-cards/run-archive.md +26 -0
- package/assets/command-cards/run-brainstorm.md +33 -0
- package/assets/command-cards/run-execute.md +29 -0
- package/assets/command-cards/run-plan.md +27 -0
- package/assets/command-cards/run-quick.md +17 -0
- package/assets/command-cards/run-verify.md +29 -0
- package/assets/command-cards/status.md +27 -0
- package/package.json +2 -1
- package/packages/dashboard/server/executor.js +2 -1
- package/packages/dashboard/server/parser.js +7 -7
- package/r7-test-env/README-R7-TEST.md +93 -0
- package/r7-test-env/demo-project/lib/calc.js +6 -0
- package/r7-test-env/demo-project/package.json +1 -0
- package/r7-test-env/demo-project/test.js +10 -0
- package/r7-test-env/prompt-R7-SMOKE.md +41 -0
- package/r7-test-env/sillyspec-r7.cmd +3 -0
- package/round4/account.mjs +98 -0
- package/round4/b1-analyze-task08.mjs +40 -0
- package/round4/b1-b1-target-validation.md +32 -0
- package/round4/b3a-prompt-audit-result.md +66 -0
- package/round4/b3a-prompt-audit.mjs +89 -0
- package/round4/brief-autocompact.md +34 -0
- package/round4/brief-session-replay.md +50 -0
- package/round4/deep-read-synthesis.md +38 -0
- package/round4/extract-full.mjs +38 -0
- package/round4/extract-timeline.mjs +43 -0
- package/round4/find-sessions.mjs +13 -0
- package/round4/full-r4-l.md +4707 -0
- package/round4/full-r4-o-l.md +4300 -0
- package/round4/full-r4-os.md +1681 -0
- package/round4/full-r4-sf.md +4255 -0
- package/round4/full-r4-sq.md +1734 -0
- package/round4/gate-audit-relay-receipt.md +30 -0
- package/round4/gate-value-audit.md +52 -0
- package/round4/optimization-plan.md +165 -0
- package/round4/prereg.md +67 -0
- package/round4/prompt-R4-L.md +63 -0
- package/round4/prompt-R4-O-L.md +59 -0
- package/round4/prompt-R4-O-S.md +56 -0
- package/round4/prompt-R4-S-F.md +60 -0
- package/round4/prompt-R4-S-Q.md +66 -0
- package/round4/r4-final-report.html +347 -0
- package/round4/r4-os-timeline.txt +297 -0
- package/round4/r4-sf-timeline.txt +738 -0
- package/round4/r4-sq-timeline.txt +322 -0
- package/round4/r4l-timeline.txt +793 -0
- package/round4/r4ol-timeline.txt +729 -0
- package/round4/r4sf-timeline.txt +852 -0
- package/round4/r5-scenario-matrix.md +46 -0
- package/round4/result-S.md +171 -0
- package/round4/result-final.md +46 -0
- package/round4/result-quality.md +63 -0
- package/src/change-list.js +9 -0
- package/src/classify-change.js +6 -0
- package/src/command-cards.js +74 -0
- package/src/commit-guard.js +2 -0
- package/src/config-schema.js +64 -12
- package/src/contract-matrix.js +26 -5
- package/src/db.js +35 -4
- package/src/decision-distill.js +9 -3
- package/src/diagnostic-codes.js +2 -1
- package/src/docs-check.js +1 -1
- package/src/doctor-diagnostics.js +44 -2
- package/src/flow-draft.js +748 -0
- package/src/flow-parity.js +236 -0
- package/src/flow-review.js +184 -0
- package/src/flow.js +1492 -0
- package/src/foreign-declared.js +17 -1
- package/src/fr-index.js +396 -22
- package/src/fs-atomic.js +5 -1
- package/src/git-helper.js +2 -2
- package/src/greenfield-bootstrap.js +98 -0
- package/src/handoff.js +120 -7
- package/src/hunk-attribution.js +191 -0
- package/src/index.js +602 -21
- package/src/init.js +25 -8
- package/src/knowledge-classify.js +47 -1
- package/src/knowledge-digest.js +162 -0
- package/src/knowledge-quicklog.js +246 -0
- package/src/machine-draft.js +128 -0
- package/src/machine-interface.js +194 -7
- package/src/mcp-server.js +1 -0
- package/src/module-impact.js +51 -22
- package/src/module-resolve.js +3 -1
- package/src/preview-progress.js +160 -0
- package/src/progress/change-registry.js +11 -3
- package/src/progress/shared.js +3 -2
- package/src/progress.js +56 -13
- package/src/quicklog.js +44 -6
- package/src/redomain.js +147 -0
- package/src/review-material-pack.js +204 -1
- package/src/run/archive-distill.js +4 -2
- package/src/run/bg-sync.js +67 -0
- package/src/run/command.js +127 -10
- package/src/run/complete-handlers.js +363 -73
- package/src/run/complete.js +356 -74
- package/src/run/gate-snapshot-ledger.js +213 -0
- package/src/run/gate-snapshot.js +260 -38
- package/src/run/gates.js +482 -268
- package/src/run/green-cache.js +123 -0
- package/src/run/junction-rm.js +70 -0
- package/src/run/next.js +14 -0
- package/src/run/prompt.js +185 -55
- package/src/run/quick-audit.js +213 -14
- package/src/run/shared.js +123 -4
- package/src/run/stage.js +182 -216
- package/src/run/test-ledger.js +264 -0
- package/src/run/verify-quality-scan.js +84 -7
- package/src/scope-audit.js +6 -1
- package/src/sentinel-assertions.js +114 -0
- package/src/setup.js +3 -3
- package/src/spec-sync.js +41 -1
- package/src/stage-contract.js +26 -8
- package/src/stage-review-checklist.js +2 -0
- package/src/stage-review.js +7 -2
- package/src/stage-templates.js +157 -0
- package/src/stages/archive.js +2 -0
- package/src/stages/brainstorm.js +24 -106
- package/src/stages/execute.js +222 -85
- package/src/stages/knowledge.js +74 -1
- package/src/stages/plan-postcheck.js +385 -20
- package/src/stages/plan.js +23 -1
- package/src/stages/quick.js +10 -2
- package/src/stages/verify.js +4 -2
- package/src/sync.js +81 -23
- package/src/task-done.js +181 -0
- package/src/task-review.js +8 -55
- package/src/taskcard-frontmatter.js +57 -0
- package/src/test-bindings.js +549 -0
- package/src/timeline.js +218 -0
- package/src/ui-visual.js +175 -0
- package/src/verify-draft.js +214 -0
- package/src/verify-postcheck.js +919 -159
- package/src/verify-probes.js +103 -25
- package/src/watcher.js +1031 -0
- package/src/worktree-apply.js +44 -4
- package/src/worktree-deps.js +22 -8
- package/src/worktree-policy.js +42 -0
- package/src/worktree.js +102 -15
- package/templates/agents-instruction.md +37 -18
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sillyspec:run-quick
|
|
3
|
+
description: 已退役重定向 — quick 通道已拒绝新会话(v3.31.0 起),小修补请用 /sillyspec:flow
|
|
4
|
+
---
|
|
5
|
+
# 通道已退役
|
|
6
|
+
|
|
7
|
+
quick 通道已于 v3.31.0 直接退役:`sillyspec run quick` 对新会话一律拒绝(exit 1 并指路 flow start)。本卡只保留触发词重定向,勿执行任何 quick 新会话命令。
|
|
8
|
+
|
|
9
|
+
范围明确的小修补请走**轻量变更**(/sillyspec:flow):
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
sillyspec flow start --change <变更名> --input "<动机与背景;随后独立一行『成功标准:』;再每行一条『- <可验证标准>』>"
|
|
13
|
+
# → 直接干活(改代码写测试,治理工件 CLI 机器起草)
|
|
14
|
+
sillyspec flow done --change <变更名>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
升级前遗留的在途 quick 会话仍可收尾:`sillyspec run quick --change <会话ID>` 续跑 / `--done` 收口 / `--cancel` 取消(以 CLI 拒绝文案里的指引为准)。
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sillyspec:run-verify
|
|
3
|
+
description: verify 验证阶段:探针核验+测试对账+验收报告
|
|
4
|
+
---
|
|
5
|
+
# 何时用
|
|
6
|
+
|
|
7
|
+
execute 收口后对照文档验收(probe 契约+known_failures 对账+测试绿)。
|
|
8
|
+
|
|
9
|
+
# 生命周期速查
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
export SILLYSPEC_SESSION_ID=<agent名+任务名> # 每条命令都带(shell 状态不持久;多会话并行的所有权判定依赖它)
|
|
13
|
+
sillyspec run verify --change <变更名>
|
|
14
|
+
sillyspec run verify --done --change <变更名> --output "<验收摘要>"
|
|
15
|
+
# 探针骨架缺失时:
|
|
16
|
+
sillyspec verify-probes --init --change <变更名> # 已存在加 --force 刷新
|
|
17
|
+
# 在隔离 worktree 内跑时(守卫默认拒绝,需双 flag):
|
|
18
|
+
# sillyspec <cmd> --allow-worktree-cwd --spec-dir "<worktree>/.sillyspec"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
# 防坑清单
|
|
22
|
+
|
|
23
|
+
- gate 失败明细落 .runtime/verify-runs/gate-<stage>-<change>.json(勿靠 stdout 记忆)。
|
|
24
|
+
- 非测试逻辑有误禁改测试来过——修逻辑。
|
|
25
|
+
- known_failures 豁免只在 local.yaml 声明位置复核,勿手抄。
|
|
26
|
+
|
|
27
|
+
# 边界声明
|
|
28
|
+
|
|
29
|
+
本卡不含步骤内容——每步的具体指令由 `sillyspec run verify` 按当前状态实时渲染(含门禁、审查档位、产物契约)。本卡只管启动与防坑。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sillyspec:status
|
|
3
|
+
description: 状态查询:进度/变更清单/断点恢复入口
|
|
4
|
+
---
|
|
5
|
+
# 何时用
|
|
6
|
+
|
|
7
|
+
任何时刻查「我在哪、下一步做什么」——多变更并行时先看再动。
|
|
8
|
+
|
|
9
|
+
# 生命周期速查
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
export SILLYSPEC_SESSION_ID=<agent名+任务名> # 每条命令都带(shell 状态不持久;多会话并行的所有权判定依赖它)
|
|
13
|
+
sillyspec progress show [--change <名>] [--all] [--json]
|
|
14
|
+
sillyspec status
|
|
15
|
+
# 有信号变更(冲突/滞留/疑似完成)保持详情渲染;--all 展开全部
|
|
16
|
+
# 在隔离 worktree 内跑时(守卫默认拒绝,需双 flag):
|
|
17
|
+
# sillyspec <cmd> --allow-worktree-cwd --spec-dir "<worktree>/.sillyspec"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
# 防坑清单
|
|
21
|
+
|
|
22
|
+
- 多会话并行:变更各自 --change 隔离,永不 reset 他人变更。
|
|
23
|
+
- 中途停下不靠额外命令存进度——上次 --done 已落盘。
|
|
24
|
+
|
|
25
|
+
# 边界声明
|
|
26
|
+
|
|
27
|
+
本卡不含步骤内容——每步的具体指令由 `sillyspec run status` 按当前状态实时渲染(含门禁、审查档位、产物契约)。本卡只管启动与防坑。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sillyspec",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.30.0",
|
|
4
4
|
"description": "SillySpec CLI — 流程状态机,让 AI 严格按步骤来",
|
|
5
5
|
"icon": "logo.jpg",
|
|
6
6
|
"homepage": "https://sillyspec.ppdmq.top/",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"scripts": {
|
|
27
|
+
"test:core": "node --test test/preview-migration.test.mjs test/preview-progress.test.mjs test/preview-outlet.test.mjs test/preview-gc.test.mjs test/preview-gate-isolation.test.mjs test/db-engine.test.mjs test/db-concurrency.test.mjs test/db-atomic-write.test.mjs test/platform-sync-schema.test.mjs test/platform-sync-serialization.test.mjs test/change-ownership-guards.test.mjs test/watcher.test.mjs test/watcher-alerts.test.mjs test/watcher-timeline.test.mjs test/sentinel-rules.test.mjs test/handoff.test.mjs test/execution-mode-render.test.mjs test/knowledge-inbox.test.mjs test/knowledge-baseline.test.mjs test/quick-laststep-fourfields-preview.test.mjs test/doctor-align-execute-progress.test.mjs test/test-ledger.test.mjs test/test-bindings.test.mjs test/flow-draft-binding-extract.test.mjs test/gate-snapshot-lifecycle.test.mjs test/gate-snapshot-cleanup.test.mjs test/verify-trace-residual.test.mjs test/platform-creds-fallback.test.mjs test/archive-timeline-bake.test.mjs",
|
|
27
28
|
"test": "node test/run-tests.mjs",
|
|
28
29
|
"lint": "node test/check-syntax.mjs",
|
|
29
30
|
"eval:dry": "node eval/run.mjs --dry-run",
|
|
@@ -21,7 +21,8 @@ export function executeCommand(projectPath, command, onOutput, onComplete) {
|
|
|
21
21
|
// .cmd 加 shell:true 而引入命令注入(体检 SEC-08)
|
|
22
22
|
const proc = spawn(process.execPath, [SILLYSPEC_ENTRY, ...args], {
|
|
23
23
|
cwd: projectPath,
|
|
24
|
-
env: { ...process.env }
|
|
24
|
+
env: { ...process.env },
|
|
25
|
+
windowsHide: true
|
|
25
26
|
})
|
|
26
27
|
|
|
27
28
|
proc.stdout.on('data', (data) => {
|
|
@@ -130,13 +130,13 @@ export function parseProjectOverview(projectPath) {
|
|
|
130
130
|
|
|
131
131
|
// --- Git info ---
|
|
132
132
|
try {
|
|
133
|
-
result.git.lastCommit = execSync('git log -1 --format=%s', { cwd: projectPath, encoding: 'utf-8' }).trim()
|
|
133
|
+
result.git.lastCommit = execSync('git log -1 --format=%s', { cwd: projectPath, encoding: 'utf-8', windowsHide: true }).trim()
|
|
134
134
|
} catch {}
|
|
135
135
|
try {
|
|
136
|
-
result.git.branch = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf-8' }).trim()
|
|
136
|
+
result.git.branch = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf-8', windowsHide: true }).trim()
|
|
137
137
|
} catch {}
|
|
138
138
|
try {
|
|
139
|
-
result.git.dirtyCount = parseInt(execSync('git status --porcelain', { cwd: projectPath, encoding: 'utf-8' }).trim().split('\n').filter(Boolean).length, 10) || 0
|
|
139
|
+
result.git.dirtyCount = parseInt(execSync('git status --porcelain', { cwd: projectPath, encoding: 'utf-8', windowsHide: true }).trim().split('\n').filter(Boolean).length, 10) || 0
|
|
140
140
|
} catch {}
|
|
141
141
|
|
|
142
142
|
return result
|
|
@@ -145,17 +145,17 @@ export function parseProjectOverview(projectPath) {
|
|
|
145
145
|
export function parseGitDetail(projectPath) {
|
|
146
146
|
const result = { branch: '', commits: [], untracked: [] }
|
|
147
147
|
try {
|
|
148
|
-
result.branch = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf-8' }).trim()
|
|
148
|
+
result.branch = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf-8', windowsHide: true }).trim()
|
|
149
149
|
} catch {}
|
|
150
150
|
try {
|
|
151
|
-
const log = execSync('git log -5 --format=%h|%s|%an|%aI', { cwd: projectPath, encoding: 'utf-8' }).trim()
|
|
151
|
+
const log = execSync('git log -5 --format=%h|%s|%an|%aI', { cwd: projectPath, encoding: 'utf-8', windowsHide: true }).trim()
|
|
152
152
|
result.commits = log.split('\n').filter(Boolean).map(line => {
|
|
153
153
|
const [hash, message, author, date] = line.split('|')
|
|
154
154
|
return { hash, message, author, date }
|
|
155
155
|
})
|
|
156
156
|
} catch {}
|
|
157
157
|
try {
|
|
158
|
-
const status = execSync('git status --porcelain', { cwd: projectPath, encoding: 'utf-8' }).trim()
|
|
158
|
+
const status = execSync('git status --porcelain', { cwd: projectPath, encoding: 'utf-8', windowsHide: true }).trim()
|
|
159
159
|
result.untracked = status.split('\n').filter(Boolean).map(line => ({
|
|
160
160
|
status: line.slice(0, 2).trim(),
|
|
161
161
|
file: line.slice(3)
|
|
@@ -453,7 +453,7 @@ export function parseProjectState(projectPath) {
|
|
|
453
453
|
// Use CLI to read current stage from SQLite
|
|
454
454
|
try {
|
|
455
455
|
const output = execSync('sillyspec progress show 2>/dev/null', {
|
|
456
|
-
cwd: projectPath, encoding: 'utf-8', timeout: 5000
|
|
456
|
+
cwd: projectPath, encoding: 'utf-8', timeout: 5000, windowsHide: true
|
|
457
457
|
})
|
|
458
458
|
const stageMatch = output.match(/当前阶段:\s*(\S+)/)
|
|
459
459
|
if (stageMatch) currentStage = stageMatch[1]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# R7 测试环境说明书(sillyspec 2-调用协议 · watcher · 机器起草 · 编辑距离路由)
|
|
2
|
+
|
|
3
|
+
> 环境组成:`sillyspec-r7.cmd`(wrapper,直跑主仓检出——**不动全局 3.29.6,不影响并行会话**)
|
|
4
|
+
> + `demo-project/`(ESM 小项目:lib/calc.js + test.js,测试命令 `node test.js`,已基线提交)。
|
|
5
|
+
> 全部命令在 `demo-project/` 目录内执行;Git Bash 里用 `cmd //c ..\sillyspec-r7.cmd ...` 或直接
|
|
6
|
+
> `node C:\Users\qinyi\IdeaProjects\sillyspec\src\index.js ...`。
|
|
7
|
+
|
|
8
|
+
## 场景 A · 薄跑道 happy path(协议必需调用=2)
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
..\sillyspec-r7.cmd flow start --change my-first-thin --input "给 calc 加乘法。成功标准:
|
|
12
|
+
- mul(2,3)=6 有测试
|
|
13
|
+
- 既有 add 测试不回归"
|
|
14
|
+
```
|
|
15
|
+
看点:输出「协议调用 1/2」+材料路径清单;`.sillyspec/changes/my-first-thin/` 自动落
|
|
16
|
+
proposal/requirements/tasks 三件**机器稿**(MACHINE-DRAFT sha256 指纹标记+`<!--AGENT:槽-->`)
|
|
17
|
+
+flow-state.yaml;watcher 同步拉起。
|
|
18
|
+
|
|
19
|
+
干活(正常开发):改 `lib/calc.js` 加 `export function mul(a,b){return a*b}`、test.js 补
|
|
20
|
+
`assert.equal(mul(2,3),6)`,然后 **git add -A && git commit -m "feat: mul"**(先提交——
|
|
21
|
+
门禁快照以 HEAD+会话文件为基,含新文件的未提交态在快照内可能缺 package.json 类配置)。
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
..\sillyspec-r7.cmd flow done --change my-first-thin
|
|
25
|
+
```
|
|
26
|
+
看点:六子步逐个 done、测试门真跑 `node test.js`、末行「flow done 完成(2/2 协议调用收口)」
|
|
27
|
+
exit 0;change 目录移入 `changes/archive/`。**全程只有这 2 次协议调用。**
|
|
28
|
+
|
|
29
|
+
## 场景 B · watcher 观测(事件与协议解耦)
|
|
30
|
+
|
|
31
|
+
另开一个终端:
|
|
32
|
+
```
|
|
33
|
+
powershell -NoProfile -Command "Get-Content -Wait .sillyspec\.runtime\watcher-events-my-first-thin.jsonl"
|
|
34
|
+
```
|
|
35
|
+
事件三类源:产物签名(proposal.md 出现/变更、任务卡 checkbox 翻格)/git 提交(HEAD 前进)/
|
|
36
|
+
工件(质量扫描记录、archived 终态)。每行恒带 `"provisional":true`——平台只展示不判定。
|
|
37
|
+
墙钟拆账:`.sillyspec/.runtime/watcher-stage-timing-my-first-thin.json`。
|
|
38
|
+
已知边界:flow done 的 events 收口行读文件时 watcher 可能差一拍(3s 轮询)——收口显示
|
|
39
|
+
「无事件文件」但事后文件在,属观测旁路 best-effort 语义。
|
|
40
|
+
|
|
41
|
+
## 场景 C · 机器稿篡改拒收(验收侧守卫)
|
|
42
|
+
|
|
43
|
+
新开 change 后,直接编辑 proposal.md 里机器段正文(改「任务原话转写」几个字)→
|
|
44
|
+
`flow done` → **三态拒收**:内容哈希失配 exit 1(不归档)。删掉整段 MACHINE-DRAFT 标记再试
|
|
45
|
+
→ 标记缺失拒收。AGENT 槽(`<!--AGENT:槽N` 注释行下方)随便写 → 放行。
|
|
46
|
+
|
|
47
|
+
## 场景 D · amend 留痕通道 + 编辑距离路由
|
|
48
|
+
|
|
49
|
+
改机器段正文后不走 flow done,走:
|
|
50
|
+
```
|
|
51
|
+
..\sillyspec-r7.cmd flow amend-draft --change X
|
|
52
|
+
```
|
|
53
|
+
看点:重锚+ledger amendment 审计+**editRatio**(首版原文为基准,改写过半 → `route_hint: thick`
|
|
54
|
+
提示——advisory 定案:测绿仍可薄过)。之后 `flow done` 正常收口,末尾醒目打印 route_hint,
|
|
55
|
+
遥测落 `.sillyspec/.runtime/flow-telemetry.jsonl`(protocolCalls=2/editRatio/routeHint)。
|
|
56
|
+
|
|
57
|
+
## 场景 E · 失败升厚 + 断点重入(fail-closed 三句)
|
|
58
|
+
|
|
59
|
+
把 test.js 改坏(如断言 add(1,2)=4)→ `flow done`:
|
|
60
|
+
- 实测失败=**整单 FAIL exit≠0**,不继续 distill/归档
|
|
61
|
+
- 自动升厚 `tier: thick` + upgrade_reason 落 flow-state(born_face=thin 保归档不死锁)
|
|
62
|
+
- 修好 test.js 再跑同一条 `flow done` → 已完成子步 `artifacts(skip)` 幂等跳过,断点续到归档
|
|
63
|
+
|
|
64
|
+
## 场景 F · legacy 一行回滚
|
|
65
|
+
|
|
66
|
+
`.sillyspec/local.yaml` 末尾加:
|
|
67
|
+
```
|
|
68
|
+
flow:
|
|
69
|
+
mode: legacy
|
|
70
|
+
```
|
|
71
|
+
`flow start` → 拒跑 exit 2 指路 `run <stage>`(既有全流程逐字不动);删掉这三行即回 thin。
|
|
72
|
+
|
|
73
|
+
## 场景 G · 恢复简报
|
|
74
|
+
|
|
75
|
+
干活干一半(有 dirty 文件未提交)时再跑 `flow start --change X` → 输出恢复简报:
|
|
76
|
+
任务勾选/提交数/dirty 数/P2 记录/六子步标记 → 做到哪、剩什么、下一步。
|
|
77
|
+
|
|
78
|
+
## 速查
|
|
79
|
+
|
|
80
|
+
| 目的 | 命令/文件 |
|
|
81
|
+
|---|---|
|
|
82
|
+
| 事件流 | `.sillyspec/.runtime/watcher-events-<change>.jsonl` |
|
|
83
|
+
| 墙钟拆账 | `.sillyspec/.runtime/watcher-stage-timing-<change>.json` |
|
|
84
|
+
| watcher 日志/锁 | `.sillyspec/.runtime/watcher.log` / `watcher.lock`(心跳租约 30s) |
|
|
85
|
+
| 机器稿台账 | `.sillyspec/.runtime/draft-ledger-<change>.json`(首版原文永存) |
|
|
86
|
+
| 协议遥测 | `.sillyspec/.runtime/flow-telemetry.jsonl` |
|
|
87
|
+
| flow 状态 | `.sillyspec/changes/<X>/flow-state.yaml`(tier/born_face/baseline_commit/子步标记) |
|
|
88
|
+
| 关 watcher | env `SILLYSPEC_WATCHER=0`(测试自救阀;自灭三闸:归档即退/git 仓蒸发退/12h 硬帽) |
|
|
89
|
+
| 重置 demo | `git reset --hard 7cc3615 && rm -rf .sillyspec/.runtime .sillyspec/changes` |
|
|
90
|
+
|
|
91
|
+
显式档:`flow start --thick`(起始即厚档)/ `--with-tasks`(薄协议+生成任务卡,中间自愿
|
|
92
|
+
task done,收尾仍 flow done)。混跑回退:thin change 上跑 `run <stage>` → flow-state 落
|
|
93
|
+
legacy_fallback,flow done 拒裁并指路厚档。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module","name":"r7-demo","version":"1.0.0"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import { add, sub, div } from './lib/calc.js'
|
|
3
|
+
assert.equal(add(1, 2), 3)
|
|
4
|
+
console.log('test ok: add(1,2)=3')
|
|
5
|
+
assert.equal(sub(5, 3), 2)
|
|
6
|
+
console.log('test ok: sub(5,3)=2')
|
|
7
|
+
assert.equal(div(6, 3), 2)
|
|
8
|
+
console.log('test ok: div(6,3)=2')
|
|
9
|
+
assert.throws(() => div(1, 0), { message: 'div by zero' })
|
|
10
|
+
console.log('test ok: div(1,0) throws div by zero')
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# R7 薄跑烟测提示词(贴给一个全新 agent 会话;30min 级小任务)
|
|
2
|
+
|
|
3
|
+
你是一个开发会话,任务:在下面的演示项目里完成一个小功能。本项目接入了一套新的
|
|
4
|
+
「2-调用」开发协议(flow),你是它的第一批真实用户——按协议干活即可,协议没让你做的事
|
|
5
|
+
就不要做。
|
|
6
|
+
|
|
7
|
+
【环境】
|
|
8
|
+
- 工作目录:C:\Users\qinyi\IdeaProjects\sillyspec\r7-test-env\demo-project(所有命令在此执行)
|
|
9
|
+
- CLI 入口(R7 版):cmd //c ..\sillyspec-r7.cmd <命令...>
|
|
10
|
+
(Git Bash 形态;PowerShell/cmd 形态:..\sillyspec-r7.cmd <命令...>)
|
|
11
|
+
- 会话标识:先执行 export SILLYSPEC_SESSION_ID=r7-smoke-1
|
|
12
|
+
- 项目现状:lib/calc.js 有 add;test.js 用断言风格测试;测试命令 node test.js
|
|
13
|
+
|
|
14
|
+
【任务】
|
|
15
|
+
给 calc 库增加两个函数并配套测试:
|
|
16
|
+
1. sub(a,b) 减法——成功标准:sub(5,3)=2 有测试
|
|
17
|
+
2. div(a,b) 除法,除零抛 Error('div by zero')——成功标准:div(6,3)=2 与除零抛错都有测试
|
|
18
|
+
既有 add 测试不得回归。
|
|
19
|
+
|
|
20
|
+
【协议契约——只有 2 次协议调用】
|
|
21
|
+
1. 第一次:cmd //c ..\sillyspec-r7.cmd flow start --change r7-smoke-add-sub-div --input "<把上面任务原话贴进去>"
|
|
22
|
+
——它会告诉你材料在哪、怎么干活。治理文档(提案/需求/任务清单)由 CLI 自动起草,你不要手写。
|
|
23
|
+
2. 中间:正常开发。改代码、写测试、git 提交(git add -A && git commit -m "...")。
|
|
24
|
+
不要跑任何 sillyspec run <stage> 命令;progress show 等只读命令也不必用——保持最小。
|
|
25
|
+
如果你觉得自动起草的文档里机器写的部分说错了,唯一合法修改通道是 flow amend-draft
|
|
26
|
+
(命令形态在上面输出里找);不想改就直接忽略,不影响验收。
|
|
27
|
+
3. 第二次:干完并提交后 cmd //c ..\sillyspec-r7.cmd flow done --change r7-smoke-add-sub-div
|
|
28
|
+
——它是唯一裁决点:会真跑测试,失败会整单 FAIL(修好重跑同一条命令即可,断点自动续)。
|
|
29
|
+
|
|
30
|
+
【边界】
|
|
31
|
+
- 全程协议类调用只许上述 2 次(这是被测量的数字)。
|
|
32
|
+
- 不要读 sillyspec 的源码或它的变更文档(.sillyspec/changes/archive/**)——你是用户不是评审。
|
|
33
|
+
- .sillyspec/ 目录里不要手写任何文件(这也是被测量的面)。
|
|
34
|
+
- 测试必须真实通过;node test.js 自己先跑绿再 flow done。
|
|
35
|
+
|
|
36
|
+
【完成后汇报(务必按此格式,这是测试数据)】
|
|
37
|
+
1. 协议调用清单:每条 sillyspec 命令原文+次数
|
|
38
|
+
2. .sillyspec 写入清单:你亲手写过的文件(应为零;若用了 amend-draft 如实列出)
|
|
39
|
+
3. 摩擦记录:协议该给你而没给的信息/你想做但被拦的事,逐条列(没有写「无」)
|
|
40
|
+
4. flow done 是否一次通过;若失败过,失败原因与重入体验
|
|
41
|
+
5. 一句话:这个流程 compared 于你平时用的开发流程,最不习惯的一点是什么
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// R4 对照实验·核算脚本 —— zcode db 会话级 token/请求/时长归账
|
|
3
|
+
// 用法:node account.mjs [--arm R4] [--title 关键词] [--since 2026-09-19]
|
|
4
|
+
// 注意(第2/3轮各踩一次的坑):model_usage.started_at / session.time_created 均按
|
|
5
|
+
// 数值 epoch-ms 处理;若遇 ISO 字符串自动 Date.parse 兜底,绝不字符串比较。
|
|
6
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
7
|
+
|
|
8
|
+
const DB = 'C:/Users/qinyi/.zcode/cli/db/db.sqlite';
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
const flag = (k) => { const i = args.indexOf(k); return i >= 0 ? args[i + 1] : null; };
|
|
11
|
+
|
|
12
|
+
const toMs = (v) => {
|
|
13
|
+
if (v === null || v === undefined) return null;
|
|
14
|
+
if (typeof v === 'number') return v;
|
|
15
|
+
const s = String(v);
|
|
16
|
+
if (/^\d+$/.test(s)) return Number(s);
|
|
17
|
+
const p = Date.parse(s.includes('T') ? s : s.replace(' ', 'T') + '+08:00');
|
|
18
|
+
return Number.isNaN(p) ? null : p;
|
|
19
|
+
};
|
|
20
|
+
const fmtMin = (ms) => (ms == null ? '?' : (ms / 60000).toFixed(1) + 'min');
|
|
21
|
+
const fmtTok = (t) => (t == null ? '?' : (t / 1e6).toFixed(2) + 'M');
|
|
22
|
+
|
|
23
|
+
const db = new DatabaseSync(DB, { readOnly: true });
|
|
24
|
+
|
|
25
|
+
// 1) 定位会话:标题关键词(可多个,逗号分隔),可加 --since YYYY-MM-DD 下限
|
|
26
|
+
const titleKw = (flag('--title') ?? 'R4').split(',').map(s => s.trim()).filter(Boolean);
|
|
27
|
+
const sinceRaw = flag('--since');
|
|
28
|
+
const sinceMs = sinceRaw ? toMs(sinceRaw + 'T00:00:00+08:00') : null;
|
|
29
|
+
|
|
30
|
+
const like = titleKw.map(() => 'title LIKE ?').join(' OR ');
|
|
31
|
+
const rows = db.prepare(
|
|
32
|
+
`SELECT id, parent_id, title, time_created FROM session WHERE (${like}) ORDER BY time_created`
|
|
33
|
+
).all(...titleKw.map(k => '%' + k + '%'));
|
|
34
|
+
|
|
35
|
+
// 2) 每会话聚合(主会话 + 递归子会话),窗口=会话创建起 48h 防 spill
|
|
36
|
+
// v2(2026-09-21 R5 准备):三分扩展——新鲜 input(=input−cache_read)、缓存读、输出,
|
|
37
|
+
// 及账单当量两界(方案 v3.2 口径:新入 1× / 缓存 0.1× / 输出 3–5×,R5 验收判法依赖)
|
|
38
|
+
const aggFor = (sid) => db.prepare(
|
|
39
|
+
`SELECT COUNT(*) req, SUM(computed_total_tokens) tok, SUM(input_tokens) itok, SUM(output_tokens) otok,
|
|
40
|
+
SUM(cache_read_input_tokens) cr,
|
|
41
|
+
SUM(duration_ms) dur, MIN(started_at) mn, MAX(started_at) mx, SUM(tool_call_count) tools
|
|
42
|
+
FROM model_usage WHERE session_id = ? AND started_at >= ?`
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const results = [];
|
|
46
|
+
for (const s of rows) {
|
|
47
|
+
const created = toMs(s.time_created);
|
|
48
|
+
const winStart = sinceMs != null ? Math.max(created ?? 0, sinceMs) : (created ?? 0);
|
|
49
|
+
const winEnd = winStart + 48 * 3600 * 1000;
|
|
50
|
+
// 递归滚子会话
|
|
51
|
+
const kids = db.prepare(
|
|
52
|
+
`WITH RECURSIVE tree(id, title) AS (SELECT id, title FROM session WHERE parent_id = ?
|
|
53
|
+
UNION ALL SELECT s.id, s.title FROM session s JOIN tree t ON s.parent_id = t.id)
|
|
54
|
+
SELECT id, title FROM tree`
|
|
55
|
+
).all(s.id);
|
|
56
|
+
const self = aggFor(s.id).get(winStart > 0 ? winStart : 0);
|
|
57
|
+
// 请求窗口上界也钳(started_at < winEnd)
|
|
58
|
+
const inWin = (r) => { const a = db.prepare(
|
|
59
|
+
`SELECT COUNT(*) req, SUM(computed_total_tokens) tok, SUM(duration_ms) dur,
|
|
60
|
+
SUM(input_tokens) itok, SUM(output_tokens) otok, SUM(cache_read_input_tokens) cr
|
|
61
|
+
FROM model_usage
|
|
62
|
+
WHERE session_id = ? AND started_at >= ? AND started_at < ?`
|
|
63
|
+
).get(r, winStart, winEnd); return a; };
|
|
64
|
+
const mainAgg = inWin(s.id);
|
|
65
|
+
let kidReq = 0, kidTok = 0, kidDur = 0, kidIt = 0, kidCr = 0, kidOt = 0;
|
|
66
|
+
for (const k of kids) {
|
|
67
|
+
const a = inWin(k.id); kidReq += a.req ?? 0; kidTok += a.tok ?? 0; kidDur += a.dur ?? 0;
|
|
68
|
+
kidIt += a.itok ?? 0; kidCr += a.cr ?? 0; kidOt += a.otok ?? 0;
|
|
69
|
+
}
|
|
70
|
+
const wall = mainAgg.req > 0 || kidReq > 0 ? null : null;
|
|
71
|
+
const span = db.prepare(
|
|
72
|
+
`SELECT MIN(started_at) mn, MAX(started_at) mx FROM model_usage WHERE session_id = ?`
|
|
73
|
+
).get(s.id);
|
|
74
|
+
const spanMs = (toMs(span.mx) ?? 0) - (toMs(span.mn) ?? 0);
|
|
75
|
+
// 三分与当量(新鲜 = input − cache_read,钳 ≥0 防口径倒挂;当量两界 = 输出 3×/5×)
|
|
76
|
+
const mIt = mainAgg.itok ?? 0, mCr = mainAgg.cr ?? 0, mOt = mainAgg.otok ?? 0;
|
|
77
|
+
const tIt = mIt + kidIt, tCr = mCr + kidCr, tOt = mOt + kidOt;
|
|
78
|
+
const fresh = Math.max(0, tIt - tCr);
|
|
79
|
+
const eq3 = fresh + 0.1 * tCr + 3 * tOt;
|
|
80
|
+
const eq5 = fresh + 0.1 * tCr + 5 * tOt;
|
|
81
|
+
results.push({
|
|
82
|
+
id: s.id, title: s.title, kids: kids.length,
|
|
83
|
+
mainReq: mainAgg.req ?? 0, mainTok: mainAgg.tok ?? 0, mainDur: mainAgg.dur ?? 0,
|
|
84
|
+
kidReq, kidTok, kidDur,
|
|
85
|
+
totReq: (mainAgg.req ?? 0) + kidReq, totTok: ((mainAgg.tok ?? 0) + kidTok),
|
|
86
|
+
spanMin: spanMs / 60000,
|
|
87
|
+
fresh, cacheR: tCr, out: tOt, eq3, eq5,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 3) 输出
|
|
92
|
+
console.log(`| 会话 | 标题 | 子代 | 主会话 req/tok/model-time | 子代 req/tok | 合计 req | 合计 tok | 活动跨度 | 新鲜in | 缓存R | 输出 | 当量@3× | 当量@5× |`);
|
|
93
|
+
console.log(`|---|---|---|---|---|---|---|---|---|---|---|---|---|`);
|
|
94
|
+
for (const r of results) {
|
|
95
|
+
console.log(`| ${r.id} | ${(r.title ?? '').slice(0, 40).replace(/\|/g, '/')} | ${r.kids} | ${r.mainReq} / ${fmtTok(r.mainTok)} / ${fmtMin(r.mainDur)} | ${r.kidReq} / ${fmtTok(r.kidTok)} | ${r.totReq} | ${fmtTok(r.totTok)} | ${fmtMin(r.spanMs ?? r.spanMin * 60000)} | ${fmtTok(r.fresh)} | ${fmtTok(r.cacheR)} | ${fmtTok(r.out)} | ${fmtTok(r.eq3)} | ${fmtTok(r.eq5)} |`);
|
|
96
|
+
}
|
|
97
|
+
if (results.length === 0) console.log('(无匹配会话——检查标题关键词或 --since');
|
|
98
|
+
db.close();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// B-① 靶点验证:解剖 R4-L 的 8.6M 实现子代理——读了什么、多大、是否越界
|
|
3
|
+
// 用法:node b1-analyze-task08.mjs
|
|
4
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
5
|
+
const db = new DatabaseSync('C:/Users/qinyi/.zcode/cli/db/db.sqlite', { readOnly: true });
|
|
6
|
+
const sid = 'sess_subagent_agent_d60364e3-c378-49b8-a715-6ac5b9d9aa4f';
|
|
7
|
+
const WT = 'C:\\Users\\qinyi\\IdeaProjects\\multi-agent-platform\\.sillyspec\\.runtime\\worktrees\\2026-09-20-r4-session-replay';
|
|
8
|
+
|
|
9
|
+
const parts = db.prepare(
|
|
10
|
+
'SELECT data, time_created tc FROM part WHERE session_id=? ORDER BY time_created ASC, sequence ASC'
|
|
11
|
+
).all(sid);
|
|
12
|
+
const t0 = Number(parts[0].tc);
|
|
13
|
+
const rows = [];
|
|
14
|
+
for (const row of parts) {
|
|
15
|
+
const d = JSON.parse(row.data);
|
|
16
|
+
if (d.type !== 'tool') continue;
|
|
17
|
+
const rel = ((Number(d.time?.created ?? row.tc) - t0) / 60000).toFixed(0);
|
|
18
|
+
const inp = d.state?.input ?? {};
|
|
19
|
+
const out = String(d.state?.output ?? '');
|
|
20
|
+
const kb = Math.round(out.length / 1024);
|
|
21
|
+
const short = (p) => String(p).split(WT + '\\').pop()?.replaceAll('\\', '/') ?? p;
|
|
22
|
+
let detail = '';
|
|
23
|
+
if (d.tool === 'Read') detail = short(inp.file_path ?? '?');
|
|
24
|
+
else if (d.tool === 'Grep') detail = 'q=' + String(inp.pattern ?? inp.query ?? '').slice(0, 40);
|
|
25
|
+
else if (d.tool === 'Bash') detail = String(inp.command ?? '').slice(0, 70);
|
|
26
|
+
else detail = JSON.stringify(inp).slice(0, 60);
|
|
27
|
+
rows.push({ rel, tool: d.tool, detail, kb, status: d.state?.status });
|
|
28
|
+
}
|
|
29
|
+
const byTool = {};
|
|
30
|
+
for (const r of rows) byTool[r.tool] = (byTool[r.tool] ?? 0) + r.kb;
|
|
31
|
+
console.log('tool calls:', rows.length, '| 按工具 KB:', JSON.stringify(byTool));
|
|
32
|
+
console.log('--- 全部调用(时间 | 工具 | 输出KB | 详情)---');
|
|
33
|
+
for (const r of rows) console.log(`${r.rel}m ${r.tool.padEnd(7)} ${String(r.kb).padStart(6)}KB ${r.detail}`);
|
|
34
|
+
console.log('--- Read 同文件累计 ---');
|
|
35
|
+
const byPath = {};
|
|
36
|
+
for (const r of rows) if (r.tool === 'Read') (byPath[r.detail] ??= []).push(r.kb);
|
|
37
|
+
const s = (a) => a.reduce((x, y) => x + y, 0);
|
|
38
|
+
for (const [p, arr] of Object.entries(byPath).sort((a, b) => s(b[1]) - s(a[1])))
|
|
39
|
+
console.log(`${String(s(arr)).padStart(6)}KB ×${arr.length} ${p}`);
|
|
40
|
+
db.close();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# B-① 靶点验证报告(2026-09-21,第 1 批执行产物)
|
|
2
|
+
|
|
3
|
+
> 预设判定规则(optimization-plan.md B-①):「靶子不实不立项」。
|
|
4
|
+
> 数据源:zcode db(C:/Users/qinyi/.zcode/cli/db/db.sqlite)sess_5cb66a7e(R4-L 主会话)及其 19 个子会话;工具 b1-analyze-task08.mjs。
|
|
5
|
+
|
|
6
|
+
## 判定:靶子不实——「越界读」零发生,B-① 实现项按预案砍掉
|
|
7
|
+
|
|
8
|
+
### 证据一:8.6M 的构成不是「读了 8.6M 新内容」
|
|
9
|
+
|
|
10
|
+
task-08 子代理(sess_subagent_agent_d60364e3,58 请求)账面:名义输入 8.57M / 缓存读 8.39M(98%)/ 输出 0.07M / **新鲜输入(名义−缓存)仅 186K**。
|
|
11
|
+
|
|
12
|
+
全部 62 次工具调用的输出总量 ≈335KB(Read 297KB + Bash 34KB)——与 186K 新鲜输入同量级自洽。8.6M 名义体量 = **58 轮 × 轮均 148K 上下文的累积重发**,是轮数乘上下文的机械积,不是读取行为。
|
|
13
|
+
|
|
14
|
+
### 证据二:读取内容全部在任务契约链内,无一次越界
|
|
15
|
+
|
|
16
|
+
62 次调用的读取对象逐条核过:task-08.md 任务卡、CLAUDE.md、turn-timeline.tsx(被适配组件)/ agent-log-card / turn-segment-views / session-log-assembler / runtime-session-helpers(契约链组件)、agent-log-card.test.tsx(测试先例)、session-panel-page(接线单点)、api-types / query-keys / agent-logs / round-divider(类型与工具链)、design.md + prototype-agent-replay.html(变更文档)。**没有一次读声明面之外的源码**,没有 node_modules / daemon / backend 深潜。重复读是「首次全读 + 后续定向切片」模式(如 turn-timeline 62KB 全读 + 16KB 切片),本身是省 token 的正确行为。
|
|
17
|
+
|
|
18
|
+
### 证据三:全扇出面同构——新鲜内容只占 3.2%
|
|
19
|
+
|
|
20
|
+
19 个子代理合计:名义输入 41.77M,**新鲜输入 1.34M(3.2%)**,输出 0.49M。各角色轮均上下文 35K–92K,唯 task-08 达 148K(契约链文件大:组件 78KB + 测试先例 37KB + design 15KB + prototype 14KB 全量进上下文)。
|
|
21
|
+
|
|
22
|
+
## 处置(按预案预设规则)
|
|
23
|
+
|
|
24
|
+
1. **砍掉第 2 批的「B-① 读清单注入」实现项**。读上界就是 1.34M 新鲜内容,其中「本可不读」的部分即使砍半也只有 ~0.7M 名义,对 42.3M 扇出是零头;allowed_paths 工作目录约束(子代理 prompt 已有)维持现状即够。B-① 前置验证本身完成使命。
|
|
25
|
+
2. **真正杠杆换位:轮数 × 上下文双乘数**。42.3M ≈ Σ(轮数 × 轮均上下文),两个乘数各有对策:
|
|
26
|
+
- **上下文**:B-④ 材料包治这个——task-08 型大契约链任务(design/prototype 通读 + 大组件全量进上下文)正是材料包的靶子,且比原估计更实(148K vs 同侪 45–92K 的差额就是可压空间)。
|
|
27
|
+
- **轮数**:**新增候选 B-⑥ 轮数纪律**(提示词级)——task-08 的 58 轮里 Edit×7(相邻同文件逐个改)+ TodoWrite×4(每条占一轮重发 148K)+ 测试 Bash 循环多次;合并相邻 Edit、TodoWrite 降频、测试合并跑,砍 1/3 轮 ≈ 砍 1/3 名义体量。此项原方案未覆盖,性价比高于已砍的 B-①。
|
|
28
|
+
3. **R5 预期路径修正**:扇出 42.3M → 28–32M 的驱动从「①②③④ 并用」改为「**B-④ 上下文压缩 + B-⑥ 轮数纪律**」双轮驱动;账单当量口径下缓存重发本就计 0.1×,硬门(扇出 ≤32M)以名义口径计不受影响。
|
|
29
|
+
|
|
30
|
+
## 复核方式
|
|
31
|
+
|
|
32
|
+
`node round4/b1-analyze-task08.mjs` 重跑可复现证据一/二;证据三的聚合查询见本报告数据源行(account.mjs 同库同表 model_usage,input−cache_read 即新鲜口径)。
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# B3a prompt 审计——db 全量口径(2026-09-21,v3 修正版)
|
|
2
|
+
|
|
3
|
+
## A. CLI 渲染体量(R4-L 主会话,129 次 sillyspec Bash,合计 204KB ≈ 60K tokens)
|
|
4
|
+
|
|
5
|
+
| 子命令 | 次数 | 累计KB | 最大单次KB |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| run | 53 | 98.4 | 6.7 |
|
|
8
|
+
| ? | 45 | 70.8 | 5.2 |
|
|
9
|
+
| verify-probes | 4 | 10.2 | 7.9 |
|
|
10
|
+
| show | 1 | 9.9 | 9.9 |
|
|
11
|
+
| register-stage-review | 5 | 3.1 | 1.8 |
|
|
12
|
+
| review | 7 | 2.8 | 0.6 |
|
|
13
|
+
| taskcard | 1 | 2.7 | 2.7 |
|
|
14
|
+
| progress | 3 | 2.4 | 1.5 |
|
|
15
|
+
| gate | 2 | 1.7 | 1.2 |
|
|
16
|
+
| module-docs-sync | 2 | 0.5 | 0.3 |
|
|
17
|
+
| endpoints | 1 | 0.4 | 0.4 |
|
|
18
|
+
| design-init | 1 | 0.3 | 0.3 |
|
|
19
|
+
| brainstorm | 1 | 0.3 | 0.3 |
|
|
20
|
+
| git | 1 | 0.2 | 0.2 |
|
|
21
|
+
| module-impact | 1 | 0.1 | 0.1 |
|
|
22
|
+
| worktree | 1 | 0.0 | 0.0 |
|
|
23
|
+
|
|
24
|
+
## B. 近重复渲染(头部签名相同出现 >1 次——重复注入的直接瘦身候选)
|
|
25
|
+
|
|
26
|
+
| 次数 | 单次体量 | 头部签名 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| ×2 | ~2.6KB | --- stage: brainstorm step: 7/8 stepName: Design Grill 交叉审查 project: project change: 2026- |
|
|
29
|
+
| ×2 | ~0.3KB | ⚠ 未匹配模块的文件 24 个(不入 sidecar): backend/app/modules/platform_sync/router.py, backend/app/modu |
|
|
30
|
+
| ×2 | ~0.0KB | (Bash completed with no output) |
|
|
31
|
+
|
|
32
|
+
近重复渲染累计 ≈6KB(占 CLI 渲染总量 3%)。
|
|
33
|
+
|
|
34
|
+
## C. 实跑措辞规则转发率(execute.js buildWavePrompt 口径 → 编排者组装的子代理 prompt)
|
|
35
|
+
|
|
36
|
+
| 规则(实跑措辞) | CLI 渲染 | 转发进子代理 prompt |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| workdir 参数是强制必传 | 2 | 0 |
|
|
39
|
+
| 破坏隔离 | 2 | 0 |
|
|
40
|
+
| 调度者 + 审查者 | 2 | 0 |
|
|
41
|
+
| 你不要自己写代码 | 4 | 0 |
|
|
42
|
+
| 禁止读 | 0 | 16 |
|
|
43
|
+
| 禁止 push | 0 | 12 |
|
|
44
|
+
| 工作目录(强制 | 0 | 12 |
|
|
45
|
+
| allowed_paths | 30 | 0 |
|
|
46
|
+
| TDD | 0 | 0 |
|
|
47
|
+
| 先读后写 | 0 | 0 |
|
|
48
|
+
|
|
49
|
+
Agent 派发 19 次,prompt 合计 49.8KB(均值 2.6KB,最大 5KB)。
|
|
50
|
+
|
|
51
|
+
## D. 解读与瘦身候选(B3a 结论,2026-09-21)
|
|
52
|
+
|
|
53
|
+
**总口径**:R4-L 主会话 CLI 渲染 204KB ≈ 60K tokens(占主会话名义 56.8M 的 ~0.1%,占峰值的次要面)——CLI 渲染不是 377K 峰值的主因(主因是会话累积),但每次渲染常驻上下文参与后续所有轮次的重发,瘦身仍有正收益。
|
|
54
|
+
|
|
55
|
+
**证据性发现**:
|
|
56
|
+
1. **近重复渲染只占 3%(~6KB)**——「同一指令反复整体重渲染」不是成本大头,各步渲染因进度态不同而不同。去重渲染**不是**瘦身抓手,预期收益上限低。
|
|
57
|
+
2. **run 子命令是渲染大头**:53 次 / 98.4KB(步骤指令渲染,单次最大 6.7KB)。同一阶段的步骤指令在 --done 循环中被多次近似重渲染(内容 90% 相同、状态行不同)。
|
|
58
|
+
3. **编排者对派发规则是「提取规范、丢弃论述」模式**:CLI 渲染的 workdir 论述段(强制必传 + 破坏隔离后果 + json 范例)转发进子代理 prompt 的字面率为 0,编排者自写成紧凑隔离块(工作目录(强制 ×12 / 禁止读 ×16 / 禁止 push ×12,每条 ~50 字)。行为合规(worktree 隔离全程成立),说明**论述段被读过但未被复述**——其价值存疑但不能仅凭字面率为 0 判死(合规可能正来自读过论述)。
|
|
59
|
+
4. allowed_paths 渲染 30 次、转发 0——但审查环节逐 task 对照 allowed_paths 检查(行为消费),属「CLI ↔ 门禁」消费而非 prompt 转发,保留。
|
|
60
|
+
|
|
61
|
+
**瘦身候选(供 B3b 依审计删减,全部低风险渐进)**:
|
|
62
|
+
- **C1(首选)run 步骤渲染增量化**:同阶段同步骤的重复渲染只出「状态 delta + 指令不变声明」,首渲染出全量。预计砍 run 渲染体量 30–50%(≈30–50KB/大任务)。机制级(CLI 渲染器小改),不是删规则——**不动规则内容**。
|
|
63
|
+
- **C2(次选,低置信)派发指令论述段压缩**:workdir/隔离的后果论述段压成一行规范 + 一行后果(保留 json 范例与 workdir 值)。省 ~1–2KB/次渲染。风险:论述可能支撑合规——R5 若有隔离事故即回滚。
|
|
64
|
+
- **不建议动**:四律请求钳(H3 实证 PASS 承重)、隔离规范行、allowed_paths、testcase-design 段(TDD 引导,taskcard 证据链)。
|
|
65
|
+
|
|
66
|
+
**方法论修正记录**:v1 transcript 口径因提取稿 700 字截断致规则渲染面全盲(17 签名 15 个零命中假象);v2 分类正则漏多 flag 前缀;v3 修正后数据可信。B3b 删任何规则前须按本 v3 口径复跑 + 行为级合规核查(字面转发率 ≠ 遵守率,本审计已实证两者背离)。
|