feat(ai): add service-owned data-rights contributor - #199
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAI 데이터 권리 contributor를 추가했다. 요청 검증, 감사 데이터 내보내기, 원자적 워크스페이스 삭제, 삭제 검증을 구현했다. PostgreSQL 권한 제어와 런타임 연결, 계약 및 수명주기 테스트도 추가했다. ChangesAI 데이터 권리 워크플로
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 반환
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore 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 head3c92ed6e98ee464724d9446253dee7c9d4b3287f. -
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"]
OpenCode Review Overview
Pull request overviewOpenCode cannot approve yet because required coverage evidence did not pass. Review outcome1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence
Coverage evidenceCoverage evidence job did not run or did not publish coverage evidence. Changed-File Evidence Mapflowchart 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"]
|
There was a problem hiding this comment.
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
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore 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 head11ffc1d1a78e5e2e256307cf9059293c38b5daa5. -
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"]
There was a problem hiding this comment.
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
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore 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 headae78023924f59fdb03ef3e88918bc8a09dc94e31. -
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"]
There was a problem hiding this comment.
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
successwith required evidence or explicit no-source not-applicable evidence. -
Regression test: Keep the approval branch checking
needs.coverage-evidence.result == successbefore 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 headae78023924f59fdb03ef3e88918bc8a09dc94e31. -
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"]
| "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", |
There was a problem hiding this comment.
🟡 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
| 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) |
There was a problem hiding this comment.
📝 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
| 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; |
There was a problem hiding this comment.
📝 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.
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", |
There was a problem hiding this comment.
🔍 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.
Was this helpful? React with 👍 or 👎 to provide feedback.
Buyer/privacy outcome
Add the AI service as an independently deployable
life-os.data-rights-contributor.v1participant without giving Identity direct access to AI persistence.Implemented scope
ACCESS EXCLUSIVElock expansion;cursor/nextCursor;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
EXECUTEon the reviewedSECURITY DEFINERfunction only; it does not receive directSELECTorINSERTauthority 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
1c783bb4ebd476a2016dd7e52371d34cc67290a44bd155dffabb12b70108949499d597f5ecd62a1bbase_shamay 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
새 기능
보안 및 안정성
테스트