Skip to content

Add canonical actor profile and identity resolution#124

Merged
abiorh-claw merged 8 commits into
mainfrom
codex/ws-auth-001-06-canonical-actor-profile
Jul 15, 2026
Merged

Add canonical actor profile and identity resolution#124
abiorh-claw merged 8 commits into
mainfrom
codex/ws-auth-001-06-canonical-actor-profile

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

WS-AUTH-001-06 PR Trust Bundle

Chunk

WS-AUTH-001-06 - Canonical Actor Profile And Identity Resolution

Goal

Replace the legacy human registry as an authorization authority with one
canonical actor profile and issuer-subject identity link, while preserving a
strictly bounded compatibility bridge for existing submitter workflows.

Human-Approved Intent

Every verified human receives one canonical profile. Authorization is based on
explicit authority and project grants, not a default contributor role. Human
product language uses contributor, submitter, and reviewer; worker remains only
for internal service execution or explicitly inventoried legacy identifiers.

What Changed

  • Migration 0020 classifies legacy identities, creates canonical actor
    profiles and identity links, enforces identity and lifecycle invariants, and
    provides guarded downgrade custody.
  • Exact issuer-subject resolution serializes first access, atomically creates
    one profile/link plus authority evidence, and updates verification timestamps
    using database time.
  • GET/PATCH /api/v1/actors/me exposes the canonical self-service contract;
    /api/v1/auth/me remains a compatibility view.
  • Verified agent, service, and Space identities fail closed without actor state.
  • First-access rate control now uses a shared dependency and maps unavailable
    infrastructure to a retryable, zero-write response.
  • Legacy submitter compatibility is restricted to the existing profile,
    claim, start, and submission boundary and cannot become authorization truth.

Why It Changed

Later grant and permission chunks require a stable actor reference that is not
coupled to email, mutable token display claims, or a legacy submitter record.
This chunk establishes that identity boundary before authorization policy is
activated.

Design Chosen

External identity is keyed only by exact, bounded issuer and subject. Human profile
state is separate from identity links and defaults to active without assigning
a role. First creation is serialized with a PostgreSQL advisory transaction
lock. Runtime repositories do not own commits or sessions, and authority events
are written in the same transaction as actor state.

Alternatives Rejected

  • Email identity and Workstream-owned login were rejected because the external
    identity issuer owns authentication.
  • A default contributor role was rejected because capabilities must come from
    explicit admin and project grants.
  • Keeping the legacy registry authoritative was rejected because contributor,
    reviewer, and manager access must resolve through one canonical actor.
  • Provisioning non-human principals through this route was rejected; later
    service-principal custody must be explicit.

Scope Control

This chunk does not implement admin-role grants, project-role grants, the
permission evaluator, artifact-storage authorization, cache consumers, frontend
identity flows, or service-principal provisioning. Those remain in later AUTH
chunks.

Product Behavior

A verified human is provisioned on first access and receives a stable actor ID.
They can read and update bounded display fields. Suspended identities remain
readable but cannot mutate; deactivated identities fail closed. Existing task
submitter flows continue through a compatibility projection while current
authorization remains unchanged until the grant and evaluator cutovers.

Acceptance Criteria Proof

  • Concurrent and repeated access produce one actor profile and one identity
    link with advancing verification timestamps and no duplicate authority rows.
  • Unknown services and non-human identities are denied before persistence.
  • Issuer and subject claims are consistently bounded at 200 characters across
    token parsing, verifier adapters, actor persistence, migration, and audit
    provenance.
  • Migration upgrade, classification, constraints, indexes, privacy, guarded
    downgrade, re-upgrade, and terminal deactivation behavior have direct tests.
  • Downgrade copies current canonical display fields, including a cleared email,
    so pre-AUTH-06 code cannot resurrect stale private data.
  • Rate-control and audit failures roll back actor state and evidence together.
  • Legacy activation is serialized and idempotent and audits only actual changes.
  • Work-context claim, start, and submit affordances require the same current
    compatibility role and active eligibility as their mutation gates.

