@peterxiaoyang/superspec 0.1.11 → 0.1.13

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.
Files changed (44) hide show
  1. package/README.md +4 -4
  2. package/adapters/codex/agents/explore.toml +13 -0
  3. package/adapters/codex/install-map.json +10 -0
  4. package/dist/src/apply_worker_chain.d.ts +6 -3
  5. package/dist/src/apply_worker_chain.js +125 -30
  6. package/dist/src/apply_worker_chain_lifecycle.d.ts +7 -5
  7. package/dist/src/apply_worker_chain_lifecycle.js +153 -22
  8. package/dist/src/cli_args.d.ts +1 -0
  9. package/dist/src/cli_args.js +33 -15
  10. package/dist/src/disclosure.js +2 -2
  11. package/dist/src/evidence.js +104 -8
  12. package/dist/src/gates.d.ts +1 -0
  13. package/dist/src/gates.js +160 -27
  14. package/dist/src/hooks/guard_api.js +2 -2
  15. package/dist/src/hooks/policy_event.js +11 -1
  16. package/dist/src/i18n.js +63 -3
  17. package/dist/src/init_cli.js +1 -1
  18. package/dist/src/openspec.d.ts +2 -0
  19. package/dist/src/openspec.js +31 -0
  20. package/dist/src/packet_render.d.ts +1 -0
  21. package/dist/src/packet_render.js +248 -31
  22. package/dist/src/packet_schema.d.ts +2 -0
  23. package/dist/src/tasks.d.ts +5 -0
  24. package/dist/src/tasks.js +62 -0
  25. package/dist/src/util.d.ts +4 -0
  26. package/dist/src/util.js +13 -0
  27. package/dist/superspec.js +4 -4
  28. package/package.json +3 -3
  29. package/templates/sidecar/discovery.md +9 -0
  30. package/templates/sidecar/test-contract.md +2 -1
  31. package/templates/workflow/prompts/code-reviewer.md +1 -1
  32. package/templates/workflow/prompts/executor.md +1 -1
  33. package/templates/workflow/prompts/explore.md +27 -0
  34. package/templates/workflow/prompts/test-engineer.md +1 -0
  35. package/templates/workflow/prompts/test-runner.md +3 -1
  36. package/templates/workflow/prompts/verifier.md +9 -9
  37. package/templates/workflow/skills/superspec-apply/SKILL.md +58 -33
  38. package/templates/workflow/skills/superspec-archive/SKILL.md +5 -5
  39. package/templates/workflow/skills/superspec-explore/SKILL.md +31 -13
  40. package/templates/workflow/skills/superspec-propose/SKILL.md +26 -15
  41. package/templates/workflow/skills/superspec-review/SKILL.md +17 -17
  42. package/dist/src/packet_measure.d.ts +0 -43
  43. package/dist/src/packet_measure.js +0 -382
  44. /package/bin/{superspec-guard.js → superspec-check.js} +0 -0
@@ -10,7 +10,7 @@ metadata:
10
10
 
11
11
  ## 语言规则 / Language
12
12
 
13
- - 默认使用简体中文写人类可读内容;命令、路径、字段名、gate 名、task/test id、代码标识符保留原文。
13
+ - 默认使用简体中文写人类可读内容;命令、路径、字段名、阶段门名、task/test id、代码标识符保留原文。
14
14
  - 用户可见文案不得使用“裁决”描述用户动作;统一说“确认”“范围取舍”“处理方式选择”或“用户确认记录”。
15
15
  - 不把内部证据种类、reason code、JSON 字段大全直接转述给用户;需要诊断时才引用原文。
16
16
  - 普通 workflow 命令使用 `--format agent`;`--format json` 只用于诊断,不作为默认上下文。
@@ -27,20 +27,20 @@ Review 合并实现审查、架构审查、SuperSpec critic、final verification
27
27
  ## 第一条必跑命令
28
28
 
29
29
  ```text
30
- superspec guard check-init --change "<change>" --format agent
30
+ superspec check check-init --change "<change>" --format agent
31
31
  ```
32
32
 
33
33
  然后检查 review readiness:
34
34
 
