| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- """Create the closed, fixture-only P3-WP13 plugin control plane."""
- from alembic import op
- revision = "20260818_553"
- down_revision = "20260818_552"
- branch_labels = None
- depends_on = None
- _TABLES = (
- "plugin_registry_versions",
- "plugin_approvals",
- "plugin_runtime_leases",
- "plugin_runs",
- "plugin_dead_letters",
- "plugin_audit_outbox",
- )
- def upgrade() -> None:
- op.get_bind().exec_driver_sql(r'''
- DO $roles$ BEGIN
- IF NOT EXISTS(SELECT 1 FROM pg_roles WHERE rolname='dataops_plugin_platform_owner' AND NOT rolcanlogin AND NOT rolsuper AND NOT rolcreaterole)
- OR NOT EXISTS(SELECT 1 FROM pg_roles WHERE rolname='dataops_plugin_platform_control' AND NOT rolcanlogin)
- OR NOT EXISTS(SELECT 1 FROM pg_roles WHERE rolname='dataops_app_runtime') THEN
- RAISE EXCEPTION 'WP13 roles must be provisioned by role-init';
- END IF;
- END $roles$;
- CREATE TABLE public.plugin_registry_versions (
- plugin_uid text NOT NULL CHECK(plugin_uid ~ '^[a-z][a-z0-9-]{2,62}$'),
- version text NOT NULL CHECK(version ~ '^[0-9]+[.][0-9]+[.][0-9]+([-.][A-Za-z0-9.]+)?$'),
- plugin_type text NOT NULL CHECK(plugin_type IN ('connector','parser','quality','notification','approval','agent_mcp')),
- manifest_digest char(64) NOT NULL CHECK(manifest_digest ~ '^[0-9a-f]{64}$'),
- artifact_digest char(64) NOT NULL CHECK(artifact_digest ~ '^[0-9a-f]{64}$'),
- trust_store_key_id text NOT NULL CHECK(trust_store_key_id='local-fixture-key-v1'),
- signature_digest char(64) NOT NULL CHECK(signature_digest ~ '^[0-9a-f]{64}$'),
- sbom_digest char(64) NOT NULL CHECK(sbom_digest ~ '^[0-9a-f]{64}$'),
- license_digest char(64) NOT NULL CHECK(license_digest ~ '^[0-9a-f]{64}$'),
- vulnerability_digest char(64) NOT NULL CHECK(vulnerability_digest ~ '^[0-9a-f]{64}$'),
- provenance_digest char(64) NOT NULL CHECK(provenance_digest ~ '^[0-9a-f]{64}$'),
- fixture_id text NOT NULL CHECK(fixture_id='ENGINEERING_EVIDENCE_ONLY'),
- permissions jsonb NOT NULL CHECK(permissions='{"file": false, "network": false, "secret": false, "child_process": false}'::jsonb),
- state text NOT NULL DEFAULT 'draft' CHECK(state IN ('draft','reviewed','approved','canary','active','paused','revoked','rolled_back','recovery')),
- review_actor text, reviewed_at timestamptz, activated_at timestamptz,
- created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
- PRIMARY KEY(plugin_uid,version), UNIQUE(manifest_digest), UNIQUE(artifact_digest)
- );
- CREATE UNIQUE INDEX plugin_registry_one_active ON public.plugin_registry_versions(plugin_uid) WHERE state='active';
- CREATE TABLE public.plugin_approvals (
- approval_uid uuid PRIMARY KEY DEFAULT gen_random_uuid(), plugin_uid text NOT NULL, version text NOT NULL,
- action_name text NOT NULL CHECK(action_name IN ('approve','canary','activate','pause','rollback','revoke','recover')),
- actor_ref text NOT NULL CHECK(actor_ref ~ '^[A-Za-z0-9_.:-]{1,120}$'),
- reviewer_ref text NOT NULL CHECK(reviewer_ref ~ '^[A-Za-z0-9_.:-]{1,120}$' AND reviewer_ref<>actor_ref),
- tenant_ref text NOT NULL CHECK(tenant_ref ~ '^[a-z][a-z0-9-]{0,62}$'), domain_ref text NOT NULL CHECK(domain_ref ~ '^[a-z][a-z0-9-]{0,62}$'),
- manifest_digest char(64) NOT NULL CHECK(manifest_digest ~ '^[0-9a-f]{64}$'), expires_at timestamptz NOT NULL,
- consumed_at timestamptz, created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
- FOREIGN KEY(plugin_uid,version) REFERENCES public.plugin_registry_versions(plugin_uid,version) ON DELETE RESTRICT,
- UNIQUE(plugin_uid,version,action_name,actor_ref,tenant_ref,domain_ref,manifest_digest)
- );
- CREATE TABLE public.plugin_runtime_leases (
- plugin_uid text NOT NULL, version text NOT NULL, tenant_ref text NOT NULL,
- lease_owner text, lease_token uuid, lease_fence bigint NOT NULL DEFAULT 0 CHECK(lease_fence>=0), lease_expires_at timestamptz,
- PRIMARY KEY(plugin_uid,version,tenant_ref), FOREIGN KEY(plugin_uid,version) REFERENCES public.plugin_registry_versions(plugin_uid,version) ON DELETE RESTRICT
- );
- CREATE TABLE public.plugin_runs (
- run_uid uuid PRIMARY KEY DEFAULT gen_random_uuid(), plugin_uid text NOT NULL, version text NOT NULL,
- tenant_ref text NOT NULL, domain_ref text NOT NULL, principal_ref text NOT NULL, operation_name text NOT NULL,
- idempotency_key text NOT NULL CHECK(idempotency_key ~ '^[A-Za-z0-9_.:-]{1,120}$'),
- input_digest char(64) NOT NULL CHECK(input_digest ~ '^[0-9a-f]{64}$'), output_digest char(64),
- request_digest char(64) NOT NULL CHECK(request_digest ~ '^[0-9a-f]{64}$'), lease_fence bigint NOT NULL CHECK(lease_fence>=0),
- state text NOT NULL CHECK(state IN ('running','succeeded','failed','dead_letter')),
- created_at timestamptz NOT NULL DEFAULT clock_timestamp(), completed_at timestamptz,
- FOREIGN KEY(plugin_uid,version) REFERENCES public.plugin_registry_versions(plugin_uid,version) ON DELETE RESTRICT,
- UNIQUE(plugin_uid,version,tenant_ref,idempotency_key)
- );
- CREATE TABLE public.plugin_dead_letters (
- dead_letter_uid uuid PRIMARY KEY DEFAULT gen_random_uuid(), run_uid uuid NOT NULL UNIQUE REFERENCES public.plugin_runs(run_uid) ON DELETE RESTRICT,
- failure_digest char(64) NOT NULL CHECK(failure_digest ~ '^[0-9a-f]{64}$'), incident_ref text, created_at timestamptz NOT NULL DEFAULT clock_timestamp()
- );
- CREATE TABLE public.plugin_audit_outbox (
- audit_uid uuid PRIMARY KEY DEFAULT gen_random_uuid(), plugin_uid text NOT NULL, version text NOT NULL, tenant_ref text NOT NULL,
- event_type text NOT NULL CHECK(event_type IN ('registered','reviewed','approved','canary','active','paused','rolled_back','revoked','recovery','invoked','dead_letter')),
- actor_ref text NOT NULL, payload_digest char(64) NOT NULL CHECK(payload_digest ~ '^[0-9a-f]{64}$'), created_at timestamptz NOT NULL DEFAULT clock_timestamp()
- );
- DO $owner$ DECLARE t text; BEGIN
- FOREACH t IN ARRAY ARRAY['plugin_registry_versions','plugin_approvals','plugin_runtime_leases','plugin_runs','plugin_dead_letters','plugin_audit_outbox'] LOOP
- EXECUTE 'ALTER TABLE public.'||quote_ident(t)||' OWNER TO dataops_plugin_platform_owner';
- EXECUTE 'REVOKE ALL ON TABLE public.'||quote_ident(t)||' FROM PUBLIC,dataops_app,dataops_app_runtime';
- END LOOP;
- END $owner$;
- CREATE FUNCTION public.plugin_platform_runtime_execute(p jsonb) RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path=pg_catalog,public AS $run$
- DECLARE r record; digest text; out_digest text;
- BEGIN
- IF NOT pg_has_role(session_user,'dataops_app_runtime','MEMBER') OR jsonb_typeof(p)<>'object'
- OR p-ARRAY['plugin_uid','version','tenant_ref','domain_ref','principal_ref','operation_name','idempotency_key','input_digest','lease_token','lease_fence']<>'{}'::jsonb
- OR p->>'plugin_uid' !~ '^[a-z][a-z0-9-]{2,62}$' OR p->>'input_digest' !~ '^[0-9a-f]{64}$' THEN RAISE EXCEPTION 'plugin_runtime_denied'; END IF;
- SELECT * INTO r FROM public.plugin_registry_versions WHERE plugin_uid=p->>'plugin_uid' AND version=p->>'version' AND state='active' AND fixture_id='ENGINEERING_EVIDENCE_ONLY' AND permissions='{"file": false, "network": false, "secret": false, "child_process": false}'::jsonb;
- IF NOT FOUND THEN RAISE EXCEPTION 'plugin_not_active'; END IF;
- digest:=encode(sha256(convert_to((p-ARRAY['lease_token'])::text,'utf8')),'hex');
- SELECT encode(sha256(convert_to('ENGINEERING_EVIDENCE_ONLY|'||r.manifest_digest||'|'||digest,'utf8')),'hex') INTO out_digest;
- INSERT INTO public.plugin_runs(plugin_uid,version,tenant_ref,domain_ref,principal_ref,operation_name,idempotency_key,input_digest,output_digest,request_digest,lease_fence,state,completed_at)
- VALUES(r.plugin_uid,r.version,p->>'tenant_ref',p->>'domain_ref',p->>'principal_ref',p->>'operation_name',p->>'idempotency_key',p->>'input_digest',out_digest,digest,(p->>'lease_fence')::bigint,'succeeded',clock_timestamp())
- ON CONFLICT(plugin_uid,version,tenant_ref,idempotency_key) DO NOTHING;
- RETURN jsonb_build_object('plugin_uid',r.plugin_uid,'version',r.version,'output_digest',out_digest,'fixture_id','ENGINEERING_EVIDENCE_ONLY');
- END $run$;
- ALTER FUNCTION public.plugin_platform_runtime_execute(jsonb) OWNER TO dataops_plugin_platform_owner;
- REVOKE ALL ON FUNCTION public.plugin_platform_runtime_execute(jsonb) FROM PUBLIC,dataops_app;
- GRANT EXECUTE ON FUNCTION public.plugin_platform_runtime_execute(jsonb) TO dataops_app_runtime;
- ''')
- def downgrade() -> None:
- bind = op.get_bind()
- checks = " OR ".join(f"EXISTS(SELECT 1 FROM public.{table} LIMIT 1)" for table in _TABLES)
- if bind.exec_driver_sql(f"SELECT {checks}").scalar():
- raise RuntimeError("downgrade refused: WP13 plugin facts are nonempty")
- bind.exec_driver_sql("""
- REVOKE ALL ON FUNCTION public.plugin_platform_runtime_execute(jsonb) FROM PUBLIC,dataops_app,dataops_app_runtime;
- DROP FUNCTION public.plugin_platform_runtime_execute(jsonb);
- DROP TABLE public.plugin_audit_outbox,public.plugin_dead_letters,public.plugin_runs,public.plugin_runtime_leases,public.plugin_approvals,public.plugin_registry_versions;
- """)
|