') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Ops capi hardening by reprewindai-dev · Pull Request #46 · reprewindai-dev/cAPI · GitHub
Skip to content

Ops capi hardening - #46

Closed
reprewindai-dev wants to merge 3 commits into
mainfrom
ops-capi-hardening
Closed

Ops capi hardening#46
reprewindai-dev wants to merge 3 commits into
mainfrom
ops-capi-hardening

Conversation

@reprewindai-dev

Copy link
Copy Markdown
Owner

No description provided.

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
c-apiReadyReadyPreviewAug 13, 2026 5:58am
veklom-id-59uwReadyReadyPreviewAug 13, 2026 5:58am

@ecc-tools

ecc-toolsBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@coderabbitai

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

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

Next review available in:119 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

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

How do review limits work?

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

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, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a896d86-bb8a-40f6-a3b9-95686242b034

📥 Commits

Reviewing files that changed from the base of the PR and between 63783a0 and 1d46a54.

⛔ Files ignored due to path filters (4)
  • package-lock.json is excluded by !**/package-lock.json
  • public/favicon.ico is excluded by !**/*.ico
  • public/og-image.jpg is excluded by !**/*.jpg
  • public/twitter-card.jpg is excluded by !**/*.jpg
📒 Files selected for processing (13)
  • .env.example
  • .github/workflows/mayhem-dast.yml
  • Mayhemfile
  • RUNTIME_PATCH.md
  • openapi.json
  • package.json
  • scripts/outly-booking-test.ts
  • src/app/api/outly/intercept/route.ts
  • src/lib/covenant/locker-client.ts
  • src/lib/covenant/runtime.ts
  • src/lib/r2.ts
  • tests/integration.spec.ts
  • wrangler.toml

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.

@reprewindai-devChatGPT Codex Connector

Copy link
Copy Markdown
OwnerAuthor

Blocking merge for concrete reasons despite green checks:

  1. .env.example hardcodes Coolify/container-specific internal hostnames (gnomledger-api-1, n13gp1nhrcdp0hvazvbnlxru-...) as defaults. Example env must stay portable; deployment-specific topology belongs in deployment config.
  2. tests/integration.spec.ts catches connection failures and passes anyway, so it does not verify the integrations it claims to test.
  3. LockerphycerClient.registerAuditRecord() returns false on outage/non-2xx, but /api/outly/intercept ignores that return value and still reports ledger: "dual-pgl-lockerphycer". That can claim dual evidence when Lockerphycer never accepted the record.
  4. The new Lockerphycer client uses permissive null/false fallbacks at an authority/security boundary. Consequential paths must fail closed where the Lockerphycer result is required.

Please split the operational port/config cleanup from the Lockerphycer/R2/Outly additions, remove deployment-specific defaults, make integration tests fail when required services fail (or explicitly mark environment-gated tests as skipped), and require a successful Lockerphycer write before returning a dual-ledger evidence claim.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:1d46a54d7f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1 to +3
import { test, expect } from '@playwright/test';

test.describe('cAPI Backend Integrations', () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Exclude Playwright specs from Vitest discovery

The existing npm test command runs vitest run, and vitest.config.ts does not exclude Playwright files, so Vitest discovers this new integration.spec.ts and evaluates Playwright's test.describe outside the Playwright runner. This makes the repository's required CI test step fail before these integration checks can run; add a Playwright-specific script/config and exclude its specs from Vitest (or use a non-Vitest filename/location).

Useful? React with 👍 / 👎.

...decision,
evidence_reference: { evidence_id: anchored.event_id, entry_hash: anchored.event_hash, ledger: "pgl" },
evidence_reference: {
evidence_id: parsed.data.action_id,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Return the PGL event ID as the evidence ID

For every successful intercept, this replaces the actual pglAnchored.event_id with the caller-controlled action ID. Consumers pass evidence_reference.evidence_id to /api/capi/v1/evidence/[id], which forwards that value to PGL's event lookup, so the returned reference can no longer retrieve the event that was just anchored; the outcome route still correctly returns the PGL event ID.

Useful? React with 👍 / 👎.

evidence_reference: {
evidence_id: parsed.data.action_id,
entry_hash: pglAnchored.event_hash,
ledger: "dual-pgl-lockerphycer"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not claim a dual anchor when Lockerphycer rejects it

When Lockerphycer is unavailable or returns any non-2xx response, registerAuditRecord() returns false, but that result is ignored and the response still labels the evidence as dual-pgl-lockerphycer. This produces a successful compliance response that asserts an audit copy exists when only the PGL event was stored; either fail closed/check lockerphycerAnchored or report only the ledger that actually accepted the record.

Useful? React with 👍 / 👎.

uses: ForAllSecure/mapi-action@v2
with:
mayhem-token: ${{ secrets.MAYHEM_TOKEN }}
api-url: http://localhost:3000

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Point Mayhem at the port started by the workflow

In this workflow, npm run dev expands to next dev -p 3003, while Mayhem is configured to connect to port 3000. Next's -p, --port <port> option explicitly selects the listening port, so the CLI argument takes precedence over the step's PORT=3000; after the fixed sleep, the action probes a port with no cAPI server and the new DAST job cannot exercise the API.

Useful? React with 👍 / 👎.

if (!this.trust.has(agent.agent_id)) {
this.trust.set(agent.agent_id, {
agent_id: agent.agent_id,
score: agent.metadata.tier === "system" ? 95 : 50,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve service-agent trust initialization

When an agent is first loaded from Lockerphycer, every non-system tier now starts at trust 50. The existing registerAgent() path assigns service agents 78 and user agents 52, so a remote service identity is unexpectedly denied by otherwise applicable policies with trust thresholds of 60 or 70 even though the same identity registered locally would pass; reuse registerAgent() or the same tier mapping here.

Useful? React with 👍 / 👎.


import type { AgentIdentity, Policy, CapabilityIdentity } from "./types";

const LOCKERPHYCER_URL = process.env.LOCKERPHYCER_URL || "http://lockerphycer-api:8092";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the Lockerphycer lookup disabled when unconfigured

When LOCKERPHYCER_URL is unset, this hard-coded hostname still enables the integration, so every unknown agent triggers an outbound fetch before the runtime can return its normal 401. In deployments outside that Docker network, an unresolved or blackholed lockerphycer-api host—and the absence of any fetch timeout—can turn attacker-controlled unknown-agent requests into long-running work instead of immediate rejection; use an empty default and skip the lookup unless explicitly configured.

Useful? React with 👍 / 👎.

Comment on lines +33 to +34
const identity: AgentIdentity = await res.json();
agentCache.set(agent_id, { identity, expiresAt: Date.now() + CACHE_TTL_MS });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate Lockerphycer identities before caching them

A successful HTTP response is cast directly to AgentIdentity without runtime validation. If Lockerphycer returns a 200 error envelope, a wrapped payload, or an otherwise incomplete record, the object is cached and runtime.process() then dereferences fields such as agent.metadata.tier, producing an uncaught 500 on this and subsequent requests rather than treating the identity lookup as unavailable; validate the full identity shape and requested agent_id before returning it.

Useful? React with 👍 / 👎.

Comment thread.env.example

# --- Phase 6 execution bridge (Veklom BYOS MCP gateway) ---
BYOS_MCP_GATEWAY_URL=
BYOS_MCP_GATEWAY_URL=http://n13gp1nhrcdp0hvazvbnlxru-213557155694:8088/api/v2/invoke

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Match the BYOS endpoint to the bridge payload

With this configuration, every mcp:// capability posts the JSON-RPC tools/call payload from src/lib/covenant/mcp-bridge.ts to /api/v2/invoke. The checked-in Interlink router binds /api/v2/invoke to an InvocationRequest requiring capability_id, arguments, and context, while its JSON-RPC handler is a different route, so the configured endpoint rejects the bridge payload before execution; configure a compatible MCP endpoint or serialize the REST invocation contract.

Useful? React with 👍 / 👎.

Comment thread.env.example
# into gnomledger's append-only, hash-chained ledger. Leave empty to keep the
# local seal only.
PGL_LEDGER_URL=
PGL_LEDGER_URL=http://gnomledger-api-1:8001

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Leave the optional PGL integration unset in the template

The file instructs developers to copy it to .env.local and explicitly says this value should be empty to retain local-only sealing, but the new default enables a Docker-network-specific hostname with no API key. A normal local setup copied from the template therefore attempts an unavailable or unauthorized external ledger instead of remaining disabled, changing Outly calls from the intended clear unconfigured response into network/integration failures and generating failed-forwarding records throughout the runtime.

Useful? React with 👍 / 👎.


console.log("\n📡 Submitting to cAPI (Governed Connection Layer) -> /api/outly/intercept");
try {
const response = await fetch("https://capi.veklom.com/api/outly/intercept", {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the booking test harness off production by default

Running this developer test script always submits its generated demo action to the production capi.veklom.com endpoint, even though its failure message tells the user to start a localhost server. Each invocation can therefore add synthetic Outly decisions to the production immutable PGL and Lockerphycer audit trail; use an environment-provided base URL with a localhost default and require an explicit opt-in for production.

Useful? React with 👍 / 👎.

@reprewindai-dev
reprewindai-dev marked this pull request as draft August 13, 2026 06:17
@reprewindai-devChatGPT Codex Connector

Copy link
Copy Markdown
OwnerAuthor

Merge-blocking reconciliation: this PR currently violates the canonical source/runtime and secret/topology boundaries. Exact head 1d46a54d7fa30c1387f81707d28194e82cae55b9 adds concrete internal BYOS container topology to .env.example/docs, uses forbidden port 3000 in Mayhem/OpenAPI fuzz configuration, and includes a demo harness that claims PGL evidence was sealed from a successful response without independently verifying durable Gnomledger evidence. cAPI canonical reported runtime is 3003; ports 3000/8000 are forbidden. Remove concrete private/internal hostnames from source/examples, make fuzz/dev targets use canonical 3003 (or an explicit isolated test port that cannot become production fallback), and replace unconditional evidence-success language with measured evidence or NOT_VERIFIED. Reconcile this branch with #44's fail-closed authority-outage work rather than overwriting/duplicating it. Do not mark ready or merge until exact-head test/lint/build/dependency/security checks execute and pass with no blocking review.

@reprewindai-devreprewindai-dev left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Merge remains blocked. Fresh review has 12 unresolved threads, including P1 failures in evidence-reference identity, false dual-anchor claims when Lockerphycer rejects/unavailable, revoked Lockerphycer identity refresh, Mayhem targeting forbidden/wrong port 3000, BYOS bridge contract mismatch, and Vitest discovering Playwright specs. There is also no exact-head Actions run. Keep this PR draft; remove concrete internal topology/default integrations, make provider/ledger integrations opt-in, use canonical cAPI 3003 everywhere, make evidence claims reflect only confirmed durable writes, and reconcile with #44's fail-closed authority path before exact-head test/lint/build/security verification.

@reprewindai-devreprewindai-dev left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

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

Exact-head remediation review: keep this PR draft and unmerged. Twelve unresolved threads remain, including P1 defects for Playwright/Vitest collision, wrong returned PGL evidence ID, false dual-anchor success when Lockerphycer did not persist, Mayhem targeting forbidden/wrong port 3000, Lockerphycer identity cache surviving revocation/key rotation, and BYOS bridge endpoint/contract mismatch. P2 issues also remain around trust initialization, OpenAPI heartbeat schema drift, unconfigured Lockerphycer fallback, response validation, PGL template defaults, and production-default test harness behavior. Reconcile this branch with #44’s fail-closed authority path; remove concrete internal topology from source-controlled examples; keep cAPI canonical runtime 3003; and do not claim PGL/Lockerphycer evidence success unless the persisted identifiers are real and independently retrievable. I attempted to push the small topology/3000 corrections directly, but the connector safety layer blocked repository file mutations, so this review records the exact missing corrections without claiming they landed.

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.

1 participant

@reprewindai-dev