Skip to content

feat(auth): add project role grant mutations#194

Open
Abiorh001 wants to merge 10 commits into
mainfrom
codex/ws-auth-001-10c-project-role-grant-mutations
Open

feat(auth): add project role grant mutations#194
Abiorh001 wants to merge 10 commits into
mainfrom
codex/ws-auth-001-10c-project-role-grant-mutations

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

PR Trust Bundle: WS-AUTH-001-10C

Chunk And Goal

WS-AUTH-001-10C adds PREP-bound, idempotent, auditable issue and revoke
mutations for independent exact-project contributor roles. Risk is L1
authorization, concurrency, and audit integrity.

Change, Design, And Scope

  • A covered Project Manager can issue submitter, reviewer, or adjudicator for
    one exact project and revoke one exact stored grant.
  • Issue captures a bounded immutable qualification snapshot. Revoke derives the
    target and role only from the locked grant and emits the closed typed
    future-obligation invalidation projection.
  • Rate consumption, idempotency, the shared authority barrier, lexical
    profile/link locking, PM authority, project, advisory/grant locking, final
    fact recomposition, consume, evidence, and commit use the contract order.
  • Replay reauthorizes and reloads canonical ownership/state. Conflict and
    concealment paths do not disclose private target or reservation facts.
  • Hosted E2E uses only public APIs for issue, active read, revoke, history,
    replay/state-change conflicts, lifecycle-independent revoke, and authority loss.

All changed files are contract-allowed. There is no migration, durable schema
change, frontend work, automated role conversion, task assignment, review
reconciliation, or successor implementation.

Proof And Review

Focused lint, compile, contract, ordering, schema, rate, invalidation, and
cancellation checks pass locally. PostgreSQL evidence exercises the real named
partial unique index, public fallback, full loser rollback, database-observed
lock wait, production cancellation rollback, and committed clean retry. The
GitHub Backend workflow must run the full shards, hosted API E2E, repository-wide
78 percent floor, and authorization-subsystem 90 percent floor.

All nine internal tracks pass reviewed implementation SHA
0d05b7096eb7a2cf7c68a1770c0b35f07d5b55df with no open finding.

External Review, Risk, And Human Focus

GitHub CI, Agent Gates, CodeRabbit, and human review remain after publication.
Human review should focus on transaction/lock order, target concealment,
Project-Manager-only authority, replay reauthorization, partial-unique fallback,
revocation availability after lifecycle loss, and audit/invalidation atomicity.
The user retains merge ownership; do not merge without explicit approval of the
specific PR. The declared successor WS-AUTH-001-11 requires a separate signed
explicit start and must not begin automatically.

Summary by CodeRabbit

  • New Features

    • Project managers can grant exact project roles through a new API endpoint, including qualification evidence and a reason.
    • Project managers can revoke project-role grants through a dedicated endpoint.
    • Added stable idempotent replay handling with clear conflict and retry behavior.
    • Role changes now produce auditable events and authority invalidation updates.
  • Bug Fixes

    • Revocation remains available when a target is suspended or their identity link is removed.
    • Improved validation, authorization checks, concurrency handling, and cancellation rollback behavior.
  • Documentation

    • Updated authorization contracts, API inventories, rollout totals, and operational guidance.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Abiorh001, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e3cb1b95-2c96-4e00-b3ea-46e6eaeecaab

📥 Commits

Reviewing files that changed from the base of the PR and between 9081161 and cbe6cc1.

📒 Files selected for processing (2)
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-pr-trust-bundle.md
📝 Walkthrough

Walkthrough

Project-role grant issue and revoke mutations are activated through strict schemas, prepared authorization, deterministic locking, idempotency handling, ordered audit evidence, typed invalidation, API routes, PostgreSQL tests, and hosted contract validation.

Changes

Project role mutation flow

Layer / File(s) Summary
Authorization contracts and guards
backend/app/modules/authorization/{catalogue,kernel,prepared,runtime,schemas,project_role_schemas}.py, backend/app/modules/audit/schemas.py
Project-role issue/revoke actions, prepared scopes, resource contexts, qualification evidence, reason validation, and invalidation projections are added or activated.
Mutation service and persistence
backend/app/modules/authorization/{project_role_service,repository,service}.py
Idempotency reservation, advisory and row locking, qualification/grant persistence, replay validation, ordered audit completion, and revoke invalidation are implemented.
Prepared API mutation routes
backend/app/modules/authorization/router.py, backend/scripts/api_contract_e2e.py, backend/tests/test_api_controls.py
Issue and revoke endpoints are wired through prepared authorization, with cancellation rollback, replay/conflict handling, OpenAPI declarations, and HTTP-driven lifecycle coverage.
Verification, evidence, and rollout records
backend/tests/test_authorization.py, docs/*authorization_service.md, .agent-loop/..., .agent-loop/merge-intents/*
Unit, PostgreSQL, API contract, rollout, review evidence, and chunk metadata are updated for the activated mutation behavior.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AuthorizationRouter
  participant PreparedAuthorizationService
  participant ProjectRoleGrantMutationService
  participant AuthorityMutationService
  Client->>AuthorizationRouter: Submit issue or revoke with Idempotency-Key
  AuthorizationRouter->>ProjectRoleGrantMutationService: Reserve mutation
  AuthorizationRouter->>PreparedAuthorizationService: Prepare and consume authorization
  AuthorizationRouter->>ProjectRoleGrantMutationService: Lock and complete mutation
  ProjectRoleGrantMutationService->>AuthorityMutationService: Append ordered audit evidence
  AuthorityMutationService-->>AuthorizationRouter: Completion event identifiers
  AuthorizationRouter-->>Client: Mutation response
Loading

Possibly related PRs

Suggested reviewers: abiorh-claw

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is on-topic but misses most required template sections, including signed provenance, scope control, evidence, and reviewer results. Expand it to match the full trust-bundle template, especially Chunk, Signed Start Provenance, Scope Control, Evidence, Test Delta, and review tables.
Docstring Coverage ⚠️ Warning Docstring coverage is 30.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding project role grant mutations.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ws-auth-001-10c-project-role-grant-mutations

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: 3

🤖 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
@.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md:
- Line 10: Re-run the internal reviewer tracks against the current HEAD, then
update
.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md
lines 10-10 with the new reviewed SHA and timestamp, and update
.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-pr-trust-bundle.md
lines 37-38 to the same SHA; ensure no non-evidence files such as
.agent-loop/REVIEW_LOG.md change afterward, or include that update in the
reviewed commit.
- Line 12: Update the reviewer evidence for chunk WS-AUTH-001-10C to use fresh
auth10c_* session identifiers, or explicitly document reassignment of the
existing sessions, including the exact reviewed commit SHA and a complete
mapping of all nine reviewer tracks to the three sessions.

In `@backend/app/modules/authorization/schemas.py`:
- Line 156: Restore strict validation in the inline ConfigDict declarations for
QualificationAvailabilitySnapshot and ProjectRoleQualificationEvidence while
retaining extra="forbid", frozen=True, and hide_input_in_errors=True. Ensure
UUID, token, and reference fields reject coerced input rather than accepting
converted values.
🪄 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: f6a56d47-6ae2-4506-8b2d-2f20a5ea9e4d

📥 Commits

Reviewing files that changed from the base of the PR and between bcf1292 and 9081161.

📒 Files selected for processing (21)
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-10C-project-role-grant-mutations.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-pr-trust-bundle.md
  • .agent-loop/merge-intents/WS-AUTH-001-10C.json
  • backend/app/modules/audit/schemas.py
  • backend/app/modules/authorization/catalogue.py
  • backend/app/modules/authorization/kernel.py
  • backend/app/modules/authorization/prepared.py
  • backend/app/modules/authorization/project_role_schemas.py
  • backend/app/modules/authorization/project_role_service.py
  • backend/app/modules/authorization/repository.py
  • backend/app/modules/authorization/router.py
  • backend/app/modules/authorization/runtime.py
  • backend/app/modules/authorization/schemas.py
  • backend/app/modules/authorization/service.py
  • backend/scripts/api_contract_e2e.py
  • backend/tests/test_api_controls.py
  • backend/tests/test_authorization.py
  • docs/operations_authorization_service.md
  • docs/spec_authorization_service.md

`bcf1292e1a591e3e84bf8ee212ee7191d80741fa`; signed start run is
`30014637065`.

Reviewed code SHA: `0d05b7096eb7a2cf7c68a1770c0b35f07d5b55df`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Reviewed SHA is stale and is blocking CI. The Agent Gates / Backend preflight gates fail because the recorded reviewed commit 0d05b7096eb7a2cf7c68a1770c0b35f07d5b55df no longer matches HEAD and a non-evidence file (.agent-loop/REVIEW_LOG.md) changed after the review was recorded. Re-run the internal reviewer tracks against the current HEAD and update both artifacts to that SHA, and avoid modifying non-evidence files after recording the review (or fold the REVIEW_LOG.md update into the reviewed commit).

  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md#L10-L10: update the Reviewed code SHA to the re-reviewed HEAD commit and re-timestamp.
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-pr-trust-bundle.md#L37-L38: update the "reviewed implementation SHA" to the same re-reviewed HEAD commit.
📍 Affects 2 files
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md#L10-L10 (this comment)
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-pr-trust-bundle.md#L37-L38
🤖 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
@.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md
at line 10, Re-run the internal reviewer tracks against the current HEAD, then
update
.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md
lines 10-10 with the new reviewed SHA and timestamp, and update
.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-pr-trust-bundle.md
lines 37-38 to the same SHA; ensure no non-evidence files such as
.agent-loop/REVIEW_LOG.md change afterward, or include that update in the
reviewed commit.

Sources: Coding guidelines, Pipeline failures


Reviewed code SHA: `0d05b7096eb7a2cf7c68a1770c0b35f07d5b55df`
Reviewed at: 2026-07-23T16:55:00+01:00
Reviewer run IDs: /root/auth10b1_final_core, /root/auth10b1_final_security_qa, /root/auth10b1_final_ops_docs_ci

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Reviewer session identifiers look inherited from a different chunk without a declared reassignment.

The run IDs are /root/auth10b1_final_core, /root/auth10b1_final_security_qa, /root/auth10b1_final_ops_docs_ci, but this evidence is for chunk WS-AUTH-001-10C, not 10b1. When reviewer-pool session identifiers are carried over from a different chunk/initiative, the evidence must explicitly state the sessions were reassigned, bind to the exact reviewed commit SHA, and map every reviewer track (the table lists nine tracks against three sessions). Add the reassignment statement and the track→session mapping, or use fresh auth10c_* identifiers.

Based on learnings: reused /root/…-style reviewer-pool session identifiers may be inherited across reviewers only if the evidence explicitly states the session was reassigned, binds to the exact reviewed commit SHA, and maps every reviewer track covered.

🤖 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
@.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-10C-internal-review-evidence.md
at line 12, Update the reviewer evidence for chunk WS-AUTH-001-10C to use fresh
auth10c_* session identifiers, or explicitly document reassignment of the
existing sessions, including the exact reviewed commit SHA and a complete
mapping of all nine reviewer tracks to the three sessions.

Source: Learnings

"""Privacy-bounded availability and opaque-reference evidence."""

model_config = _MODEL_CONFIG
model_config = ConfigDict(extra="forbid", frozen=True, hide_input_in_errors=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect _MODEL_CONFIG definition and all usages of the two evidence models.
rg -nP '_MODEL_CONFIG\s*=' backend/app/modules/authorization/schemas.py
rg -nP '\bQualificationAvailabilitySnapshot\b|\bProjectRoleQualificationEvidence\b' backend/app -C2

Repository: Flow-Research/workstream

Length of output: 5346


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant schema locations =="
sed -n '1,230p' backend/app/modules/authorization/schemas.py | cat -n

echo
echo "== read_service snapshot deserialization =="
sed -n '170,200p' backend/app/modules/authorization/read_service.py | cat -n

echo
echo "== pydantic references =="
rg -n "Configuration|ConfigDict|strict=False|model_validate|QualificationAvailabilitySnapshot|ProjectRoleQualificationEvidence" backend/app -C 2

echo
echo "== pydantic availability =="
python3 - <<'PY'
import importlib.util
print("Pydantic available:", importlib.util.find_spec("pydantic") is not None)
if importlib.util.find_spec("pydantic"):
    import pydantic
    print("Pydantic version:", pydantic.__version__)
PY

Repository: Flow-Research/workstream

Length of output: 50381


Confirm the strict=True drop is intentional.

Moving QualificationAvailabilitySnapshot and ProjectRoleQualificationEvidence to inline ConfigDict(extra="forbid", frozen=True, hide_input_in_errors=True) adds privacy for error output but removes the centralized strict=True config. Without strict validation, evidence fields such as UUIDs and tokens in skills_snapshot, reputation_snapshot, prior_project_work_refs, and external_expertise_refs may accept coerced values instead of being rejected. If only error-output privacy was intended, restore strict=True.

🛡️ Option: preserve strict while hiding input
-    model_config = ConfigDict(extra="forbid", frozen=True, hide_input在_errors=True)
+    model_config = ConfigDict(
+        extra="forbid", frozen=True, strict=True, hide_input_in_errors=True
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
model_config = ConfigDict(extra="forbid", frozen=True, hide_input_in_errors=True)
model_config = ConfigDict(
extra="forbid", frozen=True, strict=True, hide_input_in_errors=True
)
🤖 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/authorization/schemas.py` at line 156, Restore strict
validation in the inline ConfigDict declarations for
QualificationAvailabilitySnapshot and ProjectRoleQualificationEvidence while
retaining extra="forbid", frozen=True, and hide_input_in_errors=True. Ensure
UUID, token, and reference fields reject coerced input rather than accepting
converted values.

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.

1 participant