Skip to content

Add Parmana as a TRACE external evidence source - #294

Merged
imran-siddique merged 2 commits into
agentrust-io:mainfrom
pavancharak:add-parmana-server
Oct 12, 2026
Merged

imran-siddique merged 2 commits into
agentrust-io:mainfrom
pavancharak:add-parmana-server

Conversation

@pavancharak

Copy link
Copy Markdown
Contributor

Parmana as a TRACE external evidence source
Follows #286. Adds integrations/parmana-server/: Parmana's signed authorization decisions mapped to TRACE references, with an offline checker and the fixtures from one evaluation run.
Per your answers on #286 (trace-spec at db95328):
Role: external-evidence-source, no conformance level. No TRACE Trust Record is issued, so no placeholder subject, model, data_class or build_provenance.
Signing: Parmana keeps its own canonical form and signatures. A runtime's Trust Record points at them: authorized-intent to the Execution Trust Record or Refusal Record, and approval-outcome to the signed approval (retained inside the Trust Record, at #/transaction/signals/approvalArtifact).
Unit: one Parmana record per decision, refusals included.
Mocks: nothing is referenced as observed-effect. The mock label stays in fixtures/report.json, the README and a test.
Re-pinned: the fixtures are one unedited run at pavancharak/parmana commit ac22a7ed594b4a527504ce43841595c1a62f3046. That commit includes the Refusal Record policy content hash (all three records carry it) and the release workflow that publishes the server image with SLSA provenance.
Reproduction

cd integrations/parmana-server
pip install -e ".[test]"
python examples/emit_references.py
python -m pytest tests

18 tests check:
every signature, with Parmana's public key only;
that a changed amount, outcome or approval limit fails;
that the approval is the one the Trust Record was signed over;
that all three decisions name one policy content hash;
that references.json is exactly what the records produce and validates as agentrust_trace.Reference (0.11.0).
To regenerate the fixtures from Parmana itself: npm run evaluate:agentrust-refund at that commit (no network, keys or accounts).
Licence
I, Pavan Dev Singh Charak, for Parmana Systems Private Limited, the copyright holder, license everything in integrations/parmana-server/ under the Apache License 2.0: the code, the README and the fixtures, which are records generated by Parmana in that run. The parmana Python SDK it depends on is Apache-2.0 on PyPI.
Not claimed:
Any downstream effect: the connector in the run is a mock.
That the two caller-declared facts were checked: they can only refuse.
That the policy was approved through governance in the run: the governance anchor reads NO_APPROVAL_RECORD.
The README says the same.

@pavancharak

Copy link
Copy Markdown
Contributor Author

The server image with SLSA provenance is published: ghcr.io/pavancharak/parmana-api@sha256:f82c0076ebff847c5ae0afb5f9e3728e49c9dd819f8e52ba0d8659a960753865 (release server-v1.0.0, built at f95f786e).

slsa-verifier verify-image ghcr.io/pavancharak/parmana-api@sha256:f82c0076ebff847c5ae0afb5f9e3728e49c9dd819f8e52ba0d8659a960753865 --source-uri github.com/pavancharak/parmana --source-tag server-v1.0.0

returns PASSED, builder generator_container_slsa3.yml@v2.1.0. f95f786e is the fixtures’ commit ac22a7ed plus only the commit that records the evaluation report and fixtures, so the image runs the same code that produced the fixtures. The hosted API is built by Vercel and carries no provenance.

imran-siddique
imran-siddique previously approved these changes Oct 11, 2026

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Matches the #286 answers: external-evidence-source with no conformance level, Parmana's own signatures, authorized-intent and approval-outcome references, refusals as their own unit. Checked at b5d91ec in a clean venv: all 18 tests pass, examples/emit_references.py reproduces the committed references.json exactly, and both key fixtures are public keys only. I did not run slsa-verifier against the image.

One blocker: validate fails because the README index is missing the new row. Run python scripts/generate_integration_index.py from the repo root and commit the result; the only change should be the Parmana line. I will merge once validate is green.

Adds the Parmana row that scripts/generate_integration_index.py produces
from integrations/parmana-server/integration.yaml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF
@pavancharak

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I ran scripts/generate_integration_index.py and committed the result (59ce64f); the only change is the Parmana line in the README index. Could you approve the workflows and re-approve when validate is green?

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-approving at 59ce64f: the only change since my review is the Parmana row in the README index, and validate passes.

@imran-siddique
imran-siddique merged commit 6de4cb9 into agentrust-io:main Oct 12, 2026
34 of 35 checks passed
pavancharak pushed a commit to pavancharak/xyz that referenced this pull request Oct 12, 2026
…ged)

The refund evaluation package was prepared as a proposal to the
AgenTrust integrations repository. The proposal was merged on
2026-10-12 as integrations/parmana-server, a TRACE external evidence
source with no conformance level. Record what was merged, what the
maintainer checked and what they did not, and that the listing is not
a certification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF
pavancharak pushed a commit to pavancharak/xyz that referenced this pull request Oct 12, 2026
…and evaluation

agentrust-io/integrations#294 was merged on 2026-10-12. Adds CLAIMS.md
3.23 (scoped: a community listing of an evidence mapping, no conformance
level, not a certification; what the maintainer checked and did not), a
CURRENT-STATE section, a changelog entry for 2026-10-12 (the listing,
the Essays tab, and the limitations and comparison corrections) and a
link from the evaluation page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF
@pavancharak
pavancharak deleted the add-parmana-server branch October 12, 2026 23:57
pavancharak added a commit to pavancharak/xyz that referenced this pull request Oct 14, 2026
* Remaining work: what is pending for business validation, after the live checks

REMAINING-WORK section L is now the full pending list as of 2026-10-11:

- L.1 what needs the operator, in order: the refund live check, naming
  and connecting the system that owns refund eligibility, the first real
  grant, opting customer-refund in through policy governance, and one
  real refund under it.
- L.2 evidence not yet collected: the release check endpoint's log lines
  (one showing the release's conditions), a refusal at release in
  production, and GET /ready after the reported password reset.
- L.3 what is not built: cumulative limits (design ready), built in
  connectors re-asking at release, a not-released intent state, an end
  to end refusal-at-release test, a grantee existence check, limiting
  what a source may answer.
- L.4 RFC-0023's open questions; L.5 housekeeping (the livecheck-agent
  key, the two Vercel projects, step up key backups, today's key
  rotations, deploying from inside the endpoint folder).

The two live check READMEs record their cleanup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): what is left for business validation

Add a "What is left" section to the business validation concept page
(operator steps, evidence not collected, not built, open questions) and
a roadmap row linking to it, mirroring REMAINING-WORK.md section L.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: related-work note on RRSI (arXiv 2609.24972)

Keep a reference note on Regularized Recursive Self-Improvement of
Agent Harnesses: what it says, its reported results and limitations,
and what it means for Parmana (authority must sit outside what a
self-improving agent rewrites). The paper is linked, not copied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essays, first ten pages (work in progress)

Essays explaining Parmana end to end, written as plain-language pieces:
business validation, guardrails versus a gate, self-improving agents,
cumulative limits, verifiable approvals, maker checker, key rotation,
a refund agent checklist, production live checks, and what done means.
Navigation and the remaining essays follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): sixteen more essays; limitations page matches Refusal Records

Adds essays on how Parmana works end to end, policies, human approval,
authority grants, the gateway, execution authorizations, content binding,
Execution Intents, gateway attestation, Refusal Records, the caller audit
trail, replay, independent verification, signature choices, governing
the rules and running Parmana yourself.

The limitations page said no outcome goes unrecorded and that Refusal
Records are the complete list; a Refusal Record write fails open
(CLAIMS.md 3.11), so both sentences now say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): Essays tab with all 31 essays; fix stale compare and claims lines

Adds the last five essays, an overview page and an Essays tab in the
navigation, grouped from why Parmana exists through proof and honesty.

How Parmana compares said most teams require approval only above a risk
threshold and that declared facts are never checked against another
system; every action needs a signed approval (CLAIMS.md 2.47) and a
policy can name a business signal source, so both lines now say so.
CLAIMS.md section 4 still listed the Slack connector as not
implemented; it is marked superseded by 2.44 and 2.47.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essays 32 onward, first batch (work in progress)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essays 51 and 62 (work in progress, not yet in navigation)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essay on models as insider risks

Maps Satya Nadella's 'Models as Insider Risks' principles to what
Parmana does (controls outside the model, independent controls and
auditability, signed evidence, testing refusals, a public gap log) and
what it does not (tamper-evident, not tamper-proof; no mid-task brake on
a model; no chain-of-thought or model-diversity controls; only actions
routed through it). Added under Why Parmana exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: record the AgenTrust listing (agentrust-io/integrations#294 merged)

The refund evaluation package was prepared as a proposal to the
AgenTrust integrations repository. The proposal was merged on
2026-10-12 as integrations/parmana-server, a TRACE external evidence
source with no conformance level. Record what was merged, what the
maintainer checked and what they did not, and that the listing is not
a certification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: record the AgenTrust TRACE listing in claims, state, changelog and evaluation

agentrust-io/integrations#294 was merged on 2026-10-12. Adds CLAIMS.md
3.23 (scoped: a community listing of an evidence mapping, no conformance
level, not a certification; what the maintainer checked and did not), a
CURRENT-STATE section, a changelog entry for 2026-10-12 (the listing,
the Essays tab, and the limitations and comparison corrections) and a
link from the evaluation page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: record the AgenTrust Verified-tier request as pending

A follow-up PR asks AgenTrust for the Verified tier (parmana 1.6.0
pinned, exact reproduction steps). Recorded in CLAIMS.md 3.23,
CURRENT-STATE, REMAINING-WORK and the evaluation README as requested,
not granted; the tier stays community until a maintainer changes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* examples: Razorpay refund demo under Parmana (test mode)

An agent refunds a Razorpay payment through a registered external
endpoint. Policy razorpay-refund 1.0.0 needs an authority grant and a
signed manager approval for the payment covering the amount (paise).
The endpoint verifies Parmana's signed release, refuses live keys,
and refunds once: each refund carries the businessTransactionId as its
Razorpay receipt, checked before refunding. send.ts runs four cases
(no approval, approved, over the grant, replayed approval); the README
is the step-by-step runbook. Nine tests against a fake Razorpay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: AgenTrust maintainer reproduced the integration; tier change pending

On agentrust-io/integrations#313 a maintainer reproduced parmana-server
at 80c3a92 with the released parmana 1.6.0 and agentrust-trace 0.11.0
(references.json byte for byte, 18 tests passed) and said the tier
change follows in a separate maintainer PR. Recorded in CLAIMS.md 3.23,
CURRENT-STATE, REMAINING-WORK and the evaluation README; the tier stays
community until that PR merges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: agentrust-io/integrations#313 merged (1aac6c8); tier still community

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* Add judges' deck for Razorpay Builders Day (14 slides, speaker notes)

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

* Harden key generation: validate key IDs, owner-only private keys (#118)

* Harden key generation: validate key IDs, owner-only private keys

generate-keypair and rotate-verification-key wrote private keys with the
default umask (world-readable) and used the key ID in a file path without
validation, so --key-id ../x wrote outside the key directory.

- scripts/lib/key-files.ts: key ID allowlist, explicit 0600 for private
  keys (chmod after write, so the umask cannot widen it), 0700 directory
  when created.
- Both scripts use it. Overwrites are still refused without --force.
- tests/scripts/key-files.test.ts: unit tests, plus end-to-end runs of
  generate-keypair (the traversal and mode tests fail on the old script).

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Describe the replayed approval by its real refusal, and cite its evidence (#119)

* Razorpay demo: describe the replayed approval by its real refusal

The replayed approval is refused by signal-state-verification-violation
(the approval is spent and its verified state no longer matches), not by
a separate 'already used' rule. The runbook and the judges' deck said
'already used', which an AgenTrust reproduction report did not support.

- examples/razorpay-refund/README.md: request 4 names the rule and reason.
- builders-day/Parmana-Razorpay-Builders-Day.pptx: slide 7 row 4 reworded
  to match (regenerated; the PDF brief is local-only and not committed).

* Reference the replayed-approval refusal to its evidence

The replay refusal is now cited by file, line and test so it can be checked:
- docs/CLAIMS.md 3.23: where the replay case is checked (test lines,
  fixture matchedRuleId, report.json, live demo), with the real rule
  signal-state-verification-violation.
- docs/evaluation/agentrust-refund/README.md: corrected the replay reason
  (it was 'already used') and added a per-case reference list.
- docs/site/evaluation/claims-and-evidence.mdx: new row pointing at 3.23
  and the test that reproduces it.
- examples/razorpay-refund/README.md: request 4 points to the same evidence.

The referenced integration test passes on this branch.

* Reference the AgenTrust integration files for the replay refusal

Points the replay refusal to the Parmana integration as merged in
agentrust-io/integrations (commit 6de4cb9, integrations#294):
- fixtures/03-replay.refusal-record.json line 46 (matchedRuleId)
- tests/test_parmana_evidence.py line 131 (zero connector invocations)
- the reproduction command: python -m pytest tests in integrations/parmana-server

Checked on this branch: that suite at 6de4cb9 gives 18 passed. The
integration's README row for this fixture says 'already used'; the docs
here cite the fixture's rule and do not repeat that wording.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Serialize migration runners with a PostgreSQL advisory lock (#120)

* Serialize migration runners with a PostgreSQL advisory lock

Two deployments that start together both read the pending list and both
tried to run the same migration. Observed against PostgreSQL 16: the second
runner failed with a unique-constraint error, and the same race can apply a
non-idempotent migration twice.

applyPendingMigrations now takes pg_advisory_lock before reading the pending
list and releases it in finally. Dry runs take no lock.

Tests:
- lock is the first statement and unlock the last; the lock is released when
  a migration fails; dry runs take no lock (fake client).
- two concurrent runners against real PostgreSQL apply the migration once.
  Runs only when PARMANA_TEST_DATABASE_URL is set, on an empty throwaway
  database (it drops the tracking table and demo table). Without the lock this
  test fails; with it, it passes.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Python SDK: redact debug logs and refuse plain HTTP to remote hosts (#121)

* Python SDK: redact debug logs and refuse plain HTTP to remote hosts

Debug logging wrote request and response bodies in full, so an amount, an
email or a payee reached the log whenever debug=True.

- Debug logs show each body's structure with every leaf value replaced by
  <redacted>. The Authorization header is never logged.
- HttpTransport refuses an endpoint that is not https://, except localhost
  and 127.0.0.1, because the API key travels in the Authorization header.

Tests: the debug-log test checks that no amount, name, email or key appears
in the log (it fails on the old transport); the endpoint tests cover https,
localhost and a remote plain-HTTP refusal. Full Python suite: 190 passed;
ruff, black and mypy clean.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* CI: Python SDK on Node 24, Docker checks on all package changes (#122)

* CI: Python SDK on Node 24, Docker checks on all package changes

- python-sdk.yml ran on Node 22 while the root package.json requires >=24
  and every other workflow uses 24.
- docker-image.yml path filters listed packages/*/package.json, so a source
  change under packages/ (for example packages/api/src) could skip the
  Docker startup checks. They now match packages/** on push and pull request.

Not run locally: GitHub Actions. Node 24 is the version release.yml and ci.yml
already use.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
pavancharak added a commit to pavancharak/xyz that referenced this pull request Oct 14, 2026
* Remaining work: what is pending for business validation, after the live checks

REMAINING-WORK section L is now the full pending list as of 2026-10-11:

- L.1 what needs the operator, in order: the refund live check, naming
  and connecting the system that owns refund eligibility, the first real
  grant, opting customer-refund in through policy governance, and one
  real refund under it.
- L.2 evidence not yet collected: the release check endpoint's log lines
  (one showing the release's conditions), a refusal at release in
  production, and GET /ready after the reported password reset.
- L.3 what is not built: cumulative limits (design ready), built in
  connectors re-asking at release, a not-released intent state, an end
  to end refusal-at-release test, a grantee existence check, limiting
  what a source may answer.
- L.4 RFC-0023's open questions; L.5 housekeeping (the livecheck-agent
  key, the two Vercel projects, step up key backups, today's key
  rotations, deploying from inside the endpoint folder).

The two live check READMEs record their cleanup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): what is left for business validation

Add a "What is left" section to the business validation concept page
(operator steps, evidence not collected, not built, open questions) and
a roadmap row linking to it, mirroring REMAINING-WORK.md section L.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: related-work note on RRSI (arXiv 2609.24972)

Keep a reference note on Regularized Recursive Self-Improvement of
Agent Harnesses: what it says, its reported results and limitations,
and what it means for Parmana (authority must sit outside what a
self-improving agent rewrites). The paper is linked, not copied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essays, first ten pages (work in progress)

Essays explaining Parmana end to end, written as plain-language pieces:
business validation, guardrails versus a gate, self-improving agents,
cumulative limits, verifiable approvals, maker checker, key rotation,
a refund agent checklist, production live checks, and what done means.
Navigation and the remaining essays follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): sixteen more essays; limitations page matches Refusal Records

Adds essays on how Parmana works end to end, policies, human approval,
authority grants, the gateway, execution authorizations, content binding,
Execution Intents, gateway attestation, Refusal Records, the caller audit
trail, replay, independent verification, signature choices, governing
the rules and running Parmana yourself.

The limitations page said no outcome goes unrecorded and that Refusal
Records are the complete list; a Refusal Record write fails open
(CLAIMS.md 3.11), so both sentences now say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): Essays tab with all 31 essays; fix stale compare and claims lines

Adds the last five essays, an overview page and an Essays tab in the
navigation, grouped from why Parmana exists through proof and honesty.

How Parmana compares said most teams require approval only above a risk
threshold and that declared facts are never checked against another
system; every action needs a signed approval (CLAIMS.md 2.47) and a
policy can name a business signal source, so both lines now say so.
CLAIMS.md section 4 still listed the Slack connector as not
implemented; it is marked superseded by 2.44 and 2.47.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essays 32 onward, first batch (work in progress)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essays 51 and 62 (work in progress, not yet in navigation)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs(site): essay on models as insider risks

Maps Satya Nadella's 'Models as Insider Risks' principles to what
Parmana does (controls outside the model, independent controls and
auditability, signed evidence, testing refusals, a public gap log) and
what it does not (tamper-evident, not tamper-proof; no mid-task brake on
a model; no chain-of-thought or model-diversity controls; only actions
routed through it). Added under Why Parmana exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: record the AgenTrust listing (agentrust-io/integrations#294 merged)

The refund evaluation package was prepared as a proposal to the
AgenTrust integrations repository. The proposal was merged on
2026-10-12 as integrations/parmana-server, a TRACE external evidence
source with no conformance level. Record what was merged, what the
maintainer checked and what they did not, and that the listing is not
a certification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: record the AgenTrust TRACE listing in claims, state, changelog and evaluation

agentrust-io/integrations#294 was merged on 2026-10-12. Adds CLAIMS.md
3.23 (scoped: a community listing of an evidence mapping, no conformance
level, not a certification; what the maintainer checked and did not), a
CURRENT-STATE section, a changelog entry for 2026-10-12 (the listing,
the Essays tab, and the limitations and comparison corrections) and a
link from the evaluation page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: record the AgenTrust Verified-tier request as pending

A follow-up PR asks AgenTrust for the Verified tier (parmana 1.6.0
pinned, exact reproduction steps). Recorded in CLAIMS.md 3.23,
CURRENT-STATE, REMAINING-WORK and the evaluation README as requested,
not granted; the tier stays community until a maintainer changes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* examples: Razorpay refund demo under Parmana (test mode)

An agent refunds a Razorpay payment through a registered external
endpoint. Policy razorpay-refund 1.0.0 needs an authority grant and a
signed manager approval for the payment covering the amount (paise).
The endpoint verifies Parmana's signed release, refuses live keys,
and refunds once: each refund carries the businessTransactionId as its
Razorpay receipt, checked before refunding. send.ts runs four cases
(no approval, approved, over the grant, replayed approval); the README
is the step-by-step runbook. Nine tests against a fake Razorpay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: AgenTrust maintainer reproduced the integration; tier change pending

On agentrust-io/integrations#313 a maintainer reproduced parmana-server
at 80c3a92 with the released parmana 1.6.0 and agentrust-trace 0.11.0
(references.json byte for byte, 18 tests passed) and said the tier
change follows in a separate maintainer PR. Recorded in CLAIMS.md 3.23,
CURRENT-STATE, REMAINING-WORK and the evaluation README; the tier stays
community until that PR merges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* docs: agentrust-io/integrations#313 merged (1aac6c8); tier still community

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF

* Add judges' deck for Razorpay Builders Day (14 slides, speaker notes)

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

* Harden key generation: validate key IDs, owner-only private keys (#118)

* Harden key generation: validate key IDs, owner-only private keys

generate-keypair and rotate-verification-key wrote private keys with the
default umask (world-readable) and used the key ID in a file path without
validation, so --key-id ../x wrote outside the key directory.

- scripts/lib/key-files.ts: key ID allowlist, explicit 0600 for private
  keys (chmod after write, so the umask cannot widen it), 0700 directory
  when created.
- Both scripts use it. Overwrites are still refused without --force.
- tests/scripts/key-files.test.ts: unit tests, plus end-to-end runs of
  generate-keypair (the traversal and mode tests fail on the old script).

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Describe the replayed approval by its real refusal, and cite its evidence (#119)

* Razorpay demo: describe the replayed approval by its real refusal

The replayed approval is refused by signal-state-verification-violation
(the approval is spent and its verified state no longer matches), not by
a separate 'already used' rule. The runbook and the judges' deck said
'already used', which an AgenTrust reproduction report did not support.

- examples/razorpay-refund/README.md: request 4 names the rule and reason.
- builders-day/Parmana-Razorpay-Builders-Day.pptx: slide 7 row 4 reworded
  to match (regenerated; the PDF brief is local-only and not committed).

* Reference the replayed-approval refusal to its evidence

The replay refusal is now cited by file, line and test so it can be checked:
- docs/CLAIMS.md 3.23: where the replay case is checked (test lines,
  fixture matchedRuleId, report.json, live demo), with the real rule
  signal-state-verification-violation.
- docs/evaluation/agentrust-refund/README.md: corrected the replay reason
  (it was 'already used') and added a per-case reference list.
- docs/site/evaluation/claims-and-evidence.mdx: new row pointing at 3.23
  and the test that reproduces it.
- examples/razorpay-refund/README.md: request 4 points to the same evidence.

The referenced integration test passes on this branch.

* Reference the AgenTrust integration files for the replay refusal

Points the replay refusal to the Parmana integration as merged in
agentrust-io/integrations (commit 6de4cb9, integrations#294):
- fixtures/03-replay.refusal-record.json line 46 (matchedRuleId)
- tests/test_parmana_evidence.py line 131 (zero connector invocations)
- the reproduction command: python -m pytest tests in integrations/parmana-server

Checked on this branch: that suite at 6de4cb9 gives 18 passed. The
integration's README row for this fixture says 'already used'; the docs
here cite the fixture's rule and do not repeat that wording.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Serialize migration runners with a PostgreSQL advisory lock (#120)

* Serialize migration runners with a PostgreSQL advisory lock

Two deployments that start together both read the pending list and both
tried to run the same migration. Observed against PostgreSQL 16: the second
runner failed with a unique-constraint error, and the same race can apply a
non-idempotent migration twice.

applyPendingMigrations now takes pg_advisory_lock before reading the pending
list and releases it in finally. Dry runs take no lock.

Tests:
- lock is the first statement and unlock the last; the lock is released when
  a migration fails; dry runs take no lock (fake client).
- two concurrent runners against real PostgreSQL apply the migration once.
  Runs only when PARMANA_TEST_DATABASE_URL is set, on an empty throwaway
  database (it drops the tracking table and demo table). Without the lock this
  test fails; with it, it passes.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Python SDK: redact debug logs and refuse plain HTTP to remote hosts (#121)

* Python SDK: redact debug logs and refuse plain HTTP to remote hosts

Debug logging wrote request and response bodies in full, so an amount, an
email or a payee reached the log whenever debug=True.

- Debug logs show each body's structure with every leaf value replaced by
  <redacted>. The Authorization header is never logged.
- HttpTransport refuses an endpoint that is not https://, except localhost
  and 127.0.0.1, because the API key travels in the Authorization header.

Tests: the debug-log test checks that no amount, name, email or key appears
in the log (it fails on the old transport); the endpoint tests cover https,
localhost and a remote plain-HTTP refusal. Full Python suite: 190 passed;
ruff, black and mypy clean.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* CI: Python SDK on Node 24, Docker checks on all package changes (#122)

* CI: Python SDK on Node 24, Docker checks on all package changes

- python-sdk.yml ran on Node 22 while the root package.json requires >=24
  and every other workflow uses 24.
- docker-image.yml path filters listed packages/*/package.json, so a source
  change under packages/ (for example packages/api/src) could skip the
  Docker startup checks. They now match packages/** on push and pull request.

Not run locally: GitHub Actions. Node 24 is the version release.yml and ci.yml
already use.

* Razorpay demo: fix lint error that failed CI

no-useless-assignment: json was initialised to {} and always reassigned in the
try or catch. Declare it without an initial value; behaviour is unchanged
(9 endpoint tests pass).

---------

Co-authored-by: Claude <noreply@anthropic.com>

* generate-api-key: write key files owner-only

The file holds agents' API keys (the PARMANA_API_KEYS value), but it was
written with the default umask, and an existing file kept its mode.

Writes now go through writeKeyFile with mode 0600, for both the .env and the
JSON output, so an existing world-readable file is tightened too.

Tests: existing world-readable .env and a new JSON file both end at 0600 (the
first fails on the old writer). 31 passed; typecheck, ESLint and Prettier
clean.

---------

Co-authored-by: Claude <noreply@anthropic.com>
pavancharak pushed a commit to pavancharak/xyz that referenced this pull request Oct 14, 2026
…ged)

The refund evaluation package was prepared as a proposal to the
AgenTrust integrations repository. The proposal was merged on
2026-10-12 as integrations/parmana-server, a TRACE external evidence
source with no conformance level. Record what was merged, what the
maintainer checked and what they did not, and that the listing is not
a certification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF
pavancharak pushed a commit to pavancharak/xyz that referenced this pull request Oct 14, 2026
…and evaluation

agentrust-io/integrations#294 was merged on 2026-10-12. Adds CLAIMS.md
3.23 (scoped: a community listing of an evidence mapping, no conformance
level, not a certification; what the maintainer checked and did not), a
CURRENT-STATE section, a changelog entry for 2026-10-12 (the listing,
the Essays tab, and the limitations and comparison corrections) and a
link from the evaluation page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019v3V53gvHYxvLqP74uAmgF
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.

3 participants