> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parmanasystems.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Objections and Evidence

> For each capability CLAIMS.md documents, the specific objections a regulator or design partner would raise, and the real test that answers each one — or an honest admission that none does yet.

<Info>
  This page reorganizes evidence CLAIMS.md already cites, plus a small number of tests added
  specifically to close gaps this page's own research found, into objection-first language.
  It never introduces a claim CLAIMS.md doesn't already make — see [The CLAIMS.md
  discipline](/trust-and-claims/claims-discipline) for why that ordering matters. Compliance
  claims (SOC2, GDPR, ISO 27001, a specific regulator's approval) are deliberately absent:
  CLAIMS.md §5 permanently refuses "guaranteed regulatory compliance" as a claim no
  implementation could honestly back — see [What Parmana does not
  claim](/trust-and-claims/what-we-dont-claim). This page indexes evidence for claims already
  made, it does not manufacture evidence for claims that were never made.
</Info>

## How to read this page

Each row names an objection a skeptical reviewer would actually raise, then answers it one
of three ways:

* **Existing test** — cites the real file and test name. Run it yourself.
* **New test** (added while building this page) — same, plus a one-line note on what gap it closed.
* **Honest limit** — the objection's premise doesn't hold for this architecture, or the
  guarantee is real but narrower than the objection assumes. Stated precisely, not glossed
  over.

Every citation below was checked against the current repository while writing this page, not
carried over from memory. Run `npm test` yourself — 1482 passed, 37 pre-existing skips, 0
failed, as of this page's last update.

## Domain 1: Authorization and verification

| Objection                                                                                                                  | Answer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A caller lacking a capability might still get to execute it                                                                | **Existing test.** `packages/api/tests/integration/caller-capability-scoping.integration.test.ts`: blocks a caller scoped to a different capability before policy evaluation ever runs; a caller with no `allowedCapabilities` configured is denied every capability, fail-closed by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| A tampered or forged signed authorization might slip through                                                               | **Existing test.** `packages/crypto/tests/unit/authorization-envelope.test.ts`: tampered `decisionId`, `expiresAt`, `signalsHash`, `grantedCapability`, `submittedBy` (added while building this page — see below) all independently proven to fail signature verification, plus a signature from the wrong key.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| The policy layer could approve something the caller was never cleared for, and the connector would just trust it           | **Existing test**, closed this session. `packages/execution-control/tests/unit/connector-policy-granted-capability.test.ts`: execution is rejected when the signed authorization's `grantedCapability` names a different action than the one actually executed. See [Execution authorization](/concepts/execution-authorization) and `docs/CLAIMS.md` §2.31 for the honest scope of what this closes (a future code path bypassing today's single verified route) and what it doesn't (an attacker with in-process code execution, who could forge this exactly as easily as anything else).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Would a jailbroken or adversarial agent's request just work if it asked for something out of scope?                        | **Existing test, same evidence as row 1.** The capability check (`allowedCapabilities.includes(action)`) takes no input describing the requester's internal state or intent — a "jailbroken" request and a merely mistaken one are denied by the identical, unconditional check.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| A policy edited after an authorization was signed might silently change what that authorization approved                   | **Existing test.** `packages/execution-gateway/tests/unit/policy-freshness.test.ts`: an authorization is rejected at execution time, with the exact content mismatch named, when the policy's content changed since signing (`docs/CLAIMS.md` §2.27). The original authorization's own terms are never retroactively altered — a policy change affects only authorizations signed after it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Is "scope" actually enforced from a signed fact, or does the connector just re-trust whatever the policy layer says today? | **Existing test, same evidence as row 3.** `grantedCapability` is signed into `ExecutionAuthorizationPayload` at authorization time and checked at the connector layer against the payload, not re-derived by asking the policy layer a second time.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Is the connector-layer check actually independent, or a second copy of the same code path as the API-layer check?          | **Existing test.** `packages/api/tests/unit/isCapabilityAllowed.test.ts` (API edge: caller vs. their API key's grant) and `connector-policy-granted-capability.test.ts` (connector edge: signed claim vs. executed action) are two different mechanisms over two different data sources, each independently tested.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| Could a caller identity be spoofed by editing the payload after signing?                                                   | **New test**, added while building this page. `authorization-envelope.test.ts`, "rejects a tampered submittedBy" — every other signed field already had a dedicated tamper test; this one didn't, though the general "every field participates in the signature" guarantee already covered it. Gap was in test *citability*, not in the mechanism itself.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Is an authorization's expiry actually checked, or just recorded?                                                           | **Existing test.** `authorization-envelope.test.ts`, "rejects an expired authorization with a valid signature."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| Does every connector get the same caller-capability check, or could one connector implement a weaker version?              | **Existing test.** `packages/api/src/bootstrap/createConnectorRegistry.ts` wires `DefaultConnectorPolicy` identically for every registered connector (HubSpot, GitHub, and the test fixture) — one class, no per-connector override to weaken.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Is signature re-verification real cryptography, or just a boolean flag being checked?                                      | **Existing test.** `@parmana/envelope-verifier` and `AuthorizationVerifier` perform real Ed25519 (or ML-DSA-65, see [Choose a signature provider](/cryptography/overview)) signature verification — "rejects a signature from a different key" only passes because the actual cryptographic check runs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| What if the signing key itself is stolen? Does re-verification catch a forged authorization signed with the real key?      | **Honest limit — no test claims this, and none could.** If an attacker holds the actual private key, anything they sign (including a fabricated `grantedCapability`) verifies as a fully legitimate signature, because it is one — this is what "key compromise" means for every signature scheme, not a gap specific to this codebase. Signature re-verification can only catch a payload that was *not* signed by the legitimate key, or altered *after* legitimate signing; it cannot distinguish the real key holder from a thief holding the same key. This repo's actual posture: `docs/CLAIMS.md` §2.28 (key-id-aware resolution with expiry/revocation) limits exposure *after* a compromise is discovered and the key is revoked — a mitigation, not a prevention. There is currently no automated key rotation and no HSM/KMS-backed `KeyProvider` (`aws-kms`/`azure-key-vault`/`gcp-kms`/`hsm` are declared config values with zero implementing classes — see [What Parmana does not claim](/trust-and-claims/what-we-dont-claim)): keys are plain files on disk, and protecting them is entirely an operational, not a code-level, control today. |

