Skip to content

Add request and error context controls#111

Merged
abiorh-claw merged 12 commits into
mainfrom
codex/ws-auth-001-04-request-api-controls
Jul 13, 2026
Merged

Add request and error context controls#111
abiorh-claw merged 12 commits into
mainfrom
codex/ws-auth-001-04-request-api-controls

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

PR Trust Bundle: WS-AUTH-001-04A

Chunk

WS-AUTH-001-04A - Request And Error Context

Goal

Give every API response canonical request and correlation identifiers and a
stable privacy-bounded error object without changing product authority or
breaking existing clients.

Human-Approved Intent

The user explicitly started AUTH-04 after AUTH-03 memory merged through PR
#110. Required L1 review split request/error context from PostgreSQL rate
controls before implementation. This PR contains only the reviewed 04A child;
04B and later authorization chunks remain inactive.

What Changed

  • Added strict canonical request/correlation UUID handling in pure ASGI
    middleware.
  • Added stable nested error objects while preserving legacy response fields,
    status codes, and headers.
  • Added per-route OpenAPI error and response-header documentation.
  • Added privacy-bounded correlation-only failure logs.
  • Added real-ASGI behavior, inventory, schema, and API drill coverage.

Why It Changed

Workstream needs traceable API failures and a dependable error contract before
authority enforcement and rate controls expand, but existing consumers cannot
be forced through a breaking response migration.

Design Chosen

Pure ASGI middleware reads raw header pairs, stores effective IDs on request
scope state, and edits only http.response.start headers. Shared response
builders and exception handlers own JSON shapes. Existing compatibility fields
remain additive beside the canonical nested object.

Alternatives Rejected

  • BaseHTTPMiddleware, response buffering, or response-body rewriting.
  • Collapsed framework header parsing that cannot detect duplicate fields.
  • Replacing existing top-level error fields in one breaking migration.
  • Global OpenAPI statuses that routes cannot actually emit.
  • Adding PostgreSQL rate controls or provider-adapter migration to this chunk.

Scope Control

The production change remains below the contract's 500 non-comment line hard
stop. No route, dependency consumer, database model, migration, setting,
permission, role, grant, actor state, rate counter, or product lifecycle changed.

Product Behavior

Clients receive canonical X-Request-ID and X-Correlation-ID headers on
success and failure. Errors gain a required nested object with stable code,
message, bounded details, correlation ID, and retryability while retaining
existing compatible fields and headers. Product authorization is unchanged.

Acceptance Criteria Proof

Real-ASGI tests cover missing, valid, malformed, duplicate, non-ASCII, nil,
uppercase, non-hyphenated, unsupported-version, and comma-joined identifiers;
concurrency; success and every required error class; validation privacy;
streaming; background tasks; duplicate unrelated headers; task compatibility;
OpenAPI schemas; and exact route/dependency inventories.

Tests And Checks

  • 235 focused behavior tests passed.
  • Every changed production file exceeds 90 percent statement coverage: 98.08,
    90.82, 90.70, and 92.36 percent respectively.
  • The isolated-runner lifecycle suite passed 16/16 and the live API contract
    drill passed.
  • Ruff, docstring threshold, stale scans, Markdown links, loop memory, Agent
    Gates, additive test delta, and diff hygiene passed.
  • A complete local run found one Alembic logging-state test interaction after
    114 passes; its exact order passes after repair. GitHub Backend must provide
    the complete-suite rerun before merge.

Test Delta

No assertion, pytest.raises, skip/xfail marker, or skipTest line was removed
or weakened. New proof exercises actual FastAPI routes through ASGI transport.

CI Integrity

No workflow, package, dependency, threshold, exclusion, or bypass changed.
GitHub Backend and Agent Gates remain mandatory before merge. The separate
whole-app coverage initiative remains paused at its official 79.249908 percent
baseline; this chunk's changed-file threshold is at least 90 percent.

Reviewer Results

Senior engineering, QA/test, security/auth, product/ops, architecture, CI
integrity, docs, reuse/dedup, and test-delta review pass. Production was reviewed
at cdcaf77; final reviewed candidate 4fd6db9 received exact-head confirmation
for both additive test repairs with identical production blobs and no weakened
tests.

External Review

GitHub Backend, Agent Gates, CodeRabbit, and explicit human review begin after
the ready PR is published. None substitutes for the completed internal review.

Remaining Risks

  • Rate controls are intentionally absent and remain owned by inactive 04B.
  • Provider-neutral IdentityIssuerVerifier adoption depends on the shared
    external-service adapter foundation and a separate reviewed AUTH chunk.
  • The canonical nested error is additive; compatibility fields remain until a
    separately reviewed removal is safe.

