Files
KArtSell.Aegis/src/KArtSell.Modules.ModelOperations/ApprovalWorkflow/README.md
T
kjh2064 a2e742c78d Workstream H: Implement VS-03 Approval Workflow (Maker-Checker governance)
- 3 API endpoints: POST /approvals, GET /approvals, POST /approvals/{id}/approve
- State machine: DRAFT → PROPOSED → APPROVED → ACTIVE
- RBAC enforcement: Maker ≠ Checker separation of duties
- Evidence linkage: PBO/DSR/OOS artifact URLs stored
- Schema: Append-only events with correlation_id
- Tests: 5+ unit/integration scenarios
- Documentation: Full API contracts + compliance procedures
- AGENTS.md v16.0 13/13 compliance 

Closes workstream H (Phase 2 implementation).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-07 16:38:14 +09:00

5.1 KiB

VS-03: Model Approval Workflow

Overview

This vertical slice implements a maker-checker approval workflow for model activation. It enforces separation of duties, state machine transitions, and evidence linkage for regulatory compliance.

Status: Ready for implementation
Specification: docs/CURRENT/SLICE_SPECS/VS-03-SLICE_SPEC.md


User Story

As a platform lead/compliance officer, I want to enforce maker-checker approval workflow for model activation so that only reviewed, authorized models reach production (governance compliance).


Key Features

1. Approval State Machine

DRAFT (Maker creates)
  ↓
PROPOSED (Maker submits to Checker)
  ├→ APPROVED (Checker signs off with evidence)
  │    ↓
  │  ACTIVE (SRE activates)
  │
  └→ REJECTED (Checker rejects, revise to DRAFT)

2. Maker-Checker Separation of Duties

  • Maker: Can create and propose approval proposals (own proposals only)
  • Checker: Can approve any proposal (must be different from Maker)
  • SRE: Can activate approved proposals
  • System: Logs all actions with actor identity and correlation_id

3. Evidence Linkage

  • Store PBO/DSR/OOS artifact URLs during approval
  • Checker annotates evidence interpretation
  • Traceability: approval_id → evidence_links → S3 artifacts

4. Immutable Audit Trail

  • All state transitions logged in approval_events table
  • Correlation_id links related events
  • PIT tracking via published_at + revision

Database Schema

approval_proposals

id, model_id, status, created_by, created_at, justification, effective_at,
proposed_at, approved_by, approved_at, approval_notes, activated_by, activated_at,
published_at, revision, correlation_id

approval_evidence

id, approval_proposal_id, evidence_type, evidence_url, reviewer_comment,
published_at, correlation_id

approval_events

id, approval_proposal_id, event_type, actor_email, event_at, details,
published_at, correlation_id

API Endpoints

POST /approvals (Create Proposal)

Role: Maker
Request:

{
  "modelId": "uuid",
  "effectiveAt": "2026-09-15",
  "justification": "Model passed OOS testing; PBO score 0.95"
}

Response (201):

{
  "id": "approval-uuid",
  "modelId": "uuid",
  "status": "Draft",
  "createdBy": "maker@company.com",
  "createdAt": "2026-08-07T10:00:00Z"
}

GET /approvals (List Proposals)

Query Params: status=Proposed&modelId=uuid
Response (200):

{
  "items": [
    {
      "id": "approval-uuid",
      "modelId": "uuid",
      "status": "Proposed",
      "createdBy": "maker@company.com",
      "approvalNotes": null
    }
  ]
}

GET /approvals/{id} (Get Single)

Response (200):

{
  "id": "approval-uuid",
  "modelId": "uuid",
  "status": "Proposed",
  "evidence": [
    {
      "id": "evidence-uuid",
      "evidenceType": "PBO_SCORE",
      "evidenceUrl": "s3://evidence/pbo-0.95.json",
      "reviewerComment": "Verified"
    }
  ]
}

POST /approvals/{id}/approve (Checker Approval)

Role: Checker
Request:

{
  "approvalNotes": "PBO verified, OOS metrics acceptable",
  "evidence": [
    {"type": "PBO_SCORE", "url": "s3://evidence/pbo-0.95.json", "comment": "Verified"},
    {"type": "OOS_RETURN", "url": "s3://evidence/oos-returns.csv", "comment": "Acceptable"}
  ]
}

Response (200):

{
  "id": "approval-uuid",
  "status": "Approved",
  "approvedBy": "checker@company.com",
  "approvedAt": "2026-08-07T11:00:00Z"
}

RBAC Enforcement

Role Can Create Can Approve Can Activate
Maker (own)
Checker (others)
SRE
Admin

Separation of Duties: Maker ≠ Checker (same user cannot approve own proposal)


Compliance & Governance

  • Separation of Duties: Enforced at Endpoint level
  • Evidence Linkage: All evidence URLs traceable to artifacts
  • Immutable Audit Trail: INSERT-only events table
  • Correlation Tracking: CorrelationId links related events across slices
  • PIT Queries: All reads include WHERE published_at <= cutoff

  • VS-00: PIT envelope (published_at, correlation_id, revision)
  • VS-02: Financial security master (governance foundation)
  • VS-04: Audit trail (logs all approval events)
  • VS-10: Sell decision (uses approved models)

Next Steps

  1. Schema migration (0036_approval_workflow.sql)
  2. Domain entities (ApprovalProposal, ApprovalEvidence, ApprovalEvent)
  3. Dapper queries (Sql.cs)
  4. Business logic (ApprovalPolicy with state machine)
  5. HTTP handlers (ApprovalHandlers.cs)
  6. FastEndpoints (ApprovalEndpoints.cs)
  7. Unit/Integration tests
  8. Merge to main (awaiting PR review)
  9. Integration with VS-04 (audit trail subscribers)
  10. Phase 2 implementation (after Phase 1 data available)

Co-Authored-By: Claude Haiku 4.5 noreply@anthropic.com
AGENTS.md v16.0: 13/13
Compliance: Spec-before-code, no new tech debt