Skip to content

feat(ai): add service-owned data-rights contributor - #199

Open
seonghobae wants to merge 41 commits into
mainfrom
feat/ai-data-rights-contributor-v1
Open

feat(ai): add service-owned data-rights contributor#199
seonghobae wants to merge 41 commits into
mainfrom
feat/ai-data-rights-contributor-v1

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Buyer/privacy outcome

Add the AI service as an independently deployable life-os.data-rights-contributor.v1 participant without giving Identity direct access to AI persistence.

Implemented scope

  • bounded deterministic proposal/decision export with additive opaque keyset cursors for workspaces larger than 1,000 records;
  • contributor-owned SHA-256 evidence using locale-independent UTF-16 code-unit key ordering;
  • erasure preflight, owner-controlled atomic erasure, replay-safe receipts, conflicting-authority rejection and post-erasure verification;
  • workspace-level advisory serialization regardless of idempotency key;
  • transaction-local owner-only deletion authorization checked by the append-only audit triggers, avoiding global trigger disablement and ACCESS EXCLUSIVE lock expansion;
  • shared internal contract support for optional export cursor / nextCursor;
  • realistic disposable-PostgreSQL evidence for serialization, direct-delete denial, authorization-marker denial, pre-grant function denial, function-only runtime erasure, forged-receipt denial, replay, UUIDv4 validation, tenant isolation, receipt persistence, authorization cleanup and trigger state;
  • fail-closed malformed request, cursor, JSON, SQL and privilege evidence handling.

Destructive idempotency keys and secret material remain absent from portability output. Ordinary application roles retain append-only proposal/decision behavior. The erasure runtime receives schema usage plus explicit EXECUTE on the reviewed SECURITY DEFINER function only; it does not receive direct SELECT or INSERT authority over erasure receipts and cannot forge receipt evidence.

Test-first evidence

The branch preserves initial RED runtime-composition commit 0c58705e4cfee0796a7e8c5771368771a339cfa4. Subsequent regressions were added before pagination, deterministic-digest, workspace-lock, transaction-authorization and function-only runtime-authority implementations.

A local strict TypeScript compile with minimal dependency stubs covered the exact changed AI source and PostgreSQL integration test after the latest edits. This is bounded syntax/type evidence only; hosted repository tests remain authoritative.

Current identities

  • exact contributor head: 1c783bb4ebd476a2016dd7e52371d34cc67290a4
  • exact live base tip after calendar compensation integration: 4bd155dffabb12b70108949499d597f5ecd62a1b
  • PR metadata base_sha may remain the historical branch-point snapshot and is not used as live-base proof.

No predecessor check or review evidence transfers. Exact-head CI, AppGuardrail, SAST Semgrep, Security Scan and Commercial Readiness are queued and must complete on the unchanged head; merge compatibility must independently resolve and validate the current live base before readiness or merge.

Advances #55 and the data-portability portion of #21. It does not close either parent gap because additional owning-service contributors, orchestration, artifact delivery and end-to-end deletion remain.

Summary by CodeRabbit

  • 새 기능

    • AI 데이터 권리 요청을 지원합니다.
    • 데이터 내보내기, 삭제 사전 확인, 삭제 및 삭제 검증을 제공합니다.
    • 대규모 내보내기 결과에 페이지네이션을 지원합니다.
    • 삭제 결과에 대한 무결성 영수증을 생성하고 멱등 재실행을 지원합니다.
  • 보안 및 안정성

    • 권한이 없는 삭제 요청과 잘못된 입력을 차단합니다.
    • 민감한 오류 정보를 숨기고 감사 기록을 보호합니다.
    • 동시 삭제 처리를 안정화하고 운영 권한을 분리했습니다.
  • 테스트

    • 데이터 삭제, 권한, 페이지네이션, 오류 처리 및 영수증 검증 범위를 확대했습니다.

Open in Devin Review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a72378c-d0df-46bc-b6fd-23c10e5e954e

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 764b28e2-655a-428f-bb77-928e9b6342b6

📥 Commits

Reviewing files that changed from the base of the PR and between 7d9c627 and a52df6c.

📒 Files selected for processing (1)
  • infra/kubernetes/run-migrations.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • infra/kubernetes/run-migrations.sh

📝 Walkthrough

Walkthrough

AI 데이터 권리 contributor를 추가했다. 요청 검증, 감사 데이터 내보내기, 원자적 워크스페이스 삭제, 삭제 검증을 구현했다. PostgreSQL 권한 제어와 런타임 연결, 계약 및 수명주기 테스트도 추가했다.

