Skip to content

Implement actor identity profile registry#74

Merged
abiorh-claw merged 25 commits into
mainfrom
codex/ws-pol-001-11-actor-profile-registry-impl
Jul 7, 2026
Merged

Implement actor identity profile registry#74
abiorh-claw merged 25 commits into
mainfrom
codex/ws-pol-001-11-actor-profile-registry-impl

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

PR Trust Bundle: WS-POL-001-11

Chunk

WS-POL-001-11 - Actor Identity And Profile Registry

Goal

Implement Workstream's local actor identity and shared actor profile registry for verified Flow actors without turning Workstream into the auth provider or letting persisted profiles become route permissions.

Human-Approved Intent

The user asked for one shared actor/profile model instead of separate worker, reviewer, admin, project-manager, and project-owner implementations. The verified Flow token remains the authority for route access. Workstream stores local actor/profile rows for workflow eligibility, audit, display, future routing, and later reputation linkage.

Chunk contract:

  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/chunks/WS-POL-001-11-actor-identity-profile-registry.md

What Changed

  • Added actor_identities and actor_profiles with async SQLAlchemy models, repository, schemas, service, and Alembic migration.
  • Backfilled legacy worker_profiles and reviewer_profiles into the shared actor registry and removed the old profile tables as profile authority.
  • Kept get_current_actor pure and added get_registered_actor for explicit registry side effects.
  • Updated /auth/me, /workers/me/profile, and task claim paths to register actor identity/profile metadata where needed.
  • Made worker claim require current verified worker token role plus active ActorProfile(profile_type="worker").
  • Preserved active/disabled profile provenance during token observation refreshes.
  • Retired stale demo worker-profile bootstrap paths and rewired scripts/examples/UI to POST /api/v1/workers/me/profile.
  • Documented Flow issuer plus subject as the canonical identity anchor; Workstream actor id is a local durable reference.
  • Documented trusted workstream_relationship_profiles claim shape for scoped project-owner metadata.

Why It Changed

The live Terminal Benchmark drill proved worker profile setup must be real. Doing only a worker-specific profile path would create the same problem again for reviewers, project managers, admins, project owners, audit, and later reputation. This chunk creates the shared actor/profile base before the next live API drill.

Design Chosen

  • ActorIdentity stores local durable identity rows for verified Flow actors.
  • ActorProfile stores profile type, status, skill tags, scope, and non-authoritative metadata.
  • observed records token-observed metadata for audit/display only.
  • active is explicit workflow eligibility and still requires the matching current token role.
  • disabled blocks workflow eligibility and is preserved by observation refresh.
  • Route authorization still reads current ActorContext.roles, not database profile rows.
  • Actor profile audit events use the existing Workstream audit_events ledger through TaskRepository.add_audit_event.

Alternatives Rejected

  • Separate profile tables per role: rejected because it duplicates profile authority.
  • Persisted profiles as route permissions: rejected because Flow token claims are the route authorization source.
  • Automatic worker/reviewer eligibility from token observation: rejected because eligibility must come from explicit profile workflows.
  • Keeping old worker/reviewer compatibility stores: rejected because v0.1 is still under construction and should not preserve stale authority.
  • A new audit table/module in this chunk: deferred because the current accepted boundary is one v0.1 audit ledger, with extraction documented for future actor/reputation expansion.

Scope Control

Implemented only actor identity/profile registry, migration/backfill/removal, touched-route registration, worker profile activation, worker claim eligibility, tests, demo/script cleanup required by the migration, and documentation alignment.

No Workstream-owned login/signup/session/password behavior was added. No post-submit, review, revision, payment, reputation, blockchain, object storage, agent runtime, or frontend product implementation was added.

Product Behavior

  • Product review decisions remain only accept, needs_revision, and reject.
  • Worker profile setup is now the canonical authenticated worker endpoint, not a demo bootstrap route.
  • Task claim remains worker-only and now also requires active worker profile eligibility.
  • Stored profile rows do not grant access without the matching current verified token role.

Acceptance Criteria Proof

  • Migration creates actor registry tables and uniqueness constraints.
  • Migration backfills worker/reviewer rows and removes old profile tables.
  • Downgrade restores legacy rows with identity/profile data.
  • SQLAlchemy metadata imports new actor models and has negative assertions for old profile exports.
  • /auth/me registers identity/profile metadata without Workstream auth sessions.
  • Repeated requests refresh identity/profile freshness without duplicate rows.
  • Observed profiles are created for token roles but do not satisfy eligibility.
  • Active/disabled profile statuses and metadata are preserved during observation.
  • Worker profile activation requires worker token role and explicit API call.
  • Claim requires worker token role plus active worker profile.
  • Persisted active profiles without matching token roles cannot authorize worker/operator routes.
  • Overposting tests prove spoofed identity fields do not alter persisted registry rows.
  • Demo/scripts/examples no longer use /api/v1/demo/worker-profile.

Tests/Checks Run