Follow-Up Work

After this PR merges and memory is updated, AUTH-04B still requires a separate
explicit user start. AUTH-05 and later cutover chunks remain proposed.

Human Review Focus

Inspect duplicate-ID rejection, response-start-only header mutation, error and
log privacy, exact legacy compatibility, per-route OpenAPI truth, and unchanged
route/dependency inventories.

Human Merge Ownership

Only the user may approve and merge this PR. Publication is not merge approval,
and no later AUTH chunk starts automatically.

Summary by CodeRabbit

  • New Features

    • Added consistent request and correlation IDs to API responses.
    • Introduced standardized, structured error responses with clear codes, messages, retry guidance, and correlation details.
    • Preserved compatible legacy error fields and response behavior.
    • Improved authentication and task-related error reporting.
    • Updated API documentation to describe request headers and error formats.
  • Bug Fixes

    • Improved privacy by limiting sensitive validation and server-error details.
    • Added safer handling for malformed request identifiers and unexpected failures.
  • Tests

    • Expanded coverage for request context, error responses, streaming, concurrency, and API documentation.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

AUTH-04A introduces request/correlation ID middleware, structured API errors, OpenAPI documentation, and compatibility-preserving auth/task response handling. It also updates workstream planning, review evidence, tests, contract checks, and operational documentation while leaving PostgreSQL rate controls inactive.

Changes

AUTH-04A planning and contracts