Changes

AI 데이터 권리 워크플로

Layer / File(s) Summary
요청 계약 및 검증
apps/ai-service/src/ai-data-rights.ts, packages/contracts/src/data-rights.ts, packages/contracts/src/data-rights-contract.typecheck.ts, apps/ai-service/src/ai-data-rights.behavior.test.ts
요청·결과 타입, 엄격한 입력 검증, 제한된 JSON 처리, canonical JSON, SHA-256 digest 및 opaque keyset cursor 처리를 추가했다.
데이터 내보내기 및 런타임 연결
apps/ai-service/src/ai-data-rights.ts, apps/ai-service/src/ai-runtime.ts, apps/ai-service/src/ai-data-rights.test.ts, apps/ai-service/src/ai-data-rights.behavior.test.ts
두 AI 감사 테이블에서 페이지 단위 데이터를 내보내고, AiDataRightsContributorAiRuntime에 연결했다.
원자적 삭제 및 영수증
apps/ai-service/migrations/0002_data_rights_erasure.sql, apps/ai-service/src/ai-data-rights.ts, apps/ai-service/src/ai-data-rights.behavior.test.ts
트랜잭션별 삭제 권한 테이블과 append-only 감사 변경 트리거를 추가했다. advisory lock, 멱등성·충돌 검사, 삭제 후 권한 정리, SHA-256 영수증 저장을 구현했다.
PostgreSQL 수명주기 검증
apps/ai-service/src/ai-data-rights-migration.test.ts
제한된 역할의 권한, 워크스페이스 직렬화, 삭제 범위, 멱등 재실행, 오류 코드, 영수증 보존, 트리거 상태 및 임시 데이터베이스 정리를 검증했다.
마이그레이션 및 런타임 권한
infra/kubernetes/run-migrations.sh, .github/workflows/deploy.yml, apps/ai-service/migrations/README.md, infra/tests/ai-migration-role.spec.ts
전용 마이그레이션 URL과 런타임 역할을 사용하도록 배포 흐름을 변경했다. 런타임 역할 검증, AI 객체 권한 부여, 소유권 계약 테스트와 롤백 문서를 추가했다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AiRuntime
  participant AiDataRightsContributor
  participant PostgreSQL

  Client->>AiRuntime: 데이터 권리 요청 전달
  AiRuntime->>AiDataRightsContributor: handle(request)
  AiDataRightsContributor->>PostgreSQL: 감사 데이터 조회 또는 erase_workspace_data 호출
  PostgreSQL-->>AiDataRightsContributor: 페이지 결과 또는 삭제 영수증
  AiDataRightsContributor->>PostgreSQL: 삭제 후 잔여 레코드 조회
  PostgreSQL-->>AiDataRightsContributor: 잔여 레코드 수
  AiDataRightsContributor-->>Client: 계약 응답과 digest 반환
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 서비스 소유 데이터 권리 기여자 추가라는 PR의 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ai-data-rights-contributor-v1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as ready for review August 12, 2026 08:49
coderabbitai[bot]

This comment was marked as resolved.