cd backend && .venv/bin/python -m ruff check app/api/deps/auth.py app/api/routes/auth.py app/modules/actors app/modules/tasks/models.py app/modules/tasks/repository.py app/modules/tasks/router.py app/modules/tasks/schemas.py app/modules/tasks/service.py tests/test_actors.py tests/test_alembic.py tests/test_auth.py tests/test_tasks.py
cd backend && .venv/bin/docstr-coverage app/api app/modules/actors app/modules/tasks --config .docstr.yaml
python3 scripts/check_stale_workstream_wording.py
python3 scripts/check_markdown_links.py
git diff --check
cd backend && .venv/bin/python -m pytest tests/test_alembic.py tests/test_actors.py tests/test_auth.py -q
cd backend && .venv/bin/python -m pytest tests/test_tasks.py -q
cd demos/week1_api_demo_ui && npm run build
rg -n 'worker_profile_setup=demo_bootstrap|demo worker profile|Activates demo worker profile|WORKSTREAM_ENABLE_DEMO_ROUTES|/api/v1/demo/worker-profile|WorkerProfile|ReviewerProfile' backend/scripts examples/terminal_benchmark backend/app/api/routes/demo.py backend/app/modules README.md demos/week1_api_demo_ui/src/App.tsx docs/spec_chunk_2_auth_actor_boundary.md docs/architecture_data_model.md docs/operations_roles_permissions.md

Result summary:

  • Ruff: passed.
  • Docstring coverage: 100.0%.
  • Stale wording scan: passed.
  • Markdown link check: passed for 9 changed Markdown files.
  • Diff whitespace check: passed.
  • Migration/actor/auth tests: 35 passed in 518.35s.
  • Task tests: 69 passed in 1184.65s.
  • Week 1 demo UI build: passed.
  • Stale demo/profile scan: no matches.

Test Delta

  • Tests added: backend/tests/test_actors.py.
  • Tests expanded: Alembic backfill/downgrade/uniqueness, auth registration, task metadata, token-role authorization, overposting, active-profile eligibility, and stale route removal.
  • Tests removed/skipped: none.

CI Integrity

  • Coverage threshold unchanged.
  • Lint/typecheck configuration unchanged.
  • No workflow weakening.
  • No package script weakening.
  • No dependency changes.

Reviewer Results

Internal review evidence:

  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-internal-review-evidence.md

Reviewed code SHA: 912a1bef3ce7065e9563a03a440b24efe6af3f89

Reviewer run IDs: see WS-POL-001-11-internal-review-evidence.md.

Reviewer Result Blocking findings Notes
senior engineering PASS AFTER FIXES None Fixed profile freshness, identity upsert churn, and documented audit ledger coupling.
QA/test PASS None Confirmed actor registry behavior, migration, auth boundary, eligibility gates, and demo rewiring.
security/auth PASS AFTER FIXES None Confirmed token authority and fail-closed scope after fixes.
product/ops PASS None Confirmed actor/profile workflow semantics.
architecture PASS WITH LOW RISKS None Confirmed auth/profile boundaries; future shared audit module noted as follow-up.
CI integrity PASS None Confirmed the post-PR lint fix only imports uuid4 and does not weaken CI or tests.
docs PASS WITH LOW RISKS None Confirmed docs alignment after final issuer-plus-subject wording.
reuse/dedup PASS None Confirmed single actor/profile authority and audit helper reuse.
test delta PASS None Confirmed tests were strengthened and not weakened.

External Review

External review has not run yet. CodeRabbit and GitHub checks should run after the PR is opened.

Remaining Risks

  • Actor profile audit persistence currently imports the existing task audit repository. This keeps one v0.1 audit ledger but should be extracted to a shared audit module before actor/reputation work grows.
  • Existing routes outside this chunk may continue using pure get_current_actor until deliberately migrated.
  • The next Terminal Benchmark live API drill still needs to run against this implementation through real HTTP calls after merge.

Follow-Up Work

  • Open PR and wait for CodeRabbit/GitHub checks.
  • Address external review in a separate external-review response file if needed.
  • After merge, rerun the Terminal Benchmark live API drill using the canonical worker profile endpoint.

Human Review Focus

Please inspect:

  • Flow auth boundary: token role first, profile eligibility second.
  • Migration/backfill/removal of old worker/reviewer profile stores.
  • ActorProfile status semantics and preservation of explicit profile metadata.
  • Overposting protections around registry writes.
  • Demo/script cleanup from demo bootstrap to canonical worker profile API.

Human Merge Ownership

Only the user can approve and merge this PR. Codex must not merge it without explicit user approval for that specific PR.

Summary by CodeRabbit

  • New Features
    • Added a unified actor identity/profile registry with observed-profile refresh and worker-profile activation.
    • Worker profile setup/activation now uses the standard POST /api/v1/workers/me/profile flow.
  • Bug Fixes
    • Improved authorization so task, project, and checker actions consistently rely on the registered actor state.
    • Strengthened claim sanitization and prevented legacy/duplicate profile data from influencing access.
  • Chores
    • Retired the demo worker-profile route and aligned docs, UI, and automation with the canonical API path; updated CI/E2E to run the API-contract drill.

@coderabbitai

coderabbitai Bot commented Jul 6, 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: 8f8d7029-dc9c-496c-8a08-77da634ca3be

📥 Commits

Reviewing files that changed from the base of the PR and between 3b2977e and c08c1e0.

📒 Files selected for processing (18)
  • .agent-loop/LOOP_STATE.md
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/chunks/WS-POL-001-11-actor-identity-profile-registry.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-external-review-response.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-internal-review-evidence.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-pr-trust-bundle.md
  • backend/app/modules/actors/service.py
  • backend/app/modules/audit/__init__.py
  • backend/app/modules/audit/repository.py
  • backend/app/schemas/auth.py
  • backend/scripts/api_contract_e2e.py
  • backend/scripts/week2_api_e2e.py
  • backend/tests/test_actors.py
  • docs/architecture_data_model.md
  • docs/architecture_system_architecture.md
  • docs/glossary.md
  • docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md
  • docs/operations_roles_permissions.md