Tests And Checks Run

  • Actor subsystem branch coverage: 90.1031 percent across 804 statements and
    166 branches; 83 actor/classification behavior tests passed in 706.29 seconds.
  • External-review migration, concurrency, lifecycle, exact-anchor, privacy, and
    zero-side-effect scenarios passed on the integrated branch.
  • Real Postgres API contract: passed end to end through migration 0020.
  • Focused actor/auth/task/project/checker/rate-control behavior and migration
    suites passed; final coverage data includes the repaired static inventory and
    added repeated-access, unavailable-control, and compatibility assertions.
  • Ruff, stale wording, stale authorization docs, changed Markdown links, diff
    integrity, all 71 engineering-loop agent-gate tests, loop-memory state, and
    the schema-v2 AUTH-06 merge-intent validator passed.
  • The multi-hour repository suite was not repeated locally. GitHub Backend owns
    the authoritative full-suite result and repository-wide 78 percent floor.

Test Delta

Tests replace obsolete registry-authority assumptions with canonical actor
behavior and add concurrency, rollback, privacy, lifecycle, migration, and
compatibility proof. No skip, xfail, coverage threshold, or meaningful
assertion was removed or weakened.

CI Integrity

No workflow, dependency, package script, coverage exclusion, or threshold
changed. The actor subsystem meets its 90 percent branch gate, and GitHub must
still enforce the repository-wide 78 percent baseline.

Reviewer Results

Exact reviewed SHA abd76c995e51645b61d4d3ac07f1ff82ab6eb740 passed senior
engineering, QA/test, security/auth, product/ops, architecture, CI integrity,
docs, reuse/dedup, and test-delta review with no blocking findings.

External Review

CodeRabbit's seven inline findings and three nitpicks were triaged. All valid
runtime, migration, lifecycle, privacy, test-harness, and test-contract findings
were repaired. Its generic diff-local docstring percentage is not the
repository's configured gate and required no narration-only churn. GitHub checks,
the next CodeRabbit head, and human review remain pending.

Remaining Risks

  • Database-owner or DDL credentials can bypass normal-DML guards; production
    must use the documented non-owner runtime role.
  • Migration 0020 requires a quiesced deployment because it classifies and
    swaps legacy identity storage.
  • Deactivation is terminal for downgrade purposes and requires forward recovery.
  • The compatibility projection remains until its owning cutover chunk removes
    the legacy route and storage.

Follow-Up Work

After merge, automated post-merge memory, stop, and a separate human start,
AUTH-07 may implement the next approved authority boundary. Later chunks own
admin grants, project grants, the evaluator, API cutovers, artifact-storage
authorization, and invalidation consumers.

Human Review Focus

Review migration classification and downgrade custody, first-access transaction
and rate-control behavior, issuer-subject bounds, non-human zero-write denial,
and the exact limits of the legacy compatibility bridge.

Human Merge Ownership

Only the human may approve and merge this PR. Internal or external checks do
not authorize merge.

Summary by CodeRabbit

  • New Features
    • Added canonical actor self-service endpoints (GET/PATCH /api/v1/actors/me) for contributor-safe profile viewing and updates.
    • Implemented atomic first-access provisioning for verified human identities, including identity linking and audit recording.
  • Bug Fixes
    • Tightened verified identity anchor validation (issuer/subject length limit and whitespace rejection) with fail-closed behavior.
    • Improved rate-control outcomes: unavailable infrastructure returns retryable 503, and exhausted limits return retryable 429 with Retry-After.
  • Documentation
    • Updated authorization rollout and migration runbooks with clarified privacy boundaries, concurrency/idempotency expectations, and rollback procedures.
  • Tests
    • Expanded coverage for canonical actor resolution, concurrency, rate controls, and migration guards.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b83c0d5a-3ea0-4b7c-ac5b-4eb923542dc7

📥 Commits

Reviewing files that changed from the base of the PR and between dd024e5 and 4a2193f.

📒 Files selected for processing (4)
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-external-review-response.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-pr-trust-bundle.md
  • backend/tests/test_api_controls.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-external-review-response.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-pr-trust-bundle.md

📝 Walkthrough

Walkthrough

This change replaces the legacy actor registry with canonical actor profiles and issuer-subject identity links, adds transactional first-access provisioning and self-service APIs, preserves bounded legacy workflow eligibility, introduces migration guards, centralizes rate controls, and expands validation.

Changes

Canonical actor authorization

