peaks-loop 4.0.0-beta → 4.0.0-beta.3

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 (179) hide show
  1. package/CHANGELOG.md +105 -87
  2. package/README-en.md +17 -4
  3. package/README.md +17 -4
  4. package/dist/src/cli/commands/asset-commands.d.ts +45 -0
  5. package/dist/src/cli/commands/asset-commands.js +404 -0
  6. package/dist/src/cli/commands/bee-commands.d.ts +26 -0
  7. package/dist/src/cli/commands/bee-commands.js +169 -0
  8. package/dist/src/cli/commands/{solo-commands.d.ts → code-commands.d.ts} +24 -24
  9. package/dist/src/cli/commands/{solo-commands.js → code-commands.js} +78 -78
  10. package/dist/src/cli/commands/core/skill-command.js +1 -1
  11. package/dist/src/cli/commands/dispatch-from-dag.js +1 -1
  12. package/dist/src/cli/commands/evolution-commands.d.ts +27 -0
  13. package/dist/src/cli/commands/evolution-commands.js +393 -0
  14. package/dist/src/cli/commands/hook-handle.js +7 -7
  15. package/dist/src/cli/commands/job-commands.js +2 -2
  16. package/dist/src/cli/commands/loop-commands.d.ts +19 -13
  17. package/dist/src/cli/commands/loop-commands.js +147 -13
  18. package/dist/src/cli/commands/sediment-commands.js +9 -0
  19. package/dist/src/cli/commands/session-auto-compact-hook-command.js +2 -2
  20. package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.d.ts +67 -0
  21. package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.js +173 -0
  22. package/dist/src/cli/commands/sub-agent-shared.d.ts +1 -1
  23. package/dist/src/cli/commands/user-touchpoint-commands.d.ts +4 -4
  24. package/dist/src/cli/commands/user-touchpoint-commands.js +14 -14
  25. package/dist/src/cli/commands/workflow-commands.js +22 -22
  26. package/dist/src/cli/program.js +23 -6
  27. package/dist/src/services/artifacts/repair-cycle-service.js +1 -1
  28. package/dist/src/services/audit/enforcers/active-skill-resolver.d.ts +1 -1
  29. package/dist/src/services/audit/enforcers/active-skill-resolver.js +1 -1
  30. package/dist/src/services/audit/enforcers/{solo-code-ban.d.ts → code-ban.d.ts} +6 -6
  31. package/dist/src/services/audit/enforcers/{solo-code-ban.js → code-ban.js} +6 -6
  32. package/dist/src/services/audit/red-line-catalog.d.ts +2 -2
  33. package/dist/src/services/audit/red-line-catalog.js +5 -5
  34. package/dist/src/services/audit/types.d.ts +2 -2
  35. package/dist/src/services/{solo → code}/auto-compact-orchestrator.d.ts +1 -1
  36. package/dist/src/services/{solo → code}/auto-compact-orchestrator.js +3 -3
  37. package/dist/src/services/{solo → code}/dag-orchestrator.d.ts +1 -1
  38. package/dist/src/services/{solo → code}/dag-orchestrator.js +1 -1
  39. package/dist/src/services/{solo → code}/emit-handoff.d.ts +1 -1
  40. package/dist/src/services/{solo → code}/emit-handoff.js +1 -1
  41. package/dist/src/services/{solo → code}/job-shape-decision.d.ts +1 -1
  42. package/dist/src/services/{solo → code}/job-shape-decision.js +5 -5
  43. package/dist/src/services/{solo → code}/mode-gate.d.ts +9 -9
  44. package/dist/src/services/{solo → code}/mode-gate.js +5 -5
  45. package/dist/src/services/{solo → code}/post-compact-detector.d.ts +3 -3
  46. package/dist/src/services/{solo → code}/post-compact-detector.js +4 -4
  47. package/dist/src/services/{solo → code}/step-08-gate.d.ts +4 -4
  48. package/dist/src/services/{solo → code}/step-08-gate.js +4 -4
  49. package/dist/src/services/{solo → code}/user-touchpoint-classifier.d.ts +1 -1
  50. package/dist/src/services/{solo → code}/user-touchpoint-classifier.js +1 -1
  51. package/dist/src/services/context/auto-compact-dispatcher.d.ts +2 -2
  52. package/dist/src/services/context/auto-compact-dispatcher.js +2 -2
  53. package/dist/src/services/context/auto-compact-types.d.ts +1 -1
  54. package/dist/src/services/crystallization/crystallization-service.d.ts +239 -0
  55. package/dist/src/services/crystallization/crystallization-service.js +397 -0
  56. package/dist/src/services/crystallization/crystallization-store.d.ts +75 -0
  57. package/dist/src/services/crystallization/crystallization-store.js +193 -0
  58. package/dist/src/services/crystallization/crystallization-types.d.ts +313 -0
  59. package/dist/src/services/crystallization/crystallization-types.js +299 -0
  60. package/dist/src/services/crystallization/evidence-brief-builder.d.ts +237 -0
  61. package/dist/src/services/crystallization/evidence-brief-builder.js +240 -0
  62. package/dist/src/services/dispatch/slice-dag.d.ts +2 -2
  63. package/dist/src/services/dispatch/test-tool-detection.d.ts +1 -1
  64. package/dist/src/services/dispatch/test-tool-detection.js +1 -1
  65. package/dist/src/services/evolution/evolution-service.d.ts +137 -0
  66. package/dist/src/services/evolution/evolution-service.js +281 -0
  67. package/dist/src/services/evolution/evolution-store.d.ts +57 -0
  68. package/dist/src/services/evolution/evolution-store.js +232 -0
  69. package/dist/src/services/evolution/evolution-types.d.ts +706 -0
  70. package/dist/src/services/evolution/evolution-types.js +286 -0
  71. package/dist/src/services/evolution/independent-evaluator-runner.d.ts +90 -0
  72. package/dist/src/services/evolution/independent-evaluator-runner.js +106 -0
  73. package/dist/src/services/evolution/regression-skeptic-runner.d.ts +64 -0
  74. package/dist/src/services/evolution/regression-skeptic-runner.js +113 -0
  75. package/dist/src/services/feedback/feedback-promotion-service.js +2 -2
  76. package/dist/src/services/job/job-progress-store.d.ts +1 -1
  77. package/dist/src/services/job/job-progress-store.js +1 -1
  78. package/dist/src/services/loop/loop-bee-relation-service.d.ts +107 -0
  79. package/dist/src/services/loop/loop-bee-relation-service.js +211 -0
  80. package/dist/src/services/loop/loop-bee-relation-store.d.ts +53 -0
  81. package/dist/src/services/loop/loop-bee-relation-store.js +130 -0
  82. package/dist/src/services/loop/loop-bee-relation-types.d.ts +118 -0
  83. package/dist/src/services/loop/loop-bee-relation-types.js +114 -0
  84. package/dist/src/services/loop/loop-release-service.d.ts +46 -0
  85. package/dist/src/services/loop/loop-release-service.js +66 -0
  86. package/dist/src/services/loop/loop-release-store.d.ts +55 -0
  87. package/dist/src/services/loop/loop-release-store.js +134 -0
  88. package/dist/src/services/loop/loop-release-types.d.ts +250 -0
  89. package/dist/src/services/loop/loop-release-types.js +162 -0
  90. package/dist/src/services/preferences/preferences-service.d.ts +1 -1
  91. package/dist/src/services/preferences/preferences-types.d.ts +1 -1
  92. package/dist/src/services/rd/standards-diagnostic.d.ts +1 -1
  93. package/dist/src/services/rd/standards-diagnostic.js +2 -2
  94. package/dist/src/services/recommendations/capability-seed-items.js +1 -1
  95. package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
  96. package/dist/src/services/recommendations/recommendation-service.js +1 -1
  97. package/dist/src/services/refactor/refactor-service.d.ts +1 -1
  98. package/dist/src/services/share/bundle-reader.d.ts +100 -0
  99. package/dist/src/services/share/bundle-reader.js +434 -0
  100. package/dist/src/services/share/bundle-types.d.ts +392 -0
  101. package/dist/src/services/share/bundle-types.js +318 -0
  102. package/dist/src/services/share/bundle-writer.d.ts +97 -0
  103. package/dist/src/services/share/bundle-writer.js +429 -0
  104. package/dist/src/services/share/run-state-contract.d.ts +133 -0
  105. package/dist/src/services/share/run-state-contract.js +138 -0
  106. package/dist/src/services/signal/cancel-handler.js +3 -3
  107. package/dist/src/services/skill/resume-detector.js +1 -1
  108. package/dist/src/services/skillhub/release-import.js +7 -2
  109. package/dist/src/services/skillhub/release-retain.js +6 -1
  110. package/dist/src/services/skillhub/sqlite-store.js +17 -1
  111. package/dist/src/services/skillhub/types.d.ts +10 -0
  112. package/dist/src/services/skills/skill-presence-service.d.ts +1 -1
  113. package/dist/src/services/standards/loop-engineering-lint.d.ts +38 -0
  114. package/dist/src/services/standards/loop-engineering-lint.js +101 -0
  115. package/dist/src/services/standards/loop-engineering-readiness-lint.d.ts +111 -0
  116. package/dist/src/services/standards/loop-engineering-readiness-lint.js +248 -0
  117. package/dist/src/services/upgrade/1x-detector-service.js +1 -1
  118. package/dist/src/services/workflow/pipeline-verify-service.d.ts +1 -1
  119. package/dist/src/services/workflow/pipeline-verify-service.js +3 -3
  120. package/dist/src/services/workflow/workflow-autonomous-service.d.ts +3 -3
  121. package/dist/src/services/workflow/workflow-autonomous-service.js +2 -2
  122. package/dist/src/services/workflow/workflow-router-service.d.ts +6 -6
  123. package/dist/src/services/workflow/workflow-router-service.js +33 -33
  124. package/dist/src/services/workspace/claude-settings-template.d.ts +1 -1
  125. package/dist/src/services/workspace/claude-settings-template.js +5 -5
  126. package/dist/src/shared/version.d.ts +1 -1
  127. package/dist/src/shared/version.js +1 -1
  128. package/examples/video-demo/README.md +57 -0
  129. package/examples/video-demo/out/en-closing-960.png +0 -0
  130. package/examples/video-demo/out/zh-closing-960.png +0 -0
  131. package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
  132. package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
  133. package/output-styles/peaks-skill-swarm.md +3 -3
  134. package/package.json +6 -2
  135. package/skills/bee/peaks-qa/SKILL.md +1 -1
  136. package/skills/bee/peaks-qa/references/artifact-per-request.md +3 -3
  137. package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +6 -6
  138. package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +1 -1
  139. package/skills/bee/peaks-rd/references/rd-runbook.md +1 -1
  140. package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +11 -11
  141. package/skills/bee/peaks-rd/references/rd-transition-gates.md +1 -1
  142. package/skills/bee/peaks-sc/SKILL.md +1 -1
  143. package/skills/bee/peaks-txt/SKILL.md +3 -3
  144. package/skills/bee/peaks-ui/SKILL.md +8 -8
  145. package/skills/peaks-code/SKILL.md +34 -21
  146. package/skills/peaks-code/references/anchoring-and-session-info.md +2 -2
  147. package/skills/peaks-code/references/artifact-contracts.md +1 -1
  148. package/skills/peaks-code/references/boundaries.md +3 -3
  149. package/skills/peaks-code/references/codegraph-orchestration.md +1 -1
  150. package/skills/peaks-code/references/dag-orchestrator.md +7 -7
  151. package/skills/peaks-code/references/external-references.md +2 -2
  152. package/skills/peaks-code/references/fanout-mandatory.md +3 -3
  153. package/skills/peaks-code/references/fast-mode.md +2 -2
  154. package/skills/peaks-code/references/frontend-only-mode.md +9 -9
  155. package/skills/peaks-code/references/job-loop.md +1 -1
  156. package/skills/peaks-code/references/local-artifact-workspace.md +2 -2
  157. package/skills/peaks-code/references/micro-cycle.md +14 -14
  158. package/skills/peaks-code/references/mode-selection-with-stale-presence.md +5 -5
  159. package/skills/peaks-code/references/mode-selection.md +3 -3
  160. package/skills/peaks-code/references/openspec-workflow.md +16 -16
  161. package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
  162. package/skills/peaks-code/references/quality-gate-cheatsheet.md +1 -1
  163. package/skills/peaks-code/references/refactor-mode.md +1 -1
  164. package/skills/peaks-code/references/runbook.md +15 -15
  165. package/skills/peaks-code/references/step-0-55-1x-detection.md +1 -1
  166. package/skills/peaks-code/references/step-0-8-gate.md +11 -11
  167. package/skills/peaks-code/references/sub-agent-dispatch.md +8 -8
  168. package/skills/peaks-code/references/swarm-dispatch-contract.md +17 -17
  169. package/skills/peaks-code/references/workflow-gates-and-types.md +2 -2
  170. package/skills/peaks-code/references/workflow.md +5 -5
  171. package/skills/peaks-content/SKILL.md +272 -0
  172. package/skills/peaks-issue-fix-orchestrator/SKILL.md +307 -0
  173. package/skills/peaks-resume/SKILL.md +2 -2
  174. package/skills/peaks-status/SKILL.md +2 -2
  175. package/skills/peaks-test/SKILL.md +2 -2
  176. /package/dist/src/services/{solo → code}/batch-heartbeat-poller.d.ts +0 -0
  177. /package/dist/src/services/{solo → code}/batch-heartbeat-poller.js +0 -0
  178. /package/dist/src/services/{solo → code}/status-line-renderer.d.ts +0 -0
  179. /package/dist/src/services/{solo → code}/status-line-renderer.js +0 -0