✅ Files skipped from review due to trivial changes (5)
  • backend/app/modules/audit/init.py
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-external-review-response.md
  • docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/LOOP_STATE.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • docs/architecture_system_architecture.md
  • docs/glossary.md
  • backend/scripts/week2_api_e2e.py
  • docs/operations_roles_permissions.md
  • docs/architecture_data_model.md
  • backend/scripts/api_contract_e2e.py
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/chunks/WS-POL-001-11-actor-identity-profile-registry.md
  • backend/app/modules/actors/service.py

📝 Walkthrough

Walkthrough

This PR introduces a shared actor identity/profile registry with new models, repository, service, and schemas; migrates legacy worker/reviewer profile storage; rewires auth/task/project/checker flows to use registry-backed actor resolution; and updates scripts, docs, tests, and review-tracking artifacts to the canonical worker profile endpoint.

Changes

Process/Tracking Documentation

Layer / File(s) Summary
State and chunk status
.agent-loop/LOOP_STATE.md, .agent-loop/WORK_QUEUE.md, .agent-loop/initiatives/.../STATUS.md, .agent-loop/initiatives/.../CHUNK_MAP.md, .agent-loop/initiatives/.../chunks/WS-POL-001-11-*.md
Tracking documents now describe WS-POL-001-11 as an active implementation chunk, with updated allowed-file and acceptance criteria language.
Review evidence and trust bundle
.agent-loop/REVIEW_LOG.md, .agent-loop/initiatives/.../reviews/WS-POL-001-11-*.md
Review evidence and trust-bundle docs record the reviewed SHA, implementation scope, reviewer results, command history, and external review outcome.

Actor Identity/Profile Registry Implementation