Layer / File(s) Summary
Canonical schema and migration
backend/alembic/versions/0020_canonical_actor_profile.py, backend/app/modules/actors/models.py, backend/tests/test_alembic.py
Adds canonical profile and identity-link tables, legacy compatibility tables, integrity triggers, classification-aware migration, and guarded downgrade behavior.
Actor service and persistence flow
backend/app/modules/actors/{repository,schemas,service}.py
Implements identity locking, canonical provisioning, audit evidence, self updates, verification touches, and legacy identity persistence.
Auth resolution and self-service API
backend/app/schemas/auth.py, backend/app/adapters/auth/*, backend/app/api/deps/*, backend/app/api/routes/auth.py, backend/app/api/router.py
Enforces bounded issuer/subject values, centralizes rate-control errors, resolves canonical actors, and adds GET/PATCH /api/v1/actors/me.
Legacy workflow eligibility compatibility
backend/app/modules/tasks/{router,service,schemas}.py
Changes worker activation and task eligibility checks to use temporary legacy workflow eligibility records.
Behavior and integration validation
backend/tests/*, backend/scripts/api_contract_e2e.py
Covers concurrency, rollback, lifecycle denials, rate controls, migration constraints, compatibility behavior, and canonical actor API fields.
Contracts and review evidence
.agent-loop/..., docs/operations_authorization_service.md
Updates acceptance criteria, verification commands, review evidence, rollout contracts, operational migration guidance, and chunk metadata.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 51.11% 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
Title check ✅ Passed The title is concise and accurately summarizes the main change: canonical actor profile and identity resolution.
Description check ✅ Passed The description covers the key template sections, including goal, design, scope, tests, risks, and review results, with only minor formatting deviations.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ws-auth-001-06-canonical-actor-profile

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 7

🧹 Nitpick comments (3)
backend/scripts/api_contract_e2e.py (1)

1077-1086: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optionally assert the absence of legacy token and identity fields.

The assertions successfully verify the expected values in the canonical actor response. For completeness in an API contract test, consider also verifying that the endpoint properly masks private internal fields (e.g., issuer, subject, and roles), matching the strict behavior enforced in your test suite.

💡 Proposed optional addition
         canonical_actor = await request_json(
             client,
             "GET",
             "/api/v1/actors/me",
             worker_token,
         )
         assert canonical_actor["actor_kind"] == "human"
         assert canonical_actor["domains"] == ["contributor"]
         assert canonical_actor["admin_roles"] == []
         assert canonical_actor["project_role_grants"] == []
+        assert "issuer" not in canonical_actor
+        assert "subject" not in canonical_actor
+        assert "roles" not in canonical_actor
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/scripts/api_contract_e2e.py` around lines 1077 - 1086, Extend the
canonical actor assertions near the existing actor_kind, domains, admin_roles,
and project_role_grants checks to verify that legacy private fields issuer,
subject, and roles are absent from canonical_actor. Preserve the current value
assertions and use the test suite’s established absence assertion style.
backend/tests/test_auth.py (1)

52-66: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Use structural analysis for the compatibility allowlist.

Substring scanning and exact call-text counting can be bypassed by aliases or different arguments and can be tripped by comments. Parse imports and call expressions with ast so this test reliably constrains the authorization-adjacent compatibility bridge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_auth.py` around lines 52 - 66, Update
test_legacy_submitter_eligibility_adapter_has_a_shrinking_static_allowlist to
parse each Python file with ast and identify actual references to
LegacyWorkflowEligibilityCompatibility through imports and call expressions,
rather than scanning source text. Use AST call analysis to count invocations of
_require_legacy_submitter_eligibility in modules/tasks/service.py, regardless of
formatting or argument spelling, while excluding comments and unrelated text;
preserve the existing allowed-consumer set and expected count of three.
backend/tests/test_actors.py (1)

56-89: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Centralize the privileged database reset implementation. The repeated trigger-management SQL has already diverged and should have one test-owned implementation.

  • backend/tests/test_actors.py#L56-L89: move the canonical-actor reset extension behind explicit shared-helper options.
  • backend/tests/test_auth.py#L78-L98: replace the local helper with the shared reset utility.
  • backend/tests/test_checkers.py#L61-L81: replace the local helper with the shared reset utility.
  • backend/tests/test_projects.py#L85-L105: replace the local helper with the shared reset utility.
  • backend/tests/test_tasks.py#L68-L88: replace the local helper with the shared reset utility.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_actors.py` around lines 56 - 89, Centralize the privileged
reset logic in the shared test reset utility, adding explicit options for the
canonical actor reset extension currently handled by clear_test_audit_events.
Update backend/tests/test_actors.py lines 56-89 to use those options, and
replace the local reset helpers in backend/tests/test_auth.py lines 78-98,
backend/tests/test_checkers.py lines 61-81, backend/tests/test_projects.py lines
85-105, and backend/tests/test_tasks.py lines 68-88 with the shared utility;
preserve each test suite’s required reset behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/alembic/versions/0020_canonical_actor_profile.py`:
- Around line 351-359: The downgrade upsert in the canonical actor migration
must preserve current self-service fields: update display_name and contact_email
from actor_profiles on conflict, including propagating a cleared email instead
of retaining legacy values. Add a downgrade test covering both an updated
display name and a cleared contact_email.
- Line 297: Update the UUIDv5 seed used to generate actor_identity_links.id in
the migration so it cannot be ambiguous when external_issuer or external_subject
contains colons; use row.actor_id or an equivalent collision-free
length-prefixed representation while preserving deterministic UUID generation.

In `@backend/app/adapters/auth/dev.py`:
- Around line 38-46: Update the development auth validation around
dev_auth_subject and dev_auth_issuer to trim both values before checking
presence and MAX_VERIFIED_IDENTITY_ANCHOR_CHARACTERS length. Reject
whitespace-only anchors during this validation, while preserving the existing
error behavior for missing or oversized values.

In `@backend/app/modules/actors/service.py`:
- Around line 184-240: Serialize activate_legacy_workflow_eligibility per
external identity by acquiring the existing transaction-scoped identity lock, or
a dedicated eligibility lock, before upsert_legacy_identity and the eligibility
read/insert sequence. Ensure the lock makes concurrent first activations apply
the winning request deterministically and prevents auditing an insert when the
caller’s payload was not applied. Add a concurrency test using different
skill_tags payloads, asserting deterministic final state and exactly one audit
per actual transition.

In `@backend/app/modules/tasks/service.py`:
- Line 536: Update _worker_lifecycle_context to load the worker’s current
eligibility and suppress claim, start, and submit affordances whenever the
corresponding eligibility gates are inactive. Reuse the same eligibility logic
as _require_legacy_submitter_eligibility and retain existing assignment and
task-status checks, so advertised actions cannot lead to deterministic 403
responses.

In `@backend/tests/test_actors.py`:
- Around line 105-112: Make the database fixture teardown failure-safe by
wrapping the reset and cleanup sequence in nested try/finally blocks so
db_session.dispose_engine() and command.downgrade(config, "base") always
execute, even if clear_test_audit_events() fails. Apply the same teardown
structure in backend/tests/test_actors.py lines 105-112,
backend/tests/test_auth.py lines 119-126, backend/tests/test_checkers.py lines
101-108, backend/tests/test_projects.py lines 133-140, and
backend/tests/test_tasks.py lines 149-156, preserving the existing
migration_lock() and fixture yield flow.

In `@backend/tests/test_alembic.py`:
- Around line 1071-1110: Update _reset_canonical_actor_guard_state to track
whether actor_profile_history_guard was successfully disabled, then wrap the
reset updates in try/finally. In the finally block, when the trigger was
disabled, always re-enable it using a fresh transaction, including if the reset
or setup operations fail.

---

Nitpick comments:
In `@backend/scripts/api_contract_e2e.py`:
- Around line 1077-1086: Extend the canonical actor assertions near the existing
actor_kind, domains, admin_roles, and project_role_grants checks to verify that
legacy private fields issuer, subject, and roles are absent from
canonical_actor. Preserve the current value assertions and use the test suite’s
established absence assertion style.

In `@backend/tests/test_actors.py`:
- Around line 56-89: Centralize the privileged reset logic in the shared test
reset utility, adding explicit options for the canonical actor reset extension
currently handled by clear_test_audit_events. Update
backend/tests/test_actors.py lines 56-89 to use those options, and replace the
local reset helpers in backend/tests/test_auth.py lines 78-98,
backend/tests/test_checkers.py lines 61-81, backend/tests/test_projects.py lines
85-105, and backend/tests/test_tasks.py lines 68-88 with the shared utility;
preserve each test suite’s required reset behavior.

In `@backend/tests/test_auth.py`:
- Around line 52-66: Update
test_legacy_submitter_eligibility_adapter_has_a_shrinking_static_allowlist to
parse each Python file with ast and identify actual references to
LegacyWorkflowEligibilityCompatibility through imports and call expressions,
rather than scanning source text. Use AST call analysis to count invocations of
_require_legacy_submitter_eligibility in modules/tasks/service.py, regardless of
formatting or argument spelling, while excluding comments and unrelated text;
preserve the existing allowed-consumer set and expected count of three.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 099fb3fe-cd93-453a-9445-e0e483fe3b79

📥 Commits

Reviewing files that changed from the base of the PR and between fc89fb6 and 63f1dd3.

📒 Files selected for processing (29)
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-06-canonical-actor-profile.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-pr-trust-bundle.md
  • .agent-loop/merge-intents/WS-AUTH-001-06.json
  • backend/alembic/versions/0020_canonical_actor_profile.py
  • backend/app/adapters/auth/dev.py
  • backend/app/adapters/auth/flow.py
  • backend/app/api/deps/api_controls.py
  • backend/app/api/deps/auth.py
  • backend/app/api/deps/rate_controls.py
  • backend/app/api/router.py
  • backend/app/api/routes/auth.py
  • backend/app/db/models.py
  • backend/app/modules/actors/models.py
  • backend/app/modules/actors/repository.py
  • backend/app/modules/actors/schemas.py
  • backend/app/modules/actors/service.py
  • backend/app/modules/tasks/router.py
  • backend/app/modules/tasks/service.py
  • backend/app/schemas/auth.py
  • backend/scripts/api_contract_e2e.py
  • backend/tests/test_actors.py
  • backend/tests/test_alembic.py
  • backend/tests/test_api_rate_controls.py
  • backend/tests/test_auth.py
  • backend/tests/test_checkers.py
  • backend/tests/test_projects.py
  • backend/tests/test_tasks.py
  • docs/operations_authorization_service.md
💤 Files with no reviewable changes (1)
  • backend/tests/test_api_rate_controls.py

Comment thread backend/alembic/versions/0020_canonical_actor_profile.py Outdated
Comment thread backend/alembic/versions/0020_canonical_actor_profile.py
Comment thread backend/app/adapters/auth/dev.py
Comment thread backend/app/modules/actors/service.py
Comment thread backend/app/modules/tasks/service.py
Comment thread backend/tests/test_actors.py Outdated
Comment thread backend/tests/test_alembic.py

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/tests/test_tasks.py (1)

126-144: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Flatten deep try...finally nesting and release lock during yield.

Yielding inside with migration_lock(): holds the lock for the entire duration of the test. If pytest-xdist is used to run tests in parallel, this will effectively serialize test execution across workers and slow down the test suite.

Consider releasing the lock during the test execution, re-acquiring it only for teardown migrations, and flattening the try...finally blocks for better readability.

If holding the lock during the test is strictly required for this test suite (e.g., if workers share a single database and rely on the lock to prevent concurrency), you can still flatten the try...finally structure.

♻️ Proposed refactor
    config = alembic_config()
    
    with migration_lock():
        command.downgrade(config, "base")
        command.upgrade(config, "head")
        
    try:
        yield postgres_database_url
    finally:
        try:
            asyncio.run(reset_test_database_state(postgres_database_url))
        finally:
            try:
                asyncio.run(db_session.dispose_engine())
            finally:
                with migration_lock():
                    command.downgrade(config, "base")
                try:
                    asyncio.run(db_session.dispose_engine())
                finally:
                    get_settings.cache_clear()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_tasks.py` around lines 126 - 144, Refactor the fixture
teardown around migration_lock(), command.downgrade(), and command.upgrade() so
the lock is released before yielding postgres_database_url and reacquired only
for the final downgrade. Flatten the nested try/finally blocks while preserving
reset_test_database_state(), engine disposal, migration cleanup, and
get_settings.cache_clear() execution even when earlier teardown steps fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/tests/conftest.py`:
- Around line 34-47: Update the database reset fixture around the
include_canonical_actors handling to always truncate actor_profiles,
actor_identity_links, legacy_actor_identities, and legacy_workflow_eligibility
before the downgrade. Remove the conditional trigger-disabling and partial
canonical-actor reset path so every suite starts with all actor state cleared.

---

Nitpick comments:
In `@backend/tests/test_tasks.py`:
- Around line 126-144: Refactor the fixture teardown around migration_lock(),
command.downgrade(), and command.upgrade() so the lock is released before
yielding postgres_database_url and reacquired only for the final downgrade.
Flatten the nested try/finally blocks while preserving
reset_test_database_state(), engine disposal, migration cleanup, and
get_settings.cache_clear() execution even when earlier teardown steps fail.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dfe40e38-7305-419f-abd7-49cd477b4ae7

📥 Commits

Reviewing files that changed from the base of the PR and between 63f1dd3 and dd024e5.

📒 Files selected for processing (20)
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-06-canonical-actor-profile.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-external-review-response.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-pr-trust-bundle.md
  • .agent-loop/merge-intents/WS-AUTH-001-06.json
  • backend/alembic/versions/0020_canonical_actor_profile.py
  • backend/app/adapters/auth/dev.py
  • backend/app/adapters/auth/flow.py
  • backend/app/modules/actors/service.py
  • backend/app/modules/tasks/schemas.py
  • backend/app/modules/tasks/service.py
  • backend/scripts/api_contract_e2e.py
  • backend/tests/conftest.py
  • backend/tests/test_actors.py
  • backend/tests/test_alembic.py
  • backend/tests/test_auth.py
  • backend/tests/test_checkers.py
  • backend/tests/test_projects.py
  • backend/tests/test_tasks.py
  • docs/operations_authorization_service.md
🚧 Files skipped from review as they are similar to previous changes (10)
  • .agent-loop/merge-intents/WS-AUTH-001-06.json
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-internal-review-evidence.md
  • backend/scripts/api_contract_e2e.py
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-06-canonical-actor-profile.md
  • backend/app/adapters/auth/dev.py
  • backend/app/adapters/auth/flow.py
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-06-pr-trust-bundle.md
  • backend/alembic/versions/0020_canonical_actor_profile.py
  • docs/operations_authorization_service.md
  • backend/tests/test_alembic.py

Comment thread backend/tests/conftest.py
Comment on lines +34 to +47
if include_canonical_actors:
await connection.execute(
"alter table actor_profiles disable trigger actor_profile_history_guard"
)
await connection.execute(
"alter table actor_identity_links disable trigger "
"actor_identity_link_history_guard"
)
await connection.execute("truncate table audit_events cascade")
await connection.execute("truncate table api_rate_control_counters")
if include_canonical_actors:
await connection.execute(
"truncate table actor_identity_links, actor_profiles cascade"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Reset both canonical and legacy actor state for every database-backed suite.

The default path leaves canonical actors intact, while include_canonical_actors=True still leaves legacy_actor_identities and legacy_workflow_eligibility. The subsequent downgrade preserves/renames these rows, making later suites inherit identities and eligibility from earlier suites.

Truncate all four actor tables before downgrade and remove the optional partial-reset path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/conftest.py` around lines 34 - 47, Update the database reset
fixture around the include_canonical_actors handling to always truncate
actor_profiles, actor_identity_links, legacy_actor_identities, and
legacy_workflow_eligibility before the downgrade. Remove the conditional
trigger-disabling and partial canonical-actor reset path so every suite starts
with all actor state cleared.

@abiorh-claw abiorh-claw self-requested a review July 15, 2026 06:41
abiorh-claw
abiorh-claw previously approved these changes Jul 15, 2026
@abiorh-claw abiorh-claw merged commit f599551 into main Jul 15, 2026
4 checks passed
@abiorh-claw abiorh-claw deleted the codex/ws-auth-001-06-canonical-actor-profile branch July 15, 2026 08:54
github-actions Bot pushed a commit that referenced this pull request Jul 15, 2026
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