@@ -0,0 +1,318 @@
1
+ /**
2
+ * peaks.bundle/1 — share-bundle format contract (spec §7A.2).
3
+ *
4
+ * M7 / spec §7A.2 / §10 RL-9.
5
+ *
6
+ * A bundle is a self-describing tar.gz whose root manifest
7
+ * (manifest.json) declares the format constant, the major/minor
8
+ * format version, the schema_version of every contained asset, the
9
+ * assets themselves (loop_release + related bee_release rows), the
10
+ * relation rows, and the evidence briefs that back the assets. The
11
+ * bundle excludes private run_state, `.peaks/memory/personal/`, and
12
+ * raw `state.db` rows.
13
+ *
14
+ * Hard rules enforced at THIS layer:
15
+ *
16
+ * - The literal constant `format_constant = "peaks.bundle/1"` is
17
+ * set inside the manifest at write time. The CLI is the only
18
+ * writer; a future format change is signaled by bumping the
19
+ * major field and shipping a new writer.
20
+ * - `format_version_major = 1` is required for any current
21
+ * receiver. A major-version mismatch is a HARD block at read
22
+ * time (the reader throws and refuses to import).
23
+ * - `format_version_minor` is informational; a major-compatible
24
+ * minor bump emits a non-fatal warning at read time.
25
+ * - `schema_versions` carries the canonical asset schema literal
26
+ * for each emitted asset: `peaks.loop/1`, `peaks.bee/1`, plus
27
+ * the cross-cutting `peaks.loop-bee-relation/1` and
28
+ * `peaks.crystallization/1`. The reader uses the values to
29
+ * inform a version-mismatch warning.
30
+ *
31
+ * The schema is intentionally permissive on the manifests (the
32
+ * manifest sub-objects are typed as `unknown` so each asset kind
33
+ * can validate with its own Zod schema at the service layer); the
34
+ * hard invariants (format constant, format_version_major, the
35
+ * schema_versions keys, and the inclusion/exclusion rules) are
36
+ * enforced here at the format boundary.
37
+ *
38
+ * On-the-wire shape (the rendered `manifest.json`):
39
+ *
40
+ * {
41
+ * "format_constant": "peaks.bundle/1",
42
+ * "format_version_major": 1,
43
+ * "format_version_minor": 0,
44
+ * "schema_versions": {
45
+ * "loop": "peaks.loop/1",
46
+ * "bee": "peaks.bee/1",
47
+ * "loop_bee_relation": "peaks.loop-bee-relation/1",
48
+ * "crystallization": "peaks.crystallization/1"
49
+ * },
50
+ * "kind": "loop" | "bee",
51
+ * "loop_release": <LoopRelease row or omitted for bee kind>,
52
+ * "bee_release": <BeeRelease row or omitted for loop kind>,
53
+ * "related_bee_releases": Array<BeeRelease row>,
54
+ * "loop_bee_relations": Array<LoopBeeRelation row>,
55
+ * "evidence_briefs": Array<CrystallizationEvent row>,
56
+ * "exclusion_manifest": { "private_run_state": "excluded",
57
+ * "personal_memory": "excluded",
58
+ * "state_db_rows": "excluded" }
59
+ * }
60
+ *
61
+ * Excludes (spec §7A.2 hard rules): private run_state, anything
62
+ * under `.peaks/memory/personal/`, raw `state.db` rows.
63
+ */
64
+ import { z } from "zod";
65
+ /* ---------------------------------------------------------------------- */
66
+ /* Format constant + version */
67
+ /* ---------------------------------------------------------------------- */
68
+ /**
69
+ * The on-the-wire format constant, pinned to the literal
70
+ * `"peaks.bundle/1"`. The CLI is the only writer — see `bundle-writer.ts`.
71
+ * A future format change requires a major-version bump + a new writer.
72
+ */
73
+ export const PEAKS_BUNDLE_FORMAT_CONSTANT = "peaks.bundle/1";
74
+ /**
75
+ * The required `format_version_major` for any current receiver.
76
+ * Bumped only on a breaking schema change. The reader throws when
77
+ * the manifest declares any value other than `1`.
78
+ */
79
+ export const PEAKS_BUNDLE_FORMAT_VERSION_MAJOR = 1;
80
+ /**
81
+ * Default `format_version_minor`. Major-compatible minor bumps emit
82
+ * a soft warning at read time; they never block.
83
+ */
84
+ export const PEAKS_BUNDLE_DEFAULT_MINOR_VERSION = 0;
85
+ /* ---------------------------------------------------------------------- */
86
+ /* Schema-version cross-reference (per asset table) */
87
+ /* ---------------------------------------------------------------------- */
88
+ /**
89
+ * The cross-cutting schema literals a bundle is allowed to declare.
90
+ * Each value must match the canonical Zod `literal(...)` literal in
91
+ * the corresponding type module. Used for the
92
+ * `SchemaVersionsMapping` enumeration below.
93
+ */
94
+ export const PEAKS_BUNDLE_SCHEMA_VERSIONS = {
95
+ loop: "peaks.loop/1",
96
+ bee: "peaks.bee/1",
97
+ loop_bee_relation: "peaks.loop-bee-relation/1",
98
+ crystallization: "peaks.crystallization/1",
99
+ };
100
+ /* ---------------------------------------------------------------------- */
101
+ /* Schema-versions mapping — spec §7A.2 */
102
+ /* ---------------------------------------------------------------------- */
103
+ /**
104
+ * Schema-versions mapping. The writer writes the canonical literal
105
+ * for each asset kind it includes; the reader checks every key for
106
+ * presence (and that the value matches the canonical literal).
107
+ *
108
+ * `.strict()` refuses unknown keys; `.refine(...)` enforces that
109
+ * each value matches its canonical literal.
110
+ */
111
+ export const SchemaVersionsMappingSchema = z
112
+ .object({
113
+ loop: z.literal(PEAKS_BUNDLE_SCHEMA_VERSIONS.loop),
114
+ bee: z.literal(PEAKS_BUNDLE_SCHEMA_VERSIONS.bee),
115
+ loop_bee_relation: z.literal(PEAKS_BUNDLE_SCHEMA_VERSIONS.loop_bee_relation),
116
+ crystallization: z.literal(PEAKS_BUNDLE_SCHEMA_VERSIONS.crystallization),
117
+ })
118
+ .strict();
119
+ /* ---------------------------------------------------------------------- */
120
+ /* Exclusion manifest — the explicit excludes per spec §7A.2 */
121
+ /* ---------------------------------------------------------------------- */
122
+ /**
123
+ * The bundle explicitly excludes private run-state, the user's
124
+ * personal memory directory, and raw `state.db` rows. The
125
+ * `ExclusionManifestSchema` is what the writer stamps into the
126
+ * manifest; the reader uses it as a self-declaration (the writer is
127
+ * the only place that can leak those payloads, but the read-time
128
+ * stamp lets the receiver confirm the source understood the
129
+ * exclusion rules).
130
+ */
131
+ export const ExclusionManifestSchema = z
132
+ .object({
133
+ private_run_state: z.literal("excluded"),
134
+ personal_memory: z.literal("excluded"),
135
+ state_db_rows: z.literal("excluded"),
136
+ })
137
+ .strict();
138
+ /* ---------------------------------------------------------------------- */
139
+ /* Bundle kind — which asset the bundle is anchored on */
140
+ /* ---------------------------------------------------------------------- */
141
+ /**
142
+ * Bundle kind. A bundle is anchored on exactly one asset: either a
143
+ * `loop_release` (and its main bee + supporting bees) or a single
144
+ * `bee_release` (loop-scoped relations may follow but are not
145
+ * required).
146
+ */
147
+ export const PEAKS_BUNDLE_KINDS = ["loop", "bee"];
148
+ /* ---------------------------------------------------------------------- */
149
+ /* Bundle manifest schema — the on-the-wire shape */
150
+ /* ---------------------------------------------------------------------- */
151
+ /**
152
+ * The full manifest schema. The asset sub-objects are typed as
153
+ * `unknown` here; each service layer validates them with the
154
+ * appropriate per-kind Zod schema (LoopReleaseSchema,
155
+ * BeeReleaseRow, LoopBeeRelationSchema, CrystallizationEventSchema).
156
+ *
157
+ * The hard invariants are enforced HERE:
158
+ * - `format_constant = "peaks.bundle/1"` literal.
159
+ * - `format_version_major = 1` literal (HARD block at read time
160
+ * on mismatch — enforced in `bundle-reader.ts`).
161
+ * - `schema_versions` carries every required key with the
162
+ * canonical literal.
163
+ * - `exclusion_manifest` declares the three hard excludes.
164
+ */
165
+ export const BundleManifestSchema = z
166
+ .object({
167
+ /**
168
+ * The format constant. Pinned to `"peaks.bundle/1"`. A future
169
+ * format change is a major bump + a new constant value.
170
+ */
171
+ format_constant: z.literal(PEAKS_BUNDLE_FORMAT_CONSTANT),
172
+ /**
173
+ * Major version. The reader requires `1`; anything else is a
174
+ * HARD block. Enforced at the read boundary, not here.
175
+ */
176
+ format_version_major: z.literal(PEAKS_BUNDLE_FORMAT_VERSION_MAJOR),
177
+ /**
178
+ * Minor version. Defaults to `0`. Major-compatible bumps are a
179
+ * non-fatal warn at read time.
180
+ */
181
+ format_version_minor: z.number().int().min(0).default(PEAKS_BUNDLE_DEFAULT_MINOR_VERSION),
182
+ /**
183
+ * Schema-version mapping. Every required key MUST be present
184
+ * with its canonical literal; unknown keys are rejected by
185
+ * `.strict()`.
186
+ */
187
+ schema_versions: SchemaVersionsMappingSchema,
188
+ /**
189
+ * Anchor kind. Decides whether `loop_release` or `bee_release`
190
+ * is required below.
191
+ */
192
+ kind: z.enum(PEAKS_BUNDLE_KINDS),
193
+ /**
194
+ * The loop_release row. Required when `kind === "loop"`,
195
+ * omitted (or absent) when `kind === "bee"`. The writer leaves
196
+ * it `undefined` for `bee` bundles; the JSON shape is allowed
197
+ * to omit it.
198
+ */
199
+ loop_release: z.unknown().optional(),
200
+ /**
201
+ * The bee_release row. Required when `kind === "bee"`,
202
+ * optional for `kind === "loop"` (a loop bundle may include a
203
+ * main bee inline). When present, the reader uses the service
204
+ * layer to re-validate the row shape.
205
+ */
206
+ bee_release: z.unknown().optional(),
207
+ /**
208
+ * Related bee_release rows for the loop kind (main + supporting
209
+ * + candidate + retired). Empty for `kind === "bee"`.
210
+ */
211
+ related_bee_releases: z.array(z.unknown()).default([]),
212
+ /**
213
+ * Loop↔bee relation rows from `loop_bee_relation`. Always
214
+ * present (possibly empty).
215
+ */
216
+ loop_bee_relations: z.array(z.unknown()).default([]),
217
+ /**
218
+ * Evidence briefs (crystallization_event rows) that back the
219
+ * bundle's assets. The receiver uses them to render the
220
+ * post-import crystallization prompt + a brief for any
221
+ * subsequent independent evaluation.
222
+ */
223
+ evidence_briefs: z.array(z.unknown()).default([]),
224
+ /**
225
+ * Exclusion manifest — explicit declarations of the three
226
+ * hard excludes per spec §7A.2.
227
+ */
228
+ exclusion_manifest: ExclusionManifestSchema,
229
+ })
230
+ .strict()
231
+ .refine((m) => {
232
+ // kind === 'loop' implies loop_release is required.
233
+ if (m.kind === "loop" && m.loop_release === undefined)
234
+ return false;
235
+ // kind === 'bee' implies bee_release is required.
236
+ if (m.kind === "bee" && m.bee_release === undefined)
237
+ return false;
238
+ return true;
239
+ }, {
240
+ message: "bundle manifest is inconsistent: kind='loop' requires loop_release; kind='bee' requires bee_release (spec §7A.2)",
241
+ path: [],
242
+ });
243
+ /* ---------------------------------------------------------------------- */
244
+ /* Validation helpers */
245
+ /* ---------------------------------------------------------------------- */
246
+ /**
247
+ * Strict-parse an unknown value as a BundleManifest. Throws
248
+ * `z.ZodError` on any failure — including:
249
+ * - format_constant !== "peaks.bundle/1"
250
+ * - format_version_major !== 1
251
+ * - schema_versions missing or carrying non-canonical literals
252
+ * - exclusion_manifest missing any of the three hard excludes
253
+ * - kind / anchor-mismatch (loop kind without loop_release, etc.)
254
+ *
255
+ * Note: a major-version mismatch on its own is NOT a Zod failure
256
+ * (the literal is enforced at the schema boundary so it is), but
257
+ * the `bundle-reader.ts` HARD block on major mismatch is layered on
258
+ * top of this parse for defense in depth (it lets the CLI emit its
259
+ * own specific error code without catching Zod errors).
260
+ */
261
+ export function parseBundleManifest(input) {
262
+ return BundleManifestSchema.parse(input);
263
+ }
264
+ /**
265
+ * Safe-parse twin of `parseBundleManifest` — returns a Result-like
266
+ * envelope. Used by the CLI layer so a manifest-validation failure
267
+ * can be rendered as a structured error code rather than a thrown
268
+ * `ZodError`.
269
+ */
270
+ export function safeParseBundleManifest(input) {
271
+ const r = BundleManifestSchema.safeParse(input);
272
+ if (r.success)
273
+ return { ok: true, manifest: r.data };
274
+ const findings = r.error.issues.map((i) => ({
275
+ path: i.path.join("."),
276
+ message: i.message,
277
+ }));
278
+ const joined = findings.map((f) => f.path + ":" + f.message).join("|");
279
+ const code = detectManifestFailureCode(joined);
280
+ return { ok: false, code, findings };
281
+ }
282
+ function detectManifestFailureCode(joinedIssues) {
283
+ if (joinedIssues.includes("format_constant")) {
284
+ return "BUNDLE_FORMAT_CONSTANT_MISMATCH";
285
+ }
286
+ if (joinedIssues.includes("format_version_major")) {
287
+ return "BUNDLE_MAJOR_VERSION_MISMATCH";
288
+ }
289
+ if (joinedIssues.includes("schema_versions")) {
290
+ return "BUNDLE_SCHEMA_VERSIONS_MISMATCH";
291
+ }
292
+ if (joinedIssues.includes("exclusion_manifest")) {
293
+ return "BUNDLE_EXCLUSION_MANIFEST_MISSING";
294
+ }
295
+ return "BUNDLE_KIND_ANCHOR_MISMATCH";
296
+ }
297
+ /* ---------------------------------------------------------------------- */
298
+ /* Hard-block error code consts */
299
+ /* ---------------------------------------------------------------------- */
300
+ /**
301
+ * Error code string consts. Centralised here so the writer + reader
302
+ * share a single source of truth for error codes; the CLI layer
303
+ * only needs to render them.
304
+ */
305
+ export const SHARE_BUNDLE_ERROR_CODES = {
306
+ /** Major-version mismatch at read time — HARD block. */
307
+ MAJOR_VERSION_MISMATCH: "SHARE_BUNDLE_MAJOR_VERSION_MISMATCH",
308
+ /** Schema-version mapping is missing or carries non-canonical literals. */
309
+ SCHEMA_VERSIONS_MISMATCH: "SHARE_BUNDLE_SCHEMA_VERSIONS_MISMATCH",
310
+ /** Format constant is not the pinned "peaks.bundle/1". */
311
+ FORMAT_CONSTANT_MISMATCH: "SHARE_BUNDLE_FORMAT_CONSTANT_MISMATCH",
312
+ /** Source release has `shareable === false` — HARD block at write time. */
313
+ NOT_SHAREABLE: "SHARE_BUNDLE_NOT_SHAREABLE",
314
+ /** Receiver asked to land as `stable` (forbidden — bundles always land as candidate). */
315
+ IMPORT_TO_STABLE_FORBIDDEN: "SHARE_BUNDLE_IMPORT_TO_STABLE_FORBIDDEN",
316
+ /** Bundle tarball is malformed (missing manifest, bad payload). */
317
+ BUNDLE_MALFORMED: "SHARE_BUNDLE_MALFORMED",
318
+ };
@@ -0,0 +1,97 @@
1
+ /**
2
+ * bundle-writer.ts — writeBundle(loopOrBeeId, outPath) (spec §7A.2).
3
+ *
4
+ * M7 / spec §7A.2 / §10 RL-9.
5
+ *
6
+ * Writes a `peaks.bundle/1` tar.gz that captures:
7
+ *
8
+ * - One anchor asset: a loop_release (kind='loop') OR a single
9
+ * bee_release (kind='bee'). A loop bundle additionally carries
10
+ * related_bee_releases (all loop↔bee relations resolved) and
11
+ * loop_bee_relations rows.
12
+ * - All evidence_briefs (crystallization_event rows) that
13
+ * reference the anchor (created_loop_release_id /
14
+ * updated_loop_release_id / created_bee_release_id /
15
+ * updated_bee_release_id).
16
+ *
17
+ * Hard rules enforced at THIS layer:
18
+ *
19
+ * - The source release MUST have `shareable !== false`. A
20
+ * `shareable=false` source THROWS
21
+ * `SHARE_BUNDLE_NOT_SHAREABLE` BEFORE the tarball is written.
22
+ * The CLI layer is the canonical gate (per spec §7A.2 /
23
+ * §10 RL-9); the writer enforces the same gate at the
24
+ * service boundary for defense in depth.
25
+ * - The bundle NEVER captures private run_state, the personal
26
+ * `.peaks/memory/personal/` directory, or raw `state.db`
27
+ * rows. The exclusion is declared in the manifest's
28
+ * `exclusion_manifest` field; physically, the writer only
29
+ * pulls rows from the structured tables.
30
+ * - The bundle is a tarball whose root contains `manifest.json`,
31
+ * `relations.json`, `evidence_briefs/*.json`, and
32
+ * `blobs/<sha256>` content-addressed blobs (mirroring the
33
+ * SkillHub release pattern).
34
+ *
35
+ * The writer runs `tar -czf <outPath> -C <stageDir> .` exactly the
36
+ * same way `release-export.ts` does — same layout, same tar
37
+ * invocation, so the `bundle-reader.ts` symmetrical side can
38
+ * extract via `runTar(['-xzf', inPath, '-C', stageDir])` with no
39
+ * extra plumbing.
40
+ */
41
+ import type Database from "better-sqlite3";
42
+ import { SHARE_BUNDLE_ERROR_CODES, type PeaksBundleKind } from "./bundle-types.js";
43
+ /**
44
+ * Inputs to `writeBundle`. `kind` decides which asset table the
45
+ * `id` resolves against; the writer throws on unknown assets and
46
+ * on `shareable=false` sources.
47
+ */
48
+ export type WriteBundleArgs = {
49
+ db: Database.Database;
50
+ /** Blobs root for content-addressed file lookup. */
51
+ blobsDir: string;
52
+ /** Bundle kind — `loop` or `bee`. */
53
+ kind: PeaksBundleKind;
54
+ /** The asset id — loop id (kebab-case) for `kind:'loop'`, integer bee_release.id for `kind:'bee'`. */
55
+ id: string | number;
56
+ /** Output `.tar.gz` path. */
57
+ outPath: string;
58
+ };
59
+ /**
60
+ * Thrown when the source release has `shareable === false`. The
61
+ * writer throws BEFORE any tarball work; the CLI layer surfaces
62
+ * `code = SHARE_BUNDLE_NOT_SHAREABLE`.
63
+ */
64
+ export declare class BundleNotShareableError extends Error {
65
+ readonly code: typeof SHARE_BUNDLE_ERROR_CODES.NOT_SHAREABLE;
66
+ constructor(message: string);
67
+ }
68
+ /**
69
+ * Thrown when the writer cannot locate the source asset (loop id
70
+ * not present in `loop_release`, or bee_release.id not present).
71
+ * Includes both `LOOP_NOT_FOUND` and `BEE_NOT_FOUND` flavors —
72
+ * both fall under `BUNDLE_ASSET_NOT_FOUND` for the CLI envelope.
73
+ */
74
+ export declare class BundleAssetNotFoundError extends Error {
75
+ readonly code: "BUNDLE_ASSET_NOT_FOUND";
76
+ readonly assetKind: PeaksBundleKind;
77
+ readonly assetId: string | number;
78
+ constructor(assetKind: PeaksBundleKind, assetId: string | number);
79
+ }
80
+ /**
81
+ * Write a `peaks.bundle/1` tar.gz to `outPath`. The bundle
82
+ * captures ONE anchor asset (`loop` or `bee`) plus its relations,
83
+ * supporting bees (loop kind only), and evidence briefs.
84
+ *
85
+ * Hard blocks raised at THIS layer:
86
+ *
87
+ * - `BundleNotShareableError`: the source has `shareable === false`.
88
+ * - `BundleAssetNotFoundError`: the source id was not present in the table.
89
+ *
90
+ * On success the call returns the resolved asset id and kind; the
91
+ * CLI layer uses this to render a one-line status.
92
+ */
93
+ export declare function writeBundle(args: WriteBundleArgs): {
94
+ outPath: string;
95
+ kind: PeaksBundleKind;
96
+ assetId: string | number;
97
+ };