Skip to content

feat(work-items): approval projection and retention sweeper (workitem/v1 follow-up to #349) #353

Open

Description

@mashkovd

Follow-up to #349 (workitem/v1 store and routes). These are the parts of step 3 of docs/work-context-contract.md that #349 did not build.

Approvals

  • WorkItemApproval (pending|granted|denied|expired, at most one pending per item), GET /api/v1/work-items/{id}/approvals, POST .../approvals/{approval_id}/decision.
  • The decider comes from authentication only, and a body naming a different decider is 400 (the ApproveDevLoopWorkflow rule, gitops#986). The service principal may request but never decide. granted is recorded only after DevLoopClient.SignalApprove succeeds; a signal failure stays pending with 502. Denials and expiries never signal.
  • approval_requested / approval_decided events.

Retention

  • A sweeper that clears intent text and surface refs older than WORKITEM_SURFACE_RETENTION_DAYS (default 90), and deletes terminal items older than WORKITEM_RETENTION_DAYS (default 365). Rows cascade from work_items.

Acceptance criteria

  • Each rule above has a Postgres-backed test, and each regression test fails against the reverted fix.
  • OpenAPI, README, .env.example, and the contract's "Implementation status" section are updated.

Activity

  1. mashkovd commented on Sep 23, 2026

    @mashkovd
    MemberAuthor

    Scope note (2026-09-23): runtime action approvals for agent side effects (mctl-agents#197/#198) are deliberately not modelled as WorkItemApproval. A WorkItemApproval gates an item's lifecycle, with at most one pending approval per item. An action approval authorizes one hashed, single-use side effect of one execution, and an execution can hold several of them. They are tracked as a sibling record in the same service, store and audit pattern in #366, so this issue keeps its one-pending-per-item invariant unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions