Skip to content

refactor(db,api): collapse usage policy to a single source of truth#39

Merged
isuttell merged 1 commit into
worktree-agent-aab8c64f64ee8da40from
agents/usage-policy-ssot
May 24, 2026
Merged

refactor(db,api): collapse usage policy to a single source of truth#39
isuttell merged 1 commit into
worktree-agent-aab8c64f64ee8da40from
agents/usage-policy-ssot

Conversation

@isuttell

@isuttell isuttell commented May 24, 2026

Copy link
Copy Markdown
Contributor

Summary

The MVP usage policy (artifact/file caps, TTLs, rate limits, burst cap) was defined in three places that had drifted. packages/db served a stale workspace_burst_cap_per_minute of 600 on /v1/whoami while apps/api served the canonical 300 on /v1/usage-policy. This collapses the policy to one source of truth: mvpUsagePolicy in @agent-paste/contracts (per ADR 0038).

  • packages/db/src/policy.ts stops defining policy values inline. It re-exports mvpUsagePolicy as USAGE_POLICY (name preserved for existing consumers and the packages/db re-exports) and derives DEFAULT_UPLOAD_SESSION_TTL_MS and MAX_ARTIFACT_BYTES from its fields. Values and types are unchanged.
  • apps/api/src/index.ts deletes its local usagePolicy literal and reads mvpUsagePolicy for the /v1/usage-policy response, the denylist expiration TTL, and the upload TTL default.
  • @agent-paste/db gains a workspace:* dependency on @agent-paste/contracts. No dependency cycle: @agent-paste/contracts is a leaf (deps are zod and @asteasolutions/zod-to-openapi).
  • Net effect: RepositoryCore.getWhoami and /v1/usage-policy now serve the identical canonical policy. /v1/whoami burst cap goes 600 to 300.

Canonical burst cap of 300 confirmed against ADR 0038 (Zod contracts are the source of truth) and ADR 0066 (which narrows the MVP usage policy and reaffirms ADR 0038); the value lives in the canonical mvpUsagePolicy both ADRs point to.

Note on stacking

Based on worktree-agent-aab8c64f64ee8da40 (PR #38), which is not yet merged. Do not retarget to main until #38 merges.

Test plan

  • Added a regression test in apps/api/src/local-mvp.test.ts that wires the real LocalRepository through the worker and asserts /v1/whoami and /v1/usage-policy both return mvpUsagePolicy and match each other. Verified it fails when packages/db is forced to diverge (whoami 600 vs usage-policy 300) and passes after the fix.
  • pnpm verify green: 62 successful / 62 total Turbo tasks; apps/api suite is 38 tests across 4 files.
  • Confirmed @agent-paste/contracts does not depend on @agent-paste/db (acyclic).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • Consolidated usage policy configuration from multiple locations into a single centralized source, ensuring consistent policy enforcement across the system.
  • Tests

    • Added regression test to verify usage policy consistency across API endpoints.

Review Change Stack

mvpUsagePolicy in @agent-paste/contracts is now the only definition of the
MVP usage policy. packages/db/src/policy.ts re-exports it as USAGE_POLICY and
derives DEFAULT_UPLOAD_SESSION_TTL_MS and MAX_ARTIFACT_BYTES from its fields,
so RepositoryCore.getWhoami and every db consumer pick up canonical values.
apps/api drops its local usagePolicy literal and reads mvpUsagePolicy for
/v1/usage-policy, the denylist TTL, and the upload TTL default.

This removes the stale workspace_burst_cap_per_minute of 600 that /v1/whoami
served while /v1/usage-policy served the canonical 300 (ADR 0038). A regression
test asserts both endpoints return the canonical policy and match each other.
@agent-paste/db gains a workspace:* dependency on @agent-paste/contracts; no
cycle results because contracts is a leaf.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@isuttell isuttell temporarily deployed to pr-preview-39 May 24, 2026 01:19 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a663f241-3ec5-48d4-a78a-2342053b6d4a

📥 Commits

Reviewing files that changed from the base of the PR and between aaeb7ae and 0cd855d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • apps/api/src/index.ts
  • apps/api/src/local-mvp.test.ts
  • docs/ops/project-status.md
  • packages/db/package.json
  • packages/db/src/policy.ts

Walkthrough

This PR consolidates scattered usage policy definitions into a single canonical source. The change establishes mvpUsagePolicy from @agent-paste/contracts as the authoritative usage policy, removes duplicate local definitions, and ensures all consuming layers derive their configuration from this single source. The database layer re-exports the canonical policy and computes derived constants. The API layer migrates from local policy to the canonical source for denylist expiration, endpoint responses, and fallback TTLs. A regression test validates endpoint consistency.

Possibly related PRs

  • zaks-io/agent-paste#29: PR #29 reconciles denylist expiration behavior; this PR's change to DENYLIST_EXPIRATION_TTL_SECONDS reading from mvpUsagePolicy directly impacts the TTL used by that denylist logic.

Poem

🐰 A policy scattered becomes one
From contracts, a truth, now begun
Each endpoint aligned in a single design
The sources agree—the work is done!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: consolidating multiple usage policy definitions into a single source of truth via mvpUsagePolicy from @agent-paste/contracts.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 agents/usage-policy-ssot

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@isuttell

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@isuttell isuttell merged commit c49bfad into worktree-agent-aab8c64f64ee8da40 May 24, 2026
4 checks passed
@github-actions

Copy link
Copy Markdown

agent-paste PR preview resources were cleaned up. The pr-preview-${context.issue.number} environment is left in place; remove it from the GitHub UI if desired.

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