35
35
  ```text
36
- superspec guard check-review-ready --change "<change>" --format agent
36
+ superspec check check-review-ready --change "<change>" --format agent
37
37
  ```
38
38
 
39
- 遇到任何 guard `block` 就停止。review 不直接回改 `tasks.md` checkbox。
39
+ 遇到任何返回状态为 `block` 就停止。review 不直接回改 `tasks.md` checkbox。
40
40
 
41
- ## Repo-local Native Subagent 边界
41
+ ## 专用代理边界
42
42
 
43
- Review 必须使用 SuperSpec 分发包里的 repo-local native agents,不要调用全局 `$code-review`、OMX workflow、main-thread self-review 或普通 markdown 报告替代。
43
+ Review 必须使用本仓库安装的 repo-local native agents(专用代理),不要调用全局 `$code-review`、OMX workflow、主线程自审或普通 markdown 报告替代。
44
44
 
45
45
  必需入口:
46
46
 
@@ -49,12 +49,12 @@ Review 必须使用 SuperSpec 分发包里的 repo-local native agents,不要
49
49
  - `.codex/agents/critic.toml` / `.codex/prompts/critic.md`
50
50
  - `.codex/agents/verifier.toml` / `.codex/prompts/verifier.md`
51
51
 
52
- 每个 reviewer prompt 都先由 packet 生成:
52
+ 每个审查提示都先由检查命令产出:
53
53
 
54
54
  ```text
55
- superspec guard review-packet --change "<change>" --gate review_complete --role code-reviewer --round 1 --format prompt
56
- superspec guard review-packet --change "<change>" --gate review_complete --role architect --round 1 --format prompt
57
- superspec guard review-packet --change "<change>" --gate review_complete --role critic --round 1 --format prompt
55
+ superspec check review-packet --change "<change>" --gate review_complete --role code-reviewer --round 1 --format prompt
56
+ superspec check review-packet --change "<change>" --gate review_complete --role architect --round 1 --format prompt
57
+ superspec check review-packet --change "<change>" --gate review_complete --role critic --round 1 --format prompt
58
58
  ```
59
59
 
60
60
  ## Final Verification 边界
@@ -65,11 +65,11 @@ superspec guard review-packet --change "<change>" --gate review_complete --role
65
65
  openspec validate "<change>"
66
66
  ```
67
67
 
68
- 然后执行 test contract 要求的最终测试,启动 repo-local `verifier` 和 `critic` 做 verification review。verification prompt 也必须由 packet 生成:
68
+ 然后执行 test contract 要求的最终测试,启动本仓库 `verifier` 和 `critic` 做验证审查。验证提示也必须由检查命令产出:
69
69
 
70
70
  ```text
71
- superspec guard review-packet --change "<change>" --gate review_complete --role verifier --round 1 --format prompt
72
- superspec guard review-packet --change "<change>" --gate review_complete --role critic --round 1 --kind verification_review --format prompt
71
+ superspec check review-packet --change "<change>" --gate review_complete --role verifier --round 1 --format prompt
72
+ superspec check review-packet --change "<change>" --gate review_complete --role critic --round 1 --kind verification_review --format prompt
73
73
  ```
74
74
 
75
75
  verification 只提供 proof/gap,不替代主流程最终判断。
@@ -79,10 +79,10 @@ verification 只提供 proof/gap,不替代主流程最终判断。
79
79
  主线程写最终判断前读取:
80
80
 
81
81
  ```text
82
- superspec guard review-packet --change "<change>" --gate review_complete --role main-thread --round 1 --format agent
82
+ superspec check review-packet --change "<change>" --gate review_complete --role main-thread --round 1 --format agent
83
83
  ```
84
84
 
85
- `review_complete` 是 allow-only gate。allow path 必须由唯一 `main_adjudication` 承载最终判断,作者边界固定为 `execution_mode:"direct"` + `created_by:"main-thread"`;它不能携带 `agent_role`、`agent_id`、`prompt_ref`。
85
+ `review_complete` 是只允许通过的阶段检查。通过路径由主线程写本轮审查结论(主线程直接写,不携带代理字段)。
86
86
 
87
87
  `request_changes` 不是 review_complete allow。它必须写清 `request_changes_route`:
88
88
 
@@ -96,7 +96,7 @@ request-changes round 不生成 allow-path verification,也不调用 `check-re
96
96
  仅 allow path 运行:
97
97
 
98
98
  ```text
99
- superspec guard workflow-packet --change "<change>" --gate review_complete --format agent
99
+ superspec check workflow-packet --change "<change>" --gate review_complete --format agent
100
100
  ```
101
101
 
102
- 只有 packet allowed 后,才进入 `superspec-archive`。
102
+ 只有检查结果显示通过后,才进入 `superspec-archive`。
@@ -1,43 +0,0 @@
1
- export type MeasuredTextFile = {
2
- path: string;
3
- chars: number;
4
- };
5
- export type SurfaceMeasure = {
6
- total_chars: number;
7
- files: MeasuredTextFile[];
8
- };
9
- export type RepresentativeScenarioMeasure = {
10
- name: string;
11
- description: string;
12
- total_chars: number;
13
- files: MeasuredTextFile[];
14
- };
15
- export type MaterializedTextSample = {
16
- name: string;
17
- description: string;
18
- chars: number;
19
- matched_markers?: string[];
20
- };
21
- export type MaterializedTextMeasure = {
22
- total_chars: number;
23
- samples: MaterializedTextSample[];
24
- };
25
- export type PacketMeasureReport = {
26
- fixed_surface_chars_install_upper_bound: SurfaceMeasure;
27
- fixed_surface_chars_runtime_required_subset: SurfaceMeasure;
28
- materialized_workflow_packet_chars: MaterializedTextMeasure;
29
- materialized_review_packet_chars: MaterializedTextMeasure;
30
- materialized_review_prompt_chars: MaterializedTextMeasure;
31
- ledger_block_chars: MaterializedTextMeasure;
32
- representative_loaded_surface_chars: {
33
- scenarios: RepresentativeScenarioMeasure[];
34
- };
35
- };
36
- type ScenarioSpec = {
37
- name: string;
38
- description: string;
39
- files: string[];
40
- };
41
- export declare function representative_scenarios(): readonly ScenarioSpec[];
42
- export declare function measure_packet_surface_report(repoRoot: string): PacketMeasureReport;
43
- export {};
@@ -1,382 +0,0 @@
1
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { dirname, join } from "node:path";
4
- import { load_install_map } from "./install_engine.js";
5
- import { dispatch_packet } from "./packet_render.js";
6
- import { GuardError, runtime, } from "./util.js";
7
- import { file_blob_sha } from "./git.js";
8
- const REPRESENTATIVE_SCENARIOS = [
9
- {
10
- name: "explore_complete",
11
- description: "Package payload surface for discovery authoring plus proposal-entry critic review.",
12
- files: [
13
- "templates/workflow/skills/superspec-explore/SKILL.md",
14
- "templates/workflow/prompts/critic.md",
15
- "adapters/codex/agents/critic.toml",
16
- ],
17
- },
18
- {
19
- name: "proposal_reviewed",
20
- description: "Package payload surface for proposal authoring and proposal critic review.",
21
- files: [
22
- "templates/workflow/skills/superspec-propose/SKILL.md",
23
- "templates/workflow/prompts/critic.md",
24
- "adapters/codex/agents/critic.toml",
25
- ],
26
- },
27
- {
28
- name: "design_complete",
29
- description: "Package payload surface for design authoring and the architect/critic/test-engineer review bundle.",
30
- files: [
31
- "templates/workflow/skills/superspec-propose/SKILL.md",
32
- "templates/workflow/prompts/architect.md",
33
- "templates/workflow/prompts/critic.md",
34
- "templates/workflow/prompts/test-engineer.md",
35
- "adapters/codex/agents/architect.toml",
36
- "adapters/codex/agents/critic.toml",
37
- "adapters/codex/agents/test-engineer.toml",
38
- ],
39
- },
40
- {
41
- name: "test_contract_drafted",
42
- description: "Package payload surface for test-contract authoring and its review lanes.",
43
- files: [
44
- "templates/workflow/skills/superspec-propose/SKILL.md",
45
- "templates/workflow/prompts/critic.md",
46
- "templates/workflow/prompts/test-engineer.md",
47
- "adapters/codex/agents/critic.toml",
48
- "adapters/codex/agents/test-engineer.toml",
49
- ],
50
- },
51
- {
52
- name: "apply_ready",
53
- description: "Package payload surface for apply orchestration and bounded executor handoff.",
54
- files: [
55
- "templates/workflow/skills/superspec-apply/SKILL.md",
56
- "templates/workflow/prompts/executor.md",
57
- "adapters/codex/agents/executor.toml",
58
- ],
59
- },
60
- {
61
- name: "review_complete_allow",
62
- description: "Package payload surface for merged review + final verification on the allow path.",
63
- files: [
64
- "templates/workflow/skills/superspec-review/SKILL.md",
65
- "templates/workflow/prompts/code-reviewer.md",
66
- "templates/workflow/prompts/architect.md",
67
- "templates/workflow/prompts/critic.md",
68
- "templates/workflow/prompts/verifier.md",
69
- "adapters/codex/agents/code-reviewer.toml",
70
- "adapters/codex/agents/architect.toml",
71
- "adapters/codex/agents/critic.toml",
72
- "adapters/codex/agents/verifier.toml",
73
- ],
74
- },
75
- {
76
- name: "archive_ready",
77
- description: "Package payload surface for archive handoff after review passes.",
78
- files: [
79
- "templates/workflow/skills/superspec-archive/SKILL.md",
80
- ],
81
- },
82
- {
83
- name: "round2_reviewer_prompt",
84
- description: "Package payload surface for a round>1 reviewer lane.",
85
- files: [
86
- "templates/workflow/prompts/critic.md",
87
- "adapters/codex/agents/critic.toml",
88
- ],
89
- },
90
- {
91
- name: "request_changes_reopen_tasks",
92
- description: "Package payload surface for a review round that routes back to apply via reopen_tasks.",
93
- files: [
94
- "templates/workflow/skills/superspec-review/SKILL.md",
95
- "templates/workflow/prompts/code-reviewer.md",
96
- "templates/workflow/prompts/architect.md",
97
- "templates/workflow/prompts/critic.md",
98
- "adapters/codex/agents/code-reviewer.toml",
99
- "adapters/codex/agents/architect.toml",
100
- "adapters/codex/agents/critic.toml",
101
- ],
102
- },
103
- {
104
- name: "task_reopen_to_resolved",
105
- description: "Package payload surface for reopened apply work from revert through successor executor completion.",
106
- files: [
107
- "templates/workflow/skills/superspec-apply/SKILL.md",
108
- "templates/workflow/prompts/executor.md",
109
- "adapters/codex/agents/executor.toml",
110
- ],
111
- },
112
- {
113
- name: "scope_expansion",
114
- description: "Package payload surface for apply-side user confirmation when task scope expands.",
115
- files: [
116
- "templates/workflow/skills/superspec-apply/SKILL.md",
117
- ],
118
- },
119
- ];
120
- const MATERIALIZED_WORKFLOW_PACKET_SAMPLES = [
121
- {
122
- name: "apply_ready_blocked",
123
- description: "workflow-packet agent output for apply_ready before all required evidence is present.",
124
- args: { command: "workflow-packet", change: "demo-change", gate: "apply_ready", packet_format: "agent" },
125
- },
126
- {
127
- name: "task_complete_blocked",
128
- description: "workflow-packet agent output for a task-scoped apply completion packet.",
129
- args: { command: "workflow-packet", change: "demo-change", gate: "task_complete", task_id: "TASK-001", packet_format: "agent" },
130
- },
131
- ];
132
- const MATERIALIZED_REVIEW_PACKET_SAMPLES = [
133
- {
134
- name: "proposal_reviewed_critic",
135
- description: "review-packet agent output for a disclosure reviewer lane.",
136
- args: { command: "review-packet", change: "demo-change", gate: "proposal_reviewed", role: "critic", round: 1, packet_format: "agent" },
137
- },
138
- {
139
- name: "review_complete_verifier",
140
- description: "review-packet agent output for the final verification lane.",
141
- args: { command: "review-packet", change: "demo-change", gate: "review_complete", role: "verifier", round: 1, packet_format: "agent" },
142
- },
143
- ];
144
- const MATERIALIZED_REVIEW_PROMPT_SAMPLES = [
145
- {
146
- name: "proposal_reviewed_round2_critic",
147
- description: "review-packet prompt output for a round>1 disclosure reviewer lane with ledger injection.",
148
- args: { command: "review-packet", change: "demo-change", gate: "proposal_reviewed", role: "critic", round: 2, packet_format: "prompt" },
149
- requiredMarkers: ["[SUPERSPEC-FINDING-LEDGER gate=proposal_reviewed findings=1]", "PROP-SCOPE-001", "proposal silently widens scope beyond discovery"],
150
- },
151
- {
152
- name: "review_complete_critic_verification",
153
- description: "review-packet prompt output for the critic verification_review lane.",
154
- args: { command: "review-packet", change: "demo-change", gate: "review_complete", role: "critic", round: 1, evidence_kind: "verification_review", packet_format: "prompt" },
155
- },
156
- ];
157
- const LEDGER_BLOCK_SAMPLES = [
158
- {
159
- name: "proposal_reviewed_round2_ledger",
160
- description: "ledger-render output used by round>1 reviewer prompts.",
161
- args: { command: "ledger-render", change: "demo-change", gate: "proposal_reviewed", round: 2 },
162
- requiredMarkers: ["[SUPERSPEC-FINDING-LEDGER gate=proposal_reviewed findings=1]", "PROP-SCOPE-001", "proposal silently widens scope beyond discovery"],
163
- },
164
- ];
165
- function ensureReadableTextFile(repoRoot, relPath) {
166
- const absPath = join(repoRoot, relPath);
167
- if (existsSync(absPath) && statSync(absPath).isFile()) {
168
- return readFileSync(absPath, "utf8");
169
- }
170
- throw new GuardError(`packet_measure_missing_file: ${relPath}`);
171
- }
172
- function dedupePaths(paths) {
173
- return [...new Set(paths)].sort();
174
- }
175
- function measuredFiles(repoRoot, relPaths) {
176
- return dedupePaths(relPaths).map((relPath) => ({
177
- path: relPath,
178
- chars: ensureReadableTextFile(repoRoot, relPath).length,
179
- }));
180
- }
181
- function measureSurface(repoRoot, relPaths) {
182
- const files = measuredFiles(repoRoot, relPaths);
183
- return {
184
- total_chars: files.reduce((sum, item) => sum + item.chars, 0),
185
- files,
186
- };
187
- }
188
- function writeSyntheticText(repoRoot, relPath, text) {
189
- const absPath = join(repoRoot, relPath);
190
- mkdirSync(dirname(absPath), { recursive: true });
191
- writeFileSync(absPath, text, "utf8");
192
- }
193
- function syntheticRef(root, relPath) {
194
- return {
195
- path: relPath,
196
- blob_sha: file_blob_sha(join(root, relPath)),
197
- };
198
- }
199
- function syntheticStatus(repoRoot, changeRoot) {
200
- return {
201
- changeRoot,
202
- planningHome: { root: repoRoot },
203
- schemaName: "spec-driven",
204
- applyRequires: ["tasks"],
205
- artifacts: ["proposal", "specs", "design", "tasks"].map((id) => ({ id, status: "done", missingDeps: [] })),
206
- };
207
- }
208
- function materializeSyntheticEvidence(changeRoot, relPath, evidence) {
209
- const absPath = join(changeRoot, relPath);
210
- mkdirSync(dirname(absPath), { recursive: true });
211
- writeFileSync(absPath, `${JSON.stringify(evidence, null, 2)}\n`, "utf8");
212
- return { ...evidence, _path: relPath };
213
- }
214
- function syntheticDisclosureEvidences(changeRoot) {
215
- const promptRef = ".superspec/reports/proposal-r1-critic-prompt.md";
216
- const outputRef = ".superspec/reports/proposal-r1-critic.md";
217
- mkdirSync(dirname(join(changeRoot, promptRef)), { recursive: true });
218
- writeFileSync(join(changeRoot, promptRef), "critic prompt for proposal round 1\n", "utf8");
219
- writeFileSync(join(changeRoot, outputRef), "critic found a scope issue\n", "utf8");
220
- const finding = {
221
- finding_id: "PROP-SCOPE-001",
222
- finding_uid: "proposal_reviewed:EV-proposal-r1-critic:PROP-SCOPE-001",
223
- finding_type: "blocker",
224
- category: "scope",
225
- material_categories: ["scope"],
226
- decision_scope_key: "demo-change:proposal:hidden-scope",
227
- summary: "proposal silently widens scope beyond discovery",
228
- };
229
- const targetRefs = [
230
- syntheticRef(changeRoot, "proposal.md"),
231
- syntheticRef(changeRoot, ".superspec/artifacts/discovery.md"),
232
- ];
233
- const review = materializeSyntheticEvidence(changeRoot, ".superspec/evidence/reviews/EV-proposal-r1-critic.json", {
234
- schema_version: 1,
235
- evidence_id: "EV-proposal-r1-critic",
236
- change_id: "demo-change",
237
- gate: "proposal_reviewed",
238
- kind: "review",
239
- created_at: "2026-06-08T00:00:00Z",
240
- created_by: "measure",
241
- status: "pass",
242
- agent_role: "critic",
243
- execution_mode: "native_subagent",
244
- agent_id: "agent-critic",
245
- prompt_ref: promptRef,
246
- output_ref: outputRef,
247
- source_anchors: [],
248
- target_refs: targetRefs,
249
- review_round_id: "proposal_reviewed-r1",
250
- findings: [finding],
251
- });
252
- const digest = materializeSyntheticEvidence(changeRoot, ".superspec/evidence/reviews/EV-proposal-r1-digest.json", {
253
- schema_version: 1,
254
- evidence_id: "EV-proposal-r1-digest",
255
- change_id: "demo-change",
256
- gate: "proposal_reviewed",
257
- kind: "main_review_digest",
258
- created_at: "2026-06-08T00:01:00Z",
259
- created_by: "main-thread",
260
- status: "blocked",
261
- review_round_id: "proposal_reviewed-r1",
262
- target_refs: targetRefs,
263
- source_review_evidence_refs: ["EV-proposal-r1-critic"],
264
- previous_digest_refs: [],
265
- finding_dispositions: [{
266
- ...finding,
267
- origin_review_evidence_id: "EV-proposal-r1-critic",
268
- disposition: "needs_user_decision",
269
- rationale: "material scope finding requires user confirmation",
270
- route: "stay_same_gate_user_decision",
271
- route_reason: "material scope finding requires user confirmation",
272
- }],
273
- });
274
- return [review, digest];
275
- }
276
- function createMaterializedMeasureContext() {
277
- const repoRoot = mkdtempSync(join(tmpdir(), "superspec-packet-measure-"));
278
- const changeRoot = join(repoRoot, "openspec", "changes", "demo-change");
279
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/.superspec/artifacts/discovery.md", "discovery facts\n");
280
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/.superspec/artifacts/business-invariants.md", "## Business Invariants\n\n| id | description |\n| --- | --- |\n| INV-001 | Preserve behavior |\n");
281
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/.superspec/artifacts/test-contract.md", "## Test Contract\n\n| test_id | invariant_refs |\n| --- | --- |\n| TEST-001 | INV-001 |\n");
282
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/proposal.md", "proposal\n");
283
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/design.md", "design\n");
284
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/specs/demo/spec.md", "#### Scenario: Demo\n");
285
- writeSyntheticText(repoRoot, "openspec/changes/demo-change/tasks.md", "- [ ] TASK-001 Implement\n - invariant_refs: INV-001\n - test_refs: TEST-001\n");
286
- const evidences = syntheticDisclosureEvidences(changeRoot);
287
- return {
288
- repoRoot,
289
- changeRoot,
290
- status: syntheticStatus(repoRoot, changeRoot),
291
- evidences,
292
- cleanup: () => rmSync(repoRoot, { recursive: true, force: true }),
293
- };
294
- }
295
- function withMaterializedMeasureRuntime(ctx, fn) {
296
- const overrides = {
297
- load_context: () => [ctx.status, ctx.repoRoot, ctx.changeRoot, ctx.evidences],
298
- dirty_worktree_paths: () => [],
299
- file_blob_sha,
300
- };
301
- const previous = new Map();
302
- for (const [key, value] of Object.entries(overrides)) {
303
- previous.set(key, { had: Object.prototype.hasOwnProperty.call(runtime, key), value: runtime[key] });
304
- runtime[key] = value;
305
- }
306
- try {
307
- return fn();
308
- }
309
- finally {
310
- for (const [key, item] of previous) {
311
- if (item.had)
312
- runtime[key] = item.value;
313
- else
314
- delete runtime[key];
315
- }
316
- }
317
- }
318
- function packetOutputText(args) {
319
- const result = dispatch_packet(args);
320
- if (result.output_format === "prompt") {
321
- const text = String(result.payload);
322
- return text.endsWith("\n") ? text : `${text}\n`;
323
- }
324
- return `${JSON.stringify(result.payload, null, 2)}\n`;
325
- }
326
- function measureMaterializedSamples(specs) {
327
- const ctx = createMaterializedMeasureContext();
328
- try {
329
- const samples = withMaterializedMeasureRuntime(ctx, () => specs.map((spec) => {
330
- const text = packetOutputText(spec.args);
331
- const missingMarkers = (spec.requiredMarkers ?? []).filter((marker) => !text.includes(marker));
332
- if (missingMarkers.length > 0) {
333
- throw new GuardError(`packet_measure_missing_marker: ${spec.name}: ${missingMarkers.join(", ")}`);
334
- }
335
- return {
336
- name: spec.name,
337
- description: spec.description,
338
- chars: text.length,
339
- ...(spec.requiredMarkers && spec.requiredMarkers.length > 0 ? { matched_markers: [...spec.requiredMarkers] } : {}),
340
- };
341
- }));
342
- return {
343
- total_chars: samples.reduce((sum, item) => sum + item.chars, 0),
344
- samples,
345
- };
346
- }
347
- finally {
348
- ctx.cleanup();
349
- }
350
- }
351
- function installPayloadSourcePaths(repoRoot) {
352
- const { mappings, problems } = load_install_map(repoRoot);
353
- if (problems.length > 0)
354
- throw new GuardError(`packet_measure_install_map_invalid: ${problems.join("; ")}`);
355
- return mappings
356
- .filter((mapping) => mapping.kind === "skill" || mapping.kind === "prompt" || mapping.kind === "agent")
357
- .map((mapping) => mapping.source);
358
- }
359
- export function representative_scenarios() {
360
- return REPRESENTATIVE_SCENARIOS;
361
- }
362
- export function measure_packet_surface_report(repoRoot) {
363
- const packagePayloadSourcePaths = installPayloadSourcePaths(repoRoot);
364
- const fixedSurfaceInstallUpperBound = measureSurface(repoRoot, packagePayloadSourcePaths);
365
- const fixedSurfaceRuntimeRequiredSubset = measureSurface(repoRoot, packagePayloadSourcePaths);
366
- const scenarios = REPRESENTATIVE_SCENARIOS.map((scenario) => ({
367
- name: scenario.name,
368
- description: scenario.description,
369
- ...measureSurface(repoRoot, scenario.files),
370
- }));
371
- return {
372
- fixed_surface_chars_install_upper_bound: fixedSurfaceInstallUpperBound,
373
- fixed_surface_chars_runtime_required_subset: fixedSurfaceRuntimeRequiredSubset,
374
- materialized_workflow_packet_chars: measureMaterializedSamples(MATERIALIZED_WORKFLOW_PACKET_SAMPLES),
375
- materialized_review_packet_chars: measureMaterializedSamples(MATERIALIZED_REVIEW_PACKET_SAMPLES),
376
- materialized_review_prompt_chars: measureMaterializedSamples(MATERIALIZED_REVIEW_PROMPT_SAMPLES),
377
- ledger_block_chars: measureMaterializedSamples(LEDGER_BLOCK_SAMPLES),
378
- representative_loaded_surface_chars: {
379
- scenarios,
380
- },
381
- };
382
- }
File without changes