Some checks failed
verify / verify (push) Has been cancelled
Separate local parsing from model indexing, bind review decisions to immutable manifests, persist vectors behind active profiles, and expose retrieval, chat, evaluation, and document workflows through the React workbench. Constraint: Live Bailian authentication currently fails for all three configured capabilities Rejected: Direct upload-to-embedding flow | bypasses local review and manifest binding Confidence: high Scope-risk: broad Directive: Keep private-data deployment blocked until authentication, RBAC, and separate database roles land Tested: make verify; fresh and replay Docker document smoke; worker recovery smoke; frozen synthetic evaluation; migration 0003-0004 roundtrip Not-tested: Successful live Bailian calls, OCR, real multi-user authorization
124 lines
4.1 KiB
Python
124 lines
4.1 KiB
Python
"""Add optimistic document review decisions and immutable review audit.
|
|
|
|
Revision ID: 0004_document_review
|
|
Revises: 0003_document_ingestion
|
|
Create Date: 2026-07-13
|
|
"""
|
|
|
|
from collections.abc import Sequence
|
|
|
|
from alembic import op
|
|
|
|
revision: str = "0004_document_review"
|
|
down_revision: str | None = "0003_document_ingestion"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute(
|
|
"""
|
|
ALTER TABLE rag.document_versions
|
|
ADD COLUMN review_revision integer NOT NULL DEFAULT 0,
|
|
ADD CONSTRAINT document_versions_review_revision_valid
|
|
CHECK (review_revision >= 0);
|
|
"""
|
|
)
|
|
op.execute(
|
|
"""
|
|
CREATE TABLE rag.document_review_events (
|
|
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
document_id uuid NOT NULL,
|
|
document_version_id uuid NOT NULL,
|
|
actor_subject text NOT NULL,
|
|
decision text NOT NULL,
|
|
reason_code text NOT NULL,
|
|
previous_revision integer NOT NULL,
|
|
resulting_revision integer NOT NULL,
|
|
outbound_manifest_sha256 char(64),
|
|
embedding_profile_hash char(64),
|
|
trace_id uuid NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
CONSTRAINT document_review_events_document_fk
|
|
FOREIGN KEY (document_id, document_version_id)
|
|
REFERENCES rag.document_versions (document_id, id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT document_review_events_actor_nonempty
|
|
CHECK (btrim(actor_subject) <> '' AND length(actor_subject) <= 200),
|
|
CONSTRAINT document_review_events_decision_valid
|
|
CHECK (decision IN ('APPROVE', 'REJECT')),
|
|
CONSTRAINT document_review_events_reason_valid
|
|
CHECK (reason_code IN (
|
|
'SYNTHETIC_REVIEW_APPROVED',
|
|
'RIGHTS_NOT_VERIFIED',
|
|
'CONTENT_QUALITY_REJECTED',
|
|
'CLOUD_PROCESSING_REJECTED'
|
|
)),
|
|
CONSTRAINT document_review_events_revision_valid
|
|
CHECK (
|
|
previous_revision >= 0
|
|
AND resulting_revision = previous_revision + 1
|
|
),
|
|
CONSTRAINT document_review_events_hashes_valid
|
|
CHECK (
|
|
(
|
|
decision = 'APPROVE'
|
|
AND outbound_manifest_sha256 ~ '^[0-9a-f]{64}$'
|
|
AND embedding_profile_hash ~ '^[0-9a-f]{64}$'
|
|
)
|
|
OR (
|
|
decision = 'REJECT'
|
|
AND embedding_profile_hash IS NULL
|
|
)
|
|
),
|
|
CONSTRAINT document_review_events_version_revision_key
|
|
UNIQUE (document_version_id, resulting_revision)
|
|
);
|
|
"""
|
|
)
|
|
op.execute(
|
|
"""
|
|
CREATE INDEX document_review_events_document_timeline
|
|
ON rag.document_review_events (document_id, created_at, id);
|
|
"""
|
|
)
|
|
op.execute(
|
|
"""
|
|
CREATE FUNCTION rag.reject_document_review_event_mutation()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = pg_catalog, rag
|
|
AS $function$
|
|
BEGIN
|
|
RAISE EXCEPTION 'document review events are append-only'
|
|
USING ERRCODE = '23514';
|
|
END
|
|
$function$;
|
|
"""
|
|
)
|
|
op.execute(
|
|
"""
|
|
CREATE TRIGGER document_review_events_append_only
|
|
BEFORE UPDATE OR DELETE
|
|
ON rag.document_review_events
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION rag.reject_document_review_event_mutation();
|
|
"""
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute(
|
|
"DROP TRIGGER IF EXISTS document_review_events_append_only ON rag.document_review_events;"
|
|
)
|
|
op.execute("DROP FUNCTION IF EXISTS rag.reject_document_review_event_mutation();")
|
|
op.execute("DROP TABLE IF EXISTS rag.document_review_events;")
|
|
op.execute(
|
|
"""
|
|
ALTER TABLE rag.document_versions
|
|
DROP CONSTRAINT IF EXISTS document_versions_review_revision_valid,
|
|
DROP COLUMN IF EXISTS review_revision;
|
|
"""
|
|
)
|