Layer / File(s) Summary
Models and migration
backend/app/modules/actors/models.py, backend/app/db/models.py, backend/app/modules/tasks/models.py, backend/alembic/versions/0012_actor_identity_profile_registry.py
Adds ActorIdentity and ActorProfile storage and removes legacy worker/reviewer profile tables.
Actor repository and schemas
backend/app/modules/actors/repository.py, backend/app/modules/actors/schemas.py
Adds async identity/profile persistence helpers and activation/response schemas with skill-tag normalization.
Actor service and audit helpers
backend/app/modules/actors/service.py, backend/app/core/config.py, backend/app/adapters/auth/flow.py, backend/app/schemas/auth.py
Implements registration, observation, activation, refresh-window handling, claim sanitization, and audit event writing.
Auth dependency and route wiring
backend/app/api/deps/auth.py, backend/app/api/routes/auth.py, backend/app/api/router.py, backend/app/api/routes/demo.py
Adds registry-backed actor resolution, switches /auth/me, and retires the demo worker-profile route surface.
Task module cleanup
backend/app/modules/tasks/*.py
Removes legacy profile models, repository methods, and schemas, and routes worker profile activation through the actor registry.
Migration, auth, project, and task tests
backend/tests/test_actors.py, backend/tests/test_alembic.py, backend/tests/test_auth.py, backend/tests/test_projects.py, backend/tests/test_tasks.py
Adds coverage for actor registry behavior, migration shape, auth failures, project actor registration, and task authorization/overposting rules.
Scripts, demo UI, and drill updates
backend/scripts/api_contract_e2e.py, backend/scripts/week2_api_e2e.py, examples/terminal_benchmark/*, demos/week1_api_demo_ui/*, README.md, .github/workflows/backend.yml
Moves drills and demo flows to POST /api/v1/workers/me/profile and removes demo-specific UI/workflow surfaces.
Architecture, roles, and spec docs
docs/architecture_*.md, docs/glossary.md, docs/operations_roles_permissions.md, docs/spec_chunk_*.md, docs/roadmap_*.md, docs/internal_reviews/*
Updates the identity, authorization, audit, and rollout docs for the actor registry model.
Internal review evidence gate
scripts/check_internal_review_evidence.py, scripts/test_agent_gates.py
Restricts evidence detection to .agent-loop/.../reviews/*-internal-review-evidence.md and updates tests accordingly.

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

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is clear, concise, and directly matches the main change: introducing an actor identity/profile registry.
Description check ✅ Passed The description covers the template’s major sections and includes goals, changes, evidence, tests, review results, risks, and follow-up items.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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-pol-001-11-actor-profile-registry-impl

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.

@Abiorh001 Abiorh001 requested a review from abiorh-claw July 6, 2026 16:32

@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: 4

🧹 Nitpick comments (6)
backend/tests/test_auth.py (1)

41-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Same migration-fixture duplication as test_actors.py/test_tasks.py.

This auth_database_env fixture repeats the same base→head→base Alembic dance already flagged in test_actors.py (actor_database_env) and present in test_tasks.py (task_database_env). Worth extracting once into a shared conftest helper.

🤖 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 41 - 63, The auth_database_env
fixture duplicates the same Alembic base→head→base setup already used by
actor_database_env and task_database_env. Extract the shared migration
setup/teardown into a common conftest helper or shared fixture, then have
auth_database_env delegate to it while keeping the existing
db_session.dispose_engine, get_settings.cache_clear, and migration_lock behavior
intact.
backend/tests/test_actors.py (1)

25-118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate the migration fixture/helper boilerplate shared across test files.

actor_database_env/actor_client (25-55) and the alembic_config/set_dev_actor/actor_id helpers (58-118) are near-identical to the equivalents added in test_auth.py::auth_database_env and test_tasks.py::task_database_env/actor_id/set_dev_actor. Consider extracting a shared, parametrized fixture/helper module (e.g. in conftest.py) for the downgrade→upgrade→yield→downgrade pattern and the dev-actor env setup, since all three now do the same base↔head migration dance with only role/subject differences.

🤖 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 25 - 118, The migration fixtures
and dev-actor helpers are duplicated across test modules, especially the
downgrade→upgrade→yield→downgrade flow in actor_database_env/actor_client and
the env setup in set_dev_actor/alembic_config/actor_id. Move the shared Postgres
migration and dev-auth setup into a common helper or conftest fixture, then have
actor_database_env, auth_database_env, and task_database_env reuse it with
parameters for roles, subject, and any test-specific actor identity values.
backend/app/api/deps/auth.py (1)

59-76: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

DB write on every authenticated request, including hot paths.

get_registered_actor performs an identity/profile upsert plus a commit() on every call, and is wired into claim_task — a hot, frequently-polled endpoint for workers — as well as /auth/me. Consider only refreshing registry metadata periodically (e.g., skip the write if the identity was refreshed recently) rather than on every request, to avoid adding write latency/DB load to these paths.

🤖 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/app/api/deps/auth.py` around lines 59 - 76, get_registered_actor is
writing registry data on every authenticated request via
ActorService.register_actor, which hits hot paths like claim_task and /auth/me.
Update this dependency to avoid unconditional upserts/commit on every call by
adding a freshness check or periodic refresh guard inside get_registered_actor
or register_actor, so recently refreshed actors skip the DB write while still
returning the same ActorContext.
backend/app/modules/actors/models.py (1)

13-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Check-constraint literals duplicate the Python tuples.

ACTOR_PROFILE_TYPES/ACTOR_PROFILE_STATUSES are declared as module constants, but the CheckConstraint SQL strings (lines 60-61, 64-65) hardcode the same values separately. If either tuple changes without updating the constraint string, the DB will silently diverge from application-level validation (e.g. an app-accepted new profile type gets rejected by Postgres, or vice versa).

♻️ Build the constraint from the constants
+_PROFILE_TYPE_LIST = ", ".join(f"'{t}'" for t in ACTOR_PROFILE_TYPES)
+_PROFILE_STATUS_LIST = ", ".join(f"'{s}'" for s in ACTOR_PROFILE_STATUSES)
+
     __table_args__ = (
         CheckConstraint(
-            "profile_type in ('worker', 'reviewer', 'admin', 'project_manager', 'project_owner')",
+            f"profile_type in ({_PROFILE_TYPE_LIST})",
             name="ck_actor_profiles_profile_type",
         ),
         CheckConstraint(
-            "status in ('observed', 'active', 'disabled')",
+            f"status in ({_PROFILE_STATUS_LIST})",
             name="ck_actor_profiles_status",
         ),

Also applies to: 59-66

🤖 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/app/modules/actors/models.py` around lines 13 - 14, The
check-constraint SQL in the model duplicates the values already defined by
ACTOR_PROFILE_TYPES and ACTOR_PROFILE_STATUSES, so update the constraint
definitions in the actors model to be derived from those constants instead of
hardcoding the literals. Adjust the CheckConstraint setup where the profile
type/status validation is declared so it reuses the module-level tuples, keeping
the database rules aligned with the application-level constants. Use the
existing symbols ACTOR_PROFILE_TYPES, ACTOR_PROFILE_STATUSES, and the model’s
constraint declarations to locate and refactor the relevant code.
backend/app/modules/actors/service.py (2)

178-179: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Redundant identity upsert on the worker profile activation route.

activate_worker_profile re-runs upsert_identity even though the route's get_registered_actor dependency already called register_actor (which upserts identity) earlier in the same request. This causes two upsert+commit round trips for identity per activation call.

🤖 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/app/modules/actors/service.py` around lines 178 - 179, The
activate_worker_profile flow is redundantly upserting the same identity twice in
one request because get_registered_actor already registers the actor before this
method runs. Update activate_worker_profile in the Actor service to reuse the
existing registered actor/identity from the request context instead of calling
_repo.upsert_identity again, and keep the activation logic focused on profile
activation only. Use the existing register_actor and _identity_from_actor
symbols to locate the duplicate persistence path and remove the extra
upsert+commit round trip.

143-147: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

or fallback silently ignores an explicit empty-dict override.

next_metadata = profile_metadata or existing.profile_metadata treats profile_metadata={} the same as None, so a caller intending to clear metadata to {} would have that silently dropped. No current caller passes {} (all pass non-empty dicts), so this is latent, but the dict | None signature invites it.

♻️ Suggested fix
-        next_metadata = profile_metadata or existing.profile_metadata
+        next_metadata = existing.profile_metadata if profile_metadata is None else profile_metadata
🤖 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/app/modules/actors/service.py` around lines 143 - 147, In the
metadata update path, the `or` fallback in the actor service is treating an
explicit empty dict the same as no value, so `profile_metadata={}` gets ignored
instead of clearing metadata. Update the logic around `next_metadata` to
distinguish `None` from an intentional empty mapping, and preserve the existing
comparison/update flow in the `existing.profile_metadata` assignment so callers
can explicitly set metadata to `{}`.
🤖 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/0012_actor_identity_profile_registry.py`:
- Around line 168-244: The backfill logic in _backfill_legacy_profiles is
overwriting actor_identities.last_seen_roles and last_claim_snapshot on each
legacy table pass, which loses previously collected role provenance for the same
actor_id. Update the upsert in _backfill_legacy_profiles so it merges the new
profile_type into the existing role list instead of replacing it, and preserve
prior claim snapshot provenance rather than resetting it to only the current
table. Use the actor_identities_table insert/on_conflict_do_update block and its
last_seen_roles/last_claim_snapshot fields as the place to adjust the merge
behavior.

In `@backend/app/api/deps/auth.py`:
- Around line 59-76: Handle registry failures in get_registered_actor by
catching exceptions from ActorService.register_actor before they escape the
dependency. Map ActorRegistryError (and any expected persistence/DB failure from
get_db_session) to a structured HTTP error here, or add a global exception
handler if that’s the preferred central fix. Keep the current actor return path
unchanged for success, and make sure the dependency remains the single place
where get_current_actor plus registry refresh is resolved.

In `@backend/app/modules/actors/repository.py`:
- Around line 25-78: The upsert_identity method in the ActorsRepository can
return a stale ActorIdentity instance because get_identity may reuse an existing
row from the session identity map. Update the fetch after the flush to load a
fresh row using self._session.get(ActorIdentity, identity.actor_id,
populate_existing=True), or explicitly refresh the persisted ActorIdentity
before returning it, so the returned object reflects the latest values written
by the insert/on_conflict_do_update path.

In `@backend/app/modules/actors/service.py`:
- Around line 63-71: The `register_actor()` flow is causing
`ActorProfile.updated_at` to change on every observation because
`ensure_observed_profile()` writes the profile row even when only
`ActorIdentity.last_seen_at` should move. Update `ensure_observed_profile()` in
`service.py` so the `observed` and non-`observed` branches only persist the
`ActorProfile` when status or metadata actually changes, and avoid any save path
that touches `updated_at` for no-op observations. Keep the existing behavior for
real profile changes, but ensure `register_actor()` can refresh identity state
without rewriting unchanged profiles.

---

Nitpick comments:
In `@backend/app/api/deps/auth.py`:
- Around line 59-76: get_registered_actor is writing registry data on every
authenticated request via ActorService.register_actor, which hits hot paths like
claim_task and /auth/me. Update this dependency to avoid unconditional
upserts/commit on every call by adding a freshness check or periodic refresh
guard inside get_registered_actor or register_actor, so recently refreshed
actors skip the DB write while still returning the same ActorContext.

In `@backend/app/modules/actors/models.py`:
- Around line 13-14: The check-constraint SQL in the model duplicates the values
already defined by ACTOR_PROFILE_TYPES and ACTOR_PROFILE_STATUSES, so update the
constraint definitions in the actors model to be derived from those constants
instead of hardcoding the literals. Adjust the CheckConstraint setup where the
profile type/status validation is declared so it reuses the module-level tuples,
keeping the database rules aligned with the application-level constants. Use the
existing symbols ACTOR_PROFILE_TYPES, ACTOR_PROFILE_STATUSES, and the model’s
constraint declarations to locate and refactor the relevant code.

In `@backend/app/modules/actors/service.py`:
- Around line 178-179: The activate_worker_profile flow is redundantly upserting
the same identity twice in one request because get_registered_actor already
registers the actor before this method runs. Update activate_worker_profile in
the Actor service to reuse the existing registered actor/identity from the
request context instead of calling _repo.upsert_identity again, and keep the
activation logic focused on profile activation only. Use the existing
register_actor and _identity_from_actor symbols to locate the duplicate
persistence path and remove the extra upsert+commit round trip.
- Around line 143-147: In the metadata update path, the `or` fallback in the
actor service is treating an explicit empty dict the same as no value, so
`profile_metadata={}` gets ignored instead of clearing metadata. Update the
logic around `next_metadata` to distinguish `None` from an intentional empty
mapping, and preserve the existing comparison/update flow in the
`existing.profile_metadata` assignment so callers can explicitly set metadata to
`{}`.

In `@backend/tests/test_actors.py`:
- Around line 25-118: The migration fixtures and dev-actor helpers are
duplicated across test modules, especially the downgrade→upgrade→yield→downgrade
flow in actor_database_env/actor_client and the env setup in
set_dev_actor/alembic_config/actor_id. Move the shared Postgres migration and
dev-auth setup into a common helper or conftest fixture, then have
actor_database_env, auth_database_env, and task_database_env reuse it with
parameters for roles, subject, and any test-specific actor identity values.

In `@backend/tests/test_auth.py`:
- Around line 41-63: The auth_database_env fixture duplicates the same Alembic
base→head→base setup already used by actor_database_env and task_database_env.
Extract the shared migration setup/teardown into a common conftest helper or
shared fixture, then have auth_database_env delegate to it while keeping the
existing db_session.dispose_engine, get_settings.cache_clear, and migration_lock
behavior intact.
🪄 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: 6640e446-5ab9-4aed-a385-7fb50ac7aff1

📥 Commits

Reviewing files that changed from the base of the PR and between 0830bf9 and 50636b1.

📒 Files selected for processing (39)
  • .agent-loop/LOOP_STATE.md
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/WORK_QUEUE.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/STATUS.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/chunks/WS-POL-001-11-actor-identity-profile-registry.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-internal-review-evidence.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-pr-trust-bundle.md
  • README.md
  • backend/alembic/versions/0012_actor_identity_profile_registry.py
  • backend/app/api/deps/auth.py
  • backend/app/api/routes/auth.py
  • backend/app/api/routes/demo.py
  • backend/app/db/models.py
  • backend/app/modules/actors/__init__.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/models.py
  • backend/app/modules/tasks/repository.py
  • backend/app/modules/tasks/router.py
  • backend/app/modules/tasks/schemas.py
  • backend/app/modules/tasks/service.py
  • backend/scripts/week1_api_e2e.py
  • backend/scripts/week1_dry_run.py
  • backend/scripts/week2_api_e2e.py
  • backend/tests/test_actors.py
  • backend/tests/test_alembic.py
  • backend/tests/test_auth.py
  • backend/tests/test_tasks.py
  • demos/week1_api_demo_ui/src/App.tsx
  • docs/architecture_data_model.md
  • docs/architecture_system_architecture.md
  • docs/glossary.md
  • docs/operations_roles_permissions.md
  • docs/spec_chunk_2_auth_actor_boundary.md
  • docs/spec_chunk_4_task_queue_assignment.md
  • examples/terminal_benchmark/LOCAL_VALIDATION_NOTES.md
  • examples/terminal_benchmark/terminal_benchmark_api_e2e.py
💤 Files with no reviewable changes (1)
  • backend/app/modules/tasks/schemas.py

Comment on lines +168 to +244
def _backfill_legacy_profiles(connection, table_name: str, profile_type: str) -> None:
"""Backfill one legacy profile table into actor identities and profiles."""
rows = (
connection.execute(
sa.text(
f"""
select
id,
actor_id,
external_subject,
external_issuer,
display_name,
email,
skill_tags,
status,
created_at,
updated_at
from {table_name}
"""
)
)
.mappings()
.all()
)
for row in rows:
roles = [profile_type]
connection.execute(
postgresql.insert(actor_identities_table)
.values(
actor_id=row["actor_id"],
external_subject=row["external_subject"],
external_issuer=row["external_issuer"],
display_name=row["display_name"],
email=row["email"],
last_seen_roles=roles,
last_claim_snapshot={"legacy_profile_backfill": table_name},
auth_source="legacy_profile_backfill",
is_dev_auth=False,
)
.on_conflict_do_update(
index_elements=["actor_id"],
set_={
"external_subject": row["external_subject"],
"external_issuer": row["external_issuer"],
"display_name": row["display_name"],
"email": row["email"],
"last_seen_roles": roles,
"last_claim_snapshot": {"legacy_profile_backfill": table_name},
"auth_source": "legacy_profile_backfill",
"is_dev_auth": False,
"last_seen_at": sa.func.now(),
"updated_at": sa.func.now(),
},
)
)
connection.execute(
postgresql.insert(actor_profiles_table)
.values(
id=row["id"],
actor_id=row["actor_id"],
profile_type=profile_type,
status=row["status"],
skill_tags=row["skill_tags"] or [],
scope_type="global",
scope_id="global",
profile_metadata={"legacy_profile_backfill": table_name},
)
.on_conflict_do_update(
index_elements=["actor_id", "profile_type", "scope_type", "scope_id"],
set_={
"status": row["status"],
"skill_tags": row["skill_tags"] or [],
"profile_metadata": {"legacy_profile_backfill": table_name},
"updated_at": sa.func.now(),
},
)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## files\n'
git ls-files 'backend/alembic/versions/0012_actor_identity_profile_registry.py' \
  'backend/**/*.py' | sed -n '1,200p'

printf '\n## search for legacy profile tables and metadata fields\n'
rg -n --hidden --glob 'backend/**/*.py' \
  'worker_profiles|reviewer_profiles|last_seen_roles|last_claim_snapshot|actor_identities_table|actor_profiles_table|profile_type' backend

printf '\n## read migration file around the backfill call and function\n'
FILE='backend/alembic/versions/0012_actor_identity_profile_registry.py'
wc -l "$FILE"
sed -n '1,280p' "$FILE"

Repository: Flow-Research/workstream

Length of output: 32056


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## actor model and service semantics\n'
sed -n '1,180p' backend/app/modules/actors/models.py
printf '\n---\n'
sed -n '240,380p' backend/app/modules/actors/service.py

printf '\n## alembic migration tests around legacy tables and backfill\n'
sed -n '250,620p' backend/tests/test_alembic.py

printf '\n## actor tests that exercise multi-role identity state\n'
sed -n '120,220p' backend/tests/test_actors.py

Repository: Flow-Research/workstream

Length of output: 25886


Merge legacy role metadata during backfill

worker_profiles and reviewer_profiles can both exist for the same actor_id, so the second pass overwrites actor_identities.last_seen_roles/last_claim_snapshot with a single-role snapshot. That leaves multi-role actors with misleading audit metadata until their next login refreshes it. Merge the role list and preserve prior claim provenance instead of replacing it.