github-advanced-security[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 3c92ed6e98ee464724d9446253dee7c9d4b3287f.

  • Head SHA: 3c92ed6e98ee464724d9446253dee7c9d4b3287f

  • Workflow run: 31637413785

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (13 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (13 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Workflow: deploy.yml"]
  S2 --> I2["GitHub Actions review job"]
  I2 --> R2["Review risk: Workflow: deploy.yml"]
  R2 --> V2["actionlint plus required checks"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: ae78023924f59fdb03ef3e88918bc8a09dc94e31
  • Workflow run: 31897654137
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head ae78023924f59fdb03ef3e88918bc8a09dc94e31.

  • Head SHA: ae78023924f59fdb03ef3e88918bc8a09dc94e31

  • Workflow run: 31897654137

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (14 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (14 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Workflow: deploy.yml"]
  S2 --> I2["GitHub Actions review job"]
  I2 --> R2["Review risk: Workflow: deploy.yml"]
  R2 --> V2["actionlint plus required checks"]
Loading

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 11ffc1d1a78e5e2e256307cf9059293c38b5daa5.

  • Head SHA: 11ffc1d1a78e5e2e256307cf9059293c38b5daa5

  • Workflow run: 31648066102

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (13 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (13 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Workflow: deploy.yml"]
  S2 --> I2["GitHub Actions review job"]
  I2 --> R2["Review risk: Workflow: deploy.yml"]
  R2 --> V2["actionlint plus required checks"]
Loading

@seonghobae seonghobae closed this Aug 13, 2026
@seonghobae seonghobae reopened this Aug 13, 2026
github-advanced-security[bot]

This comment was marked as resolved.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head ae78023924f59fdb03ef3e88918bc8a09dc94e31.

  • Head SHA: ae78023924f59fdb03ef3e88918bc8a09dc94e31

  • Workflow run: 31894226481

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (14 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (14 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Workflow: deploy.yml"]
  S2 --> I2["GitHub Actions review job"]
  I2 --> R2["Review risk: Workflow: deploy.yml"]
  R2 --> V2["actionlint plus required checks"]
Loading

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head ae78023924f59fdb03ef3e88918bc8a09dc94e31.

  • Head SHA: ae78023924f59fdb03ef3e88918bc8a09dc94e31

  • Workflow run: 31897654137

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (14 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (14 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Workflow: deploy.yml"]
  S2 --> I2["GitHub Actions review job"]
  I2 --> R2["Review risk: Workflow: deploy.yml"]
  R2 --> V2["actionlint plus required checks"]
Loading

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

Open in Devin Review

"build": "nest build",
"dev": "nest start --watch --entryFile server",
"lint": "tsc --noEmit && prettier --single-quote --check package.json tsconfig.json vitest.config.ts \"src/**/*.ts\" ../../AGENTS.md ../../CLAUDE.md ../../ARCHITECTURE.md ../../CHANGELOG.md ../../docs/operations/ai-proposal-audit-assurance.md ../../docs/superpowers/specs/2026-08-04-ai-service-quality-gates-design.md ../../docs/superpowers/plans/2026-08-04-ai-service-quality-gates.md migrations/README.md ../../docs/operations/ai-gateway-key-rotation.md ../../docs/research/2026-08-04-ai-gateway-key-rotation-standards.md ../../docs/superpowers/specs/2026-08-04-ai-gateway-key-rotation-design.md ../../docs/superpowers/plans/2026-08-04-ai-gateway-key-rotation.md ../../docs/operations/contextual-orchestrator-proposal-transport.md ../../docs/research/2026-08-05-contextual-orchestrator-proposal-transport-standards.md ../../docs/superpowers/specs/2026-08-05-contextual-orchestrator-proposal-transport-design.md ../../docs/superpowers/plans/2026-08-05-contextual-orchestrator-proposal-transport.md ../../docs/operations/ai-proposal-quality-evaluation.md ../../docs/research/2026-08-05-ai-proposal-quality-evaluation-standards.md ../../docs/superpowers/specs/2026-08-05-ai-proposal-quality-evaluation-design.md ../../docs/superpowers/plans/2026-08-05-ai-proposal-quality-evaluation.md ../../docs/superpowers/specs/2026-08-06-ai-nim-live-conformance-design.md ../../docs/superpowers/plans/2026-08-06-ai-nim-live-conformance.md",
"lint": "tsc --noEmit && prettier --single-quote --check src/ai-data-rights-migration.test.ts src/ai-data-rights.behavior.test.ts src/ai-data-rights.test.ts src/ai-data-rights.ts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Format check narrowed to four files

The prettier --check invocation dropped its src/**/*.ts glob and its config and documentation targets, now listing only the four new data-rights files. Formatting regressions in every other source, config, and doc file in the package pass unchecked, and newly added files are never covered.

Prompt for agents
The ai-service lint script previously ran prettier --check against package.json, tsconfig.json, vitest.config.ts, the src/**/*.ts glob, and a long list of documentation files. The PR replaced that entire target list with just the four new data-rights files, so prettier no longer checks the rest of the package or its docs, and the src glob no longer catches future files. Restore the broad target set (re-add the src/**/*.ts glob, config files, and the documentation paths) and add the four new files to it, rather than replacing the list.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +503 to +528
AND (
$2::timestamptz IS NULL
OR (created_at, 'proposal'::text, proposal_id) >
($2::timestamptz, $3::text, $4::uuid)
)
UNION ALL
SELECT
recorded_at AS evidence_time,
'decision'::text AS evidence_kind,
id AS evidence_id,
jsonb_build_object(
'decisionId', id,
'proposalId', proposal_id,
'proposalContentDigest', proposal_content_digest,
'actorId', actor_id,
'decisionKind', decision_kind,
'reason', reason_text,
'decidedAt', to_char(decided_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"'),
'recordedAt', to_char(recorded_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"')
) AS evidence_data
FROM ai.proposal_decision_events
WHERE workspace_id = $1
AND (
$2::timestamptz IS NULL
OR (recorded_at, 'decision'::text, id) >
($2::timestamptz, $3::text, $4::uuid)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Cross-table keyset pagination boundary is correct

The export UNION keys proposals by (created_at,'proposal',proposal_id) and decisions by (recorded_at,'decision',id), ordered by (evidence_time, evidence_kind, evidence_id). Because evidence_kind is a per-branch constant, the same-time boundary between decisions and proposals is handled correctly, and fetching MAX+1 with the cursor built from the 1000th row avoids skips or duplicates.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +175 to +202
INSERT INTO ai.data_rights_erasure_authorizations (
backend_process_id,
transaction_id,
workspace_id
) VALUES (
pg_backend_pid(),
pg_current_xact_id(),
target_workspace_id
);

DELETE FROM ai.proposal_decision_events
WHERE workspace_id = target_workspace_id;
GET DIAGNOSTICS deleted_decisions = ROW_COUNT;

DELETE FROM ai.proposal_audit_records
WHERE workspace_id = target_workspace_id;
GET DIAGNOSTICS deleted_proposals = ROW_COUNT;

DELETE FROM ai.data_rights_erasure_authorizations
WHERE backend_process_id = pg_backend_pid()
AND transaction_id = pg_current_xact_id()
AND workspace_id = target_workspace_id;

IF NOT FOUND THEN
RAISE EXCEPTION USING
ERRCODE = '55000',
MESSAGE = 'AI erasure authorization cleanup failed';
END IF;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Erasure authorization scoping is sound

erase_workspace_data inserts a (backend_pid, xact_id, workspace_id) authorization row, deletes (the BEFORE DELETE trigger permits deletes only when that row exists), then removes it and fails closed if absent. Both functions are SECURITY DEFINER owned by the migration role, so a runtime role with only EXECUTE cannot forge authorization or write receipts. Delete order respects the composite FK.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

"build": "nest build",
"dev": "nest start --watch --entryFile server",
"lint": "tsc --noEmit && prettier --single-quote --check package.json tsconfig.json vitest.config.ts \"src/**/*.ts\" ../../AGENTS.md ../../CLAUDE.md ../../ARCHITECTURE.md ../../CHANGELOG.md ../../docs/operations/ai-proposal-audit-assurance.md ../../docs/superpowers/specs/2026-08-04-ai-service-quality-gates-design.md ../../docs/superpowers/plans/2026-08-04-ai-service-quality-gates.md migrations/README.md ../../docs/operations/ai-gateway-key-rotation.md ../../docs/research/2026-08-04-ai-gateway-key-rotation-standards.md ../../docs/superpowers/specs/2026-08-04-ai-gateway-key-rotation-design.md ../../docs/superpowers/plans/2026-08-04-ai-gateway-key-rotation.md ../../docs/operations/contextual-orchestrator-proposal-transport.md ../../docs/research/2026-08-05-contextual-orchestrator-proposal-transport-standards.md ../../docs/superpowers/specs/2026-08-05-contextual-orchestrator-proposal-transport-design.md ../../docs/superpowers/plans/2026-08-05-contextual-orchestrator-proposal-transport.md ../../docs/operations/ai-proposal-quality-evaluation.md ../../docs/research/2026-08-05-ai-proposal-quality-evaluation-standards.md ../../docs/superpowers/specs/2026-08-05-ai-proposal-quality-evaluation-design.md ../../docs/superpowers/plans/2026-08-05-ai-proposal-quality-evaluation.md ../../docs/superpowers/specs/2026-08-06-ai-nim-live-conformance-design.md ../../docs/superpowers/plans/2026-08-06-ai-nim-live-conformance.md",
"lint": "tsc --noEmit && prettier --single-quote --check src/ai-data-rights-migration.test.ts src/ai-data-rights.behavior.test.ts src/ai-data-rights.test.ts src/ai-data-rights.ts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Root format:check omits the new data-rights files

The repo-root format:check uses an explicit file list with no globs and does not include the four new data-rights files; it covers ai-runtime.ts but not src/ai-data-rights.ts or its tests. Those files are only reachable through the ai-service package lint script, which this PR narrowed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants