thinkwork-cli 0.13.0 → 0.13.2
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.
- package/dist/{api-client-JUBCQQDF.js → api-client-JYZXYQJR.js} +3 -1
- package/dist/bowser-6Z6JFAIR.js +2822 -0
- package/dist/chunk-DV3MRBR5.js +43 -0
- package/dist/chunk-DVPBI5HM.js +1728 -0
- package/dist/chunk-EI5ZX7CN.js +522 -0
- package/dist/chunk-EUJ7X6YD.js +126 -0
- package/dist/chunk-GG5WKBOX.js +436 -0
- package/dist/chunk-I64EZSU5.js +358 -0
- package/dist/chunk-ILZKG5WV.js +6151 -0
- package/dist/chunk-KMIJ5KGT.js +128 -0
- package/dist/chunk-OCPHU34C.js +996 -0
- package/dist/chunk-QOERT44A.js +3286 -0
- package/dist/chunk-XYM7PE2A.js +2264 -0
- package/dist/{chunk-STY44FQO.js → chunk-Z2F6RJFR.js} +12 -18
- package/dist/cli.js +72564 -18884
- package/dist/dist-es-CRV46D5B.js +315 -0
- package/dist/dist-es-DCY4IC3Y.js +2000 -0
- package/dist/dist-es-ENBUC3JP.js +14726 -0
- package/dist/dist-es-G54LBMRN.js +48 -0
- package/dist/dist-es-G7PTG75M.js +176 -0
- package/dist/dist-es-GKDBE7E6.js +88 -0
- package/dist/dist-es-HY3535OI.js +70 -0
- package/dist/dist-es-KL7Y5NB2.js +377 -0
- package/dist/dist-es-LDE437AM.js +170 -0
- package/dist/dist-es-P26FWFLT.js +485 -0
- package/dist/dist-es-Q57SZXZ7.js +70 -0
- package/dist/dist-es-R7FGL2IB.js +88 -0
- package/dist/dist-es-USORBXZ5.js +318 -0
- package/dist/dist-es-ZKC2QKD2.js +377 -0
- package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +2 -1
- package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +1 -0
- package/dist/drizzle/0090_brain_schema_extraction.sql +10 -0
- package/dist/drizzle/0132_drop_computer_tables.sql +3 -0
- package/dist/drizzle/0160_compliance_event_types_plugins.sql +2 -0
- package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +1 -0
- package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +1 -0
- package/dist/drizzle/0227_analyst_reader_role.sql +106 -38
- package/dist/drizzle/0230_analyst_rls.sql +192 -66
- package/dist/drizzle/0232_memory_source_thin_ledger.sql +176 -0
- package/dist/drizzle/0232_message_source_event_id.sql +9 -0
- package/dist/drizzle/0233_msteams_install_and_links.sql +151 -0
- package/dist/drizzle/0233_workflow_memory_stage_tokens.sql +20 -0
- package/dist/drizzle/0234_memory_claim_lifecycle.sql +160 -0
- package/dist/drizzle/0235_workflow_token_execution_claim.sql +34 -0
- package/dist/drizzle/0236_memory_retraction_fencing.sql +50 -0
- package/dist/drizzle/0237_memory_claims_active_value_uidx.sql +172 -0
- package/dist/drizzle/0238_memory_erase_generation_fence.sql +97 -0
- package/dist/drizzle/0239_canonical_entity_identity.sql +257 -0
- package/dist/drizzle/0240_memory_personal_scope.sql +45 -0
- package/dist/drizzle/0241_knowledge_base_document_manifest.sql +67 -0
- package/dist/drizzle/0242_search_queries.sql +28 -0
- package/dist/drizzle/0243_section_sources_thread_refs.sql +12 -0
- package/dist/drizzle/0244_system_automations_and_memory_stage_overrides.sql +45 -0
- package/dist/drizzle/0245_wiki_page_render.sql +21 -0
- package/dist/drizzle/0246_automation_workflow_ownership.sql +30 -0
- package/dist/drizzle/0247_capability_runtime.sql +402 -0
- package/dist/drizzle/0248_capability_private_interpreter.sql +13 -0
- package/dist/drizzle/0249_capability_headless_execution_evidence.sql +40 -0
- package/dist/drizzle/0250_kg_schema_extraction.sql +576 -0
- package/dist/drizzle/0251_agents_json_render_ui.sql +25 -0
- package/dist/drizzle/0251_brain_stragglers.sql +263 -0
- package/dist/drizzle/0252_drop_kg_and_straggler_compat_views.sql +100 -0
- package/dist/drizzle/0253_drop_brain_substrate.sql +93 -0
- package/dist/drizzle/0254_capability_autonomous_admission.sql +29 -0
- package/dist/drizzle/0255_capability_autonomous_approval_mode.sql +16 -0
- package/dist/drizzle/0256_agent_profile_manifest_authority.sql +18 -0
- package/dist/drizzle/0257_agents_runtime_allow_harness.sql +24 -0
- package/dist/drizzle/0257_capability_approvals.sql +53 -0
- package/dist/drizzle/0258_pending_tool_approvals.sql +84 -0
- package/dist/drizzle/0259_tenant_capability_registry_trust.sql +19 -0
- package/dist/drizzle/0260_scheduled_jobs_run_as_user.sql +20 -0
- package/dist/drizzle/0261_managed_harness_multiplayer.sql +313 -0
- package/dist/drizzle/0261_native_auth_control_plane.sql +328 -0
- package/dist/drizzle/0262_auth_subscription_tickets.sql +59 -0
- package/dist/drizzle/0262_parallel_harness_threads.sql +9 -0
- package/dist/drizzle/0263_agentcore_runtime_identifier.sql +69 -0
- package/dist/drizzle/0263_drop_workos_auth_runtime.sql +236 -0
- package/dist/drizzle/0264_auth_enrollment_attempt_limits.sql +15 -0
- package/dist/drizzle/0264_harness_tool_execution_ledger.sql +113 -0
- package/dist/drizzle/0265_eval_runs_requester_identity.sql +28 -0
- package/dist/drizzle/0265_require_fully_valid_auth_publication.sql +27 -0
- package/dist/drizzle/0266_auth_identity_recovery_grants.sql +9 -0
- package/dist/drizzle/0266_eval_profiles_runtime_type.sql +12 -0
- package/dist/drizzle/0267_ontology_candidate_rejections.sql +53 -0
- package/dist/drizzle/0268_identity_crosswalk_routing.sql +182 -0
- package/dist/drizzle/0269_ontology_system_map.sql +31 -0
- package/dist/event-streams-7JNLJEEL.js +894 -0
- package/dist/event-streams-KDF5RWR6.js +1515 -0
- package/dist/loadSso-DJVB7BXE.js +576 -0
- package/dist/loadSso-JAMNA3WY.js +583 -0
- package/dist/plugins/catalog/package.json +1 -2
- package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
- package/dist/plugins/catalog/src/__tests__/contracts.test.ts +0 -69
- package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
- package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
- package/dist/plugins/catalog/src/contracts.ts +2 -179
- package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
- package/dist/signin-UGDWTGS4.js +821 -0
- package/dist/sso-oidc-Q4VXANXY.js +837 -0
- package/dist/sts-CWLSE3GH.js +1241 -0
- package/dist/sts-DNZLNVOV.js +1245 -0
- package/dist/terraform/examples/greenfield/main.tf +247 -50
- package/dist/terraform/examples/greenfield/terraform.tfvars.example +15 -1
- package/dist/terraform/modules/app/agentcore-admin/main.tf +341 -0
- package/dist/terraform/modules/app/agentcore-admin/outputs.tf +20 -0
- package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +61 -0
- package/dist/terraform/modules/app/agentcore-gateway/main.tf +305 -0
- package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +44 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +93 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +33 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +543 -0
- package/dist/terraform/modules/app/agentcore-gateway/variables.tf +70 -0
- package/dist/terraform/modules/app/agentcore-harness/main.tf +330 -0
- package/dist/terraform/modules/app/agentcore-harness/outputs.tf +72 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +430 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +180 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +193 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/variables.tf +96 -0
- package/dist/terraform/modules/app/agentcore-identity/main.tf +173 -0
- package/dist/terraform/modules/app/agentcore-identity/outputs.tf +51 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +122 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +25 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_twenty_identity.sh +16 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +40 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_identity.sh +73 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +74 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +61 -0
- package/dist/terraform/modules/app/agentcore-identity/variables.tf +54 -0
- package/dist/terraform/modules/app/agentcore-pi/main.tf +7 -0
- package/dist/terraform/modules/app/appsync-subscriptions/main.tf +127 -21
- package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +0 -6
- package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +5 -0
- package/dist/terraform/modules/app/capability-broker/main.tf +393 -0
- package/dist/terraform/modules/app/capability-broker/outputs.tf +54 -0
- package/dist/terraform/modules/app/capability-broker/variables.tf +98 -0
- package/dist/terraform/modules/app/deployment-control-plane/runner.py +1011 -31
- package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +655 -2
- package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +88 -0
- package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +91 -0
- package/dist/terraform/modules/app/lambda-api/capability-search-alarms.tf +60 -0
- package/dist/terraform/modules/app/lambda-api/handlers.tf +606 -37
- package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +192 -21
- package/dist/terraform/modules/app/lambda-api/main.tf +35 -0
- package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +181 -4
- package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +92 -0
- package/dist/terraform/modules/app/lambda-api/msteams-app-secrets.tf +46 -0
- package/dist/terraform/modules/app/lambda-api/outputs.tf +35 -0
- package/dist/terraform/modules/app/lambda-api/runtime-config.tf +3 -21
- package/dist/terraform/modules/app/lambda-api/variables.tf +188 -3
- package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/alarms.tf +47 -0
- package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +43 -2
- package/dist/terraform/modules/foundation/cognito/main.tf +319 -73
- package/dist/terraform/modules/foundation/cognito/outputs.tf +42 -0
- package/dist/terraform/modules/foundation/cognito/variables.tf +124 -2
- package/dist/terraform/modules/foundation/vpc/outputs.tf +5 -0
- package/dist/terraform/modules/thinkwork/main.tf +396 -26
- package/dist/terraform/modules/thinkwork/outputs.tf +188 -5
- package/dist/terraform/modules/thinkwork/variables.tf +154 -5
- package/dist/terraform/schema.graphql +69 -36
- package/dist/workspace-defaults/files/TOOLS.md +39 -0
- package/dist/workspace-defaults/files/USER.md +1 -0
- package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +18 -0
- package/dist/workspace-defaults/files/agents/coding/INSTRUCTIONS.md +11 -0
- package/dist/workspace-defaults/files/agents/research/INSTRUCTIONS.md +12 -0
- package/dist/workspace-defaults/files/agents/reviewer/INSTRUCTIONS.md +15 -0
- package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +6 -2
- package/package.json +6 -3
- package/dist/plugins/workos-auth/package.json +0 -22
- package/dist/plugins/workos-auth/src/index.ts +0 -30
- package/dist/plugins/workos-auth/src/manifest.ts +0 -40
- package/dist/plugins/workos-auth/src/provider-contract.ts +0 -39
- package/dist/plugins/workos-auth/test/manifest.test.ts +0 -94
- package/dist/plugins/workos-auth/tsconfig.json +0 -8
- /package/dist/workspace-defaults/files/{AGENTS.md → INSTRUCTIONS.md} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- THINK-193 U1: widen workflow_task_tokens purpose domain with
|
|
2
|
+
-- 'memory_stage' (task tokens held while a memory pipeline stage runs).
|
|
3
|
+
--
|
|
4
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
5
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0233_workflow_memory_stage_tokens.sql
|
|
6
|
+
-- creates-constraint: public.workflow_task_tokens.workflow_task_tokens_purpose_check_v2
|
|
7
|
+
--
|
|
8
|
+
-- The constraint is RENAMED (_v2), not redefined in place: the drift
|
|
9
|
+
-- reporter probes constraints by NAME only, so redefining under the old
|
|
10
|
+
-- name would report APPLIED on environments still carrying the narrow
|
|
11
|
+
-- 0221 list. The _v2 name makes an unapplied widening visible as MISSING.
|
|
12
|
+
|
|
13
|
+
ALTER TABLE public.workflow_task_tokens
|
|
14
|
+
DROP CONSTRAINT IF EXISTS workflow_task_tokens_purpose_check;
|
|
15
|
+
ALTER TABLE public.workflow_task_tokens
|
|
16
|
+
DROP CONSTRAINT IF EXISTS workflow_task_tokens_purpose_check_v2;
|
|
17
|
+
ALTER TABLE public.workflow_task_tokens
|
|
18
|
+
ADD CONSTRAINT workflow_task_tokens_purpose_check_v2 CHECK (
|
|
19
|
+
purpose IN ('agent_step', 'approval', 'memory_stage')
|
|
20
|
+
);
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
-- THINK-193 U2: external-memory claim lifecycle.
|
|
2
|
+
-- Contents:
|
|
3
|
+
-- * memory_source_authorizations — explicit grant, the MAXIMUM readable
|
|
4
|
+
-- envelope per (processor, family, binding) (partial unique on active).
|
|
5
|
+
-- * memory_claims — durable ontology-shaped claims with a null-safe
|
|
6
|
+
-- fingerprint unique index (COALESCE folds NULL effective_from).
|
|
7
|
+
-- * memory_claim_evidence — many-to-many claim <- evidence support edges.
|
|
8
|
+
-- * memory_retraction_attempts — idempotent multi-system retraction ledger
|
|
9
|
+
-- (retain-attempts-shaped: status/attempt/lock columns, partial unique so
|
|
10
|
+
-- a completed retraction can be re-queued later).
|
|
11
|
+
-- * memory_evidence_items.snapshot_expires_at — app-enforced S3 snapshot TTL.
|
|
12
|
+
--
|
|
13
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
14
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0234_memory_claim_lifecycle.sql
|
|
15
|
+
-- creates: public.memory_source_authorizations
|
|
16
|
+
-- creates: public.memory_claims
|
|
17
|
+
-- creates: public.memory_claim_evidence
|
|
18
|
+
-- creates: public.memory_retraction_attempts
|
|
19
|
+
-- creates-column: public.memory_evidence_items.snapshot_expires_at
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS public.memory_source_authorizations (
|
|
22
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
23
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
24
|
+
processor_config_id uuid NOT NULL
|
|
25
|
+
REFERENCES public.memory_processor_configs(id) ON DELETE CASCADE,
|
|
26
|
+
source_family text NOT NULL,
|
|
27
|
+
source_binding_key text NOT NULL,
|
|
28
|
+
boundary jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
29
|
+
granted_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
|
|
30
|
+
grant_version integer NOT NULL DEFAULT 1,
|
|
31
|
+
status text NOT NULL DEFAULT 'active',
|
|
32
|
+
expires_at timestamptz,
|
|
33
|
+
revoked_at timestamptz,
|
|
34
|
+
sensitivity jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
35
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
36
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
37
|
+
CONSTRAINT memory_source_authorizations_source_family_check
|
|
38
|
+
CHECK (source_family IN ('twenty', 'firecrawl', 'email', 'bedrock_kb')),
|
|
39
|
+
CONSTRAINT memory_source_authorizations_status_check
|
|
40
|
+
CHECK (status IN ('active', 'revoked', 'expired'))
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
CREATE UNIQUE INDEX IF NOT EXISTS memory_source_authorizations_active_uidx
|
|
44
|
+
ON public.memory_source_authorizations (processor_config_id, source_family, source_binding_key)
|
|
45
|
+
WHERE status = 'active';
|
|
46
|
+
|
|
47
|
+
CREATE INDEX IF NOT EXISTS memory_source_authorizations_tenant_idx
|
|
48
|
+
ON public.memory_source_authorizations (tenant_id);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE IF NOT EXISTS public.memory_claims (
|
|
51
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
52
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
53
|
+
target_scope text NOT NULL,
|
|
54
|
+
target_id uuid NOT NULL,
|
|
55
|
+
canonical_subject_id uuid,
|
|
56
|
+
subject_key text NOT NULL,
|
|
57
|
+
subject_entity_type text NOT NULL DEFAULT 'customer',
|
|
58
|
+
ontology_predicate text NOT NULL,
|
|
59
|
+
value jsonb NOT NULL,
|
|
60
|
+
value_hash text NOT NULL,
|
|
61
|
+
effective_from timestamptz,
|
|
62
|
+
effective_to timestamptz,
|
|
63
|
+
status text NOT NULL DEFAULT 'active',
|
|
64
|
+
conflict_state text NOT NULL DEFAULT 'none',
|
|
65
|
+
extraction_version text NOT NULL,
|
|
66
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
67
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
68
|
+
CONSTRAINT memory_claims_target_scope_check
|
|
69
|
+
CHECK (target_scope IN ('space', 'tenant')),
|
|
70
|
+
CONSTRAINT memory_claims_status_check
|
|
71
|
+
CHECK (status IN ('active', 'superseded', 'retracted')),
|
|
72
|
+
CONSTRAINT memory_claims_conflict_state_check
|
|
73
|
+
CHECK (conflict_state IN ('none', 'conflicted'))
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
-- Null-safe fingerprint: COALESCE folds NULL effective_from into '-infinity'
|
|
77
|
+
-- so duplicate open-ended claims collide instead of coexisting.
|
|
78
|
+
CREATE UNIQUE INDEX IF NOT EXISTS memory_claims_fingerprint_uidx
|
|
79
|
+
ON public.memory_claims (
|
|
80
|
+
tenant_id,
|
|
81
|
+
target_scope,
|
|
82
|
+
target_id,
|
|
83
|
+
subject_key,
|
|
84
|
+
ontology_predicate,
|
|
85
|
+
value_hash,
|
|
86
|
+
COALESCE(effective_from, '-infinity'::timestamptz)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
CREATE INDEX IF NOT EXISTS memory_claims_target_subject_idx
|
|
90
|
+
ON public.memory_claims (tenant_id, target_scope, target_id, subject_key);
|
|
91
|
+
|
|
92
|
+
CREATE INDEX IF NOT EXISTS memory_claims_tenant_status_idx
|
|
93
|
+
ON public.memory_claims (tenant_id, status);
|
|
94
|
+
|
|
95
|
+
CREATE TABLE IF NOT EXISTS public.memory_claim_evidence (
|
|
96
|
+
id bigserial PRIMARY KEY,
|
|
97
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
98
|
+
claim_id uuid NOT NULL
|
|
99
|
+
REFERENCES public.memory_claims(id) ON DELETE CASCADE,
|
|
100
|
+
evidence_item_id uuid NOT NULL
|
|
101
|
+
REFERENCES public.memory_evidence_items(id) ON DELETE CASCADE,
|
|
102
|
+
source_config_id uuid NOT NULL
|
|
103
|
+
REFERENCES public.memory_source_configs(id) ON DELETE CASCADE,
|
|
104
|
+
status text NOT NULL DEFAULT 'active',
|
|
105
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
106
|
+
retracted_at timestamptz,
|
|
107
|
+
CONSTRAINT memory_claim_evidence_status_check
|
|
108
|
+
CHECK (status IN ('active', 'retracted'))
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
CREATE UNIQUE INDEX IF NOT EXISTS memory_claim_evidence_pair_uidx
|
|
112
|
+
ON public.memory_claim_evidence (claim_id, evidence_item_id);
|
|
113
|
+
|
|
114
|
+
CREATE INDEX IF NOT EXISTS memory_claim_evidence_evidence_idx
|
|
115
|
+
ON public.memory_claim_evidence (evidence_item_id);
|
|
116
|
+
|
|
117
|
+
CREATE INDEX IF NOT EXISTS memory_claim_evidence_claim_status_idx
|
|
118
|
+
ON public.memory_claim_evidence (claim_id, status);
|
|
119
|
+
|
|
120
|
+
CREATE TABLE IF NOT EXISTS public.memory_retraction_attempts (
|
|
121
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
122
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
123
|
+
scope text NOT NULL,
|
|
124
|
+
derivation_id uuid REFERENCES public.memory_derivations(id) ON DELETE SET NULL,
|
|
125
|
+
source_config_id uuid NOT NULL
|
|
126
|
+
REFERENCES public.memory_source_configs(id) ON DELETE CASCADE,
|
|
127
|
+
provider text NOT NULL DEFAULT 'hindsight',
|
|
128
|
+
provider_document_id text NOT NULL,
|
|
129
|
+
target_bank_id text NOT NULL,
|
|
130
|
+
status text NOT NULL DEFAULT 'queued',
|
|
131
|
+
attempt_count integer NOT NULL DEFAULT 0,
|
|
132
|
+
max_attempts integer NOT NULL DEFAULT 5,
|
|
133
|
+
next_retry_at timestamptz,
|
|
134
|
+
locked_at timestamptz,
|
|
135
|
+
locked_by text,
|
|
136
|
+
error_class text,
|
|
137
|
+
error_message text,
|
|
138
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
139
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
140
|
+
completed_at timestamptz,
|
|
141
|
+
CONSTRAINT memory_retraction_attempts_scope_check
|
|
142
|
+
CHECK (scope IN ('derivation', 'source')),
|
|
143
|
+
CONSTRAINT memory_retraction_attempts_status_check
|
|
144
|
+
CHECK (status IN ('queued', 'running', 'supports_updated', 'provider_deleted', 'reconsolidated', 'retracted', 'failed', 'dead_lettered')),
|
|
145
|
+
CONSTRAINT memory_retraction_attempts_attempt_count_nonnegative
|
|
146
|
+
CHECK (attempt_count >= 0),
|
|
147
|
+
CONSTRAINT memory_retraction_attempts_max_attempts_positive
|
|
148
|
+
CHECK (max_attempts > 0)
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
-- Partial unique — a completed retraction can be re-queued later.
|
|
152
|
+
CREATE UNIQUE INDEX IF NOT EXISTS memory_retraction_attempts_document_uidx
|
|
153
|
+
ON public.memory_retraction_attempts (tenant_id, provider, provider_document_id)
|
|
154
|
+
WHERE status NOT IN ('retracted', 'dead_lettered');
|
|
155
|
+
|
|
156
|
+
CREATE INDEX IF NOT EXISTS memory_retraction_attempts_due_idx
|
|
157
|
+
ON public.memory_retraction_attempts (status, next_retry_at, created_at);
|
|
158
|
+
|
|
159
|
+
ALTER TABLE public.memory_evidence_items
|
|
160
|
+
ADD COLUMN IF NOT EXISTS snapshot_expires_at timestamptz;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- THINK-193 U1 (Codex F1/F7/F9): durable pre-execution claim for workflow
|
|
2
|
+
-- task tokens. Adds the 'executing' status (pending -> executing -> consumed),
|
|
3
|
+
-- lease columns (locked_at/locked_by, stale claims are re-claimable), and a
|
|
4
|
+
-- persisted completion result for safe redrive after a SendTaskSuccess
|
|
5
|
+
-- transient failure.
|
|
6
|
+
--
|
|
7
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
8
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0235_workflow_token_execution_claim.sql
|
|
9
|
+
-- creates-constraint: public.workflow_task_tokens.workflow_task_tokens_status_check_v2
|
|
10
|
+
-- creates-column: public.workflow_task_tokens.locked_at
|
|
11
|
+
-- creates-column: public.workflow_task_tokens.locked_by
|
|
12
|
+
-- creates-column: public.workflow_task_tokens.result
|
|
13
|
+
--
|
|
14
|
+
-- The constraint is RENAMED (_v2), not redefined in place: the drift
|
|
15
|
+
-- reporter probes constraints by NAME only, so redefining under the old
|
|
16
|
+
-- name would report APPLIED on environments still carrying the narrow
|
|
17
|
+
-- three-status list. The _v2 name makes an unapplied widening visible as
|
|
18
|
+
-- MISSING. (Same precedent as 0233's purpose-check widening.)
|
|
19
|
+
|
|
20
|
+
ALTER TABLE public.workflow_task_tokens
|
|
21
|
+
ADD COLUMN IF NOT EXISTS locked_at timestamptz;
|
|
22
|
+
ALTER TABLE public.workflow_task_tokens
|
|
23
|
+
ADD COLUMN IF NOT EXISTS locked_by text;
|
|
24
|
+
ALTER TABLE public.workflow_task_tokens
|
|
25
|
+
ADD COLUMN IF NOT EXISTS result jsonb;
|
|
26
|
+
|
|
27
|
+
ALTER TABLE public.workflow_task_tokens
|
|
28
|
+
DROP CONSTRAINT IF EXISTS workflow_task_tokens_status_check;
|
|
29
|
+
ALTER TABLE public.workflow_task_tokens
|
|
30
|
+
DROP CONSTRAINT IF EXISTS workflow_task_tokens_status_check_v2;
|
|
31
|
+
ALTER TABLE public.workflow_task_tokens
|
|
32
|
+
ADD CONSTRAINT workflow_task_tokens_status_check_v2 CHECK (
|
|
33
|
+
status IN ('pending', 'executing', 'consumed', 'expired')
|
|
34
|
+
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
-- THINK-193 U2 (Codex P1/P2 merge blockers): retraction saga worker fencing
|
|
2
|
+
-- and durable source-erase aggregate markers.
|
|
3
|
+
-- Contents:
|
|
4
|
+
-- * memory_retraction_attempts.lock_generation — fencing token; every CAS
|
|
5
|
+
-- claim increments it and all saga transitions (recordProgress /
|
|
6
|
+
-- finalizeInternalState / markRetracted / markFailed) CAS on
|
|
7
|
+
-- (locked_by, lock_generation) so a worker reclaimed past a stale lease
|
|
8
|
+
-- can never clobber the newer claimant's progress.
|
|
9
|
+
-- * memory_retraction_attempts.reconsolidation_note — non-null when the
|
|
10
|
+
-- reconsolidation step was skipped (delete-capable adapter without a
|
|
11
|
+
-- consolidator): durable skipped-with-reason, distinct from success.
|
|
12
|
+
-- * scope CHECK v2 — adds 'erase': one durable aggregate marker row per
|
|
13
|
+
-- source erase (synthetic erase:<sourceConfigId> document id under the
|
|
14
|
+
-- existing partial unique document index). Markers are excluded from the
|
|
15
|
+
-- per-document saga; the scheduled memory-retraction-drainer keys its
|
|
16
|
+
-- self-finalizing cleanup sweep (S3 snapshot prefix -> evidence purge ->
|
|
17
|
+
-- checkpoints LAST) on them, covering sources with zero derivations.
|
|
18
|
+
-- NEW constraint name: the drift reporter probes by name only.
|
|
19
|
+
--
|
|
20
|
+
-- No status CHECK changes: the status value set is unchanged; only the
|
|
21
|
+
-- saga's transition ORDER moved (provider delete now precedes the internal
|
|
22
|
+
-- finalize transaction).
|
|
23
|
+
--
|
|
24
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
25
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0236_memory_retraction_fencing.sql
|
|
26
|
+
-- creates-column: public.memory_retraction_attempts.lock_generation
|
|
27
|
+
-- creates-column: public.memory_retraction_attempts.reconsolidation_note
|
|
28
|
+
-- creates-constraint: public.memory_retraction_attempts.memory_retraction_attempts_scope_check_v2
|
|
29
|
+
|
|
30
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
31
|
+
ADD COLUMN IF NOT EXISTS lock_generation integer NOT NULL DEFAULT 0;
|
|
32
|
+
|
|
33
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
34
|
+
ADD COLUMN IF NOT EXISTS reconsolidation_note text;
|
|
35
|
+
|
|
36
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
37
|
+
DROP CONSTRAINT IF EXISTS memory_retraction_attempts_scope_check;
|
|
38
|
+
|
|
39
|
+
DO $$
|
|
40
|
+
BEGIN
|
|
41
|
+
IF NOT EXISTS (
|
|
42
|
+
SELECT 1 FROM pg_constraint
|
|
43
|
+
WHERE conname = 'memory_retraction_attempts_scope_check_v2'
|
|
44
|
+
AND conrelid = 'public.memory_retraction_attempts'::regclass
|
|
45
|
+
) THEN
|
|
46
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
47
|
+
ADD CONSTRAINT memory_retraction_attempts_scope_check_v2
|
|
48
|
+
CHECK (scope IN ('derivation', 'source', 'erase'));
|
|
49
|
+
END IF;
|
|
50
|
+
END $$;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
-- THINK-193 U2 (Codex concurrency finding): structural backstop against
|
|
2
|
+
-- duplicate ACTIVE same-value claims. upsertClaimsForEvidence serializes
|
|
3
|
+
-- writers with a per-subject transaction-scoped advisory lock; this partial
|
|
4
|
+
-- unique index guarantees the invariant even if a future caller bypasses
|
|
5
|
+
-- the lock. Superseded/retracted rows keep full temporal history (a value
|
|
6
|
+
-- may recur later as a NEW active edition — only one can be active).
|
|
7
|
+
--
|
|
8
|
+
-- Codex round-5/6 P1: a bare CREATE UNIQUE INDEX cannot upgrade a database
|
|
9
|
+
-- that already contains the duplicates the index forbids, and repair +
|
|
10
|
+
-- index creation must be ATOMIC against concurrent writers. The whole file
|
|
11
|
+
-- is ONE explicit transaction that write-locks memory_claims and
|
|
12
|
+
-- memory_claim_evidence before scanning:
|
|
13
|
+
-- 1. ABORT loudly if any active duplicate group has the same value_hash
|
|
14
|
+
-- but DIFFERENT full JSON values (sha256 collision — human decision).
|
|
15
|
+
-- 2. Per duplicate group, keep the EARLIEST row (created_at, id). Edge
|
|
16
|
+
-- merge is PAIR-SAFE: first materialize the DISTINCT
|
|
17
|
+
-- (keeper, evidence) pairs implied by all loser ACTIVE edges, then
|
|
18
|
+
-- ensure exactly ONE ACTIVE keeper edge per pair (reactivating a
|
|
19
|
+
-- pre-existing retracted keeper edge, inserting otherwise — never
|
|
20
|
+
-- violating the (claim_id, evidence_item_id) pair unique), then
|
|
21
|
+
-- retract all loser edges. Finally close the losers as 'superseded'
|
|
22
|
+
-- with the duplicate-edition interval policy: zero-length at their own
|
|
23
|
+
-- effective_from when the keeper is earlier-or-equal (NULL keeper
|
|
24
|
+
-- counts as earliest), else closed at the keeper's effective_from; a
|
|
25
|
+
-- NULL result falls back to now() so every ended interval is closed.
|
|
26
|
+
-- 3. Assert zero remaining active duplicates (RAISE rolls the whole
|
|
27
|
+
-- transaction back).
|
|
28
|
+
-- Re-running is idempotent: with no duplicates the repair is a no-op and
|
|
29
|
+
-- the index CREATE is IF NOT EXISTS.
|
|
30
|
+
--
|
|
31
|
+
-- Hand-rolled (partial index + repair; drizzle-kit cannot express it).
|
|
32
|
+
-- Apply with:
|
|
33
|
+
-- psql "$DATABASE_URL" -f drizzle/0237_memory_claims_active_value_uidx.sql
|
|
34
|
+
-- creates: public.memory_claims_active_value_uidx
|
|
35
|
+
|
|
36
|
+
BEGIN;
|
|
37
|
+
|
|
38
|
+
LOCK TABLE public.memory_claims IN SHARE ROW EXCLUSIVE MODE;
|
|
39
|
+
LOCK TABLE public.memory_claim_evidence IN SHARE ROW EXCLUSIVE MODE;
|
|
40
|
+
|
|
41
|
+
DO $$
|
|
42
|
+
DECLARE
|
|
43
|
+
collision_groups integer;
|
|
44
|
+
remaining_duplicates integer;
|
|
45
|
+
BEGIN
|
|
46
|
+
-- 1. Same hash, different value: refuse to merge automatically.
|
|
47
|
+
SELECT count(*) INTO collision_groups FROM (
|
|
48
|
+
SELECT 1
|
|
49
|
+
FROM memory_claims
|
|
50
|
+
WHERE status = 'active'
|
|
51
|
+
GROUP BY tenant_id, target_scope, target_id, subject_key,
|
|
52
|
+
ontology_predicate, value_hash
|
|
53
|
+
HAVING count(*) > 1 AND count(DISTINCT value::text) > 1
|
|
54
|
+
) t;
|
|
55
|
+
IF collision_groups > 0 THEN
|
|
56
|
+
RAISE EXCEPTION
|
|
57
|
+
'memory_claims: % active duplicate group(s) share value_hash with DIFFERING values (hash collision) — resolve manually before applying 0237',
|
|
58
|
+
collision_groups;
|
|
59
|
+
END IF;
|
|
60
|
+
|
|
61
|
+
-- 2. Deterministic repair of identical-value active duplicates.
|
|
62
|
+
CREATE TEMP TABLE _mc_active_dupe_losers ON COMMIT DROP AS
|
|
63
|
+
SELECT id,
|
|
64
|
+
keeper_id,
|
|
65
|
+
keeper_effective_from,
|
|
66
|
+
effective_from AS own_effective_from
|
|
67
|
+
FROM (
|
|
68
|
+
SELECT id,
|
|
69
|
+
effective_from,
|
|
70
|
+
first_value(id) OVER w AS keeper_id,
|
|
71
|
+
first_value(effective_from) OVER w AS keeper_effective_from,
|
|
72
|
+
row_number() OVER w AS rn
|
|
73
|
+
FROM memory_claims
|
|
74
|
+
WHERE status = 'active'
|
|
75
|
+
WINDOW w AS (
|
|
76
|
+
PARTITION BY tenant_id, target_scope, target_id, subject_key,
|
|
77
|
+
ontology_predicate, value_hash
|
|
78
|
+
ORDER BY created_at, id
|
|
79
|
+
)
|
|
80
|
+
) ranked
|
|
81
|
+
WHERE rn > 1;
|
|
82
|
+
|
|
83
|
+
-- 2a. Materialize the DISTINCT (keeper, evidence) pairs implied by loser
|
|
84
|
+
-- ACTIVE edges — several losers sharing one evidence item collapse to
|
|
85
|
+
-- one target pair, so the merge can never violate the
|
|
86
|
+
-- (claim_id, evidence_item_id) pair unique.
|
|
87
|
+
CREATE TEMP TABLE _mc_keeper_pairs ON COMMIT DROP AS
|
|
88
|
+
SELECT DISTINCT ON (l.keeper_id, e.evidence_item_id)
|
|
89
|
+
l.keeper_id,
|
|
90
|
+
e.evidence_item_id,
|
|
91
|
+
e.tenant_id,
|
|
92
|
+
e.source_config_id
|
|
93
|
+
FROM memory_claim_evidence e
|
|
94
|
+
JOIN _mc_active_dupe_losers l ON l.id = e.claim_id
|
|
95
|
+
WHERE e.status = 'active';
|
|
96
|
+
|
|
97
|
+
-- 2b. Reactivate a pre-existing (possibly retracted) keeper edge for each
|
|
98
|
+
-- pair — the keeper must end with ACTIVE support wherever a loser had
|
|
99
|
+
-- it.
|
|
100
|
+
UPDATE memory_claim_evidence k
|
|
101
|
+
SET status = 'active', retracted_at = NULL
|
|
102
|
+
FROM _mc_keeper_pairs p
|
|
103
|
+
WHERE k.claim_id = p.keeper_id
|
|
104
|
+
AND k.evidence_item_id = p.evidence_item_id
|
|
105
|
+
AND k.status <> 'active';
|
|
106
|
+
|
|
107
|
+
-- 2c. Insert the keeper edges that do not exist at all.
|
|
108
|
+
INSERT INTO memory_claim_evidence
|
|
109
|
+
(tenant_id, claim_id, evidence_item_id, source_config_id, status)
|
|
110
|
+
SELECT p.tenant_id, p.keeper_id, p.evidence_item_id, p.source_config_id,
|
|
111
|
+
'active'
|
|
112
|
+
FROM _mc_keeper_pairs p
|
|
113
|
+
WHERE NOT EXISTS (
|
|
114
|
+
SELECT 1 FROM memory_claim_evidence k
|
|
115
|
+
WHERE k.claim_id = p.keeper_id
|
|
116
|
+
AND k.evidence_item_id = p.evidence_item_id
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
-- 2d. Retract ALL loser active edges (their support now lives on the
|
|
120
|
+
-- keeper).
|
|
121
|
+
UPDATE memory_claim_evidence e
|
|
122
|
+
SET status = 'retracted', retracted_at = now()
|
|
123
|
+
FROM _mc_active_dupe_losers l
|
|
124
|
+
WHERE e.claim_id = l.id
|
|
125
|
+
AND e.status = 'active';
|
|
126
|
+
|
|
127
|
+
-- 2e. Close and supersede the losers (duplicate-edition interval policy).
|
|
128
|
+
UPDATE memory_claims c
|
|
129
|
+
SET status = 'superseded',
|
|
130
|
+
effective_to = COALESCE(
|
|
131
|
+
c.effective_to,
|
|
132
|
+
CASE
|
|
133
|
+
WHEN l.keeper_effective_from IS NULL
|
|
134
|
+
OR (l.own_effective_from IS NOT NULL
|
|
135
|
+
AND l.keeper_effective_from <= l.own_effective_from)
|
|
136
|
+
THEN l.own_effective_from
|
|
137
|
+
ELSE l.keeper_effective_from
|
|
138
|
+
END,
|
|
139
|
+
now()
|
|
140
|
+
),
|
|
141
|
+
updated_at = now()
|
|
142
|
+
FROM _mc_active_dupe_losers l
|
|
143
|
+
WHERE c.id = l.id;
|
|
144
|
+
|
|
145
|
+
-- 3. The invariant must hold before the index lands.
|
|
146
|
+
SELECT count(*) INTO remaining_duplicates FROM (
|
|
147
|
+
SELECT 1
|
|
148
|
+
FROM memory_claims
|
|
149
|
+
WHERE status = 'active'
|
|
150
|
+
GROUP BY tenant_id, target_scope, target_id, subject_key,
|
|
151
|
+
ontology_predicate, value_hash
|
|
152
|
+
HAVING count(*) > 1
|
|
153
|
+
) t;
|
|
154
|
+
IF remaining_duplicates > 0 THEN
|
|
155
|
+
RAISE EXCEPTION
|
|
156
|
+
'memory_claims duplicate repair left % active duplicate group(s) — aborting index creation',
|
|
157
|
+
remaining_duplicates;
|
|
158
|
+
END IF;
|
|
159
|
+
END $$;
|
|
160
|
+
|
|
161
|
+
CREATE UNIQUE INDEX IF NOT EXISTS memory_claims_active_value_uidx
|
|
162
|
+
ON public.memory_claims (
|
|
163
|
+
tenant_id,
|
|
164
|
+
target_scope,
|
|
165
|
+
target_id,
|
|
166
|
+
subject_key,
|
|
167
|
+
ontology_predicate,
|
|
168
|
+
value_hash
|
|
169
|
+
)
|
|
170
|
+
WHERE status = 'active';
|
|
171
|
+
|
|
172
|
+
COMMIT;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
-- THINK-193 U2 (Codex rounds 3-6): erase write-fence, per-generation child
|
|
2
|
+
-- scoping, durable bounded-cleanup progress, and DB-level integrity for the
|
|
3
|
+
-- retraction saga.
|
|
4
|
+
-- Contents:
|
|
5
|
+
-- * memory_source_configs.erase_generation — the erase write-fence. Bumped
|
|
6
|
+
-- in the SAME transaction that disables the source and persists the
|
|
7
|
+
-- durable 'erase' marker (beginSourceErase). Stage writers capture it
|
|
8
|
+
-- with the source row; internal writes CAS on it inside their own
|
|
9
|
+
-- transaction and external writes (Hindsight upsert, S3 put) check it
|
|
10
|
+
-- immediately before AND after the call (with compensation on movement),
|
|
11
|
+
-- so an in-flight acquire/project/retain cannot resurrect
|
|
12
|
+
-- claims/snapshots/documents after an erase starts.
|
|
13
|
+
-- * memory_retraction_attempts.erase_generation — tags 'erase' markers and
|
|
14
|
+
-- their 'source'-scoped children with the generation they belong to, so
|
|
15
|
+
-- aggregate child accounting never counts dead-lettered children from a
|
|
16
|
+
-- PREVIOUS (remediated) erase. Constrained to 0 for derivation-scoped
|
|
17
|
+
-- rows.
|
|
18
|
+
-- * memory_retraction_attempts.cleanup_phase / cleanup_cursor — durable
|
|
19
|
+
-- bounded-cleanup progress on the 'erase' marker (NULL →
|
|
20
|
+
-- 'snapshots_deleted' → 'evidence_purged'; checkpoints last, then
|
|
21
|
+
-- terminal). Closed CHECK domain, valid only on scope='erase'.
|
|
22
|
+
-- * Composite accounting index for the per-generation child queries.
|
|
23
|
+
--
|
|
24
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
25
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0238_memory_erase_generation_fence.sql
|
|
26
|
+
-- creates-column: public.memory_source_configs.erase_generation
|
|
27
|
+
-- creates-column: public.memory_retraction_attempts.erase_generation
|
|
28
|
+
-- creates-column: public.memory_retraction_attempts.cleanup_phase
|
|
29
|
+
-- creates-column: public.memory_retraction_attempts.cleanup_cursor
|
|
30
|
+
-- creates-constraint: public.memory_source_configs.memory_source_configs_erase_generation_nonnegative
|
|
31
|
+
-- creates-constraint: public.memory_retraction_attempts.memory_retraction_attempts_erase_generation_nonnegative
|
|
32
|
+
-- creates-constraint: public.memory_retraction_attempts.memory_retraction_attempts_derivation_generation_check
|
|
33
|
+
-- creates-constraint: public.memory_retraction_attempts.memory_retraction_attempts_cleanup_phase_check
|
|
34
|
+
-- creates: public.memory_retraction_attempts_erase_accounting_idx
|
|
35
|
+
|
|
36
|
+
ALTER TABLE public.memory_source_configs
|
|
37
|
+
ADD COLUMN IF NOT EXISTS erase_generation integer NOT NULL DEFAULT 0;
|
|
38
|
+
|
|
39
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
40
|
+
ADD COLUMN IF NOT EXISTS erase_generation integer NOT NULL DEFAULT 0;
|
|
41
|
+
|
|
42
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
43
|
+
ADD COLUMN IF NOT EXISTS cleanup_phase text;
|
|
44
|
+
|
|
45
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
46
|
+
ADD COLUMN IF NOT EXISTS cleanup_cursor text;
|
|
47
|
+
|
|
48
|
+
DO $$
|
|
49
|
+
BEGIN
|
|
50
|
+
IF NOT EXISTS (
|
|
51
|
+
SELECT 1 FROM pg_constraint
|
|
52
|
+
WHERE conname = 'memory_source_configs_erase_generation_nonnegative'
|
|
53
|
+
AND conrelid = 'public.memory_source_configs'::regclass
|
|
54
|
+
) THEN
|
|
55
|
+
ALTER TABLE public.memory_source_configs
|
|
56
|
+
ADD CONSTRAINT memory_source_configs_erase_generation_nonnegative
|
|
57
|
+
CHECK (erase_generation >= 0);
|
|
58
|
+
END IF;
|
|
59
|
+
|
|
60
|
+
IF NOT EXISTS (
|
|
61
|
+
SELECT 1 FROM pg_constraint
|
|
62
|
+
WHERE conname = 'memory_retraction_attempts_erase_generation_nonnegative'
|
|
63
|
+
AND conrelid = 'public.memory_retraction_attempts'::regclass
|
|
64
|
+
) THEN
|
|
65
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
66
|
+
ADD CONSTRAINT memory_retraction_attempts_erase_generation_nonnegative
|
|
67
|
+
CHECK (erase_generation >= 0);
|
|
68
|
+
END IF;
|
|
69
|
+
|
|
70
|
+
IF NOT EXISTS (
|
|
71
|
+
SELECT 1 FROM pg_constraint
|
|
72
|
+
WHERE conname = 'memory_retraction_attempts_derivation_generation_check'
|
|
73
|
+
AND conrelid = 'public.memory_retraction_attempts'::regclass
|
|
74
|
+
) THEN
|
|
75
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
76
|
+
ADD CONSTRAINT memory_retraction_attempts_derivation_generation_check
|
|
77
|
+
CHECK (scope <> 'derivation' OR erase_generation = 0);
|
|
78
|
+
END IF;
|
|
79
|
+
|
|
80
|
+
IF NOT EXISTS (
|
|
81
|
+
SELECT 1 FROM pg_constraint
|
|
82
|
+
WHERE conname = 'memory_retraction_attempts_cleanup_phase_check'
|
|
83
|
+
AND conrelid = 'public.memory_retraction_attempts'::regclass
|
|
84
|
+
) THEN
|
|
85
|
+
ALTER TABLE public.memory_retraction_attempts
|
|
86
|
+
ADD CONSTRAINT memory_retraction_attempts_cleanup_phase_check
|
|
87
|
+
CHECK (
|
|
88
|
+
cleanup_phase IS NULL
|
|
89
|
+
OR (scope = 'erase'
|
|
90
|
+
AND cleanup_phase IN ('snapshots_deleted', 'evidence_purged'))
|
|
91
|
+
);
|
|
92
|
+
END IF;
|
|
93
|
+
END $$;
|
|
94
|
+
|
|
95
|
+
CREATE INDEX IF NOT EXISTS memory_retraction_attempts_erase_accounting_idx
|
|
96
|
+
ON public.memory_retraction_attempts
|
|
97
|
+
(source_config_id, erase_generation, scope, status);
|