🤖 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/alembic/versions/0012_actor_identity_profile_registry.py` around
lines 168 - 244, The backfill logic in _backfill_legacy_profiles is overwriting
actor_identities.last_seen_roles and last_claim_snapshot on each legacy table
pass, which loses previously collected role provenance for the same actor_id.
Update the upsert in _backfill_legacy_profiles so it merges the new profile_type
into the existing role list instead of replacing it, and preserve prior claim
snapshot provenance rather than resetting it to only the current table. Use the
actor_identities_table insert/on_conflict_do_update block and its
last_seen_roles/last_claim_snapshot fields as the place to adjust the merge
behavior.

Comment thread backend/app/api/deps/auth.py
Comment thread backend/app/modules/actors/repository.py Outdated
Comment thread backend/app/modules/actors/service.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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
backend/alembic/versions/0012_actor_identity_profile_registry.py (1)

19-83: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Restore the legacy-profile backfill before dropping these tables. upgrade() deletes worker_profiles and reviewer_profiles outright, but the new flow only registers the token-derived actor and requires an existing active ActorProfile to claim tasks. That permanently loses prior skill_tags, status, and timestamps, and existing workers will stop qualifying until they re-activate in the new API.

🤖 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/alembic/versions/0012_actor_identity_profile_registry.py` around
lines 19 - 83, The `upgrade()` migration drops `worker_profiles` and
`reviewer_profiles` too early, causing existing profile data to be lost before
it is copied into the new actor registry. Add a backfill step in `upgrade()` for
the `actor_identities` / `actor_profiles` transition so legacy rows from
`worker_profiles` and `reviewer_profiles` are migrated into `ActorProfile`
records (preserving `skill_tags`, status, and timestamps) before the
`drop_table` calls. Use the existing migration symbols `upgrade`,
`actor_profiles`, `worker_profiles`, and `reviewer_profiles` to place the copy
logic immediately before the destructive cleanup.
backend/app/modules/actors/service.py (1)

