peaks-loop 4.0.0-beta.2 → 4.0.0-beta.4

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 (72) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README-en.md +16 -3
  3. package/README.md +16 -3
  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/evolution-commands.d.ts +27 -0
  9. package/dist/src/cli/commands/evolution-commands.js +393 -0
  10. package/dist/src/cli/commands/loop-commands.d.ts +19 -13
  11. package/dist/src/cli/commands/loop-commands.js +147 -13
  12. package/dist/src/cli/commands/sediment-commands.js +9 -0
  13. package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.d.ts +67 -0
  14. package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.js +173 -0
  15. package/dist/src/cli/program.js +17 -0
  16. package/dist/src/services/crystallization/crystallization-service.d.ts +239 -0
  17. package/dist/src/services/crystallization/crystallization-service.js +397 -0
  18. package/dist/src/services/crystallization/crystallization-store.d.ts +75 -0
  19. package/dist/src/services/crystallization/crystallization-store.js +193 -0
  20. package/dist/src/services/crystallization/crystallization-types.d.ts +313 -0
  21. package/dist/src/services/crystallization/crystallization-types.js +299 -0
  22. package/dist/src/services/crystallization/evidence-brief-builder.d.ts +237 -0
  23. package/dist/src/services/crystallization/evidence-brief-builder.js +240 -0
  24. package/dist/src/services/evolution/evolution-service.d.ts +137 -0
  25. package/dist/src/services/evolution/evolution-service.js +281 -0
  26. package/dist/src/services/evolution/evolution-store.d.ts +57 -0
  27. package/dist/src/services/evolution/evolution-store.js +232 -0
  28. package/dist/src/services/evolution/evolution-types.d.ts +706 -0
  29. package/dist/src/services/evolution/evolution-types.js +286 -0
  30. package/dist/src/services/evolution/independent-evaluator-runner.d.ts +90 -0
  31. package/dist/src/services/evolution/independent-evaluator-runner.js +106 -0
  32. package/dist/src/services/evolution/regression-skeptic-runner.d.ts +64 -0
  33. package/dist/src/services/evolution/regression-skeptic-runner.js +113 -0
  34. package/dist/src/services/loop/loop-bee-relation-service.d.ts +107 -0
  35. package/dist/src/services/loop/loop-bee-relation-service.js +211 -0
  36. package/dist/src/services/loop/loop-bee-relation-store.d.ts +53 -0
  37. package/dist/src/services/loop/loop-bee-relation-store.js +130 -0
  38. package/dist/src/services/loop/loop-bee-relation-types.d.ts +118 -0
  39. package/dist/src/services/loop/loop-bee-relation-types.js +114 -0
  40. package/dist/src/services/loop/loop-release-service.d.ts +46 -0
  41. package/dist/src/services/loop/loop-release-service.js +66 -0
  42. package/dist/src/services/loop/loop-release-store.d.ts +55 -0
  43. package/dist/src/services/loop/loop-release-store.js +134 -0
  44. package/dist/src/services/loop/loop-release-types.d.ts +250 -0
  45. package/dist/src/services/loop/loop-release-types.js +162 -0
  46. package/dist/src/services/share/bundle-reader.d.ts +100 -0
  47. package/dist/src/services/share/bundle-reader.js +434 -0
  48. package/dist/src/services/share/bundle-types.d.ts +392 -0
  49. package/dist/src/services/share/bundle-types.js +318 -0
  50. package/dist/src/services/share/bundle-writer.d.ts +97 -0
  51. package/dist/src/services/share/bundle-writer.js +429 -0
  52. package/dist/src/services/share/run-state-contract.d.ts +133 -0
  53. package/dist/src/services/share/run-state-contract.js +138 -0
  54. package/dist/src/services/skillhub/release-import.js +7 -2
  55. package/dist/src/services/skillhub/release-retain.js +6 -1
  56. package/dist/src/services/skillhub/sqlite-store.js +17 -1
  57. package/dist/src/services/skillhub/types.d.ts +10 -0
  58. package/dist/src/services/standards/loop-engineering-lint.d.ts +38 -0
  59. package/dist/src/services/standards/loop-engineering-lint.js +101 -0
  60. package/dist/src/services/standards/loop-engineering-readiness-lint.d.ts +111 -0
  61. package/dist/src/services/standards/loop-engineering-readiness-lint.js +248 -0
  62. package/dist/src/shared/version.d.ts +1 -1
  63. package/dist/src/shared/version.js +1 -1
  64. package/examples/video-demo/README.md +57 -0
  65. package/examples/video-demo/out/en-closing-960.png +0 -0
  66. package/examples/video-demo/out/zh-closing-960.png +0 -0
  67. package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
  68. package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
  69. package/package.json +6 -2
  70. package/skills/peaks-code/SKILL.md +13 -0
  71. package/skills/peaks-content/SKILL.md +272 -0
  72. package/skills/peaks-issue-fix-orchestrator/SKILL.md +307 -0