Layer / File(s) Summary
Split scope and rollout gates
.agent-loop/..., .../CHUNK_MAP.md, .../STATUS.md, .../chunks/*
AUTH-04 is split into active request/error context work in 04A and inactive PostgreSQL rate controls in 04B, with updated dependencies, stop conditions, and review requirements.
Request, error, and authorization contracts
.../DECISIONS.md, .../DISCOVERY.md, .../chunks/WS-AUTH-001-04A-request-error-context.md
The contracts define UUID header handling, additive structured errors, privacy limits, OpenAPI requirements, validation proof, and a provider-neutral identity verification boundary.

Runtime API behavior

Layer / File(s) Summary
Request context and canonical error infrastructure
backend/app/core/api_controls.py, backend/app/main.py
The application adds request/correlation ID middleware, structured error models and responses, bounded validation summaries, exception handlers, response headers, and OpenAPI schema wiring.
Auth and task error integration
backend/app/api/deps/auth.py, backend/app/modules/tasks/router.py
Authentication failures and task-domain failures now emit canonical error objects while preserving selected legacy fields, statuses, and headers.

Validation and operational evidence

Layer / File(s) Summary
Behavioral and contract verification
backend/tests/test_api_controls.py, backend/tests/test_auth.py, backend/tests/test_tasks.py, backend/scripts/api_contract_e2e.py
Tests and the contract script validate header propagation, malformed and duplicate rejection, concurrency, streaming, background failures, redaction, OpenAPI schemas, auth errors, and task errors.
Review evidence and operations documentation
.../reviews/*, docs/operations_authorization_service.md
Review records describe validation results and remaining gates; the operations guide documents request IDs, structured errors, retryability, redaction, and AUTH-04A scope limits.

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

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant RequestContextMiddleware
  participant FastAPI
  participant AuthDependencies
  participant TaskRouter

  Client->>RequestContextMiddleware: Send request with optional ID headers
  RequestContextMiddleware->>RequestContextMiddleware: Validate or generate request and correlation IDs
  RequestContextMiddleware->>FastAPI: Forward request with IDs in scope state
  FastAPI->>AuthDependencies: Resolve authentication when required
  FastAPI->>TaskRouter: Execute task route
  TaskRouter-->>FastAPI: Return success or structured domain error
  FastAPI-->>RequestContextMiddleware: Produce response
  RequestContextMiddleware-->>Client: Return canonical ID headers and error payload when applicable
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.87% 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 clearly matches the main change: adding canonical request and error context controls.
Description check ✅ Passed The description covers the required template sections and main implementation/test details, though some evidence and checklist sections are abbreviated.
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-04-request-api-controls

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

🤖 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/chunks/WS-AUTH-001-04A-request-error-context.md:
- Around line 218-220: The AUTH-04A lifecycle notes are stale because
implementation and internal review have passed. In
.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md
lines 218-220, remove the preimplementation re-review gate or clearly mark it
historical; in .agent-loop/WORK_QUEUE.md lines 59-63, update the “Proposed Next”
text so contract repair/re-review is no longer presented as active and reflects
PR publication being active.

In
@.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-04A-pr-trust-bundle.md:
- Around line 15-16: Update the paragraph beginning “The user explicitly started
AUTH-04” so the reference to “PR `#110`” remains on the same Markdown line as the
surrounding sentence; do not alter the wording or other review content.

In `@backend/tests/test_api_controls.py`:
- Around line 469-476: Update the request and response header schemas in
api_controls to include the canonical lowercase RFC 4122 UUID pattern alongside
the existing uuid format and request length constraints. Extend the test
covering request and response headers to assert the expected pattern for both
X-Request-ID and X-Correlation-ID, not just their presence and required flags.

In `@docs/operations_authorization_service.md`:
- Around line 118-131: Update the canonical error object example in the
documentation to include the existing top-level detail compatibility field, or
explicitly label the snippet as only the nested error portion. Keep the
documented nested error fields unchanged and ensure the example matches the
stated compatibility contract.
🪄 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: 118e6023-b7f9-4e92-a641-92ba24cf8a58

📥 Commits

Reviewing files that changed from the base of the PR and between 1864867 and 36c4aa5.

📒 Files selected for processing (21)
  • .agent-loop/LOOP_STATE.md
  • .agent-loop/REVIEW_LOG.md
  • .agent-loop/WORK_QUEUE.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04-request-api-controls.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04B-postgres-rate-controls.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-04A-internal-review-evidence.md
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-04A-pr-trust-bundle.md
  • backend/app/api/deps/auth.py
  • backend/app/core/api_controls.py
  • backend/app/main.py
  • backend/app/modules/tasks/router.py
  • backend/scripts/api_contract_e2e.py
  • backend/tests/test_api_controls.py
  • backend/tests/test_auth.py
  • backend/tests/test_tasks.py
  • docs/operations_authorization_service.md

Comment on lines +218 to +220
The user explicitly started parent AUTH-04 on 2026-07-13. Required plan review
split it before implementation. Only this repaired 04A contract is active;
runtime edits remain gated on its required preimplementation re-review.

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 '.agent-loop/LOOP_STATE.md' '.agent-loop/WORK_QUEUE.md' '.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md'

printf '\n== LOOP_STATE excerpt ==\n'
sed -n '1,260p' .agent-loop/LOOP_STATE.md | nl -ba | sed -n '1,260p'

printf '\n== WORK_QUEUE excerpt ==\n'
sed -n '1,140p' .agent-loop/WORK_QUEUE.md | nl -ba | sed -n '1,140p'

printf '\n== CHUNK excerpt ==\n'
sed -n '180,250p' .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md | nl -ba | sed -n '180,250p'

Repository: Flow-Research/workstream

Length of output: 410


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== LOOP_STATE ==\n'
cat -n .agent-loop/LOOP_STATE.md | sed -n '1,260p'

printf '\n== WORK_QUEUE ==\n'
cat -n .agent-loop/WORK_QUEUE.md | sed -n '1,140p'

printf '\n== CHUNK ==\n'
cat -n .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md | sed -n '180,250p'

Repository: Flow-Research/workstream

Length of output: 23436


Update AUTH-04A lifecycle wording
These entries still read as preimplementation-gated, while .agent-loop/LOOP_STATE.md now says implementation and internal review passed and PR publication is active.

  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md#L218-L220: remove the “preimplementation re-review” gate or mark this note historical.
  • .agent-loop/WORK_QUEUE.md#L59-L63: update the “Proposed Next” text so it no longer says contract repair/re-review is active.
📍 Affects 2 files
  • .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md#L218-L220 (this comment)
  • .agent-loop/WORK_QUEUE.md#L59-L63
🤖 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/chunks/WS-AUTH-001-04A-request-error-context.md
around lines 218 - 220, The AUTH-04A lifecycle notes are stale because
implementation and internal review have passed. In
.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-04A-request-error-context.md
lines 218-220, remove the preimplementation re-review gate or clearly mark it
historical; in .agent-loop/WORK_QUEUE.md lines 59-63, update the “Proposed Next”
text so contract repair/re-review is no longer presented as active and reflects
PR publication being active.

Source: Coding guidelines

Comment on lines +15 to +16
The user explicitly started AUTH-04 after AUTH-03 memory merged through PR
#110. Required L1 review split request/error context from PostgreSQL rate

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

Keep PR #110`` on one Markdown line.

Line 16 is parsed as a malformed heading rather than the continuation of the sentence.

Proposed fix
-The user explicitly started AUTH-04 after AUTH-03 memory merged through PR
-#110. Required L1 review split request/error context from PostgreSQL rate
+The user explicitly started AUTH-04 after AUTH-03 memory merged through
+PR `#110`. Required L1 review split request/error context from PostgreSQL rate
📝 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
The user explicitly started AUTH-04 after AUTH-03 memory merged through PR
#110. Required L1 review split request/error context from PostgreSQL rate
The user explicitly started AUTH-04 after AUTH-03 memory merged through
PR `#110`. Required L1 review split request/error context from PostgreSQL rate
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 16-16: No space after hash on atx style heading

(MD018, no-missing-space-atx)

🤖 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-04A-pr-trust-bundle.md
around lines 15 - 16, Update the paragraph beginning “The user explicitly
started AUTH-04” so the reference to “PR `#110`” remains on the same Markdown line
as the surrounding sentence; do not alter the wording or other review content.

Source: Linters/SAST tools

Comment on lines +469 to +476
request_headers = {
parameter["name"] for parameter in operation["parameters"]
}
assert {"X-Request-ID", "X-Correlation-ID"} <= request_headers
for response in operation["responses"].values():
assert {"X-Request-ID", "X-Correlation-ID"} <= set(response["headers"])
assert response["headers"]["X-Request-ID"]["required"] is True
assert response["headers"]["X-Correlation-ID"]["required"] is 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.

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep outline backend/app/core/api_controls.py --items all
rg -n -C4 'minLength|X-Request-ID|invalid_request' \
  backend/app/core/api_controls.py backend/tests/test_api_controls.py

Repository: Flow-Research/workstream

Length of output: 12067


🏁 Script executed:

#!/bin/bash
sed -n '130,320p' backend/app/core/api_controls.py
printf '\n---\n'
sed -n '1,220p' backend/tests/test_api_controls.py

Repository: Flow-Research/workstream

Length of output: 14935


🏁 Script executed:

#!/bin/bash
rg -n -C3 '"pattern"|format": "uuid"|minLength|maxLength|X-Request-ID|X-Correlation-ID' backend/app/core/api_controls.py backend/tests/test_api_controls.py
python3 - <<'PY'
from uuid import UUID, uuid4, RFC_4122

def ok(v):
    try:
        p = UUID(v)
        return len(v) == 36 and p.int != 0 and p.variant == RFC_4122 and p.version in range(1, 9) and str(p) == v
    except Exception:
        return False

cases = {
    "lower_v4": str(uuid4()),
    "upper_v4": str(uuid4()).upper(),
    "compact": str(uuid4()).replace("-", ""),
    "nil": "00000000-0000-0000-0000-000000000000",
    "v9_like": "00000000-0000-9000-8000-000000000001",
}
for name, v in cases.items():
    print(name, ok(v))
PY

Repository: Flow-Research/workstream

Length of output: 6677


Add the canonical UUID pattern to these OpenAPI header schemas. backend/app/core/api_controls.py still documents the request context headers with only format: uuid (plus length on request params), but the middleware accepts only lowercase RFC 4122 UUID strings and rejects uppercase, nil, compact, and unsupported-version values. Add the matching pattern for both request and response headers, and have backend/tests/test_api_controls.py:469-476 assert that schema instead of only header presence.

🤖 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_api_controls.py` around lines 469 - 476, Update the
request and response header schemas in api_controls to include the canonical
lowercase RFC 4122 UUID pattern alongside the existing uuid format and request
length constraints. Extend the test covering request and response headers to
assert the expected pattern for both X-Request-ID and X-Correlation-ID, not just
their presence and required flags.

Comment on lines +118 to +131
Errors add this canonical object while retaining the existing top-level
`detail` or domain `code/details` compatibility fields:

```json
{
"error": {
"code": "invalid_request",
"message": "Request validation failed",
"details": {},
"correlation_id": "00000000-0000-4000-8000-000000000001",
"retryable": false
}
}
```

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

Make the example match the compatibility contract.

The prose says existing top-level fields remain, but the example omits detail. Include it or label this explicitly as only the nested error portion.

🤖 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 `@docs/operations_authorization_service.md` around lines 118 - 131, Update the
canonical error object example in the documentation to include the existing
top-level detail compatibility field, or explicitly label the snippet as only
the nested error portion. Keep the documented nested error fields unchanged and
ensure the example matches the stated compatibility contract.

@abiorh-claw abiorh-claw self-requested a review July 13, 2026 21:16
@abiorh-claw abiorh-claw merged commit 90c9a28 into main Jul 13, 2026
4 checks passed
@abiorh-claw abiorh-claw deleted the codex/ws-auth-001-04-request-api-controls branch July 13, 2026 22:03
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