55-92: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

N+1 profile queries on every get_registered_actor call.

_can_skip_registry_refresh issues one get_profile query per required profile type/relationship in addition to the identity fetch. Since get_registered_actor is now the dependency for nearly all authenticated routes (projects, tasks, checkers), this adds several sequential DB round trips to the hot path of most API requests — even when the freshness check ultimately decides to skip all writes. list_profiles(actor_id) already fetches all of an actor's profiles in a single query and can replace the per-profile loop.

⚡ Proposed fix using a single `list_profiles` query
         required_profiles.extend(self._trusted_relationship_profiles(actor))
-        for required_profile in required_profiles:
-            profile = await self._repo.get_profile(
-                actor.actor_id,
-                required_profile["profile_type"],
-                required_profile["scope_type"],
-                required_profile["scope_id"],
-            )
-            if profile is None:
+        existing_profiles = {
+            (p.profile_type, p.scope_type, p.scope_id): p
+            for p in await self._repo.list_profiles(actor.actor_id)
+        }
+        for required_profile in required_profiles:
+            profile = existing_profiles.get(
+                (
+                    required_profile["profile_type"],
+                    required_profile["scope_type"],
+                    required_profile["scope_id"],
+                )
+            )
+            if profile is None:
                 return False
             if (
                 profile.status == "observed"
                 and profile.profile_metadata != required_profile.get("profile_metadata")
             ):
                 return False
         return True

Also applies to: 282-322

🤖 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/app/modules/actors/service.py` around lines 55 - 92, The freshness
check in register_actor/_can_skip_registry_refresh is doing N+1 profile lookups
by calling get_profile repeatedly on the hot path. Update
_can_skip_registry_refresh to use a single list_profiles(actor_id) query, build
the needed profile set from that result, and keep the existing identity
fetch/skip logic intact so get_registered_actor avoids sequential DB round trips
when no refresh is needed.
🧹 Nitpick comments (2)
backend/app/modules/actors/service.py (2)

414-446: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated project_owner claim validation logic.

This loop repeats the same dict/type/trim/empty-string validation for workstream_relationship_profiles entries already implemented in sanitized_claim_snapshot (backend/app/schemas/auth.py). Consider extracting a shared helper that yields validated (profile_type, scope_type, scope_id) tuples, with each caller attaching its own metadata, to avoid the two implementations drifting on a security-relevant claim 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/app/modules/actors/service.py` around lines 414 - 446, The
`_trusted_relationship_profiles` validation for
`workstream_relationship_profiles` duplicates the same `project_owner`
sanitization already handled in `sanitized_claim_snapshot`, so the two paths can
drift. Extract or reuse a shared helper for validating and normalizing the claim
entries into `(profile_type, scope_type, scope_id)` values, then have both
`ActorService._trusted_relationship_profiles` and the auth schema path attach
their own metadata as needed.

452-488: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Actor audit writes go through TaskRepository.

self._audit_repo = TaskRepository(session) (line 53) is reused here purely for add_audit_event, even though these are actor-profile audit events unrelated to tasks. Consider extracting a generic AuditRepository (or renaming/relocating the method) so ActorService doesn't depend on the tasks module for an unrelated concern.

🤖 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/app/modules/actors/service.py` around lines 452 - 488, ActorService
is using TaskRepository for actor-profile audit writes, which couples unrelated
task storage to audit handling. Refactor the audit path in _write_profile_audit
to use a dedicated AuditRepository (or move the audit persistence behind a
generic audit-specific dependency) and update the ActorService constructor/field
setup so add_audit_event is no longer sourced from the tasks module.
🤖 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 `@docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md`:
- Around line 117-124: The quoted CLI result in this doc does not match the
actual output from api_contract_e2e.py. Update the text in the deterministic
hardening section to use the exact string printed by scripts/api_contract_e2e.py
(the message containing “real API”), and keep the second quoted result aligned
with the script’s actual PASS output so the documentation reflects
evidence-backed output rather than paraphrased wording.

---

Outside diff comments:
In `@backend/alembic/versions/0012_actor_identity_profile_registry.py`:
- Around line 19-83: The `upgrade()` migration drops `worker_profiles` and
`reviewer_profiles` too early, causing existing profile data to be lost before
it is copied into the new actor registry. Add a backfill step in `upgrade()` for
the `actor_identities` / `actor_profiles` transition so legacy rows from
`worker_profiles` and `reviewer_profiles` are migrated into `ActorProfile`
records (preserving `skill_tags`, status, and timestamps) before the
`drop_table` calls. Use the existing migration symbols `upgrade`,
`actor_profiles`, `worker_profiles`, and `reviewer_profiles` to place the copy
logic immediately before the destructive cleanup.

In `@backend/app/modules/actors/service.py`:
- Around line 55-92: The freshness check in
register_actor/_can_skip_registry_refresh is doing N+1 profile lookups by
calling get_profile repeatedly on the hot path. Update
_can_skip_registry_refresh to use a single list_profiles(actor_id) query, build
the needed profile set from that result, and keep the existing identity
fetch/skip logic intact so get_registered_actor avoids sequential DB round trips
when no refresh is needed.

---

Nitpick comments:
In `@backend/app/modules/actors/service.py`:
- Around line 414-446: The `_trusted_relationship_profiles` validation for
`workstream_relationship_profiles` duplicates the same `project_owner`
sanitization already handled in `sanitized_claim_snapshot`, so the two paths can
drift. Extract or reuse a shared helper for validating and normalizing the claim
entries into `(profile_type, scope_type, scope_id)` values, then have both
`ActorService._trusted_relationship_profiles` and the auth schema path attach
their own metadata as needed.
- Around line 452-488: ActorService is using TaskRepository for actor-profile
audit writes, which couples unrelated task storage to audit handling. Refactor
the audit path in _write_profile_audit to use a dedicated AuditRepository (or
move the audit persistence behind a generic audit-specific dependency) and
update the ActorService constructor/field setup so add_audit_event is no longer
sourced from the tasks module.
🪄 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: 442248ac-79d0-4f4d-b1f6-e45c671a498f

📥 Commits

Reviewing files that changed from the base of the PR and between 50636b1 and 3b2977e.

⛔ Files ignored due to path filters (1)
  • demos/week1_api_demo_ui/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (56)
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/chunks/WS-POL-001-11-actor-identity-profile-registry.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-internal-review-evidence.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-pr-trust-bundle.md
  • .github/workflows/backend.yml
  • .github/workflows/week1-api-demo-ui.yml
  • README.md
  • backend/alembic/versions/0012_actor_identity_profile_registry.py
  • backend/app/adapters/auth/flow.py
  • backend/app/api/deps/auth.py
  • backend/app/api/router.py
  • backend/app/api/routes/demo.py
  • backend/app/core/config.py
  • backend/app/modules/actors/__init__.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/checkers/router.py
  • backend/app/modules/projects/router.py
  • backend/app/modules/projects/service.py
  • backend/app/modules/tasks/router.py
  • backend/app/schemas/auth.py
  • backend/scripts/api_contract_e2e.py
  • backend/scripts/week1_dry_run.py
  • backend/scripts/week2_api_e2e.py
  • backend/tests/test_actors.py
  • backend/tests/test_alembic.py
  • backend/tests/test_auth.py
  • backend/tests/test_projects.py
  • backend/tests/test_tasks.py
  • demos/week1_api_demo_ui/index.html
  • demos/week1_api_demo_ui/package.json
  • demos/week1_api_demo_ui/src/App.tsx
  • demos/week1_api_demo_ui/src/api.ts
  • demos/week1_api_demo_ui/src/main.tsx
  • demos/week1_api_demo_ui/src/styles.css
  • demos/week1_api_demo_ui/tsconfig.app.json
  • demos/week1_api_demo_ui/tsconfig.json
  • demos/week1_api_demo_ui/vite.config.ts
  • docs/architecture_brief/workstream_architecture_brief.md
  • docs/architecture_data_model.md
  • docs/diagrams/workstream_v01_container.md
  • docs/glossary.md
  • docs/internal_reviews/2026-06-12_week2_closeout_real_api_drill.md
  • docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md
  • docs/operations_roles_permissions.md
  • docs/roadmap_30_day_master_plan.md
  • docs/roadmap_day_by_day_execution_plan.md
  • docs/roadmap_status.md
  • docs/spec_chunk_2_auth_actor_boundary.md
  • docs/spec_week2_checker_framework.md
  • examples/terminal_benchmark/terminal_benchmark_api_e2e.py
  • scripts/check_internal_review_evidence.py
  • scripts/test_agent_gates.py
💤 Files with no reviewable changes (17)
  • .github/workflows/week1-api-demo-ui.yml
  • demos/week1_api_demo_ui/package.json
  • demos/week1_api_demo_ui/src/main.tsx
  • demos/week1_api_demo_ui/tsconfig.json
  • backend/app/modules/actors/init.py
  • demos/week1_api_demo_ui/vite.config.ts
  • demos/week1_api_demo_ui/index.html
  • demos/week1_api_demo_ui/src/styles.css
  • demos/week1_api_demo_ui/tsconfig.app.json
  • backend/app/api/router.py
  • backend/app/modules/projects/service.py
  • demos/week1_api_demo_ui/src/api.ts
  • backend/app/api/routes/demo.py
  • backend/app/modules/actors/schemas.py
  • demos/week1_api_demo_ui/src/App.tsx
  • backend/scripts/week1_dry_run.py
  • README.md
✅ Files skipped from review due to trivial changes (10)
  • docs/diagrams/workstream_v01_container.md
  • docs/architecture_brief/workstream_architecture_brief.md
  • docs/spec_week2_checker_framework.md
  • docs/roadmap_30_day_master_plan.md
  • docs/internal_reviews/2026-06-12_week2_closeout_real_api_drill.md
  • docs/roadmap_day_by_day_execution_plan.md
  • docs/glossary.md
  • docs/roadmap_status.md
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/CHUNK_MAP.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • backend/app/api/deps/auth.py
  • backend/app/modules/actors/models.py
  • docs/architecture_data_model.md
  • docs/spec_chunk_2_auth_actor_boundary.md
  • .agent-loop/initiatives/WS-POL-001-submission-artifact-policy-foundation/reviews/WS-POL-001-11-pr-trust-bundle.md
  • backend/tests/test_tasks.py

@abiorh-claw abiorh-claw merged commit 5cec0e0 into main Jul 7, 2026
4 checks passed
@abiorh-claw abiorh-claw deleted the codex/ws-pol-001-11-actor-profile-registry-impl branch July 7, 2026 08:50
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