memkin 0.4.2 → 0.4.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 (149) hide show
  1. package/dist/apply/candidate-selection.d.ts +60 -0
  2. package/dist/apply/candidate-selection.d.ts.map +1 -0
  3. package/dist/apply/candidate-selection.js +159 -0
  4. package/dist/apply/candidate-selection.js.map +1 -0
  5. package/dist/apply/cutover.d.ts +45 -0
  6. package/dist/apply/cutover.d.ts.map +1 -0
  7. package/dist/apply/cutover.js +85 -0
  8. package/dist/apply/cutover.js.map +1 -0
  9. package/dist/apply/engine.d.ts +34 -0
  10. package/dist/apply/engine.d.ts.map +1 -0
  11. package/dist/apply/engine.js +255 -0
  12. package/dist/apply/engine.js.map +1 -0
  13. package/dist/apply/ids.d.ts +9 -0
  14. package/dist/apply/ids.d.ts.map +1 -0
  15. package/dist/apply/ids.js +0 -0
  16. package/dist/apply/ids.js.map +1 -0
  17. package/dist/apply/page-content.d.ts +14 -0
  18. package/dist/apply/page-content.d.ts.map +1 -0
  19. package/dist/apply/page-content.js +0 -0
  20. package/dist/apply/page-content.js.map +1 -0
  21. package/dist/apply/rematerialize.d.ts +13 -0
  22. package/dist/apply/rematerialize.d.ts.map +1 -0
  23. package/dist/apply/rematerialize.js +150 -0
  24. package/dist/apply/rematerialize.js.map +1 -0
  25. package/dist/apply/rollback.d.ts +20 -0
  26. package/dist/apply/rollback.d.ts.map +1 -0
  27. package/dist/apply/rollback.js +117 -0
  28. package/dist/apply/rollback.js.map +1 -0
  29. package/dist/apply/shadow-runner.d.ts +47 -0
  30. package/dist/apply/shadow-runner.d.ts.map +1 -0
  31. package/dist/apply/shadow-runner.js +84 -0
  32. package/dist/apply/shadow-runner.js.map +1 -0
  33. package/dist/apply/types.d.ts +51 -0
  34. package/dist/apply/types.d.ts.map +1 -0
  35. package/dist/apply/types.js +13 -0
  36. package/dist/apply/types.js.map +1 -0
  37. package/dist/cli.js +8 -6
  38. package/dist/cli.js.map +1 -1
  39. package/dist/consolidator/consolidator.d.ts +21 -2
  40. package/dist/consolidator/consolidator.d.ts.map +1 -1
  41. package/dist/consolidator/consolidator.js +16 -1
  42. package/dist/consolidator/consolidator.js.map +1 -1
  43. package/dist/core/config.d.ts +42 -0
  44. package/dist/core/config.d.ts.map +1 -1
  45. package/dist/core/config.js +25 -0
  46. package/dist/core/config.js.map +1 -1
  47. package/dist/core/pipeline.d.ts +26 -1
  48. package/dist/core/pipeline.d.ts.map +1 -1
  49. package/dist/core/pipeline.js +26 -0
  50. package/dist/core/pipeline.js.map +1 -1
  51. package/dist/core/schemas.d.ts +16 -16
  52. package/dist/daemon/serve-runtime.d.ts +1 -1
  53. package/dist/daemon/serve-runtime.d.ts.map +1 -1
  54. package/dist/daemon/serve-runtime.js +26 -1
  55. package/dist/daemon/serve-runtime.js.map +1 -1
  56. package/dist/distiller/authority-matrix.d.ts +22 -0
  57. package/dist/distiller/authority-matrix.d.ts.map +1 -0
  58. package/dist/distiller/authority-matrix.js +29 -0
  59. package/dist/distiller/authority-matrix.js.map +1 -0
  60. package/dist/distiller/contract.d.ts +1427 -0
  61. package/dist/distiller/contract.d.ts.map +1 -0
  62. package/dist/distiller/contract.js +166 -0
  63. package/dist/distiller/contract.js.map +1 -0
  64. package/dist/distiller/index.d.ts +83 -0
  65. package/dist/distiller/index.d.ts.map +1 -0
  66. package/dist/distiller/index.js +226 -0
  67. package/dist/distiller/index.js.map +1 -0
  68. package/dist/distiller/map-reduce.d.ts +81 -0
  69. package/dist/distiller/map-reduce.d.ts.map +1 -0
  70. package/dist/distiller/map-reduce.js +92 -0
  71. package/dist/distiller/map-reduce.js.map +1 -0
  72. package/dist/distiller/msg-id.d.ts +55 -0
  73. package/dist/distiller/msg-id.d.ts.map +1 -0
  74. package/dist/distiller/msg-id.js +91 -0
  75. package/dist/distiller/msg-id.js.map +1 -0
  76. package/dist/distiller/payload-privacy.d.ts +18 -0
  77. package/dist/distiller/payload-privacy.d.ts.map +1 -0
  78. package/dist/distiller/payload-privacy.js +51 -0
  79. package/dist/distiller/payload-privacy.js.map +1 -0
  80. package/dist/distiller/prompt.d.ts +28 -0
  81. package/dist/distiller/prompt.d.ts.map +1 -0
  82. package/dist/distiller/prompt.js +69 -0
  83. package/dist/distiller/prompt.js.map +1 -0
  84. package/dist/distiller/raw-privacy.d.ts +55 -0
  85. package/dist/distiller/raw-privacy.d.ts.map +1 -0
  86. package/dist/distiller/raw-privacy.js +123 -0
  87. package/dist/distiller/raw-privacy.js.map +1 -0
  88. package/dist/distiller/segmenter.d.ts +40 -0
  89. package/dist/distiller/segmenter.d.ts.map +1 -0
  90. package/dist/distiller/segmenter.js +75 -0
  91. package/dist/distiller/segmenter.js.map +1 -0
  92. package/dist/embedded-assets.generated.d.ts.map +1 -1
  93. package/dist/embedded-assets.generated.js +5 -4
  94. package/dist/embedded-assets.generated.js.map +1 -1
  95. package/dist/eval/golden.d.ts +12 -12
  96. package/dist/extractors/providers/index.d.ts +1 -0
  97. package/dist/extractors/providers/index.d.ts.map +1 -1
  98. package/dist/extractors/providers/index.js +17 -1
  99. package/dist/extractors/providers/index.js.map +1 -1
  100. package/dist/server/api.d.ts.map +1 -1
  101. package/dist/server/api.js +6 -1
  102. package/dist/server/api.js.map +1 -1
  103. package/dist/server/serve.d.ts +20 -0
  104. package/dist/server/serve.d.ts.map +1 -0
  105. package/dist/server/serve.js +70 -0
  106. package/dist/server/serve.js.map +1 -0
  107. package/dist/server/setup-server.d.ts.map +1 -1
  108. package/dist/server/setup-server.js +38 -38
  109. package/dist/server/setup-server.js.map +1 -1
  110. package/dist/setup/generate-config.d.ts.map +1 -1
  111. package/dist/setup/generate-config.js +3 -0
  112. package/dist/setup/generate-config.js.map +1 -1
  113. package/dist/setup/init-wizard.d.ts.map +1 -1
  114. package/dist/setup/init-wizard.js +2 -1
  115. package/dist/setup/init-wizard.js.map +1 -1
  116. package/dist/setup/validate-config.d.ts +2 -1
  117. package/dist/setup/validate-config.d.ts.map +1 -1
  118. package/dist/setup/validate-config.js.map +1 -1
  119. package/dist/store/agent-sessions.d.ts.map +1 -1
  120. package/dist/store/agent-sessions.js +3 -1
  121. package/dist/store/agent-sessions.js.map +1 -1
  122. package/dist/store/distilled-payload.d.ts +50 -0
  123. package/dist/store/distilled-payload.d.ts.map +1 -0
  124. package/dist/store/distilled-payload.js +117 -0
  125. package/dist/store/distilled-payload.js.map +1 -0
  126. package/dist/store/engine-factory.d.ts.map +1 -1
  127. package/dist/store/engine-factory.js +8 -1
  128. package/dist/store/engine-factory.js.map +1 -1
  129. package/dist/store/migrations/index.d.ts.map +1 -1
  130. package/dist/store/migrations/index.js +139 -0
  131. package/dist/store/migrations/index.js.map +1 -1
  132. package/dist/store/search.d.ts.map +1 -1
  133. package/dist/store/search.js +15 -8
  134. package/dist/store/search.js.map +1 -1
  135. package/dist/store/source-filter.d.ts +19 -0
  136. package/dist/store/source-filter.d.ts.map +1 -0
  137. package/dist/store/source-filter.js +44 -0
  138. package/dist/store/source-filter.js.map +1 -0
  139. package/dist/store/timeline.d.ts.map +1 -1
  140. package/dist/store/timeline.js +15 -8
  141. package/dist/store/timeline.js.map +1 -1
  142. package/dist/synth/scope.d.ts.map +1 -1
  143. package/dist/synth/scope.js +10 -4
  144. package/dist/synth/scope.js.map +1 -1
  145. package/package.json +2 -1
  146. package/web/dist/assets/index-Cie2dVF3.js +5167 -0
  147. package/web/dist/assets/index-diZtO98v.css +2 -0
  148. package/web/dist/assets/newsreader-T5L87s1n.woff2 +0 -0
  149. package/web/dist/index.html +19 -0
@@ -0,0 +1,60 @@
1
+ import type { DistilledSignal } from "../distiller/contract.js";
2
+ import type { StoredPayload } from "../store/distilled-payload.js";
3
+ import type { SqlConn } from "../store/sql-executor.js";
4
+ import { type ApplyAction, type ApplyPlanData, type ApplyTarget, type Candidate } from "./types.js";
5
+ export declare const DEFAULT_CANDIDATE_LIMIT = 5;
6
+ /** The LLM's decision for one signal against its candidate set. */
7
+ export interface CandidateDecision {
8
+ action: ApplyAction;
9
+ target_slug?: string | null;
10
+ reason?: string;
11
+ }
12
+ /** Pluggable decider — a thin LLM seam so tests can mock it deterministically. */
13
+ export interface CandidateDecider {
14
+ decide(input: {
15
+ signal: DistilledSignal;
16
+ candidates: Candidate[];
17
+ target: ApplyTarget;
18
+ }): Promise<CandidateDecision>;
19
+ }
20
+ /** Source of candidate pages, scoped to one target schema. */
21
+ export interface CandidateRepository {
22
+ findCandidates(signal: DistilledSignal, limit: number): Promise<Candidate[]>;
23
+ }
24
+ /**
25
+ * Read candidate pages from a target schema. Trigram-ranked against the signal's
26
+ * topic + what, restricted to the v2 candidate pool (spec §3.1 / §7).
27
+ */
28
+ export declare class SchemaCandidateRepository implements CandidateRepository {
29
+ private readonly pg;
30
+ private readonly schema;
31
+ constructor(pg: SqlConn, target: ApplyTarget);
32
+ findCandidates(signal: DistilledSignal, limit: number): Promise<Candidate[]>;
33
+ }
34
+ /**
35
+ * Build the apply plan for one payload against one target. Pure orchestration —
36
+ * no writes; the returned data is what ApplyPlanStore.save persists.
37
+ */
38
+ export declare function buildApplyPlan(params: {
39
+ payload: StoredPayload;
40
+ target: ApplyTarget;
41
+ repo: CandidateRepository;
42
+ decider: CandidateDecider;
43
+ candidateLimit?: number;
44
+ }): Promise<ApplyPlanData>;
45
+ export interface StoredApplyPlan {
46
+ id: number;
47
+ payloadId: number;
48
+ target: ApplyTarget;
49
+ data: ApplyPlanData;
50
+ }
51
+ /** Persists / retrieves frozen apply plans (one per payload+target). */
52
+ export declare class ApplyPlanStore {
53
+ private readonly pg;
54
+ constructor(pg: SqlConn);
55
+ /** Upsert the plan for (payload_id, target); returns the plan id. */
56
+ save(data: ApplyPlanData): Promise<number>;
57
+ getById(id: number): Promise<StoredApplyPlan | null>;
58
+ getByPayloadTarget(payloadId: number, target: ApplyTarget): Promise<StoredApplyPlan | null>;
59
+ }
60
+ //# sourceMappingURL=candidate-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-selection.d.ts","sourceRoot":"","sources":["../../src/apply/candidate-selection.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,SAAS,EAGf,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAGzC,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,KAAK,EAAE;QACZ,MAAM,EAAE,eAAe,CAAC;QACxB,UAAU,EAAE,SAAS,EAAE,CAAC;QACxB,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAChC;AAED,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IAClC,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;CAC9E;AAQD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,mBAAmB;IAIjE,OAAO,CAAC,QAAQ,CAAC,EAAE;IAHrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAGb,EAAE,EAAE,OAAO,EAC5B,MAAM,EAAE,WAAW;IAKf,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAuCnF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAC3C,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,aAAa,CAAC,CAuEzB;AAUD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,aAAa,CAAC;CACrB;AAOD,wEAAwE;AACxE,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,OAAO;IAExC,qEAAqE;IAC/D,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAW1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAKpD,kBAAkB,CACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAOnC"}
@@ -0,0 +1,159 @@
1
+ // src/apply/candidate-selection.ts
2
+ //
3
+ // Restricted upsert candidate selection (spec §7). For each signal in a
4
+ // distilled payload this picks one of five actions —
5
+ // NEW | UPDATE | SUPERSEDE | LINK_EXISTING | NOOP — against a top-5 candidate
6
+ // pool drawn from the CURRENT TARGET's schema (staging candidates ≠ production
7
+ // candidates). The result is frozen into an apply_plan(payload_id, target); the
8
+ // apply engine later replays that plan WITHOUT calling the LLM again (spec §6.2).
9
+ //
10
+ // Guardrails:
11
+ // - Authority admissibility (spec §5): session-log-only signals become NOOP
12
+ // and never reach the LLM (no candidate page is created for them).
13
+ // - Candidate pool is restricted (pre-legacy-cleanup) to v2-pipeline pages +
14
+ // identity entity pages (spec §3.1).
15
+ // - Restricted actions (UPDATE/SUPERSEDE/LINK_EXISTING) must reference a slug
16
+ // that is actually in the offered candidate set; an out-of-pool pick is
17
+ // coerced to NEW so the LLM can never point at an arbitrary page.
18
+ import { admissibility } from "../distiller/authority-matrix.js";
19
+ import { contributionId, normalizeTopic, signalFamilyKey } from "./ids.js";
20
+ import { ENTITY_PAGE_TYPES, } from "./types.js";
21
+ export const DEFAULT_CANDIDATE_LIMIT = 5;
22
+ const BODY_TRUNCATE = 1000;
23
+ function truncate(s) {
24
+ return s.length > BODY_TRUNCATE ? `${s.slice(0, BODY_TRUNCATE)}…` : s;
25
+ }
26
+ const RESTRICTED_ACTIONS = new Set(["UPDATE", "SUPERSEDE", "LINK_EXISTING"]);
27
+ /**
28
+ * Read candidate pages from a target schema. Trigram-ranked against the signal's
29
+ * topic + what, restricted to the v2 candidate pool (spec §3.1 / §7).
30
+ */
31
+ export class SchemaCandidateRepository {
32
+ pg;
33
+ schema;
34
+ constructor(pg, target) {
35
+ this.pg = pg;
36
+ this.schema = target === "staging" ? "staging" : "public";
37
+ }
38
+ async findCandidates(signal, limit) {
39
+ const probe = `${signal.topic} ${signal.what}`.trim();
40
+ const rows = await this.pg.query(`SELECT p.slug, p.title,
41
+ LEFT(p.compiled_truth, ${BODY_TRUNCATE}) AS body,
42
+ p.updated_at::text AS updated_at,
43
+ p.content_hash,
44
+ p.frontmatter->>'project' AS project,
45
+ (
46
+ SELECT COALESCE(string_agg(mc.signal->>'what', '; '), '')
47
+ FROM ${this.schema}.memory_contributions mc
48
+ WHERE mc.canonical_page_id = p.id AND mc.active
49
+ ) AS contributions_summary
50
+ FROM ${this.schema}.pages p
51
+ WHERE (p.frontmatter->>'pipeline' = 'v2' OR p.type = ANY($2::text[]))
52
+ AND GREATEST(similarity(p.title, $1), similarity(p.compiled_truth, $1)) > 0
53
+ ORDER BY GREATEST(similarity(p.title, $1), similarity(p.compiled_truth, $1)) DESC,
54
+ p.updated_at DESC
55
+ LIMIT $3`, [probe, ENTITY_PAGE_TYPES, limit]);
56
+ return rows.rows.map((r) => ({
57
+ slug: r.slug,
58
+ title: r.title,
59
+ body: truncate(r.body ?? ""),
60
+ updated_at: r.updated_at,
61
+ content_hash: r.content_hash,
62
+ project: r.project,
63
+ contributions_summary: r.contributions_summary ?? "",
64
+ }));
65
+ }
66
+ }
67
+ /**
68
+ * Build the apply plan for one payload against one target. Pure orchestration —
69
+ * no writes; the returned data is what ApplyPlanStore.save persists.
70
+ */
71
+ export async function buildApplyPlan(params) {
72
+ const { payload, target, repo, decider } = params;
73
+ const limit = params.candidateLimit ?? DEFAULT_CANDIDATE_LIMIT;
74
+ const actions = [];
75
+ const signals = payload.payload.signals;
76
+ for (let i = 0; i < signals.length; i++) {
77
+ const signal = signals[i];
78
+ const normalizedTopic = normalizeTopic(signal.topic);
79
+ const cid = contributionId(payload.revisionId, signal.type, normalizedTopic);
80
+ const fam = signalFamilyKey(payload.sourceInstance, payload.sessionId, signal.type, normalizedTopic);
81
+ const base = {
82
+ signal_index: i,
83
+ signal,
84
+ contribution_id: cid,
85
+ signal_family_key: fam,
86
+ normalized_topic: normalizedTopic,
87
+ };
88
+ // Authority gate (spec §5): session-log-only signals never create a page.
89
+ if (admissibility(signal.type, signal.authority) === "session_log_only") {
90
+ actions.push({
91
+ ...base,
92
+ action: "NOOP",
93
+ target_slug: null,
94
+ target_content_hash: null,
95
+ candidates: [],
96
+ reason: "session_log_only (authority admissibility)",
97
+ });
98
+ continue;
99
+ }
100
+ const candidates = await repo.findCandidates(signal, limit);
101
+ const decision = await decider.decide({ signal, candidates, target });
102
+ let action = decision.action;
103
+ let targetSlug = decision.target_slug ?? null;
104
+ let reason = decision.reason ?? "";
105
+ let contentHash = null;
106
+ if (RESTRICTED_ACTIONS.has(action)) {
107
+ const match = candidates.find((c) => c.slug === targetSlug);
108
+ if (!match) {
109
+ // Out-of-pool pick — coerce to NEW rather than trust an arbitrary slug.
110
+ action = "NEW";
111
+ targetSlug = null;
112
+ reason = `${reason} [coerced to NEW: target not in candidate pool]`.trim();
113
+ }
114
+ else {
115
+ contentHash = match.content_hash;
116
+ }
117
+ }
118
+ else if (action === "NOOP") {
119
+ targetSlug = null;
120
+ }
121
+ actions.push({
122
+ ...base,
123
+ action,
124
+ target_slug: targetSlug,
125
+ target_content_hash: contentHash,
126
+ candidates,
127
+ reason,
128
+ });
129
+ }
130
+ return { payload_id: payload.id, target, actions };
131
+ }
132
+ function parsePlan(row) {
133
+ const data = typeof row.plan === "string" ? JSON.parse(row.plan) : row.plan;
134
+ return { id: row.id, payloadId: row.payload_id, target: row.target, data };
135
+ }
136
+ /** Persists / retrieves frozen apply plans (one per payload+target). */
137
+ export class ApplyPlanStore {
138
+ pg;
139
+ constructor(pg) {
140
+ this.pg = pg;
141
+ }
142
+ /** Upsert the plan for (payload_id, target); returns the plan id. */
143
+ async save(data) {
144
+ const r = await this.pg.query(`INSERT INTO apply_plan (payload_id, target, plan)
145
+ VALUES ($1, $2, $3::jsonb)
146
+ ON CONFLICT (payload_id, target) DO UPDATE SET plan = EXCLUDED.plan
147
+ RETURNING id`, [data.payload_id, data.target, JSON.stringify(data)]);
148
+ return r.rows[0].id;
149
+ }
150
+ async getById(id) {
151
+ const r = await this.pg.query("SELECT * FROM apply_plan WHERE id = $1", [id]);
152
+ return r.rows[0] ? parsePlan(r.rows[0]) : null;
153
+ }
154
+ async getByPayloadTarget(payloadId, target) {
155
+ const r = await this.pg.query("SELECT * FROM apply_plan WHERE payload_id = $1 AND target = $2", [payloadId, target]);
156
+ return r.rows[0] ? parsePlan(r.rows[0]) : null;
157
+ }
158
+ }
159
+ //# sourceMappingURL=candidate-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-selection.js","sourceRoot":"","sources":["../../src/apply/candidate-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { AgentPipelineMode } from "../core/config.js";
2
+ import type { SqlExecutor } from "../store/sql-executor.js";
3
+ import { type CandidateDecider, type CandidateRepository } from "./candidate-selection.js";
4
+ import { type ApplyOutcome } from "./engine.js";
5
+ import { type RollbackOutcome } from "./rollback.js";
6
+ export interface CutoverDeps {
7
+ executor: SqlExecutor;
8
+ /** Decides the restricted upsert action per signal (LLM seam; mockable). */
9
+ decider: CandidateDecider;
10
+ /** Override the production candidate repository (defaults to the public schema). */
11
+ repo?: CandidateRepository;
12
+ candidateLimit?: number;
13
+ }
14
+ export interface CutoverOutcome {
15
+ payloadId: number;
16
+ /** The persisted production apply_plan id (freshly regenerated, not the staging one). */
17
+ planId: number;
18
+ /** The apply engine result (target is always "production"). */
19
+ apply: ApplyOutcome;
20
+ /** True when the apply failed / dead-lettered → flip the source flag to legacy. */
21
+ recommendLegacyFallback: boolean;
22
+ /** The mode to flip back to when recommendLegacyFallback is set. */
23
+ fallbackMode: AgentPipelineMode;
24
+ }
25
+ export interface CutoverRollbackOutcome {
26
+ rollback: RollbackOutcome;
27
+ /** After a rollback, the source flag should return to legacy to stop the bleeding. */
28
+ fallbackMode: AgentPipelineMode;
29
+ }
30
+ export declare class Cutover {
31
+ private readonly deps;
32
+ private readonly payloads;
33
+ private readonly plans;
34
+ private readonly engine;
35
+ private readonly rollbacker;
36
+ constructor(deps: CutoverDeps);
37
+ /** Regenerate the production plan for one existing payload and apply it. */
38
+ run(payloadId: number): Promise<CutoverOutcome>;
39
+ /**
40
+ * Roll back a cutover apply via the PR-4 contributions-based rollback and
41
+ * signal that the source flag should return to legacy (spec §3.1).
42
+ */
43
+ rollback(attemptId: number): Promise<CutoverRollbackOutcome>;
44
+ }
45
+ //# sourceMappingURL=cutover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cutover.d.ts","sourceRoot":"","sources":["../../src/apply/cutover.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAGzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAKpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,WAAW,CAAC;IACtB,4EAA4E;IAC5E,OAAO,EAAE,gBAAgB,CAAC;IAC1B,oFAAoF;IACpF,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,KAAK,EAAE,YAAY,CAAC;IACpB,mFAAmF;IACnF,uBAAuB,EAAE,OAAO,CAAC;IACjC,oEAAoE;IACpE,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,eAAe,CAAC;IAC1B,sFAAsF;IACtF,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAED,qBAAa,OAAO;IAMN,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;gBAEd,IAAI,EAAE,WAAW;IAO9C,4EAA4E;IACtE,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkCrD;;;OAGG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;CAInE"}
@@ -0,0 +1,85 @@
1
+ // src/apply/cutover.ts
2
+ //
3
+ // Cutover (extraction-quality-redesign PR-6, spec §3.1, §11).
4
+ //
5
+ // Promotes an EXISTING distilled payload to production with the SINGLE PR-4 apply
6
+ // engine (target=production). The load-bearing rule (spec §3.1, review R3-3):
7
+ //
8
+ // The staging plan is NEVER reused for production. Candidate page sets,
9
+ // content_hashes, and slug collisions differ between the staging and public
10
+ // schemas, so cutover ALWAYS rebuilds the production candidate selection from
11
+ // scratch (this step is allowed to call the LLM). The distilled payload itself
12
+ // is NOT re-distilled — only the candidate selection is redone.
13
+ //
14
+ // Flow per payload:
15
+ // 1. buildApplyPlan(target=production) — candidate pool from the PUBLIC schema;
16
+ // 2. persist the production apply_plan under (payload_id, target=production);
17
+ // 3. apply via the target-agnostic ApplyEngine (one transaction, CAS + retry).
18
+ //
19
+ // Stop-the-bleeding: cutover is flag-gated (agent_pipeline=new). If an apply
20
+ // fails or dead-letters, `recommendLegacyFallback` is set and `fallbackMode` is
21
+ // "legacy" so the operator can flip the source flag back to legacy. The same
22
+ // applies to a triggered rollback (spec §3.1): `rollback()` undoes the apply via
23
+ // the PR-4 contributions-based ApplyRollback and returns fallbackMode "legacy".
24
+ import { DistilledPayloadStore } from "../store/distilled-payload.js";
25
+ import { ApplyPlanStore, buildApplyPlan, SchemaCandidateRepository, } from "./candidate-selection.js";
26
+ import { ApplyEngine } from "./engine.js";
27
+ import { ApplyRollback } from "./rollback.js";
28
+ /** The mode an operator flips back to when a cutover apply/rollback fires. */
29
+ const LEGACY_FALLBACK_MODE = "legacy";
30
+ export class Cutover {
31
+ deps;
32
+ payloads;
33
+ plans;
34
+ engine;
35
+ rollbacker;
36
+ constructor(deps) {
37
+ this.deps = deps;
38
+ this.payloads = new DistilledPayloadStore(deps.executor);
39
+ this.plans = new ApplyPlanStore(deps.executor);
40
+ this.engine = new ApplyEngine(deps.executor);
41
+ this.rollbacker = new ApplyRollback(deps.executor);
42
+ }
43
+ /** Regenerate the production plan for one existing payload and apply it. */
44
+ async run(payloadId) {
45
+ const payload = await this.payloads.getById(payloadId);
46
+ if (!payload)
47
+ throw new Error(`cutover: payload ${payloadId} not found`);
48
+ // Rebuild the production candidate selection from scratch — never reuse the
49
+ // staging plan (candidate pools differ per target, spec §3.1). This does NOT
50
+ // re-distill: it only re-decides candidates against the production schema.
51
+ const repo = this.deps.repo ?? new SchemaCandidateRepository(this.deps.executor, "production");
52
+ const planData = await buildApplyPlan({
53
+ payload,
54
+ target: "production",
55
+ repo,
56
+ decider: this.deps.decider,
57
+ candidateLimit: this.deps.candidateLimit,
58
+ });
59
+ const planId = await this.plans.save(planData);
60
+ const plan = {
61
+ id: planId,
62
+ payloadId,
63
+ target: "production",
64
+ data: planData,
65
+ };
66
+ const apply = await this.engine.apply(plan);
67
+ const recommendLegacyFallback = apply.status !== "applied";
68
+ return {
69
+ payloadId,
70
+ planId,
71
+ apply,
72
+ recommendLegacyFallback,
73
+ fallbackMode: LEGACY_FALLBACK_MODE,
74
+ };
75
+ }
76
+ /**
77
+ * Roll back a cutover apply via the PR-4 contributions-based rollback and
78
+ * signal that the source flag should return to legacy (spec §3.1).
79
+ */
80
+ async rollback(attemptId) {
81
+ const rollback = await this.rollbacker.rollback(attemptId);
82
+ return { rollback, fallbackMode: LEGACY_FALLBACK_MODE };
83
+ }
84
+ }
85
+ //# sourceMappingURL=cutover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cutover.js","sourceRoot":"","sources":["../../src/apply/cutover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { SqlExecutor } from "../store/sql-executor.js";
2
+ import type { StoredApplyPlan } from "./candidate-selection.js";
3
+ import type { ApplyAction, ApplyTarget } from "./types.js";
4
+ export interface ApplyOutcome {
5
+ attemptId: number;
6
+ status: "applied" | "failed" | "dead_letter";
7
+ target: ApplyTarget;
8
+ applied: {
9
+ slug: string;
10
+ action: ApplyAction;
11
+ }[];
12
+ retried: boolean;
13
+ replay: boolean;
14
+ error?: string;
15
+ }
16
+ export declare class ApplyEngine {
17
+ private readonly ex;
18
+ constructor(ex: SqlExecutor);
19
+ /**
20
+ * Apply a frozen plan. Idempotent per plan; target-parameterized; single
21
+ * transaction; CAS with one retry then dead_letter.
22
+ */
23
+ apply(plan: StoredApplyPlan): Promise<ApplyOutcome>;
24
+ private loadPayloadMeta;
25
+ private runTransaction;
26
+ private applyAction;
27
+ /** Lock the target row and enforce the plan-snapshot CAS (spec §7). */
28
+ private lockForCas;
29
+ /** Insert (or reactivate) the page row; journal a brand-new page for rollback. */
30
+ private ensurePage;
31
+ private markSuperseded;
32
+ private attachContribution;
33
+ }
34
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/apply/engine.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AA8B1E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC7C,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,EAAE,CAAC;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,WAAW;IAE5C;;;OAGG;IACG,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;YA2E3C,eAAe;YAoBf,cAAc;YAmBd,WAAW;IAoDzB,uEAAuE;YACzD,UAAU;IAiBxB,kFAAkF;YACpE,UAAU;YAsBV,cAAc;YAsBd,kBAAkB;CAwCjC"}