rememberstack 0.1.0__py3-none-any.whl

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 (186) hide show
  1. rememberstack/__init__.py +9 -0
  2. rememberstack/adapters/__init__.py +42 -0
  3. rememberstack/adapters/codex_writer.py +221 -0
  4. rememberstack/adapters/markitdown_converter.py +42 -0
  5. rememberstack/adapters/openrouter.py +136 -0
  6. rememberstack/adapters/selfhost/__init__.py +54 -0
  7. rememberstack/adapters/selfhost/forget.py +66 -0
  8. rememberstack/adapters/selfhost/git.py +374 -0
  9. rememberstack/adapters/selfhost/lance.py +328 -0
  10. rememberstack/adapters/selfhost/minio.py +279 -0
  11. rememberstack/adapters/selfhost/mounts.py +249 -0
  12. rememberstack/adapters/selfhost/object_store.py +130 -0
  13. rememberstack/adapters/selfhost/projection.py +80 -0
  14. rememberstack/adapters/selfhost/queue.py +137 -0
  15. rememberstack/adapters/selfhost/telemetry.py +45 -0
  16. rememberstack/adapters/selfhost/watcher.py +70 -0
  17. rememberstack/adapters/testing/__init__.py +15 -0
  18. rememberstack/adapters/testing/cost_meter.py +13 -0
  19. rememberstack/adapters/testing/model_provider.py +83 -0
  20. rememberstack/adapters/testing/queue.py +43 -0
  21. rememberstack/adapters/testing/telemetry.py +22 -0
  22. rememberstack/client.py +19 -0
  23. rememberstack/core/__init__.py +127 -0
  24. rememberstack/core/blockizer.py +189 -0
  25. rememberstack/core/chunker.py +216 -0
  26. rememberstack/core/consumption_skill.py +275 -0
  27. rememberstack/core/conversion.py +76 -0
  28. rememberstack/core/core_manifest.py +598 -0
  29. rememberstack/core/extension_packs.py +124 -0
  30. rememberstack/core/forget.py +17 -0
  31. rememberstack/core/knowledge_authored.py +276 -0
  32. rememberstack/core/knowledge_compile.py +215 -0
  33. rememberstack/core/knowledge_fact_sheet.py +210 -0
  34. rememberstack/core/knowledge_hashing.py +68 -0
  35. rememberstack/core/knowledge_planner.py +64 -0
  36. rememberstack/core/knowledge_writer.py +175 -0
  37. rememberstack/core/ranking.py +200 -0
  38. rememberstack/core/recipe_linter.py +149 -0
  39. rememberstack/core/section_snap.py +209 -0
  40. rememberstack/core/storage_routing.py +27 -0
  41. rememberstack/eval/__init__.py +53 -0
  42. rememberstack/eval/consumption.py +141 -0
  43. rememberstack/eval/contradiction.py +184 -0
  44. rememberstack/eval/harness.py +136 -0
  45. rememberstack/eval/lifecycle.py +400 -0
  46. rememberstack/eval/operational_scale.py +49 -0
  47. rememberstack/eval/resolution.py +255 -0
  48. rememberstack/eval/retrieval_spikes.py +50 -0
  49. rememberstack/eval/skeleton.py +231 -0
  50. rememberstack/llm/__init__.py +1 -0
  51. rememberstack/model/__init__.py +589 -0
  52. rememberstack/model/adjudication.py +100 -0
  53. rememberstack/model/auth.py +27 -0
  54. rememberstack/model/blocks.py +30 -0
  55. rememberstack/model/chunks.py +190 -0
  56. rememberstack/model/claims.py +162 -0
  57. rememberstack/model/client.py +98 -0
  58. rememberstack/model/clustering.py +54 -0
  59. rememberstack/model/component_version.py +124 -0
  60. rememberstack/model/consumption.py +88 -0
  61. rememberstack/model/conversion.py +31 -0
  62. rememberstack/model/deployment.py +53 -0
  63. rememberstack/model/documents.py +168 -0
  64. rememberstack/model/envelope.py +513 -0
  65. rememberstack/model/evaluation.py +72 -0
  66. rememberstack/model/forget.py +143 -0
  67. rememberstack/model/git.py +13 -0
  68. rememberstack/model/knowledge.py +840 -0
  69. rememberstack/model/knowledge_authored.py +325 -0
  70. rememberstack/model/knowledge_planner.py +431 -0
  71. rememberstack/model/lifecycle.py +42 -0
  72. rememberstack/model/model_provider.py +78 -0
  73. rememberstack/model/mounts.py +24 -0
  74. rememberstack/model/object_store.py +21 -0
  75. rememberstack/model/operational_scale.py +59 -0
  76. rememberstack/model/operations.py +153 -0
  77. rememberstack/model/processing.py +228 -0
  78. rememberstack/model/queue.py +73 -0
  79. rememberstack/model/recipes.py +83 -0
  80. rememberstack/model/relations.py +79 -0
  81. rememberstack/model/resolution.py +83 -0
  82. rememberstack/model/retrieval_spikes.py +62 -0
  83. rememberstack/model/sections.py +120 -0
  84. rememberstack/model/telemetry.py +30 -0
  85. rememberstack/ports/__init__.py +29 -0
  86. rememberstack/ports/auth.py +16 -0
  87. rememberstack/ports/connector.py +23 -0
  88. rememberstack/ports/cost_meter.py +17 -0
  89. rememberstack/ports/forget.py +20 -0
  90. rememberstack/ports/git.py +20 -0
  91. rememberstack/ports/model_provider.py +28 -0
  92. rememberstack/ports/mounts.py +16 -0
  93. rememberstack/ports/object_store.py +27 -0
  94. rememberstack/ports/p1_index.py +92 -0
  95. rememberstack/ports/purge.py +93 -0
  96. rememberstack/ports/queue.py +23 -0
  97. rememberstack/ports/telemetry.py +21 -0
  98. rememberstack/profiles/__init__.py +22 -0
  99. rememberstack/profiles/selfhost.py +324 -0
  100. rememberstack/profiles/selfhost_forget.py +158 -0
  101. rememberstack/profiles/selfhost_operations.py +95 -0
  102. rememberstack/py.typed +1 -0
  103. rememberstack/spine/__init__.py +93 -0
  104. rememberstack/spine/admission.py +26 -0
  105. rememberstack/spine/backfill.py +168 -0
  106. rememberstack/spine/catalog_contract.py +742 -0
  107. rememberstack/spine/chunk_catalog.py +237 -0
  108. rememberstack/spine/claim_catalog.py +298 -0
  109. rememberstack/spine/clustering.py +740 -0
  110. rememberstack/spine/component_versions.py +208 -0
  111. rememberstack/spine/consumption.py +81 -0
  112. rememberstack/spine/deployment_bootstrap.py +445 -0
  113. rememberstack/spine/document_catalog.py +621 -0
  114. rememberstack/spine/entity_registry.py +205 -0
  115. rememberstack/spine/extension_packs.py +220 -0
  116. rememberstack/spine/fact_catalog.py +571 -0
  117. rememberstack/spine/forget.py +1753 -0
  118. rememberstack/spine/knowledge.py +5467 -0
  119. rememberstack/spine/lifecycle.py +1071 -0
  120. rememberstack/spine/migrations/__init__.py +1 -0
  121. rememberstack/spine/migrations/_helpers.py +153 -0
  122. rememberstack/spine/migrations/env.py +58 -0
  123. rememberstack/spine/migrations/script.py.mako +27 -0
  124. rememberstack/spine/migrations/versions/__init__.py +1 -0
  125. rememberstack/spine/migrations/versions/p0_02_0001_extensions_enums.py +189 -0
  126. rememberstack/spine/migrations/versions/p0_02_0002_infrastructure_registries.py +321 -0
  127. rememberstack/spine/migrations/versions/p0_02_0003_entities_evaluation_e0_e1.py +631 -0
  128. rememberstack/spine/migrations/versions/p0_02_0004_claims_facts_evidence.py +411 -0
  129. rememberstack/spine/migrations/versions/p0_02_0005_projection_knowledge_retrieval.py +391 -0
  130. rememberstack/spine/migrations/versions/p0_02_0006_partitions_views.py +158 -0
  131. rememberstack/spine/migrations/versions/p2_06_0007_invalidated_outcome.py +26 -0
  132. rememberstack/spine/migrations/versions/p3_01_0008_document_version_target.py +58 -0
  133. rememberstack/spine/migrations/versions/p3_05_0009_reconcile_stage.py +27 -0
  134. rememberstack/spine/migrations/versions/p3_07_0010_lifecycle_eval_suite.py +25 -0
  135. rememberstack/spine/migrations/versions/p4_01_0011_survivor_view_rewrite.py +57 -0
  136. rememberstack/spine/migrations/versions/p6_02_0012_knowledge_compile_recovery.py +58 -0
  137. rememberstack/spine/migrations/versions/p6_04_0013_knowledge_writer_ledger.py +46 -0
  138. rememberstack/spine/migrations/versions/p6_05_0014_knowledge_planner_runtime.py +217 -0
  139. rememberstack/spine/migrations/versions/p6_06_0015_authored_dispatch_runtime.py +38 -0
  140. rememberstack/spine/migrations/versions/p7_02_0016_operational_eval_suite.py +19 -0
  141. rememberstack/spine/migrations/versions/p7_05_0017_hard_forget.py +55 -0
  142. rememberstack/spine/observation_adjudication.py +778 -0
  143. rememberstack/spine/operations.py +298 -0
  144. rememberstack/spine/projection.py +662 -0
  145. rememberstack/spine/recipes.py +276 -0
  146. rememberstack/spine/resolver.py +763 -0
  147. rememberstack/spine/review.py +650 -0
  148. rememberstack/spine/settings.py +22 -0
  149. rememberstack/spine/supersession.py +510 -0
  150. rememberstack/spine/sync.py +128 -0
  151. rememberstack/spine/work_ledger.py +816 -0
  152. rememberstack/surfaces/__init__.py +110 -0
  153. rememberstack/surfaces/cli.py +447 -0
  154. rememberstack/surfaces/consumption_skill.py +87 -0
  155. rememberstack/surfaces/graph_queries.py +698 -0
  156. rememberstack/surfaces/http_api.py +377 -0
  157. rememberstack/surfaces/mcp.py +67 -0
  158. rememberstack/surfaces/query_engine.py +1591 -0
  159. rememberstack/surfaces/recipe_executor.py +185 -0
  160. rememberstack/surfaces/recipe_surface.py +219 -0
  161. rememberstack/surfaces/remote_mcp.py +133 -0
  162. rememberstack/surfaces/sdk.py +324 -0
  163. rememberstack/workers/__init__.py +155 -0
  164. rememberstack/workers/base.py +312 -0
  165. rememberstack/workers/e0.py +577 -0
  166. rememberstack/workers/e1.py +425 -0
  167. rememberstack/workers/e2.py +525 -0
  168. rememberstack/workers/e3.py +434 -0
  169. rememberstack/workers/forget.py +299 -0
  170. rememberstack/workers/knowledge_authored.py +146 -0
  171. rememberstack/workers/knowledge_driver.py +735 -0
  172. rememberstack/workers/knowledge_fact_sheet.py +123 -0
  173. rememberstack/workers/knowledge_planner.py +325 -0
  174. rememberstack/workers/knowledge_writer.py +393 -0
  175. rememberstack/workers/operations.py +42 -0
  176. rememberstack/workers/p1.py +234 -0
  177. rememberstack/workers/p2.py +513 -0
  178. rememberstack/workers/p2_analytics.py +276 -0
  179. rememberstack/workers/p3.py +673 -0
  180. rememberstack/workers/reconcile.py +485 -0
  181. rememberstack/workers/sync.py +168 -0
  182. rememberstack-0.1.0.dist-info/METADATA +213 -0
  183. rememberstack-0.1.0.dist-info/RECORD +186 -0
  184. rememberstack-0.1.0.dist-info/WHEEL +4 -0
  185. rememberstack-0.1.0.dist-info/entry_points.txt +2 -0
  186. rememberstack-0.1.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,27 @@