@@ -0,0 +1,162 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * LoopRelease — spec §4.1 (Loop Engineering Asset).
4
+ *
5
+ * M1 scope was the §4.1 fields. M3 (this slice) ADDS the share /
6
+ * desktop extension fields from §4.1 / §7A:
7
+ * - shareable (boolean, default true)
8
+ * - share_excluded_paths (string[], default [])
9
+ * - desktop_visible (boolean, default true)
10
+ * - export_bundle_format ('peaks.bundle/1', CLI-written constant)
11
+ *
12
+ * The four M3 fields are added with `.default(...)` so an in-memory
13
+ * object built from a pre-M3 snapshot still parses after the
14
+ * migration runs. NO enforcement on `shareable=false` is added in M3
15
+ * — the schema-only addition is the contract; full export /
16
+ * desktop enforcement lands in M7 (see plan
17
+ * m3-bee-release-extension.md and spec §7A).
18
+ *
19
+ * Field semantics — see the spec for full prose. Highlights:
20
+ *
21
+ * - `id` is the stable kebab-case loop id; the storage key.
22
+ * - `schema_version` is the constant literal `"peaks.loop/1"`; a
23
+ * schema-version bump requires a new table / new enum case and a
24
+ * migration — never edit this literal in place.
25
+ * - `lifecycle_status` is `candidate` / `stable` / `retired`; the
26
+ * default on first crystallization is `candidate`. LLMs cannot
27
+ * auto-promote to `stable` (see spec §5.6).
28
+ * - `linked_bees` is a denormalized pointer list of bee ids; the
29
+ * authoritative loop↔bee relations live in `loop_bee_relation`
30
+ * (M2). Keeping it here matches the spec §4.1 row shape and lets
31
+ * M1 readers iterate the loop without an extra join.
32
+ * - `success_criteria` / `evaluator_policy` are NL strings, not
33
+ * machine-checked predicates; the evaluator definitions live in
34
+ * the M4 evolution layer.
35
+ * - `share_excluded_paths` is a JSON-encoded TEXT column at the
36
+ * SQLite layer; the Zod schema accepts a string[] and the store
37
+ * does the JSON.stringify/parse boundary work. Matches the
38
+ * existing `loop_release` style (success_criteria_json, …).
39
+ * - `export_bundle_format` is pinned to the literal
40
+ * `"peaks.bundle/1"` per the spec §7A.2 contract — no other
41
+ * value is accepted in this schema version.
42
+ */
43
+ export const LoopReleaseLifecycleStatusSchema = z.enum([
44
+ "candidate",
45
+ "stable",
46
+ "retired",
47
+ ]);
48
+ /**
49
+ * The M3 share / desktop extension fields, listed for code-search /
50
+ * lint discoverability. They are now part of the schema (with safe
51
+ * defaults) — see `LoopReleaseM3ExtensionSchema` below.
52
+ *
53
+ * - shareable: defaults to true.
54
+ * - share_excluded_paths: string[] (defaults to []).
55
+ * - desktop_visible: defaults to true.
56
+ * - export_bundle_format: constant "peaks.bundle/1" (CLI-written).
57
+ */
58
+ export const LOOP_RELEASE_M3_FIELDS = [
59
+ "shareable",
60
+ "share_excluded_paths",
61
+ "desktop_visible",
62
+ "export_bundle_format",
63
+ ];
64
+ /**
65
+ * M3 share / desktop extension schema. Added to `LoopReleaseInputSchema`
66
+ * via `.extend(...)` so existing callers that omit these fields still
67
+ * parse — the Zod defaults below supply the spec values
68
+ * (true / [] / true / "peaks.bundle/1").
69
+ *
70
+ * `export_bundle_format` is pinned to a literal per spec §7A.2: the
71
+ * CLI is the only writer and only `"peaks.bundle/1"` is accepted. A
72
+ * schema-version bump is required to introduce another value.
73
+ */
74
+ export const LoopReleaseM3ExtensionSchema = z.object({
75
+ shareable: z.boolean().default(true),
76
+ share_excluded_paths: z
77
+ .array(z.string().min(1).max(4096))
78
+ .default([]),
79
+ desktop_visible: z.boolean().default(true),
80
+ export_bundle_format: z
81
+ .literal("peaks.bundle/1")
82
+ .default("peaks.bundle/1"),
83
+ });
84
+ /**
85
+ * Zod schema for the create payload (LoopReleaseInput). Mirrors the
86
+ * §4.1 row shape; `schema_version` is defaulted (clients cannot
87
+ * override it) and `created_at` is not part of the input — the store
88
+ * stamps it from the server clock.
89
+ */
90
+ export const LoopReleaseInputSchema = z
91
+ .object({
92
+ id: z
93
+ .string()
94
+ .min(1)
95
+ .max(64)
96
+ .regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/, {
97
+ message: "id must be kebab-case starting with a lowercase letter (e.g. loop-onboarding-research)",
98
+ }),
99
+ name: z.string().min(1).max(200),
100
+ scenario: z.string().trim().min(1).max(4000),
101
+ trigger_policy: z.string().trim().min(1).max(2000),
102
+ success_criteria: z
103
+ .array(z.string().trim().min(1).max(1000))
104
+ .min(1, "success_criteria must list at least one declarative criterion"),
105
+ interaction_policy: z
106
+ .string()
107
+ .trim()
108
+ .min(1, "interaction_policy must declare human-NL-choice-only semantics")
109
+ .max(2000),
110
+ feedback_policy: z.string().trim().min(1).max(2000),
111
+ evolution_policy: z.string().trim().min(1).max(2000),
112
+ evaluator_policy: z.array(z.string().trim().min(1).max(1000)).min(1),
113
+ linked_bees: z.array(z.string().min(1).max(64)).default([]),
114
+ run_history: z.array(z.string().min(1).max(128)).default([]),
115
+ crystallization_evidence: z.array(z.string().min(1).max(128)).default([]),
116
+ lifecycle_status: LoopReleaseLifecycleStatusSchema,
117
+ version: z
118
+ .string()
119
+ .regex(/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/, {
120
+ message: "version must be a semver string (e.g. 0.1.0)",
121
+ }),
122
+ })
123
+ .extend(LoopReleaseM3ExtensionSchema.shape);
124
+ /**
125
+ * Full Zod schema for a LoopRelease row as persisted. Differs from the
126
+ * input schema only in that `schema_version` is exposed (and defaulted
127
+ * to the fixed literal). The literal constraint still rejects any
128
+ * client-supplied value other than `"peaks.loop/1"`; the default
129
+ * means omitting the key is fine and the output always carries the
130
+ * constant.
131
+ *
132
+ * We expose this as the canonical "row schema" used by lint and
133
+ * service.create/read paths.
134
+ */
135
+ export const LoopReleaseSchema = LoopReleaseInputSchema.extend({
136
+ schema_version: z
137
+ .literal("peaks.loop/1")
138
+ .default("peaks.loop/1"),
139
+ });
140
+ /**
141
+ * Convenience: strict-parse an unknown payload into a LoopRelease row.
142
+ * Throws ZodError on failure. This is the public validation boundary.
143
+ */
144
+ export function parseLoopRelease(input) {
145
+ return LoopReleaseSchema.parse(input);
146
+ }
147
+ /**
148
+ * Convenience: safe-parse that returns a Result-like shape so callers
149
+ * (CLI layer in M5) can render findings without try/catch noise.
150
+ */
151
+ export function safeParseLoopRelease(input) {
152
+ const r = LoopReleaseSchema.safeParse(input);
153
+ if (r.success)
154
+ return { ok: true, row: r.data };
155
+ return {
156
+ ok: false,
157
+ findings: r.error.issues.map((i) => ({
158
+ path: i.path.join("."),
159
+ message: i.message,
160
+ })),
161
+ };
162
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * bundle-reader.ts — readBundle(inPath) (spec §7A.2).
3
+ *
4
+ * M7 / spec §7A.2 / §10 RL-9 / acceptance AC-25 / AC-26.
5
+ *
6
+ * Reads a `peaks.bundle/1` tar.gz and lands the contained release
7
+ * on the local SkillHub. The reader is the symmetrical counterpart
8
+ * of `bundle-writer.ts` — same layout, same content-addressed
9
+ * blobs/, but with three hard guards:
10
+ *
11
+ * 1. `format_version_major !== 1` is a HARD block. The reader
12
+ * throws `SHARE_BUNDLE_MAJOR_VERSION_MISMATCH` before any
13
+ * SQL side-effect. (Major-version bumps are reserved for
14
+ * breaking schema changes; the receiver is not assumed to
15
+ * know how to translate.)
16
+ * 2. `format_version_minor` mismatch is a non-fatal warn (the
17
+ * reader collects it as a warning on the return envelope).
18
+ * 3. The imported release ALWAYS lands as `candidate`. The
19
+ * reader refuses to write any other status; the receiver
20
+ * MUST run an independent evaluation before promoting the
21
+ * imported release to `stable` (AC-26 — peaks loop promote
22
+ * reads evolution_evaluation rows).
23
+ *
24
+ * The reader is also the integration point for AC-26 — the loop
25
+ * promote path (which lives in a future slice / CLI command) checks
26
+ * `evolution_evaluation.independent_scorer_verdict` before allowing
27
+ * a candidate → stable transition; this slice does not add a new
28
+ * `peaks loop promote` because `peaks asset crystallize` already
29
+ * enforces the brief-section + pre-run gates and creates the
30
+ * initial `candidate` row. The integration test for AC-26 verifies
31
+ * that a freshly imported bundle has no `evolution_evaluation`
32
+ * row and that promotion therefore cannot proceed.
33
+ */
34
+ import type Database from "better-sqlite3";
35
+ import { SHARE_BUNDLE_ERROR_CODES, type PeaksBundleKind } from "./bundle-types.js";
36
+ /**
37
+ * Thrown when `format_version_major !== 1`. This is the explicit
38
+ * HARD block per spec §7A.2 (major mismatch).
39
+ */
40
+ export declare class BundleMajorVersionMismatchError extends Error {
41
+ readonly code: typeof SHARE_BUNDLE_ERROR_CODES.MAJOR_VERSION_MISMATCH;
42
+ readonly receivedMajor: number;
43
+ constructor(receivedMajor: number);
44
+ }
45
+ /**
46
+ * Thrown when the schema-versions mapping is missing or carries
47
+ * non-canonical literals.
48
+ */
49
+ export declare class BundleSchemaVersionsMismatchError extends Error {
50
+ readonly code: typeof SHARE_BUNDLE_ERROR_CODES.SCHEMA_VERSIONS_MISMATCH;
51
+ readonly received: Record<string, unknown> | undefined;
52
+ constructor(received: Record<string, unknown> | undefined);
53
+ }
54
+ /**
55
+ * Thrown when the caller asks to land as anything other than
56
+ * `candidate` (the only allowed target status).
57
+ */
58
+ export declare class BundleImportToStableForbiddenError extends Error {
59
+ readonly code: typeof SHARE_BUNDLE_ERROR_CODES.IMPORT_TO_STABLE_FORBIDDEN;
60
+ constructor(receivedStatus: string);
61
+ }
62
+ /**
63
+ * Thrown when the bundle tarball is malformed (no manifest.json,
64
+ * bad JSON, etc.). Distinct from a ZodError so the CLI can map
65
+ * to a single BUNDLE_MALFORMED code.
66
+ */
67
+ export declare class BundleMalformedError extends Error {
68
+ readonly code: typeof SHARE_BUNDLE_ERROR_CODES.BUNDLE_MALFORMED;
69
+ constructor(message: string);
70
+ }
71
+ export type ReadBundleArgs = {
72
+ db: Database.Database;
73
+ /** Blobs root for content-addressed file write-back. */
74
+ blobsDir: string;
75
+ /** Input `.tar.gz` bundle path. */
76
+ inPath: string;
77
+ /**
78
+ * Optional rename for the anchor asset on import. For `loop`
79
+ * bundles this is the loop id to overwrite the source id; for
80
+ * `bee` bundles this is the `--as` bee name.
81
+ */
82
+ asName?: string;
83
+ };
84
+ /**
85
+ * Successful read result. The reader lands the bundle as a
86
+ * `candidate` regardless of any other lifecycle status on the
87
+ * source — this is the hard import rule per spec §7A.2 / AC-25.
88
+ */
89
+ export type ReadBundleResult = {
90
+ /** Anchor asset id actually written. */
91
+ assetId: string | number;
92
+ kind: PeaksBundleKind;
93
+ /** Always `candidate` — the reader does not honor any other status. */
94
+ importedAs: "candidate";
95
+ /** Non-fatal warnings (e.g. minor-version mismatch). */
96
+ warnings: string[];
97
+ /** Count of crystallization_event rows imported. */
98
+ evidenceBriefCount: number;
99
+ };
100
+ export declare function readBundle(args: ReadBundleArgs): ReadBundleResult;