## Domain 2: Credential management

<Warning>
  The premise behind several of these objections — that a credential itself carries an
  embedded, per-action "scope" claim like `transfer_up_to_500` — doesn't match this
  architecture. `SessionCredentialVault.issue(connectorId, authorizationId)`
  (`packages/execution-control/src/SessionCredentialVault.ts`) scopes a credential to a
  *connector*, single-use, time-bounded. The action and parameters actually executed are
  pinned earlier and separately, by the signed `businessTransactionHash` on the authorization
  itself, before a credential is ever issued — a session credential is never asked "does this
  permit action X," only "is this connector's secret available, unused, unexpired,
  unrevoked." The rows below answer the real mechanism, not the assumed one.
</Warning>

| Objection                                                                                                  | Answer                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| How do you ensure a credential is actually scoped down, not general-purpose?                               | **Existing test.** `packages/execution-control/tests/unit/session-credential-vault.test.ts`: `issue()` never resolves or holds the underlying secret itself, confirmed by reading `SessionCredentialVault.ts`.                                                                                                                                                                                                                                                      |
| Could an agent use its credential for an action other than what was authorized?                            | **Honest limit, real mechanism differs from the premise.** There's no separate "does this credential permit action X" check to test, by design — `SessionCredentialSecureConnector.execute()` always passes the connector's executor the exact frozen `executableContent` from the one verified request, never an action derived from or checked against the credential. Enforcement is upstream (content-binding hash + `ConnectorPolicy`), not at the credential. |
| Is there a backdoor path that creates a credential without going through the scoped issuance flow?         | **Existing test.** A repository-wide search for every `.issue(` call on a credential vault finds exactly one production call site: `SessionCredentialSecureConnector.ts`.                                                                                                                                                                                                                                                                                           |
| If a credential leaks, is it still usable after expiry or revocation?                                      | **Existing test.** `session-credential-vault.test.ts`: rejects a credential after expiry and after revocation, including the exact boundary instant (`expiresAt` itself is expired, one millisecond before is not).                                                                                                                                                                                                                                                 |
| Can a credential's scope be independently, cryptographically proven — not just trusted as in-memory state? | **Honest limit, real gap.** A `SessionCredential`'s connector/authorization scoping is plain in-memory session state, not itself signed. The provable, signed guarantee lives one layer up, on `ExecutionAuthorizationPayload` (content hash, and now `grantedCapability`, §2.31) — not on the session credential in isolation. No test claims otherwise.                                                                                                           |
| Can a credential be used twice?                                                                            | **Existing test.** "rejects reuse of an already-consumed session credential."                                                                                                                                                                                                                                                                                                                                                                                       |
| Is the revocation check optional, or could some code path skip it?                                         | **Existing test.** `consume()`/`revoke()` sit inside an unconditional `try`/`finally` in `SessionCredentialSecureConnector.ts` — every `execute()` call path runs them.                                                                                                                                                                                                                                                                                             |
| Is there a timing window where a credential could be consumed twice under concurrency?                     | **Existing test.** "under two concurrent consume() calls on one session, exactly one succeeds" — deterministic by construction (the used flag is set synchronously before the only `await`), not a probabilistic pass.                                                                                                                                                                                                                                              |
| If execution fails downstream, is the credential still burned, or can it be retried indefinitely?          | **Existing test.** "destroys the session credential after a failing execution" — `revoke()` runs in `finally`, so a failed executor call still consumes the credential.                                                                                                                                                                                                                                                                                             |
| Does a retry after failure get a fresh credential, or reuse the dead one?                                  | **Existing test, true by construction.** A consumed session always throws on reuse ("rejects direct invocation with an already-consumed session"), so a retry necessarily requires a fresh authorization and credential — there is no code path that could hand back the same one.                                                                                                                                                                                  |

## Domain 3: Audit trail and evidence

<Note>
  This repo has three separate signed/durable record mechanisms, not one — `ExecutionTrustRecord`
  (every execution, success or policy-rejected), `RefusalRecord` (RFC-0021, a policy `REJECT`'s
  own dedicated evidence), and `CallerAuditEvent` (the caller-authentication layer, `CallerAuditSink`).
  Rows below name which mechanism actually applies.
</Note>

| Objection                                                                                 | Answer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Could an execution outcome go completely unrecorded?                                      | **Existing test.** `packages/api/tests/integration/structural-validation-audit.integration.test.ts` covers malformed/oversized bodies, malformed IDs, structural validation failure, and duplicate submission — each produces a `CallerAuditEvent`. Policy denials produce a `RefusalRecord`; successful executions produce an `ExecutionTrustRecord`. Every outcome category has a durable record, via one of the three mechanisms.                                                                                                                                                                                                                                                                                                                  |
| Could an audit or trust record be deleted after the fact?                                 | **Existing test (by absence).** No `delete`/`remove` method exists anywhere on `ExecutionTrustRecordRepository`, `RefusalRecordRepository`, or any `CallerAuditSink` implementation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Is an audit entry missing context that would matter to an investigator (who, what, when)? | **Existing test.** Each `CallerAuditEvent` type's required field subset is exercised across the structural-validation-audit suite; no single test asserts every field for every type in one place, but no field is untested for the event type it applies to.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Could an audit entry be lost if the process crashes right after logging it?               | **Existing test.** `createCallerAuditSink.ts` fails closed at startup (`assertDatabaseUrlConfigured`) unless `NODE_ENV=test` — production never silently falls back to an in-memory sink; every write goes to durable Postgres.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Could an audit or trust record be edited without detection?                               | **Existing test, two mechanisms.** `AuditEventCrypto`/`SupabaseCallerAuditSink` sign every `CallerAuditEvent` (proven in `packages/api/tests/integration/audit-verify.integration.test.ts`, "reports a tampered audit event as invalid, not as a crash," and now also in a dedicated unit test, see below). `ExecutionTrustRecord.trustRecordHash` tamper detection is proven in `verification-service.test.ts`.                                                                                                                                                                                                                                                                                                                                      |
| Can an audit record be verified without trusting Parmana's running process?               | **Existing test for `ExecutionTrustRecord`** ([Verify a trust record independently](/guides/verify-independently), demonstrated with the server stopped). **New test for `CallerAuditEvent`**, added while building this page — see below; this specific artifact type had no standalone, no-server proof before now.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Does the verification key change without notice, breaking old verifications?              | **Existing test.** `docs/CLAIMS.md` §2.28, key-id-aware resolution with expiry/revocation checking.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Are verification tools proprietary, or something only Parmana can run?                    | **Existing, trivially.** `@parmana/envelope-verifier` and `@parmana/crypto` are ordinary packages in the public repository.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Does verification require a live network call to Parmana or anyone else?                  | **Existing test, same evidence as the offline-verification row above.** `EnvelopeVerifier`/`AuditEventCrypto` make no network calls; verification needs only the artifact, its signature, and a public key file.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| If someone deleted a row from the audit table, would anything notice?                     | **Closed.** `SupabaseCallerAuditSink.record()` now chains each caller's events to their own immediately-preceding event (`previousChainHash`/`chainHash`, folded into the same object `AuditEventCrypto` already signs — no second signature column), using a Postgres advisory lock scoped per caller rather than a table-wide lock, since `caller_audit_events` is the highest-write-volume table in this system. `CallerAuditChainVerifier` (`packages/crypto/src/CallerAuditChainVerifier.ts`) proves a deleted row breaks the chain, standalone, with no server or database. See `docs/CLAIMS.md` §2.32 for the full design, including its honest limits (an entire caller's history deleted at once, or cross-caller reordering, isn't caught). |

