Skip to content

Add the Microsoft AGT adapter as a first-class integration - #52

Merged
blocksifrdev merged 2 commits into
mainfrom
feat/agt-adapter
Sep 15, 2026
Merged

blocksifrdev merged 2 commits into
mainfrom
feat/agt-adapter

Conversation

@blocksifrdev

Copy link
Copy Markdown
Collaborator

AGT (Microsoft Agent Governance Toolkit) is a mandatory integration target, so it gets a real bridge rather than a line in the framework list.

The contract implemented here is the one this repo already specifies in docs/integration-guide.md Part 6 and docs/ecosystem-integrations.md — nothing about AGT was invented for this PR.

The closed loop

1. AGT enforces pre-execution policy
2. PCTR observes the consequence, the route and the signed receipt
3. Trust is recomputed from that behavioural evidence
4. AGT consumes it and adjusts the next decision

AGT stays authoritative for allow/deny. PCTR supplies the evidence it decides on and never builds a parallel privilege model — the guide rules that out explicitly ("avoid parallel privilege models; map TTP scores into existing AGT trust/ring constructs instead").

What's implemented

Surface Guide Implementation
OPA/Rego bridge 6.2 agtClaims() returns input.ttp with ttp_domain, ttp_score, issuer_count — the three claims the guide's own Rego example evaluates — plus consequence, severity, reversibility, route and receipt hash
SPIFFE/SVID identity 6.3 SVID URIs work as agent ids unmodified; parseSpiffeId() exposes the trust domain; claims surface spiffe_ids
Canonical score adapter 6.4 toAgtScore() = round(score * 1000), clamped; the 0-1 score travels alongside for audit
AgentMesh bridge 6.5 toMeshAttestation() maps a receipt to a peer attestation carrying receiptId, receiptHash and signing key

Plus toTrustEvidence(), which weights a denial by what the action could have caused — a refused CRITICAL transfer is stronger behavioural evidence than a permitted read.

On AGT's event vocabulary

It isn't pinned in this repo, so normalizeAgtEvent is deliberately tolerant about field naming (agentId / agent_id / subject, type / event / eventType / kind) and returns null for anything it cannot read. Unrecognised events are dropped rather than invented into security events — there's a test for exactly that. When the AGT schema is fixed, one function changes.

Verification

  • 11 new tests, 134 total, all passing
  • Worked demo: npm run demo:pctr-agt — ingests AGT events, prints the input.ttp Rego payload, runs the protected execution, and emits the evidence and mesh attestation that go back

🤖 Generated with Claude Code

AGT is a mandatory target, so it gets a real bridge rather than a mention
in the framework list. The contract implemented here is the one this repo
already specifies in docs/integration-guide.md Part 6 and
docs/ecosystem-integrations.md — not an invented one.

The closed loop: AGT enforces pre-execution policy, PCTR observes the
consequence, the route and the signed receipt, trust is recomputed from
that evidence, and AGT consumes it on the next decision. AGT stays
authoritative for allow/deny; PCTR never builds a parallel privilege
model, which the guide rules out explicitly.

- OPA/Rego bridge (6.2): agtClaims() returns input.ttp carrying
  ttp_domain, ttp_score and issuer_count — the three claims the guide's
  own Rego example evaluates — plus the consequence, severity,
  reversibility, route and receipt hash that only PCTR knows.
- SPIFFE/SVID identity (6.3): SVID URIs work as agent ids unmodified;
  parseSpiffeId() exposes the trust domain and claims surface spiffe_ids.
- Canonical score adapter (6.4): toAgtScore() is round(score * 1000) with
  clamping, and the original 0-1 score travels alongside for audit.
- AgentMesh bridge (6.5): toMeshAttestation() maps a receipt to a peer
  attestation carrying receiptId, receiptHash and the signing key, so mesh
  telemetry traces back to the execution it describes.
- toTrustEvidence() weights a denial by what the action could have caused:
  a refused CRITICAL transfer is stronger evidence than a permitted read.

AGT's event vocabulary is not pinned in this repo, so normalizeAgtEvent is
tolerant about field naming and returns null for anything it cannot read.
Unrecognized events are dropped, never invented into security events —
there is a test for exactly that. When the schema is fixed, one function
changes.

11 new tests (134 total) and a worked demo: npm run demo:pctr-agt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

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

AGT is microsoft/agent-governance-toolkit on GitHub, so the shapes are
public. This replaces the defensive guesses with its actual definitions
from agent-governance-typescript/src/types.ts.

The correction that matters: AGT's TrustScore is 0-1, banded into tiers
(untrusted 0.0, provisional 0.3, trusted 0.6, verified 0.85, per
src/trust.ts), NOT the 0-1000 integer scale our integration guide
specifies in 6.4. PCTR's effective trust is already 0-1, so it maps
across unscaled. Sending 918 where AGT expects 0.918 would have read as
out-of-range on every call. toAgtScore() is kept for the downstream
consumers the guide mentions, but it is documented as not the AGT-native
path, and toAgtTrustScore() now returns a real TrustScore.

Event normalization now reads AGT's own shapes:
- PolicyDecisionResult with every PolicyAction: allow/log/warn permit,
  deny denies, and require_approval is not executable yet, carrying the
  approvers list rather than collapsing to a flat denial.
- AuditEntry, including its hash/previousHash chain — AGT hash-chains its
  audit log exactly as PCTR chains receipts, so the two trails line up.
- CascadeEvent containment: a quarantined or killed agent has no trust
  left; health_propagated is telemetry and is dropped.
- RingViolation, with ExecutionRing carried through, plus
  ringForSeverity() proposing a ring from what the action can cause.
  AGT's own actionRings config stays authoritative.
- TrustVerificationResult, tier intact.

138 tests. The demo prints AGT's real TrustScore and required ring.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@blocksifrdev
blocksifrdev merged commit a06dfeb into main Sep 15, 2026
4 checks passed
@blocksifrdev
blocksifrdev deleted the feat/agt-adapter branch September 15, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant