Skip to content

feat: wire cAPI evidence to gnomledger, audit all rejections, add queryable audit endpoint - #6

Merged
reprewindai-dev merged 3 commits into
mainfrom
devin/1782066008-capi-gnomledger-audit
Jun 21, 2026
Merged

feat: wire cAPI evidence to gnomledger, audit all rejections, add queryable audit endpoint#6
reprewindai-dev merged 3 commits into
mainfrom
devin/1782066008-capi-gnomledger-audit

Conversation

@reprewindai-dev

@reprewindai-devreprewindai-dev commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the three evidence/audit gaps from the Veklom handoff for the cAPI (Covenant) runtime. Before this, the 9-phase pipeline only sealed evidence in-process and only for calls that reached Phase 2+, with no way to query the trail or push it to the canonical ledger.

#2 — Forward sealed evidence to gnomledger (PGL). New src/lib/covenant/pgl-ledger.ts mirrors every sealed record into gnomledger's append-only, per-agent hash chain via POST /api/v1/ledger/events. Env-driven (PGL_LEDGER_URL, PGL_LEDGER_API_KEY), same convention as mcp-bridge.ts. The local SHA-256 seal stays authoritative; forwarding is best-effort and never blocks or fails the pipeline:

// runtime.generateEvidence() -> after local seal:forwardToPgl(evidence)// sets evidence.external_ledger// disabled (no URL) | pending -> sealed {event_hash, event_id} | failed {error}

details.idempotency_key = evidence.pgl_hash, so retries/duplicate forwards collapse to one chained gnomledger event. The returned gnomledger event_hash is captured on the evidence record.

#1 — Audit every action, including pre-authorization rejections. Previously the Phase-1 fail() path (agent-not-found, suspended, invalid signature, replay) and the Phase-2 capability-not-found path returned audit_logged: false and sealed nothing — those actions escaped the ledger. Replaced fail() with reject(), which seals an evidence record (policy security-reject, a reason, audit_logged: true) and returns an evidence_hash. generateEvidence now accepts an agent: AgentIdentity | undefined so rejections with no resolved agent still seal (with agent_public_key: "unverified"). Trust-delta semantics are unchanged (this also fixes a pre-existing double trust-apply on replay).

#3 — Queryable audit endpoint. New GET /api/audit backed by runtime.queryAudit():

/api/audit?agent_id=&capability_id=&status=&forwarded=&since=<ISO8601>&limit=<1..500>
-> { pgl_ledger: { configured }, query, total, matched, records[] }

status and forwarded are validated against the enums (400 on bad input).

Notes

  • Evidence gains optional external_ledger: LedgerForward (disabled|pending|sealed|failed + event_hash/error); surfaced in the Phase 7/8 trace and /api/audit. Additive, so the Ledger UI and existing routes are unaffected.
  • Added .env.example documenting the new + existing (BYOS_*) env vars, and README rows for /api/audit and a PGL-forwarding section.

Verification

  • npx tsc --noEmit, npx next lint, npm run build all clean.
  • Smoke-tested the running server: unknown-agent POST now returns evidence_hash + audit_logged: true; /api/audit?status=error surfaces the sealed rejection; bad status/forwarded/limit -> 400; forwarded=disabled matches all records when no ledger URL is set.

Link to Devin session: https://app.devin.ai/sessions/b6f4b646dcc148eca73341d75e02bef8

Summary by CodeRabbit

  • New Features

    • Added /api/audit endpoint to query and filter audit records by agent, capability, status, and ledger forwarding state
    • Enabled optional PGL ledger integration for mirroring evidence records to external service
  • Documentation

    • Added environment configuration template for optional ledger and execution bridge settings
    • Documented new audit endpoint and PGL ledger forwarding behavior

…ryable audit endpoint
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercelBot commented Jun 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
c-apiReadyReadyPreview, CommentJun 21, 2026 6:41pm
veklom-id-59uwReadyReadyPreview, CommentJun 21, 2026 6:41pm

@coderabbitai

coderabbitaiBot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@reprewindai-dev, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 15 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

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 credits.

🚦 How do rate limits work?

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

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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 51d45488-1ec5-4b00-b184-1de9e7e276e2

📥 Commits

Reviewing files that changed from the base of the PR and between 461b950 and bf8fd4c.

📒 Files selected for processing (3)
  • src/app/api/audit/route.ts
  • src/lib/covenant/pgl-ledger.ts
  • src/lib/covenant/runtime.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1782066008-capi-gnomledger-audit

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 and usage tips.

@coderabbitai

coderabbitaiBot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Note

Docstrings generation - SUCCESS
Generated docstrings and committed to branch devin/1782066008-capi-gnomledger-audit (commit: 9891619444adaa30391220c36f30b35a255e6150)

Docstrings generation was requested by @reprewindai-dev.
The following files were modified:
* `src/app/api/audit/route.ts`
* `src/lib/covenant/pgl-ledger.ts`
These file types are not supported:
* `.env.example`
* `README.md`

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/lib/covenant/runtime.ts (1)

238-244: 🧹 Nitpick | 🔵 Trivial

Unreachable catch block — forwardEvidence never rejects.

The forwardEvidence function (pgl-ledger.ts:60-125) explicitly documents "Never rejects" in its JSDoc and implements all error handling internally, always returning a resolved Promise<LedgerForward> with status: "failed" on errors rather than throwing. This makes the .catch() handler dead code that will never execute.

Consider removing the catch block and relying on the .then() handler to process the LedgerForward result, which already includes failure information.

🤖 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 `@src/lib/covenant/runtime.ts` around lines 238 - 244, The `.catch()` block
attached to the `forwardEvidence()` call is unreachable dead code because the
`forwardEvidence` function documents that it never rejects and always returns a
resolved Promise containing a LedgerForward object with error information
included in the status field. Remove the entire `.catch()` block and instead
handle all response processing (both success and failure cases) in the `.then()`
handler, since the returned LedgerForward object already contains the necessary
failure status and error details that would have been captured in the catch
block.
🤖 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 `@src/app/api/audit/route.ts`:
- Around line 37-41: The limit parameter validation in the route handler is
incomplete and allows non-integer values and values exceeding the documented
contract. Update the validation condition in the if statement that checks
limitParam to also verify that the limit is an integer using Number.isInteger()
and that it does not exceed 500, ensuring the limit falls within the documented
range of 1-500. Adjust the error message to reflect the complete constraint.
In `@src/lib/covenant/pgl-ledger.ts`:
- Around line 21-22: The LEDGER_TIMEOUT constant on line 21 does not validate
the parsed environment variable, allowing NaN or non-positive numeric values
which cause immediate aborts when used to schedule timeouts at line 72. Add
validation after parsing the environment variable to ensure the resulting
LEDGER_TIMEOUT is a positive number; if the parsed value is invalid or
non-positive, fall back to the default value of 8000 milliseconds.
---
Nitpick comments:
In `@src/lib/covenant/runtime.ts`:
- Around line 238-244: The `.catch()` block attached to the `forwardEvidence()`
call is unreachable dead code because the `forwardEvidence` function documents
that it never rejects and always returns a resolved Promise containing a
LedgerForward object with error information included in the status field. Remove
the entire `.catch()` block and instead handle all response processing (both
success and failure cases) in the `.then()` handler, since the returned
LedgerForward object already contains the necessary failure status and error
details that would have been captured in the catch block.
🪄 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

Run ID: b26e58bf-4dbf-4fd1-8d62-93bb16ab7e25

📥 Commits

Reviewing files that changed from the base of the PR and between 10058cd and 461b950.

📒 Files selected for processing (6)
  • .env.example
  • README.md
  • src/app/api/audit/route.ts
  • src/lib/covenant/pgl-ledger.ts
  • src/lib/covenant/runtime.ts
  • src/lib/covenant/types.ts

Comment threadsrc/app/api/audit/route.ts
Comment threadsrc/lib/covenant/pgl-ledger.ts Outdated
@reprewindai-dev
reprewindai-dev marked this pull request as ready for review June 21, 2026 18:39
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for freeto 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

@reprewindai-dev@anthonymillwater2-creator