1
+ """Add the `reconcile` pipeline stage (Phase 3, D54/D55).
2
+
3
+ Reconciliation — currency transitions, the D54 recount, per-shape closure,
4
+ and the `evidence_changed` emission — runs as its own queued stage at the
5
+ end of a version's chain, so it inherits the work ledger's claim/retry/
6
+ idempotency machinery like every other stage (its processing_id doubles as
7
+ the run's `reconciliation_id`, which is what makes a retried run re-emit
8
+ its ledger rows as no-ops).
9
+ """
10
+
11
+ from collections.abc import Sequence
12
+
13
+ from alembic import op
14
+
15
+ revision: str = "p3_05_0009"
16
+ down_revision: str | None = "p3_01_0008"
17
+ branch_labels: str | Sequence[str] | None = None
18
+ depends_on: str | Sequence[str] | None = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ """Append the enum value (additive; existing rows untouched)."""
23
+ op.execute("ALTER TYPE pipeline_stage ADD VALUE IF NOT EXISTS 'reconcile'")
24
+
25
+
26
+ def downgrade() -> None:
27
+ """PostgreSQL cannot remove an enum value in place; additive no-op."""
@@ -0,0 +1,25 @@
1
+ """Add the `lifecycle` eval suite (Phase 3, WP-3.7, D22/D35).
2
+
3
+ The lifecycle pack guards the D54 economy itself: cache-vs-ledger currency
4
+ coherence, cached-count correctness, closure-record coherence, and the
5
+ flag-rate rollout canary — the invariants that must hold on ANY deployment
6
+ state, plus the regression canaries planted by `restore_support` verdicts.
7
+ """
8
+
9
+ from collections.abc import Sequence
10
+
11
+ from alembic import op
12
+
13
+ revision: str = "p3_07_0010"
14
+ down_revision: str | None = "p3_05_0009"
15
+ branch_labels: str | Sequence[str] | None = None
16
+ depends_on: str | Sequence[str] | None = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ """Append the enum value (additive; existing rows untouched)."""
21
+ op.execute("ALTER TYPE eval_suite ADD VALUE IF NOT EXISTS 'lifecycle'")
22
+
23
+
24
+ def downgrade() -> None:
25
+ """PostgreSQL cannot remove an enum value in place; additive no-op."""
@@ -0,0 +1,57 @@
1
+ """Rewrite `v_graph_survivor` without the per-row correlated subquery.
2
+
3
+ The WP-4.1 spike battery caught the shipped form being quadratic when its
4
+ columns are actually materialized: the survivor was picked by a correlated
5
+ `(SELECT … ORDER BY depth DESC LIMIT 1)` per output row over the un-indexed
6
+ recursive CTE — invisible to `count(*)` (dead-column elimination) but
7
+ O(n²) for the real export. At 32k entities the projection export took
8
+ 50.6 s; the `DISTINCT ON` form below produces the identical terminal-row
9
+ semantics in 0.03 s (`plan/analysis/p2_spike_battery.md`). Same columns,
10
+ same cycle guard, same contract — only the plan shape changes.
11
+ """
12
+
13
+ from collections.abc import Sequence
14
+
15
+ from alembic import op
16
+
17
+ revision: str = "p4_01_0011"
18
+ down_revision: str | None = "p3_07_0010"
19
+ branch_labels: str | Sequence[str] | None = None
20
+ depends_on: str | Sequence[str] | None = None
21
+
22
+ _REWRITTEN = """
23
+ CREATE OR REPLACE VIEW v_graph_survivor AS
24
+ WITH RECURSIVE chain(entity_id, cur, depth) AS (
25
+ SELECT entity_id, entity_id, 0 FROM entities
26
+ UNION ALL
27
+ SELECT c.entity_id, e.merged_into, c.depth + 1
28
+ FROM chain c JOIN entities e ON e.entity_id = c.cur
29
+ WHERE e.merged_into IS NOT NULL AND c.depth < 64 -- cycle / runaway guard
30
+ )
31
+ SELECT DISTINCT ON (entity_id) entity_id, cur AS survivor
32
+ FROM chain ORDER BY entity_id, depth DESC -- the terminal row per chain, one pass
33
+ """
34
+
35
+ _ORIGINAL = """
36
+ CREATE OR REPLACE VIEW v_graph_survivor AS
37
+ WITH RECURSIVE chain(entity_id, cur, depth) AS (
38
+ SELECT entity_id, entity_id, 0 FROM entities
39
+ UNION ALL
40
+ SELECT c.entity_id, e.merged_into, c.depth + 1
41
+ FROM chain c JOIN entities e ON e.entity_id = c.cur
42
+ WHERE e.merged_into IS NOT NULL AND c.depth < 64
43
+ )
44
+ SELECT entity_id,
45
+ (SELECT cur FROM chain x WHERE x.entity_id = chain.entity_id ORDER BY depth DESC LIMIT 1) AS survivor
46
+ FROM chain GROUP BY entity_id
47
+ """
48
+
49
+
50
+ def upgrade() -> None:
51
+ """Swap in the single-pass survivor resolution (same columns/semantics)."""
52
+ op.execute(_REWRITTEN)
53
+
54
+
55
+ def downgrade() -> None:
56
+ """Restore the original (quadratic) form."""
57
+ op.execute(_ORIGINAL)
@@ -0,0 +1,58 @@
1
+ """Persist the finalize payload needed to recover a published K cycle."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from alembic import op
6
+
7
+ revision: str = "p6_02_0012"
8
+ down_revision: str | None = "p4_01_0011"
9
+ branch_labels: str | Sequence[str] | None = None
10
+ depends_on: str | Sequence[str] | None = None
11
+
12
+ _UPGRADE = """
13
+ ALTER TABLE knowledge_compilations
14
+ ADD COLUMN cycle_id uuid,
15
+ ADD COLUMN page_summary text,
16
+ ADD COLUMN content_hash text,
17
+ ADD COLUMN citations jsonb,
18
+ ADD COLUMN failed_at timestamptz,
19
+ ADD COLUMN failure text;
20
+
21
+ CREATE INDEX ix_kcompilations_pending_cycle
22
+ ON knowledge_compilations (deployment_id, cycle_id, compiled_at)
23
+ WHERE git_commit IS NULL AND failed_at IS NULL;
24
+
25
+ COMMENT ON COLUMN knowledge_compilations.cycle_id IS
26
+ 'One driver publish batch. Every page in a cycle is finalized in one Postgres transaction.';
27
+ COMMENT ON COLUMN knowledge_compilations.page_summary IS
28
+ 'Recovery copy of the writer summary; required to finalize after a post-publish process crash.';
29
+ COMMENT ON COLUMN knowledge_compilations.content_hash IS
30
+ 'Recovery copy of the compiled markdown hash; also verifies that remote HEAD contains the pending output.';
31
+ COMMENT ON COLUMN knowledge_compilations.citations IS
32
+ 'Recovery copy of the typed binding citation set; counts alone cannot reconstruct citation identities.';
33
+ COMMENT ON COLUMN knowledge_compilations.failed_at IS
34
+ 'Set when a pending cycle was never published or no longer matches remote HEAD.';
35
+ COMMENT ON COLUMN knowledge_compilations.failure IS
36
+ 'Visible reason a pending cycle could not be recovered; its pages remain stale.';
37
+ """
38
+
39
+ _DOWNGRADE = """
40
+ DROP INDEX IF EXISTS ix_kcompilations_pending_cycle;
41
+ ALTER TABLE knowledge_compilations
42
+ DROP COLUMN IF EXISTS failure,
43
+ DROP COLUMN IF EXISTS failed_at,
44
+ DROP COLUMN IF EXISTS citations,
45
+ DROP COLUMN IF EXISTS content_hash,
46
+ DROP COLUMN IF EXISTS page_summary,
47
+ DROP COLUMN IF EXISTS cycle_id;
48
+ """
49
+
50
+
51
+ def upgrade() -> None:
52
+ """Add durable pending-cycle recovery data without rewriting old transcripts."""
53
+ op.execute(_UPGRADE)
54
+
55
+
56
+ def downgrade() -> None:
57
+ """Remove the WP-6.2 recovery payload and pending-cycle index."""
58
+ op.execute(_DOWNGRADE)
@@ -0,0 +1,46 @@
1
+ """Record capped writer bundles and inert writer suggestions."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from alembic import op
6
+
7
+ revision: str = "p6_04_0013"
8
+ down_revision: str | None = "p6_02_0012"
9
+ branch_labels: str | Sequence[str] | None = None
10
+ depends_on: str | Sequence[str] | None = None
11
+
12
+ _UPGRADE = """
13
+ ALTER TABLE knowledge_compilations
14
+ ADD COLUMN claims_cut_count integer NOT NULL DEFAULT 0,
15
+ ADD COLUMN suggestions jsonb NOT NULL DEFAULT '[]'::jsonb;
16
+
17
+ ALTER TABLE knowledge_compilations
18
+ ADD CONSTRAINT ck_kcompilations_claims_cut_nonnegative
19
+ CHECK (claims_cut_count >= 0);
20
+
21
+ COMMENT ON COLUMN knowledge_compilations.claims_cut_count IS
22
+ 'Rule-matched D54 claim coordinates omitted by the settings-bound writer bundle cap.';
23
+ COMMENT ON COLUMN knowledge_compilations.suggestions IS
24
+ 'Typed writer suggestions retained as planner inputs; compilation never applies them directly.';
25
+ COMMENT ON COLUMN knowledge_compilations.cited_count IS
26
+ 'Offered fact and D54 claim-coordinate candidates covered by accepted citations.';
27
+ COMMENT ON COLUMN knowledge_compilations.uncited_count IS
28
+ 'Offered fact and D54 claim-coordinate candidates not covered by accepted citations.';
29
+ """
30
+
31
+ _DOWNGRADE = """
32
+ ALTER TABLE knowledge_compilations
33
+ DROP CONSTRAINT IF EXISTS ck_kcompilations_claims_cut_nonnegative,
34
+ DROP COLUMN IF EXISTS suggestions,
35
+ DROP COLUMN IF EXISTS claims_cut_count;
36
+ """
37
+
38
+
39
+ def upgrade() -> None:
40
+ """Add the WP-6.4 bundle-cut and suggestion ledger fields."""
41
+ op.execute(_UPGRADE)
42
+
43
+
44
+ def downgrade() -> None:
45
+ """Remove the WP-6.4 writer ledger extension."""
46
+ op.execute(_DOWNGRADE)
@@ -0,0 +1,217 @@
1
+ """Add transcript-bearing planner runs and compiled-edit quarantine."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from alembic import op
6
+
7
+ revision: str = "p6_05_0014"
8
+ down_revision: str | None = "p6_04_0013"
9
+ branch_labels: str | Sequence[str] | None = None
10
+ depends_on: str | Sequence[str] | None = None
11
+
12
+ _UPGRADE = """
13
+ CREATE TABLE knowledge_plan_runs (
14
+ run_id uuid PRIMARY KEY,
15
+ deployment_id uuid NOT NULL REFERENCES deployments,
16
+ scope_id uuid,
17
+ run_kind text NOT NULL CHECK (run_kind IN ('planner','reflection')),
18
+ trigger plan_trigger NOT NULL,
19
+ component_version text NOT NULL,
20
+ input_hash text NOT NULL,
21
+ session_transcript_uri text NOT NULL,
22
+ status text NOT NULL CHECK (status IN ('succeeded','failed')),
23
+ failure text,
24
+ tokens integer CHECK (tokens IS NULL OR tokens >= 0),
25
+ cost_usd numeric CHECK (cost_usd IS NULL OR cost_usd >= 0),
26
+ completed_at timestamptz NOT NULL DEFAULT now(),
27
+ FOREIGN KEY (deployment_id, scope_id)
28
+ REFERENCES scopes (deployment_id, scope_id) ON DELETE CASCADE,
29
+ CHECK ((status = 'failed') = (failure IS NOT NULL))
30
+ );
31
+
32
+ CREATE INDEX ix_kplan_runs_deployment
33
+ ON knowledge_plan_runs (deployment_id, completed_at DESC);
34
+
35
+ ALTER TABLE knowledge_plan_decisions
36
+ ADD COLUMN plan_run_id uuid REFERENCES knowledge_plan_runs (run_id),
37
+ ADD COLUMN confidence numeric,
38
+ ADD COLUMN blast_radius integer,
39
+ ADD COLUMN expected_impact numeric,
40
+ ADD COLUMN reviewed_by text,
41
+ ADD COLUMN reviewed_at timestamptz,
42
+ ADD COLUMN application_commit text;
43
+
44
+ ALTER TABLE knowledge_plan_decisions
45
+ ADD CONSTRAINT ck_kplan_confidence
46
+ CHECK (confidence IS NULL OR confidence BETWEEN 0 AND 1),
47
+ ADD CONSTRAINT ck_kplan_blast_radius
48
+ CHECK (blast_radius IS NULL OR blast_radius >= 0),
49
+ ADD CONSTRAINT ck_kplan_expected_impact
50
+ CHECK (expected_impact IS NULL OR expected_impact >= 0),
51
+ ADD CONSTRAINT ck_kplan_review_pair
52
+ CHECK ((reviewed_by IS NULL) = (reviewed_at IS NULL));
53
+
54
+ ALTER TABLE knowledge_artifact_evidence
55
+ ADD COLUMN claim_lineage_id uuid,
56
+ ADD COLUMN claim_chunk_content_hash text;
57
+
58
+ UPDATE knowledge_artifact_evidence e
59
+ SET claim_lineage_id = resolved.doc_id,
60
+ claim_chunk_content_hash = resolved.chunk_content_hash
61
+ FROM (
62
+ SELECT DISTINCT ON (c.claim_id)
63
+ c.claim_id, c.doc_id, ch.chunk_content_hash
64
+ FROM claims c
65
+ JOIN chunks ch
66
+ ON ch.deployment_id = c.deployment_id AND ch.chunk_id = c.chunk_id
67
+ ORDER BY c.claim_id, c.ingested_at DESC
68
+ ) resolved
69
+ WHERE e.claim_id = resolved.claim_id;
70
+
71
+ DO $$
72
+ BEGIN
73
+ IF EXISTS (
74
+ SELECT 1 FROM knowledge_artifact_evidence
75
+ WHERE claim_id IS NOT NULL AND claim_lineage_id IS NULL
76
+ ) THEN
77
+ RAISE EXCEPTION
78
+ 'cannot migrate unresolved knowledge_artifact_evidence claim citations';
79
+ END IF;
80
+ END $$;
81
+
82
+ DELETE FROM knowledge_artifact_evidence e
83
+ USING (
84
+ SELECT evidence_link_id
85
+ FROM (
86
+ SELECT evidence_link_id,
87
+ row_number() OVER (
88
+ PARTITION BY artifact_id, role, claim_lineage_id,
89
+ claim_chunk_content_hash, relation_id, doc_id
90
+ ORDER BY evidence_link_id
91
+ ) AS duplicate_ordinal
92
+ FROM knowledge_artifact_evidence
93
+ ) ranked
94
+ WHERE duplicate_ordinal > 1
95
+ ) duplicates
96
+ WHERE e.evidence_link_id = duplicates.evidence_link_id;
97
+
98
+ DROP INDEX ux_kae_link;
99
+ DROP INDEX ix_kae_claim;
100
+ ALTER TABLE knowledge_artifact_evidence
101
+ DROP CONSTRAINT knowledge_artifact_evidence_check,
102
+ DROP COLUMN claim_id,
103
+ ADD CONSTRAINT ck_kae_claim_coordinate_pair CHECK (
104
+ (claim_lineage_id IS NULL) = (claim_chunk_content_hash IS NULL)
105
+ ),
106
+ ADD CONSTRAINT ck_kae_exactly_one_target CHECK (
107
+ num_nonnulls(claim_lineage_id, relation_id, doc_id) = 1
108
+ );
109
+ CREATE UNIQUE INDEX ux_kae_link ON knowledge_artifact_evidence (
110
+ artifact_id, role, claim_lineage_id, claim_chunk_content_hash, relation_id, doc_id
111
+ ) NULLS NOT DISTINCT;
112
+ CREATE INDEX ix_kae_claim_coordinate ON knowledge_artifact_evidence (
113
+ claim_lineage_id, claim_chunk_content_hash
114
+ ) WHERE claim_lineage_id IS NOT NULL;
115
+
116
+ CREATE TABLE knowledge_quarantines (
117
+ quarantine_id uuid PRIMARY KEY,
118
+ decision_id uuid NOT NULL UNIQUE
119
+ REFERENCES knowledge_plan_decisions (decision_id),
120
+ deployment_id uuid NOT NULL REFERENCES deployments,
121
+ artifact_id uuid NOT NULL,
122
+ recorded_content_hash text NOT NULL,
123
+ detected_content_hash text NOT NULL,
124
+ proposed_sidecar_entry text NOT NULL,
125
+ status text NOT NULL DEFAULT 'proposed'
126
+ CHECK (status IN ('proposed','curation_accepted','adopted','rejected')),
127
+ resolution_note text,
128
+ curation_content_hash text,
129
+ detected_at timestamptz NOT NULL DEFAULT now(),
130
+ resolved_at timestamptz,
131
+ FOREIGN KEY (deployment_id, artifact_id)
132
+ REFERENCES knowledge_artifacts (deployment_id, artifact_id) ON DELETE CASCADE,
133
+ CHECK ((status = 'proposed') = (resolved_at IS NULL)),
134
+ CHECK (status <> 'curation_accepted' OR curation_content_hash IS NOT NULL)
135
+ );
136
+
137
+ CREATE UNIQUE INDEX ux_kquarantine_open_artifact
138
+ ON knowledge_quarantines (artifact_id) WHERE status = 'proposed';
139
+
140
+ COMMENT ON TABLE knowledge_plan_runs IS
141
+ 'Append-only D52 transcript ledger for planner and independent reflection sessions, including terminal failures.';
142
+ COMMENT ON COLUMN knowledge_plan_decisions.expected_impact IS
143
+ 'D24-style blast_radius * (1 - confidence), computed by the deterministic driver rather than the proposing agent.';
144
+ COMMENT ON COLUMN knowledge_plan_decisions.application_commit IS
145
+ 'Git revision whose tree first reflects an applied structural decision; NULL while driver reconciliation is pending.';
146
+ COMMENT ON TABLE knowledge_quarantines IS
147
+ 'Direct compiled-body edits preserved verbatim as proposed curation, excluded from compilation until explicit curation, adoption, or rejection triage.';
148
+ COMMENT ON COLUMN knowledge_artifact_evidence.claim_lineage_id IS
149
+ 'D54-stable claim citation coordinate; paired with claim_chunk_content_hash, never a raw extraction-generation claim ID.';
150
+ """
151
+
152
+ _DOWNGRADE = """
153
+ DROP TABLE IF EXISTS knowledge_quarantines;
154
+
155
+ ALTER TABLE knowledge_artifact_evidence ADD COLUMN claim_id uuid;
156
+ UPDATE knowledge_artifact_evidence e
157
+ SET claim_id = resolved.claim_id
158
+ FROM (
159
+ SELECT DISTINCT ON (c.doc_id, ch.chunk_content_hash)
160
+ c.doc_id, ch.chunk_content_hash, c.claim_id
161
+ FROM claims c
162
+ JOIN chunks ch
163
+ ON ch.deployment_id = c.deployment_id AND ch.chunk_id = c.chunk_id
164
+ ORDER BY c.doc_id, ch.chunk_content_hash, c.is_current_testimony DESC,
165
+ c.ingested_at DESC
166
+ ) resolved
167
+ WHERE e.claim_lineage_id = resolved.doc_id
168
+ AND e.claim_chunk_content_hash = resolved.chunk_content_hash;
169
+ DO $$
170
+ BEGIN
171
+ IF EXISTS (
172
+ SELECT 1 FROM knowledge_artifact_evidence
173
+ WHERE claim_lineage_id IS NOT NULL AND claim_id IS NULL
174
+ ) THEN
175
+ RAISE EXCEPTION
176
+ 'cannot downgrade unresolved knowledge_artifact_evidence claim coordinates';
177
+ END IF;
178
+ END $$;
179
+ DROP INDEX ix_kae_claim_coordinate;
180
+ DROP INDEX ux_kae_link;
181
+ ALTER TABLE knowledge_artifact_evidence
182
+ DROP CONSTRAINT ck_kae_exactly_one_target,
183
+ DROP CONSTRAINT ck_kae_claim_coordinate_pair,
184
+ DROP COLUMN claim_chunk_content_hash,
185
+ DROP COLUMN claim_lineage_id,
186
+ ADD CHECK (num_nonnulls(claim_id, relation_id, doc_id) = 1);
187
+ CREATE UNIQUE INDEX ux_kae_link ON knowledge_artifact_evidence (
188
+ artifact_id, role, claim_id, relation_id, doc_id
189
+ ) NULLS NOT DISTINCT;
190
+ CREATE INDEX ix_kae_claim ON knowledge_artifact_evidence (claim_id)
191
+ WHERE claim_id IS NOT NULL;
192
+
193
+ ALTER TABLE knowledge_plan_decisions
194
+ DROP CONSTRAINT IF EXISTS ck_kplan_review_pair,
195
+ DROP CONSTRAINT IF EXISTS ck_kplan_expected_impact,
196
+ DROP CONSTRAINT IF EXISTS ck_kplan_blast_radius,
197
+ DROP CONSTRAINT IF EXISTS ck_kplan_confidence,
198
+ DROP COLUMN IF EXISTS application_commit,
199
+ DROP COLUMN IF EXISTS reviewed_at,
200
+ DROP COLUMN IF EXISTS reviewed_by,
201
+ DROP COLUMN IF EXISTS expected_impact,
202
+ DROP COLUMN IF EXISTS blast_radius,
203
+ DROP COLUMN IF EXISTS confidence,
204
+ DROP COLUMN IF EXISTS plan_run_id;
205
+
206
+ DROP TABLE IF EXISTS knowledge_plan_runs;
207
+ """
208
+
209
+
210
+ def upgrade() -> None:
211
+ """Add the WP-6.5 planner ledger, impact routing, and quarantine records."""
212
+ op.execute(_UPGRADE)
213
+
214
+
215
+ def downgrade() -> None:
216
+ """Remove the WP-6.5 planner runtime schema extension."""
217
+ op.execute(_DOWNGRADE)
@@ -0,0 +1,38 @@
1
+ """Add the D67 work-ledger route for WP-6.6 knowledge dispatches."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from alembic import op
6
+
7
+ revision: str = "p6_06_0015"
8
+ down_revision: str | None = "p6_05_0014"
9
+ branch_labels: str | Sequence[str] | None = None
10
+ depends_on: str | Sequence[str] | None = None
11
+
12
+
13
+ def upgrade() -> None:
14
+ """Append the dispatch target and stage used by the generic D12 worker."""
15
+ op.execute(
16
+ "ALTER TYPE processing_target ADD VALUE IF NOT EXISTS 'knowledge_dispatch'"
17
+ )
18
+ op.execute("ALTER TYPE pipeline_stage ADD VALUE IF NOT EXISTS 'dispatch_knowledge'")
19
+ op.execute(
20
+ """
21
+ CREATE UNIQUE INDEX ux_krefresh_open_authored_review
22
+ ON knowledge_refresh_queue (deployment_id, artifact_id)
23
+ WHERE trigger = 'authored_review' AND processed_at IS NULL
24
+ """
25
+ )
26
+ op.execute(
27
+ """
28
+ CREATE UNIQUE INDEX ux_kdispatch_pending_subscription
29
+ ON knowledge_dispatches (deployment_id, subscription_id)
30
+ WHERE status = 'pending'
31
+ """
32
+ )
33
+
34
+
35
+ def downgrade() -> None:
36
+ """PostgreSQL enum additions are intentionally additive across downgrades."""
37
+ op.execute("DROP INDEX IF EXISTS ux_kdispatch_pending_subscription")
38
+ op.execute("DROP INDEX IF EXISTS ux_krefresh_open_authored_review")
@@ -0,0 +1,19 @@
1
+ """Add the WP-7.2 operational scale eval suite."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from alembic import op
6
+
7
+ revision: str = "p7_02_0016"
8
+ down_revision: str | None = "p6_06_0015"
9
+ branch_labels: str | Sequence[str] | None = None
10
+ depends_on: str | Sequence[str] | None = None
11
+
12
+
13
+ def upgrade() -> None:
14
+ """Append the provider-neutral operational measurement suite."""
15
+ op.execute("ALTER TYPE eval_suite ADD VALUE IF NOT EXISTS 'operational'")
16
+
17
+
18
+ def downgrade() -> None:
19
+ """PostgreSQL cannot remove an enum value in place; additive no-op."""
@@ -0,0 +1,55 @@
1
+ """Add the D74 hard-forget manifest materialization and worker vocabulary."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from rememberstack.spine.migrations._helpers import apply_ddl
6
+ from rememberstack.spine.migrations._helpers import drop_tables
7
+ from rememberstack.spine.migrations._helpers import drop_types
8
+
9
+ revision: str = "p7_05_0017"
10
+ down_revision: str | None = "p7_02_0016"
11
+ branch_labels: str | Sequence[str] | None = None
12
+ depends_on: str | Sequence[str] | None = None
13
+
14
+ _DDL = r"""ALTER TYPE pipeline_component ADD VALUE IF NOT EXISTS 'forgetter';
15
+ ALTER TYPE pipeline_stage ADD VALUE IF NOT EXISTS 'hard_forget';
16
+ CREATE TYPE forget_manifest_status AS ENUM ('preparing','accepted','complete');
17
+
18
+ CREATE TABLE forget_manifests (
19
+ forget_id uuid PRIMARY KEY, -- stable portable intent identity
20
+ deployment_id uuid NOT NULL REFERENCES deployments, -- deployment that owns the lineage
21
+ doc_id uuid NOT NULL, -- lineage target; intentionally retained for replay
22
+ schema_version smallint NOT NULL, -- portable manifest schema version
23
+ manifest_hash text, -- set with manifest before portable append
24
+ manifest jsonb, -- content-free immutable IDs, hashes, and keys
25
+ source_identity_hash text, -- irreversible stable-source ingest guard
26
+ content_hashes text[] NOT NULL DEFAULT '{}', -- irreversible raw-content ingest guards
27
+ status forget_manifest_status NOT NULL DEFAULT 'preparing', -- admission lifecycle
28
+ prepared_at timestamptz NOT NULL DEFAULT now(), -- barrier establishment time
29
+ accepted_at timestamptz, -- portable append acknowledgement time
30
+ completed_at timestamptz, -- latest successful full purge time
31
+ last_verified_at timestamptz, -- latest all-store readiness re-honor
32
+ UNIQUE (deployment_id, doc_id),
33
+ UNIQUE (deployment_id, forget_id),
34
+ CHECK ((status = 'preparing') OR
35
+ (manifest_hash IS NOT NULL AND manifest IS NOT NULL AND accepted_at IS NOT NULL)),
36
+ CHECK ((status = 'complete') = (completed_at IS NOT NULL))
37
+ );
38
+ COMMENT ON TABLE forget_manifests IS
39
+ 'D74 hard-forget manifest materialization: preparing is the admission barrier; accepted means portable intent is durable; complete never lets readiness skip external-store re-honor.';
40
+ CREATE INDEX ix_forget_source_guard
41
+ ON forget_manifests (deployment_id, source_identity_hash)
42
+ WHERE source_identity_hash IS NOT NULL;
43
+ CREATE INDEX ix_forget_content_guard ON forget_manifests USING gin (content_hashes);
44
+ """
45
+
46
+
47
+ def upgrade() -> None:
48
+ """Add one manifest table plus the unlaned hard-forget work identity."""
49
+ apply_ddl(sql=_DDL)
50
+
51
+
52
+ def downgrade() -> None:
53
+ """Drop reversible D74 objects; additive pipeline enum values remain."""
54
+ drop_tables(table_names=("forget_manifests",))
55
+ drop_types(type_names=("forget_manifest_status",))