## Domain 4: Fail-closed behavior

| Objection                                                                                                     | Answer                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| If the database is unreachable at startup, does the server start anyway?                                      | **Existing test.** `packages/api/tests/unit/bootstrap/create-nonce-store.test.ts`, `create-caller-audit-sink.test.ts`: "(G-13) fails closed with a named, actionable error when NODE\_ENV is not test and DATABASE\_URL is not configured."                                                                                                                                                                                  |
| If signature verification fails, does anything retry it, possibly against a different, more permissive check? | **Existing test (by absence).** No retry logic exists anywhere in `EnvelopeVerifier`/`AuthorizationVerifier`'s verify path — denial is immediate and single-pass.                                                                                                                                                                                                                                                            |
| If verification takes too long, does it default to allowing the request through?                              | **Honest limit.** No timeout mechanism exists in `ExecutionGateway.verify()` or `RuntimeEngine.execute()` at all — the pipeline is fully synchronous. There is no "times out and allows" failure mode to test, because there is no timeout concept in this code path in the first place; whatever timeout behavior exists comes from underlying infrastructure (HTTP server, database driver), not from Parmana's own logic. |
| If some checks pass and only one fails, does the request still get approved?                                  | **Existing test.** `ExecutionGateway.ts`'s `priorChecksPassed` ANDs every independent check; `policy-freshness.test.ts` and `signal-freshness.test.ts` each prove a single named check failing (with every other check passing) still denies the whole request.                                                                                                                                                              |
| If a connector is unreachable, does the request queue, retry, or silently succeed?                            | **Existing test.** Every connector adapter (`github`, `hubspot`, the generic `http` adapter) has a dedicated "fails closed on a non-2xx response" and "fails closed on a timeout, never returning a partial success" test.                                                                                                                                                                                                   |
| When something fails, does the audit trail say why, or just that it failed?                                   | **Existing test.** Reasons are specific, asserted-by-name strings (e.g. a policy rule's own rejection reason, a named hash mismatch), not a generic boolean, across `RefusalRecord` and `CallerAuditEvent` tests.                                                                                                                                                                                                            |
| If the system recovers from a transient failure, is that recovery itself observable?                          | **Honest limit, arguably not applicable.** This system has no background-retriable job model — every attempt is its own independently-audited request/response cycle. "Recovery" as a distinct event doesn't exist as a concept to test; each retry is simply a new, separately-audited attempt.                                                                                                                             |

## Domain 5: Performance

<Warning>
  Before this page, zero committed, automated performance measurements existed anywhere in
  this repository — only a manual script (`latency-test.cjs`) requiring a live deployed key
  and manual invocation, and an investigation
  (`docs/investigations/2026-08-10-latency-and-voice-ai-readiness.md`) that explicitly states
  a full `POST /execute` round trip "remains unmeasured." The two tests below close part of
  that gap — the part safe to measure deterministically in CI — and are explicit about what
  they still don't cover.
</Warning>

| Objection                                                                   | Answer                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Does cryptographic signing/verification add meaningful latency?             | **New test.** `packages/crypto/tests/unit/authorization-signing-performance.test.ts`, 200 in-process sign/verify round trips: **0.102ms/op to sign, 0.142ms/op to verify** (Ed25519, measured on this session's machine — re-run it yourself, numbers will vary by hardware). No network, no database.                                                                                                                                                                                                                           |
| Does the full authorization/execution pipeline add meaningful latency?      | **New test**, narrower than the objection. `packages/runtime/tests/unit/execution-pipeline-latency.test.ts`, 50 in-process `RuntimeEngine.execute()` calls (validate → evaluate policy → sign → execute → assemble trust record, in-memory `DefaultExecutionSystem`, no real connector): **avg 3.71ms, p50 3.40ms, p99 8.10ms**. This explicitly excludes HTTP overhead, Express middleware, real Postgres/Supabase writes, and a real connector's network round trip — the still-open question the linked investigation raises. |
| Can the system handle high throughput?                                      | **Honest limit, not closed.** No load/throughput test exists. The two tests above measure per-operation cost, not sustained concurrent throughput; extrapolating one from the other would be a claim this page isn't making.                                                                                                                                                                                                                                                                                                     |
| Does the system misbehave (e.g. default-allow) under load-induced timeouts? | **Honest limit, same as the fail-closed timeout row above.** No timeout concept exists in this code path to misbehave under load in the first place; a real answer here needs the throughput test that doesn't exist yet, run against whatever HTTP/database timeout behavior a real deployment actually has.                                                                                                                                                                                                                    |

## What this page deliberately did not build

* **No test for a claim CLAIMS.md doesn't make.** SOC2, GDPR, ISO 27001, and similar were
  considered and dropped — see the note at the top of this page.
* **No throughput/load test.** Real load testing needs a decision about target hardware and
  acceptable concurrency, not something this page should assume on your behalf.

## Next

<CardGroup cols={2}>
  <Card title="The CLAIMS.md discipline" icon="shield-check" href="/trust-and-claims/claims-discipline">
    How every citation on this page traces back to a real file or test.
  </Card>

  <Card title="What Parmana does not claim" icon="circle-minus" href="/trust-and-claims/what-we-dont-claim">
    The permanent boundaries this page's scope respects.
  </Card>
</CardGroup>
