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.
- rememberstack/__init__.py +9 -0
- rememberstack/adapters/__init__.py +42 -0
- rememberstack/adapters/codex_writer.py +221 -0
- rememberstack/adapters/markitdown_converter.py +42 -0
- rememberstack/adapters/openrouter.py +136 -0
- rememberstack/adapters/selfhost/__init__.py +54 -0
- rememberstack/adapters/selfhost/forget.py +66 -0
- rememberstack/adapters/selfhost/git.py +374 -0
- rememberstack/adapters/selfhost/lance.py +328 -0
- rememberstack/adapters/selfhost/minio.py +279 -0
- rememberstack/adapters/selfhost/mounts.py +249 -0
- rememberstack/adapters/selfhost/object_store.py +130 -0
- rememberstack/adapters/selfhost/projection.py +80 -0
- rememberstack/adapters/selfhost/queue.py +137 -0
- rememberstack/adapters/selfhost/telemetry.py +45 -0
- rememberstack/adapters/selfhost/watcher.py +70 -0
- rememberstack/adapters/testing/__init__.py +15 -0
- rememberstack/adapters/testing/cost_meter.py +13 -0
- rememberstack/adapters/testing/model_provider.py +83 -0
- rememberstack/adapters/testing/queue.py +43 -0
- rememberstack/adapters/testing/telemetry.py +22 -0
- rememberstack/client.py +19 -0
- rememberstack/core/__init__.py +127 -0
- rememberstack/core/blockizer.py +189 -0
- rememberstack/core/chunker.py +216 -0
- rememberstack/core/consumption_skill.py +275 -0
- rememberstack/core/conversion.py +76 -0
- rememberstack/core/core_manifest.py +598 -0
- rememberstack/core/extension_packs.py +124 -0
- rememberstack/core/forget.py +17 -0
- rememberstack/core/knowledge_authored.py +276 -0
- rememberstack/core/knowledge_compile.py +215 -0
- rememberstack/core/knowledge_fact_sheet.py +210 -0
- rememberstack/core/knowledge_hashing.py +68 -0
- rememberstack/core/knowledge_planner.py +64 -0
- rememberstack/core/knowledge_writer.py +175 -0
- rememberstack/core/ranking.py +200 -0
- rememberstack/core/recipe_linter.py +149 -0
- rememberstack/core/section_snap.py +209 -0
- rememberstack/core/storage_routing.py +27 -0
- rememberstack/eval/__init__.py +53 -0
- rememberstack/eval/consumption.py +141 -0
- rememberstack/eval/contradiction.py +184 -0
- rememberstack/eval/harness.py +136 -0
- rememberstack/eval/lifecycle.py +400 -0
- rememberstack/eval/operational_scale.py +49 -0
- rememberstack/eval/resolution.py +255 -0
- rememberstack/eval/retrieval_spikes.py +50 -0
- rememberstack/eval/skeleton.py +231 -0
- rememberstack/llm/__init__.py +1 -0
- rememberstack/model/__init__.py +589 -0
- rememberstack/model/adjudication.py +100 -0
- rememberstack/model/auth.py +27 -0
- rememberstack/model/blocks.py +30 -0
- rememberstack/model/chunks.py +190 -0
- rememberstack/model/claims.py +162 -0
- rememberstack/model/client.py +98 -0
- rememberstack/model/clustering.py +54 -0
- rememberstack/model/component_version.py +124 -0
- rememberstack/model/consumption.py +88 -0
- rememberstack/model/conversion.py +31 -0
- rememberstack/model/deployment.py +53 -0
- rememberstack/model/documents.py +168 -0
- rememberstack/model/envelope.py +513 -0
- rememberstack/model/evaluation.py +72 -0
- rememberstack/model/forget.py +143 -0
- rememberstack/model/git.py +13 -0
- rememberstack/model/knowledge.py +840 -0
- rememberstack/model/knowledge_authored.py +325 -0
- rememberstack/model/knowledge_planner.py +431 -0
- rememberstack/model/lifecycle.py +42 -0
- rememberstack/model/model_provider.py +78 -0
- rememberstack/model/mounts.py +24 -0
- rememberstack/model/object_store.py +21 -0
- rememberstack/model/operational_scale.py +59 -0
- rememberstack/model/operations.py +153 -0
- rememberstack/model/processing.py +228 -0
- rememberstack/model/queue.py +73 -0
- rememberstack/model/recipes.py +83 -0
- rememberstack/model/relations.py +79 -0
- rememberstack/model/resolution.py +83 -0
- rememberstack/model/retrieval_spikes.py +62 -0
- rememberstack/model/sections.py +120 -0
- rememberstack/model/telemetry.py +30 -0
- rememberstack/ports/__init__.py +29 -0
- rememberstack/ports/auth.py +16 -0
- rememberstack/ports/connector.py +23 -0
- rememberstack/ports/cost_meter.py +17 -0
- rememberstack/ports/forget.py +20 -0
- rememberstack/ports/git.py +20 -0
- rememberstack/ports/model_provider.py +28 -0
- rememberstack/ports/mounts.py +16 -0
- rememberstack/ports/object_store.py +27 -0
- rememberstack/ports/p1_index.py +92 -0
- rememberstack/ports/purge.py +93 -0
- rememberstack/ports/queue.py +23 -0
- rememberstack/ports/telemetry.py +21 -0
- rememberstack/profiles/__init__.py +22 -0
- rememberstack/profiles/selfhost.py +324 -0
- rememberstack/profiles/selfhost_forget.py +158 -0
- rememberstack/profiles/selfhost_operations.py +95 -0
- rememberstack/py.typed +1 -0
- rememberstack/spine/__init__.py +93 -0
- rememberstack/spine/admission.py +26 -0
- rememberstack/spine/backfill.py +168 -0
- rememberstack/spine/catalog_contract.py +742 -0
- rememberstack/spine/chunk_catalog.py +237 -0
- rememberstack/spine/claim_catalog.py +298 -0
- rememberstack/spine/clustering.py +740 -0
- rememberstack/spine/component_versions.py +208 -0
- rememberstack/spine/consumption.py +81 -0
- rememberstack/spine/deployment_bootstrap.py +445 -0
- rememberstack/spine/document_catalog.py +621 -0
- rememberstack/spine/entity_registry.py +205 -0
- rememberstack/spine/extension_packs.py +220 -0
- rememberstack/spine/fact_catalog.py +571 -0
- rememberstack/spine/forget.py +1753 -0
- rememberstack/spine/knowledge.py +5467 -0
- rememberstack/spine/lifecycle.py +1071 -0
- rememberstack/spine/migrations/__init__.py +1 -0
- rememberstack/spine/migrations/_helpers.py +153 -0
- rememberstack/spine/migrations/env.py +58 -0
- rememberstack/spine/migrations/script.py.mako +27 -0
- rememberstack/spine/migrations/versions/__init__.py +1 -0
- rememberstack/spine/migrations/versions/p0_02_0001_extensions_enums.py +189 -0
- rememberstack/spine/migrations/versions/p0_02_0002_infrastructure_registries.py +321 -0
- rememberstack/spine/migrations/versions/p0_02_0003_entities_evaluation_e0_e1.py +631 -0
- rememberstack/spine/migrations/versions/p0_02_0004_claims_facts_evidence.py +411 -0
- rememberstack/spine/migrations/versions/p0_02_0005_projection_knowledge_retrieval.py +391 -0
- rememberstack/spine/migrations/versions/p0_02_0006_partitions_views.py +158 -0
- rememberstack/spine/migrations/versions/p2_06_0007_invalidated_outcome.py +26 -0
- rememberstack/spine/migrations/versions/p3_01_0008_document_version_target.py +58 -0
- rememberstack/spine/migrations/versions/p3_05_0009_reconcile_stage.py +27 -0
- rememberstack/spine/migrations/versions/p3_07_0010_lifecycle_eval_suite.py +25 -0
- rememberstack/spine/migrations/versions/p4_01_0011_survivor_view_rewrite.py +57 -0
- rememberstack/spine/migrations/versions/p6_02_0012_knowledge_compile_recovery.py +58 -0
- rememberstack/spine/migrations/versions/p6_04_0013_knowledge_writer_ledger.py +46 -0
- rememberstack/spine/migrations/versions/p6_05_0014_knowledge_planner_runtime.py +217 -0
- rememberstack/spine/migrations/versions/p6_06_0015_authored_dispatch_runtime.py +38 -0
- rememberstack/spine/migrations/versions/p7_02_0016_operational_eval_suite.py +19 -0
- rememberstack/spine/migrations/versions/p7_05_0017_hard_forget.py +55 -0
- rememberstack/spine/observation_adjudication.py +778 -0
- rememberstack/spine/operations.py +298 -0
- rememberstack/spine/projection.py +662 -0
- rememberstack/spine/recipes.py +276 -0
- rememberstack/spine/resolver.py +763 -0
- rememberstack/spine/review.py +650 -0
- rememberstack/spine/settings.py +22 -0
- rememberstack/spine/supersession.py +510 -0
- rememberstack/spine/sync.py +128 -0
- rememberstack/spine/work_ledger.py +816 -0
- rememberstack/surfaces/__init__.py +110 -0
- rememberstack/surfaces/cli.py +447 -0
- rememberstack/surfaces/consumption_skill.py +87 -0
- rememberstack/surfaces/graph_queries.py +698 -0
- rememberstack/surfaces/http_api.py +377 -0
- rememberstack/surfaces/mcp.py +67 -0
- rememberstack/surfaces/query_engine.py +1591 -0
- rememberstack/surfaces/recipe_executor.py +185 -0
- rememberstack/surfaces/recipe_surface.py +219 -0
- rememberstack/surfaces/remote_mcp.py +133 -0
- rememberstack/surfaces/sdk.py +324 -0
- rememberstack/workers/__init__.py +155 -0
- rememberstack/workers/base.py +312 -0
- rememberstack/workers/e0.py +577 -0
- rememberstack/workers/e1.py +425 -0
- rememberstack/workers/e2.py +525 -0
- rememberstack/workers/e3.py +434 -0
- rememberstack/workers/forget.py +299 -0
- rememberstack/workers/knowledge_authored.py +146 -0
- rememberstack/workers/knowledge_driver.py +735 -0
- rememberstack/workers/knowledge_fact_sheet.py +123 -0
- rememberstack/workers/knowledge_planner.py +325 -0
- rememberstack/workers/knowledge_writer.py +393 -0
- rememberstack/workers/operations.py +42 -0
- rememberstack/workers/p1.py +234 -0
- rememberstack/workers/p2.py +513 -0
- rememberstack/workers/p2_analytics.py +276 -0
- rememberstack/workers/p3.py +673 -0
- rememberstack/workers/reconcile.py +485 -0
- rememberstack/workers/sync.py +168 -0
- rememberstack-0.1.0.dist-info/METADATA +213 -0
- rememberstack-0.1.0.dist-info/RECORD +186 -0
- rememberstack-0.1.0.dist-info/WHEEL +4 -0
- rememberstack-0.1.0.dist-info/entry_points.txt +2 -0
- rememberstack-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"""Bounded read-only operational inspection over the durable Postgres truth."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from uuid import UUID
|
|
5
|
+
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
from pydantic_settings import BaseSettings
|
|
8
|
+
from pydantic_settings import SettingsConfigDict
|
|
9
|
+
from sqlalchemy import text
|
|
10
|
+
from sqlalchemy.engine import Connection
|
|
11
|
+
from sqlalchemy.engine import Engine
|
|
12
|
+
from sqlalchemy.sql.elements import TextClause
|
|
13
|
+
|
|
14
|
+
from rememberstack.model import CurrencyLedgerAudit
|
|
15
|
+
from rememberstack.model import CurrencyMismatch
|
|
16
|
+
from rememberstack.model import DeadLetterGroup
|
|
17
|
+
from rememberstack.model import DeadLetterRecord
|
|
18
|
+
from rememberstack.model import DeadLetterReport
|
|
19
|
+
from rememberstack.model import OperationalReport
|
|
20
|
+
from rememberstack.model import PipelineRouteStatus
|
|
21
|
+
from rememberstack.model import PoisonTargetRecord
|
|
22
|
+
from rememberstack.model import PoisonTargetReport
|
|
23
|
+
from rememberstack.model import ProjectionSnapshotState
|
|
24
|
+
from rememberstack.spine.lifecycle import CURRENCY_CACHE_MISMATCH_SQL
|
|
25
|
+
|
|
26
|
+
_ERROR_CLASS = re.compile(r"^[A-Za-z_][A-Za-z0-9_.]*$")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class OperationalSettings(BaseSettings):
|
|
30
|
+
"""One cap shared by every variable-size operational detail collection."""
|
|
31
|
+
|
|
32
|
+
model_config = SettingsConfigDict(
|
|
33
|
+
env_prefix="REMEMBERSTACK_OPERATIONAL_", extra="ignore"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
sample_limit: int = Field(default=20, ge=1, le=1_000)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class OperationalCatalog:
|
|
40
|
+
"""Build a coherent deployment report without a dashboard or control plane."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, *, engine: Engine, settings: OperationalSettings) -> None:
|
|
43
|
+
"""Bind an engine and the single explicit sample bound."""
|
|
44
|
+
self._engine = engine
|
|
45
|
+
self._settings = settings
|
|
46
|
+
|
|
47
|
+
def inspect(self, *, deployment_id: UUID) -> OperationalReport:
|
|
48
|
+
"""Return aggregate truth plus bounded evidence in one repeatable-read view."""
|
|
49
|
+
parameters = {
|
|
50
|
+
"deployment_id": deployment_id,
|
|
51
|
+
"sample_limit": self._settings.sample_limit,
|
|
52
|
+
}
|
|
53
|
+
with self._engine.connect().execution_options(
|
|
54
|
+
isolation_level="REPEATABLE READ"
|
|
55
|
+
) as connection:
|
|
56
|
+
generated_at = connection.execute(text("SELECT now()")).scalar_one()
|
|
57
|
+
routes = tuple(
|
|
58
|
+
PipelineRouteStatus(**row)
|
|
59
|
+
for row in connection.execute(_ROUTE_STATUS, parameters).mappings()
|
|
60
|
+
)
|
|
61
|
+
dead_letters = self._dead_letters(
|
|
62
|
+
connection=connection, parameters=parameters
|
|
63
|
+
)
|
|
64
|
+
poison_targets = self._poison_targets(
|
|
65
|
+
connection=connection, parameters=parameters
|
|
66
|
+
)
|
|
67
|
+
latest_projections = tuple(
|
|
68
|
+
ProjectionSnapshotState(**row)
|
|
69
|
+
for row in connection.execute(
|
|
70
|
+
_LATEST_PROJECTIONS, parameters
|
|
71
|
+
).mappings()
|
|
72
|
+
)
|
|
73
|
+
currency = self._currency(connection=connection, parameters=parameters)
|
|
74
|
+
return OperationalReport(
|
|
75
|
+
deployment_id=deployment_id,
|
|
76
|
+
generated_at=generated_at,
|
|
77
|
+
routes=routes,
|
|
78
|
+
dead_letters=dead_letters,
|
|
79
|
+
poison_targets=poison_targets,
|
|
80
|
+
latest_projections=latest_projections,
|
|
81
|
+
currency=currency,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def _dead_letters(
|
|
85
|
+
self, *, connection: Connection, parameters: dict[str, object]
|
|
86
|
+
) -> DeadLetterReport:
|
|
87
|
+
"""Return DLQ totals and bounded grouped/detail evidence."""
|
|
88
|
+
total = _count(connection=connection, statement=_DLQ_TOTAL, values=parameters)
|
|
89
|
+
group_total = _count(
|
|
90
|
+
connection=connection, statement=_DLQ_GROUP_TOTAL, values=parameters
|
|
91
|
+
)
|
|
92
|
+
groups = tuple(
|
|
93
|
+
DeadLetterGroup(**row)
|
|
94
|
+
for row in connection.execute(_DLQ_GROUPS, parameters).mappings()
|
|
95
|
+
)
|
|
96
|
+
items = tuple(
|
|
97
|
+
DeadLetterRecord(
|
|
98
|
+
**row, error_class=error_class_from_traceback(row["last_error"])
|
|
99
|
+
)
|
|
100
|
+
for row in connection.execute(_DLQ_ITEMS, parameters).mappings()
|
|
101
|
+
)
|
|
102
|
+
return DeadLetterReport(
|
|
103
|
+
total=total, group_total=group_total, groups=groups, items=items
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def _poison_targets(
|
|
107
|
+
self, *, connection: Connection, parameters: dict[str, object]
|
|
108
|
+
) -> PoisonTargetReport:
|
|
109
|
+
"""Find targets whose same stage failed under multiple component versions."""
|
|
110
|
+
total = _count(
|
|
111
|
+
connection=connection, statement=_POISON_TOTAL, values=parameters
|
|
112
|
+
)
|
|
113
|
+
items = tuple(
|
|
114
|
+
PoisonTargetRecord(
|
|
115
|
+
target_kind=row["target_kind"],
|
|
116
|
+
target_id=row["target_id"],
|
|
117
|
+
stage=row["stage"],
|
|
118
|
+
component_version_total=row["component_version_total"],
|
|
119
|
+
component_versions=tuple(row["component_versions"]),
|
|
120
|
+
dead_letters=row["dead_letters"],
|
|
121
|
+
)
|
|
122
|
+
for row in connection.execute(_POISON_ITEMS, parameters).mappings()
|
|
123
|
+
)
|
|
124
|
+
return PoisonTargetReport(total=total, items=items)
|
|
125
|
+
|
|
126
|
+
def _currency(
|
|
127
|
+
self, *, connection: Connection, parameters: dict[str, object]
|
|
128
|
+
) -> CurrencyLedgerAudit:
|
|
129
|
+
"""Apply the exact lifecycle invariant and bound its diagnostic rows."""
|
|
130
|
+
claims = _count(
|
|
131
|
+
connection=connection, statement=_CLAIM_TOTAL, values=parameters
|
|
132
|
+
)
|
|
133
|
+
mismatch_total = _count(
|
|
134
|
+
connection=connection, statement=_CURRENCY_TOTAL, values=parameters
|
|
135
|
+
)
|
|
136
|
+
mismatches = tuple(
|
|
137
|
+
CurrencyMismatch(**row)
|
|
138
|
+
for row in connection.execute(_CURRENCY_ITEMS, parameters).mappings()
|
|
139
|
+
)
|
|
140
|
+
return CurrencyLedgerAudit(
|
|
141
|
+
claims=claims, mismatch_total=mismatch_total, mismatches=mismatches
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def error_class_from_traceback(error: str | None) -> str:
|
|
146
|
+
"""Derive one stable class from the last non-empty traceback line."""
|
|
147
|
+
if error is None:
|
|
148
|
+
return "unknown"
|
|
149
|
+
lines = [line.strip() for line in error.splitlines() if line.strip()]
|
|
150
|
+
if not lines:
|
|
151
|
+
return "unknown"
|
|
152
|
+
candidate = lines[-1].split(":", maxsplit=1)[0].strip()
|
|
153
|
+
return candidate if _ERROR_CLASS.fullmatch(candidate) is not None else "unknown"
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _count(
|
|
157
|
+
*, connection: Connection, statement: TextClause, values: dict[str, object]
|
|
158
|
+
) -> int:
|
|
159
|
+
"""Normalize one PostgreSQL count scalar."""
|
|
160
|
+
return int(connection.execute(statement, values).scalar_one())
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
_ROUTE_STATUS = text(
|
|
164
|
+
"""
|
|
165
|
+
SELECT stage, lane, status, count(*) AS count
|
|
166
|
+
FROM processing_state
|
|
167
|
+
WHERE deployment_id = :deployment_id
|
|
168
|
+
GROUP BY stage, lane, status
|
|
169
|
+
ORDER BY stage, lane NULLS FIRST, status
|
|
170
|
+
"""
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
_CLASSIFIED_DEAD_LETTERS = """
|
|
174
|
+
WITH dead_letters AS (
|
|
175
|
+
SELECT stage, component_version, enqueued_at, finished_at,
|
|
176
|
+
btrim(reverse(split_part(
|
|
177
|
+
reverse(rtrim(coalesce(last_error, ''), E' \\t\\n\\r')),
|
|
178
|
+
E'\\n', 1
|
|
179
|
+
))) AS last_line
|
|
180
|
+
FROM processing_state
|
|
181
|
+
WHERE deployment_id = :deployment_id AND status = 'dead_letter'
|
|
182
|
+
), classified AS (
|
|
183
|
+
SELECT stage, component_version, enqueued_at, finished_at,
|
|
184
|
+
CASE
|
|
185
|
+
WHEN split_part(last_line, ':', 1)
|
|
186
|
+
~ '^[A-Za-z_][A-Za-z0-9_.]*$'
|
|
187
|
+
THEN split_part(last_line, ':', 1)
|
|
188
|
+
ELSE 'unknown'
|
|
189
|
+
END AS error_class
|
|
190
|
+
FROM dead_letters
|
|
191
|
+
)
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
_DLQ_TOTAL = text(
|
|
195
|
+
"""
|
|
196
|
+
SELECT count(*) FROM processing_state
|
|
197
|
+
WHERE deployment_id = :deployment_id AND status = 'dead_letter'
|
|
198
|
+
"""
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
_DLQ_GROUP_TOTAL = text(
|
|
202
|
+
_CLASSIFIED_DEAD_LETTERS
|
|
203
|
+
+ """
|
|
204
|
+
SELECT count(*) FROM (
|
|
205
|
+
SELECT 1 FROM classified
|
|
206
|
+
GROUP BY stage, error_class, component_version
|
|
207
|
+
) groups
|
|
208
|
+
"""
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
_DLQ_GROUPS = text(
|
|
212
|
+
_CLASSIFIED_DEAD_LETTERS
|
|
213
|
+
+ """
|
|
214
|
+
SELECT stage, error_class, component_version, count(*) AS count,
|
|
215
|
+
min(enqueued_at) AS oldest_enqueued_at,
|
|
216
|
+
max(finished_at) AS latest_finished_at
|
|
217
|
+
FROM classified
|
|
218
|
+
GROUP BY stage, error_class, component_version
|
|
219
|
+
ORDER BY count(*) DESC, stage, error_class, component_version
|
|
220
|
+
LIMIT :sample_limit
|
|
221
|
+
"""
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
_DLQ_ITEMS = text(
|
|
225
|
+
"""
|
|
226
|
+
SELECT processing_id, target_kind, target_id, stage, component_version,
|
|
227
|
+
content_hash, lane, attempts, max_attempts, last_error, payload,
|
|
228
|
+
enqueued_at, finished_at
|
|
229
|
+
FROM processing_state
|
|
230
|
+
WHERE deployment_id = :deployment_id AND status = 'dead_letter'
|
|
231
|
+
ORDER BY finished_at DESC NULLS LAST, processing_id
|
|
232
|
+
LIMIT :sample_limit
|
|
233
|
+
"""
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
_POISON_GROUPS = """
|
|
237
|
+
SELECT target_kind, target_id, stage,
|
|
238
|
+
count(DISTINCT component_version) AS component_version_total,
|
|
239
|
+
count(*) AS dead_letters
|
|
240
|
+
FROM processing_state
|
|
241
|
+
WHERE deployment_id = :deployment_id AND status = 'dead_letter'
|
|
242
|
+
GROUP BY target_kind, target_id, stage
|
|
243
|
+
HAVING count(DISTINCT component_version) >= 2
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
_POISON_TOTAL = text("SELECT count(*) FROM (" + _POISON_GROUPS + ") poison")
|
|
247
|
+
|
|
248
|
+
_POISON_ITEMS = text(
|
|
249
|
+
"WITH poison AS ("
|
|
250
|
+
+ _POISON_GROUPS
|
|
251
|
+
+ ")"
|
|
252
|
+
+ """
|
|
253
|
+
SELECT poison.*,
|
|
254
|
+
ARRAY(
|
|
255
|
+
SELECT DISTINCT versioned.component_version
|
|
256
|
+
FROM processing_state versioned
|
|
257
|
+
WHERE versioned.deployment_id = :deployment_id
|
|
258
|
+
AND versioned.status = 'dead_letter'
|
|
259
|
+
AND versioned.target_kind = poison.target_kind
|
|
260
|
+
AND versioned.target_id = poison.target_id
|
|
261
|
+
AND versioned.stage = poison.stage
|
|
262
|
+
ORDER BY versioned.component_version
|
|
263
|
+
LIMIT :sample_limit
|
|
264
|
+
) AS component_versions
|
|
265
|
+
FROM poison
|
|
266
|
+
ORDER BY poison.dead_letters DESC, poison.target_kind,
|
|
267
|
+
poison.target_id, poison.stage
|
|
268
|
+
LIMIT :sample_limit
|
|
269
|
+
"""
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
_LATEST_PROJECTIONS = text(
|
|
273
|
+
"""
|
|
274
|
+
SELECT snapshot_id, plane, version, gcs_uri AS store_uri, row_counts,
|
|
275
|
+
built_at, published_at
|
|
276
|
+
FROM projection_snapshots
|
|
277
|
+
WHERE deployment_id = :deployment_id
|
|
278
|
+
AND plane IN ('P2_graph', 'P3_corpusfs')
|
|
279
|
+
AND is_latest
|
|
280
|
+
ORDER BY plane
|
|
281
|
+
"""
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
_CLAIM_TOTAL = text("SELECT count(*) FROM claims WHERE deployment_id = :deployment_id")
|
|
285
|
+
|
|
286
|
+
_CURRENCY_TOTAL = text(
|
|
287
|
+
"WITH mismatches AS ("
|
|
288
|
+
+ CURRENCY_CACHE_MISMATCH_SQL
|
|
289
|
+
+ ") SELECT count(*) FROM mismatches"
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
_CURRENCY_ITEMS = text(
|
|
293
|
+
CURRENCY_CACHE_MISMATCH_SQL
|
|
294
|
+
+ """
|
|
295
|
+
ORDER BY cl.claim_id
|
|
296
|
+
LIMIT :sample_limit
|
|
297
|
+
"""
|
|
298
|
+
)
|