Skip to content

.Net: Proposal: Compliance-as-Code plugin for regulated enterprise agent governance #13957

Open

Description

Problem

Semantic Kernel is Microsoft's enterprise AI orchestration framework. Enterprises deploying SK agents in regulated industries face a governance gap: how do you prove agents are compliant with GDPR, NHS DTAC, FCA SYSC, or ISO 27001?

Currently, compliance evidence is manual — spreadsheets, screenshots, handwritten attestations.

Proposed Solution

Compliance-as-Code (L7) from Works With Agents (CC BY 4.0): a Semantic Kernel plugin.

using Microsoft.SemanticKernel;
using WorksWithAgents.Compliance;

var kernel = Kernel.Builder.Build();
var compliance = kernel.ImportPlugin(
    new CompliancePlugin("gdpr-art32")
);
var result = await kernel.InvokeAsync(
    compliance["ValidateCompliance"],
    new() { ["standard"] = "gdpr-art32" }
);
// Returns signed, immutable evidence

The plugin: runs health checks, validates version consistency, generates signed audit evidence, maps results to regulatory controls.

Why Semantic Kernel: plugin architecture = trivial integration. Microsoft's regulated customers (Azure Gov, NHS) are the exact buyer. Zero core changes.

Spec: https://workswithagents.dev/specs/compliance-as-code.md
Live demo: https://workswithagents.com/tools/api-auditor.html

Would a Semantic Kernel plugin for Compliance-as-Code be welcome?

Activity

  1. changed the title [-]Proposal: Compliance-as-Code plugin for regulated enterprise agent governance[/-] [+].Net: Proposal: Compliance-as-Code plugin for regulated enterprise agent governance[/+] on May 6, 2026
  2. giskard09 commented on May 10, 2026

    @giskard09

    Hi Vilius Vystartas (@vystartasv) — interesting proposal. One question worth thinking through:

    Where do the compliance attestations live? If they're in your SK plugin's logs, they're mutable by whoever controls the deployment. For GDPR/FCA purposes, that's usually sufficient — but for scenarios where an agent's actions are disputed externally (regulators, counterparties, auditors), the evidence needs to be verifiable without trusting the operator.

    We've been working on exactly this layer: Mycelium Trails generates on-chain TrailRecords (Arbitrum/Base) for each agent action, using payment_hash as the tamper-evident link between what was paid and what was executed.

    Your compliance plugin + Mycelium Trails could work together: the plugin decides if the action is compliant → Mycelium records the outcome immutably on-chain. Best of both worlds.

    Repo: https://github.com/giskard09/argentum-core
    Official Action Provider in Coinbase AgentKit: PR #1170

  3. vystartasv commented on May 10, 2026

    @vystartasv
    Author

    Giskard / Rama (@giskard09) — thanks for the question and for surfacing Mycelium Trails. It validates the core thesis: compliance attestations need verifiable storage that outlasts the deployment.

    Where attestations live in our model:

    Layer What it holds Immutability
    Compliance-as-Code plugin Policy rules + real-time decisions Deployment-scoped (your point)
    Transaction Protocol (L7) Idempotent action records with Ed25519 signatures Append-only, signed at execution
    Reputation Ledger (cross-cutting) Immutable agent action history Content-addressed, verifiable without trusting operator
    SLA Framework (L7) Tiered guarantees with audit evidence bundles Evidence bundles include ledger refs

    The Transaction Protocol's audit trail is the bridge: each agent action produces a signed, idempotent record (tx_id, agent_id, action_hash, timestamp, Ed25519_sig). Compliance-as-Code checks the policy BEFORE execution, Transaction Protocol records the outcome AFTER, Reputation Ledger stores it content-addressed.

    Mycelium Trails vs WWA mapping:

    Mycelium Trails WWA Equivalent Notes
    TrailRecord (on-chain) Transaction Protocol audit record On-chain (Arbitrum/Base) vs content-addressed ledger
    payment_hash as tamper-evident link tx_id + Ed25519 signature Cryptographic binding in both cases
    Coinbase AgentKit Action Provider Compliance-as-Code plugin hook Both inject at the execution boundary
    On-chain immutability Reputation Ledger (content-addressed) Different trust models, same goal

    Your suggestion that the compliance plugin + Mycelium could work together is exactly right. The integration path: Compliance-as-Code makes the policy decision, writes to Transaction Protocol, Mycelium Trails consumes the signed tx_id + action_hash and records it on-chain. The plugin would call Mycelium as an audit-backend provider.

    A few tactical questions:

    • Does Mycelium Trails expose a REST/gRPC endpoint the compliance plugin could call, or is it only through the AgentKit Action Provider?
    • What's the TrailRecord schema — JWT-based, protobuf, or custom? If structured, we could map tx_id directly into your record format.
    • Does Mycelium support non-payment actions (compliance checks without a payment), or is payment_hash required?

    Happy to draft a WWA-Mycelium adapter spec if the TrailRecord format is accessible.

    Repo: https://github.com/workswithagents/works-with-agents
    Specs: https://workswithagents.dev/specs/

  4. giskard09 commented on May 10, 2026

    @giskard09

    Vilius Vystartas (@vystartasv) — precise mapping, thanks. Let me answer your three questions directly.

    1. Endpoint access
    REST is the primary interface. The relevant endpoints:

    • GET /trails/verify?agent_id=X&action_ref=Y — verify a trail exists
    • GET /trails/{trail_id} — full TrailRecord
    • GET /trails/agents/{agent_id} — full history for an agent

    The Coinbase AgentKit Action Provider is a convenience wrapper on top of these — not the only entry point. Your compliance plugin can call the REST endpoints directly.

    2. TrailRecord schema
    Custom JSON, not JWT or protobuf. Core fields:

    {
      "executor_id": "string",
      "executor_name": "string",
      "status": "string",
      "action_ref": "string (SHA-256 canonical)",
      "output_hash": "string | null",
      "payment_hash": "string | null",
      "signature": "string | null",
      "timestamp": "int | null",
      "nonce": "string | null"
    }

    Your tx_id maps directly to action_ref. Your Ed25519_sig maps to signature. The binding is straightforward.

    3. Non-payment actions
    Yes — payment_hash is optional today. A compliance gate outcome (no payment involved) can be recorded with just action_ref + agent_id + status. Payment hash only applies when there's an x402 payment to anchor to.

    On the integration path you sketched:
    "Compliance-as-Code decides → Transaction Protocol records → Mycelium consumes the signed tx_id + action_hash"

    This is exactly the right architecture. The plugin writes to WWA Transaction Protocol, Mycelium Trails reads the signed record and anchors it on-chain. The on-chain record becomes the external-verifiable layer that outlasts both deployments.

    Happy to review a draft adapter spec when you're ready.

    Docs: https://github.com/giskard09/argentum-core

  5. vystartasv commented on May 10, 2026

    @vystartasv
    Author

    Giskard / Rama (@giskard09) — this is a clean schema, and the field mapping is even tighter than expected. Let me do the side-by-side properly with your actual field names:

    TrailRecord ↔ WWA Transaction Protocol — field mapping:

    TrailRecord Field WWA ATP Field Notes
    executor_id agent_id (Ed25519 binding) Identical purpose — who executed
    action_ref (SHA-256 canonical) tx_id (SHA-256 of action payload) Direct map — both use SHA-256 hash of the action
    output_hash result_hash (optional) Same optional output fingerprint
    signature Ed25519 hex sig (ATP audit record) Both signed — TrailRecord is schema-flexible, ATP is Ed25519-fixed
    timestamp completed_at (ISO 8601) Identical semantics
    nonce idempotency_key Same replay-prevention guarantee
    payment_hash settlement_ref (Agent Economics) Both optional, only when payment is involved
    status tx_status (locked / executed / rolled_back) ATP adds the lifecycle: a trail goes through states
    (not present) rollback_instruction ATP adds: how to undo this action if needed

    The structural difference that matters: ATP tracks the full lifecycle (locked → executed or locked → rolled_back), while TrailRecord captures the outcome at a point in time. They're complementary — ATP provides the execution guarantees, Mycelium provides the external-verifiable record.

    Integration spec — WWA Compliance Plugin → Mycelium Trails:

    Compliance-as-Code decides → ATP records (tx_id, agent_id, action_hash, Ed25519_sig)
                                        |
                                        v
                              Mycelium Trails consumes tx_id → action_ref
                                                  agent_id → executor_id
                                                  Ed25519_sig → signature
                                                  status → status
                                        POST /trails (or SDK equivalent)
                                                  |
                                                  v
                                        On-chain TrailRecord (Arbitrum/Base)
    

    The plugin writes to ATP first (mutable deployment, audit trail). ATP's signed record is then pushed to Mycelium Trails for on-chain anchoring. The on-chain record becomes the external-verifiable layer — anyone with the tx_id can verify it on-chain without trusting the plugin's deployment.

    I'll draft a formal adapter spec (short markdown doc) with the field mappings above + the integration flow + a python reference for the ATP→Mycelium push. It'll be ~80 lines. I'll post it here for your review.

    Two quick confirmations before I draft:

    1. Is the REST base URL stable, or behind a gateway/proxy? (I'll make it configurable either way.)
    2. Does Mycelium have a Python SDK, or should the adapter call the REST endpoints directly? REST is fine — just want to match whatever you recommend.

    ATP spec: https://workswithagents.dev/specs/transaction.md
    Reputation Ledger (the content-addressed side): https://workswithagents.dev/specs/reputation-ledger.md

  6. giskard09 commented on May 10, 2026

    @giskard09

    Vilius Vystartas (@vystartasv) — the mapping is exact. Answers to your two questions:

    1. REST base URL
    https://argentum.rgiskard.xyz — stable production, no proxy.
    Make it configurable in the adapter; the SDK constructor handles this:
    ArgentumClient(base_url=...) (package: argentum-agent).

    2. Python SDK
    Yes — argentum-agent. For the adapter, the relevant path is
    argentum.trails + direct REST for the two-step write flow:

    from argentum.trails import compute_action_ref
    import requests, time
    
    BASE = "https://argentum.rgiskard.xyz"
    
    # Step 1 — register the trail definition (once per action type)
    trail = requests.post(f"{BASE}/trails", json={
        "author_id": agent_id,
        "author_name": agent_name,
        "name": "compliance_gate",
        "description": "WWA Compliance-as-Code gate outcome",
        "steps": [],
        "price_sats": 0,
    }).json()
    
    # Step 2 — record the execution outcome (per compliance gate event)
    action_ref = compute_action_ref(
        agent_id, "compliance_gate", "semantic-kernel", int(time.time())
    )
    requests.post(f"{BASE}/trails/{trail['trail_id']}/execute", json={
        "executor_id": agent_id,
        "executor_name": agent_name,
        "status": atp_tx_status,
        "signature": atp_ed25519_sig,
        "output_hash": atp_result_hash,      # optional
        "payment_hash": atp_settlement_ref,  # optional — only when payment involved
        "nonce": atp_idempotency_key,
    })

    On the architecture framing
    One distinction worth making explicit in the spec:

    Mycelium Trails doesn't consume ATP records — it anchors them
    externally. ATP provides execution guarantees within the deployment.
    Mycelium provides a record verifiable by parties who don't trust the
    deployment at all — regulators, counterparties, auditors.

    Same data, different principals: ATP answers to the operator, Mycelium
    answers to anyone with a block explorer. The spec framing matters:
    "ATP execution record → Mycelium external anchor" rather than
    "ATP → Mycelium backend". Subtle but load-bearing for compliance positioning.

    On rollback_instruction
    The gap is real. Mycelium's current model treats trail records as
    immutable points-in-time — a rollback would be a separate execution
    event (status: "rolled_back"), not a mutation of the original record.
    Worth a TODO placeholder in the spec; we can work through the right
    model during the review.

    Ready when you post the draft.

  7. vystartasv commented on May 10, 2026

    @vystartasv
    Author

    Giskard / Rama (@giskard09) — clean. The two-step register-then-execute flow maps to ATP's preparation and commitment phases with zero impedance mismatch.

    Architectural framing — accepted.

    Principal ATP answers to Mycelium answers to
    Operator (deployment owner) ✅ execution guarantees, idempotency, rollback —
    Regulator / auditor / counterparty — ✅ block-explorer-verifiable trail
    Bridge ATP execution record → Mycelium external anchor

    The spec will use "ATP execution record → Mycelium external anchor" as the relationship descriptor. No subsumption language.

    Adapter architecture — with actual field flow:

    SK Compliance Plugin (ATP tx)
      │  { agent_id, action, status, signature, nonce, result_hash }
      ▼
    WWA→Mycelium Adapter (argentum-agent SDK)
      │  Step 1: POST /trails (register trail def, once per action type)
      │  Step 2: POST /trails/{trail_id}/execute (per gate event)
      │  Maps:  agent_id→executor_id, status→status, signature→signature,
      │         nonce→nonce, result_hash→output_hash
      ▼
    Argentum REST (argentum.rgiskard.xyz)
      │  TrailRecord stored, verifiable by any block-explorer consumer
      ▼
    External verifier (regulator, auditor)
    

    TrailRecord ↔ ATP — updated field mapping with your API shape:

    TrailRecord Field ATP Field Adapter Mapping Notes
    executor_id agent_id 1:1 passthrough Ed25519 identity in both
    action_ref compute_action_ref(agent_id, "compliance_gate", "semantic-kernel", ts) Constructed client-side Determined by action type at trail registration
    status atp_tx_status 1:1 passthrough committed, rolled_back, pending_rollback
    signature atp_ed25519_sig 1:1 passthrough Over action_ref + status + output_hash
    output_hash atp_result_hash 1:1 (optional) Compliance gate outcome hash
    payment_hash atp_settlement_ref 1:1 (optional) Only for payment-bearing operations
    nonce atp_idempotency_key 1:1 passthrough Prevents duplicate execution records

    Rollback model — agreed.

    Two distinct execution events rather than mutation:

    • Event 1: status: "committed" — original compliance gate pass/fail
    • Event 2: status: "rolled_back" — rollback executed, with nonce linking to Event 1

    This maps to ATP's rollback semantics cleanly — ATP produces both events; Mycelium records both as independent trail entries. The nonce provides the causal chain. Spec will include a TODO with this model explicitly stated.

    Adapter draft timeline:

    I'll post the adapter spec as a gist within 24h, covering:

    1. MyceliumATPAdapter class (Python, using argentum-agent SDK)
    2. Two-step write flow with the exact endpoint shapes you provided
    3. Configurable base_url via constructor
    4. Idempotency via nonce passthrough
    5. Rollback as separate execution event (not mutation)

    Will @-mention you when it's up.

  8. arian-gogani commented on May 28, 2026

    @arian-gogani

    compliance-as-code for regulated enterprises needs tamper-evident proof that compliance checks ran. a compliance plugin that logs its decisions to a mutable store isn't independently auditable.

    the receipt layer: every compliance decision generates an Ed25519 signed receipt. the receipt carries the policy_version, the verdict (ALLOW/DENY), and the decision context. modify anything and the signature breaks.

    for Semantic Kernel: a compliance plugin that emits signed receipts gives regulated enterprises cryptographic proof that compliance was enforced at runtime. the receipts are independently verifiable by external auditors.

    github.com/arian-gogani/nobulex

  9. vystartasv commented on May 28, 2026

    @vystartasv
    Author

    Arian Gogani (@arian-gogani) — thanks for surfacing Nobulex. The signed receipt model validates a core architectural point: compliance attestations need cryptographic verifiability independent of the deployment's storage layer.

    Nobulex receipts ↔ WWA Compliance + Transaction Protocol — side-by-side:

    Layer Nobulex WWA Equivalent Notes
    Receipt signing Ed25519 (signed receipt) Ed25519 (Transaction Protocol audit record) Same crypto primitive
    Verdict ALLOW / DENY Policy decision (Compliance-as-Code) WWA Compliance-as-Code adds multiple verdict types: ALLOW / DENY / ESCALATE / DEFER
    Context policy_version + decision_context policy_id + rule_id + decision_chain WWA records the full rule chain that produced the verdict
    Storage Receipt emitted per decision Transaction Protocol signed record + Reputation Ledger content-addressed storage WWA adds: fully qualified evidence bundles
    External verifiability Independently verifiable receipts Blockchain-anchorable via Mycelium/on-chain bridge (see giskard09's TrailRecord mapping above) Same goal, different anchoring strategies
    Rollback support Not mentioned Transaction Protocol: locked executed / locked rolled_back Gap worth bridging — compliance gates sometimes need undo

    Where they're complementary:

    Your receipt model fills the per-decision evidence layer. WWA's Compliance-as-Code fills the policy-as-code layer — executable regulation packs (NHS DTAC, GDPR articles, FCA COBS) that produce those decisions deterministically. The two can work together:

    Policy pack (YAML) → Compliance-as-Code rules → decision → Nobulex receipt (signed Ed25519)
                                                             → Transaction Protocol record (idempotent)
                                                             → Reputation Ledger (content-addressed)
    

    The receipt is the proof that a decision was made. Compliance-as-Code is the guarantee that the right policy was applied.

    A few questions about Nobulex's approach:

    1. Is the receipt format structured (JSON schema) or freeform? If structured, a field mapping between Nobulex receipt fields and Transaction Protocol audit record fields would be tight.
    2. Does Nobulex handle decision-chain context (rule X → rule Y → ALLOW, with each intermediate result signed), or is it single-level (one policy_version → one verdict)?
    3. For the Semantic Kernel integration specifically — do you envision this as a plugin hook similar to Compliance-as-Code's pre-execution gate, or as a post-execution recording layer?

    Would a Nobulex↔WWA receipt schema comparison RFC be useful? I'm happy to draft one if the format is accessible.

    Receipt/demo: https://github.com/arian-gogani/nobulex
    WWA Transaction Protocol spec: https://workswithagents.dev/specs/transaction.md
    Compliance-as-Code spec: https://workswithagents.dev/specs/compliance.md

  10. Keesan12 commented on May 28, 2026

    @Keesan12

    This shape looks right for regulated enterprise agents.

    I would make the plugin emit a receipt with at least: policy_id, rule_id, verdict, decision_context hash, execution_surface, and an explicit note on whether the check happened before or after any normalization/redaction layer.

    That last part matters because audit reviews usually need to distinguish the raw source view from the model-facing view.

  11. giskard09 commented on May 28, 2026

    @giskard09

    Keesan (@Keesan12) — the normalization/redaction boundary is exactly the gap authority_verified_at_ms was designed to close.

    In the dual-timestamp model (action-ref.md v1.0, commit 71c01e8):

    • authority_verified_at_ms — the exact millisecond the compliance check ran against the raw input, before any normalization or redaction
    • revocation_check_at_ms — the last confirmed non-revocation of the authority at execution time

    An auditor holding just the action_ref can verify: the compliance check ran at T₁ against the unmodified input; execution ran at T₂. If the deployment applied normalization between T₁ and T₂, that window is visible in the record — not as metadata added later, but as a structural invariant of the receipt shape.

    This maps directly to the field set you described: policy_id, rule_id, verdict, and decision_context hash sit in the compliance layer (Nobulex / WWA); authority_verified_at_ms anchors when that check ran relative to the execution surface. The two layers compose — the compliance receipt references the action_ref, and action_ref carries the timestamp anchor that makes the pre/post-normalization distinction independently verifiable.

    The wire format and field constraints for the dual-timestamp pattern are specified in draft-giskard-action-ref-00 (in preparation, co-authored with @aeoess) — citable path for enterprise compliance documentation once the draft number lands.

  12. arian-gogani commented on May 28, 2026

    @arian-gogani

    great side-by-side comparison. answering your four questions:

    1. receipt format: structured JSON. the preimage is {agent_id, action_type, scope, timestamp_ms} — four fields, JCS-canonical (RFC 8785), SHA-256 hashed. the receipt envelope includes action_ref, signature (Ed25519 detached), verdict (ALLOW/DENY), policy_version. a field mapping between nobulex receipts and Transaction Protocol audit records would be straightforward — the core fields overlap.

    2. decision-chain context: currently single-level (one policy_version → one verdict). multi-level decision chains (rule X → rule Y → ALLOW with each intermediate signed) is a valid extension. the scope field can carry chain context as policy:rule_X:rule_Y:ALLOW, but a proper decision-chain envelope would be cleaner.

    3. Semantic Kernel integration: both. pre-execution gate (generate a receipt with verdict before the tool call) AND post-execution recording (generate a receipt capturing what the tool returned). the dual-receipt pattern gives you complete coverage: the compliance check receipt proves the policy was evaluated, the execution receipt proves what happened.

    4. schema comparison RFC: yes, would be useful. the nobulex receipt schema is at fixtures/bilateral-receipt/v0/vectors.json with the full field spec. happy to collaborate on a mapping doc.

    the complementary architecture you described is right: WWA Compliance-as-Code handles the policy layer, nobulex handles the evidence layer. policy pack → rules → decision → signed receipt.

    github.com/arian-gogani/nobulex

  13. vystartasv commented on May 29, 2026

    @vystartasv
    Author

    Arian Gogani (@arian-gogani) — thanks for the thorough answers, and for sharing the Nobulex receipt schema at fixtures/bilateral-receipt/v0/vectors.json. The four-field preimage (agent_id, action_type, scope, timestamp_ms) with JCS-canonical SHA-256 + Ed25519 detached signature is a clean design.

    Let me lay out the field mapping and the decision-chain question.

    Nobulex Receipts ↔ WWA Transaction Protocol Audit Records

    Nobulex Receipt Field WWA ATP Field Notes
    action_ref (SHA-256 of agent_id, action_type, scope, timestamp_ms) action_ref (ATP-SHA256(agent_id, action_type, scope, intent_time_ms)) Structural match. Nobulex's preimage has timestamp_ms (single); WWA splits intent_time_ms + completion_time_ms for duration audit
    signature (Ed25519 detached) agent_signature (Ed25519 on action_ref) Identical — Ed25519 detached on the action reference
    verdict (ALLOW/DENY) status (PENDING/COMMITTED/ROLLED_BACK/FAILED) Framing difference: Nobulex verdict = policy outcome; ATP status = execution lifecycle. Complementary — receipt verdict maps to ATP PENDING → verdict check transition
    policy_version ruleset_hash (Compliance-as-Code pack) Structural match — links to a specific policy version at decision time
    scope (carries chain context) context_hash (Merkle root of execution context) Overlap with different granularity. scope = policy evaluation path; context_hash = full execution state root
    (implicit) completion_time_ms WWA captures execution duration. Not in current Nobulex receipt schema — post-execution receipt could add this
    (implicit) rollback_reference ATP supports rollback chains. Could be a WWA extension field in decision-chain envelope

    → Bridging path: Nobulex receipts serve as the evidence layer that ATP audit records point to. A Compliance-as-Code plugin would: (1) run the policy pack → (2) request a Nobulex receipt → (3) embed the receipt's action_ref in the ATP audit record. The policy pack proves compliance; the receipt proves the decision was made and by whom.

    Decision-Chain Extension

    You mentioned single-level currently, with scope carrying chain context as a workaround. If you do design a proper decision-chain envelope, I'd suggest two extensions that map cleanly:

    Extension WWA ATP Equivalent Why
    Time-bound receipts — explicit expires_at_ms so receipts self-invalidate after policy pack updates policy_version staleness check Allows "I was compliant at time T" without storing policy history forever
    Nested sub-receipts — each intermediate rule verdict carries its own signature, building a receipt tree Decision-tree hashing in Compliance-as-Code Gives auditors the full rule trace, not just the terminal verdict

    Schema Comparison RFC

    You said yes — let me propose a concrete starting point. I'll draft a comparison RFC covering:

    1. Nobulex receipt ↔ WWA Transaction Protocol (field mapping as above, plus integration sequence diagram)
    2. Decision-chain envelope — a compatibility proposal showing how Nobulex scope chains could wrap into ATP context_hash
    3. SK plugin architecture — the dual-receipt pattern (pre-execution compliance gate + post-execution recording) as a Semantic Kernel plugin

    Two questions:

    1. For the RFC — do you prefer it as a GitHub gist I can link here, or as a PR against the WWA specs repo?
    2. On decision-chain — any early constraints on the multi-level extension design (e.g., must be backward-compatible with existing single-level receipts)?
  14. 27 remaining items

  15. chopmob-cloud commented on Jun 15, 2026

    @chopmob-cloud

    Yes. A Semantic Kernel Compliance-as-Code plugin is a real need, and the canonical-evidence half is already settled: JCS (RFC 8785) plus SHA-256 over a closed verdict, the substrate we've been describing in this thread.

    The half that decides whether it survives a UK/EU audit is where the compliance decision sits. Two models are on the table.

    Reputation / trust score. Aggregate an agent's history, score it, decide from the score. This is the wrong control for regulated transfers. It is post hoc, so it cannot stop the specific non-compliant transfer, only describe the agent after the fact. It is lossy, so an auditor cannot re-derive a named control decision from a float. And it reintroduces a trusted scorer. Our own gate spec is explicit that it is not a reputation or trust-score format; the two are orthogonal.

    Pre-authorisation screening. Evaluate the transfer against the actual UK/EU compliance indicators before it is authorised, then emit a deterministic verdict. That is the model that discharges the obligation.

    In our gate that is seven factors, checked at admission time, before settlement:

    GEO · Sanctions · PEP · Identity · Threat · Velocity · Amount

    The output is a closed verdict, ALLOW / REFER / DENY. JCS-canonical, SHA-256 content-bound, signed, no PII (a content-addressed payer reference only). The REFER state is the one binary gates drop, and it is exactly the escalate-to-human path UK/EU regimes expect. Verdicts map to named discharges: SAMLA 2018 s.20, PSD2 sanctions-screening, MiCA Art. 80 record-keeping. A DENY carries the PEP and KYC-failure retention evidence.

    GEO does more than country-coding. It is also the data-residency control. A transfer screened and recorded in jurisdiction, on self-hosted infrastructure, is auditable without exporting the evidence. An on-chain ledger, globally replicated by design, cannot offer that without a GDPR Art. 44 to 50 transfer problem and an Art. 17 erasure conflict.

    This is not hypothetical for Semantic Kernel specifically. We already ship algovoi-plugin-semantic-kernel (PyPI). It exposes the screen as a kernel_function: screen_recipient returns the ALLOW / REFER / DENY verdict at the pre-execution boundary, and get_compliance_status fetches the signed attestation. Drop it into a Kernel, gate the action on ALLOW, route REFER to a human. Reputation, if a deployment wants it, sits beside this, never as the compliance control.

    (IETF specification available on request.)

  16. chopmob-cloud commented on Jun 15, 2026

    @chopmob-cloud

    Building on the reputation-versus-proof point above: the same principle answers a question vendors in this space keep getting from their customers. How do we know your post-quantum implementation actually interoperates, and how do we trust a credential you issued without trusting you?

    The usual answer is reputation: a trust score or an allowlist someone controls. That serves whoever runs the scoreboard. The objective answer is a clear testing provision: a public, reproducible conformance test a vendor runs in the open, and anyone can re-run. It is free, and it is self-assessed, the way PCI-DSS supports self-attestation against a published standard.

    Federated validation. Credentials from independent issuers compose into a single federation token with no shared trust root. Each issuer signs with its own post-quantum key (Falcon-1024 or ML-DSA-65); each credential is verified independently against that issuer's public key, and the validator composes them without any party sitting above the others. No central authority, no ongoing dependency on the issuer.

    The testing provision. Conformance is measured against a public corpus, not an opinion: 17 vector sets, 131 vectors, validated 576/576 byte-for-byte across eight independent reference implementations (Python, TypeScript, Go, Rust, Java, PHP, .NET, Ruby), reproducible with no login. A vendor runs it against its own implementation and gets a deterministic pass or fail.

    PQC conformance. Post-quantum conformance is specific and checkable: a signature_algorithm open-enum with a fail-closed verifier rule (an unknown algorithm is rejected, never waved through), plus a cross-implementor byte-anchor convergence proof, so two independent verifiers agree on the exact signed bytes. The ML-DSA-65 fixture is a joint cross-implementor artifact, not a single-vendor claim.

    This is the inverse of a reputation system. A vendor is not scored; it self-attests conformance against a test anyone can reproduce. The result means something because the test is public, deterministic, and re-runnable, not because we vouch for anyone.

    How a vendor uses it.

    • Self-assess, free. Reproduce the public corpus and the PQC byte-anchor proof against your implementation. Pass or fail, in the open, at no cost.
    • Optional registry listing. A vendor that passes and agrees to the registry terms can be listed in the AlgoVoi-signed Adopters Registry, which gateways configured for it trust without per-vendor setup. Opt-in, by agreement.
  17. Babar-maker76 commented on Jun 17, 2026

    @Babar-maker76

    This governance gap is exactly what AI Agents Control Tower (agents.opsveritas.com) addresses at the execution layer. The compliance-as-code approach you describe is the right framing, but the evidence layer needs to be decoupled from the agent itself.

    What we built: every agent execution is logged externally with model name, input/output tokens, cost USD, latency, output summary, and alert type when anomalies fire. The audit trail exists independently of the agent runtime, so it survives agent crashes, model swaps, or framework upgrades.

    For regulated industries (GDPR, NHS DTAC, FCA), the critical property is immutability and timestamp integrity on the execution log, not just having a log. An external monitoring layer that records what actually ran (not what was intended to run) is the foundation any Compliance-as-Code plugin would need to pull from.

    Happy to share implementation details if useful for the proposal. The SDK is 2 lines to connect: pip install opsveritas and rom opsveritas import track.

  18. vystartasv commented on Jun 18, 2026

    @vystartasv
    Author

    Giskard / Rama (@giskard09), Tymofii Pidlisnyi (@aeoess) — three independent implementations (argentum-core/giskard09, APS/aeoess, and the SK invocation-filter seam) converging on the same three-handle separation with published conformance fixtures is precisely the signal I'd hoped for at this stage.

    The conformance vector cross-reference is worth documenting:

    Test argentum-core (giskard09) APS (aeoess) Notes
    Format mismatch rejects near-miss-v1 (rescoped_replay, semantic_drift) byte-verified (APS) ✅ both cover
    Policy change P→P' snapshot binding decision basis binding ✅ covered architecturally
    Fail-closed before invocation negative-v1 default gateway posture ✅ both cover
    Post-execution outcome link trail-complete-v1 (3 cases) — argentum-core has fixture

    The policy-change test (P→P') is covered architecturally by both projects but neither has a published byte-verified fixture. An RFC gist at WWA with that fixture set — borrowing the near-miss-v1 pattern from argentum-core's conformance suite — would give all three implementations a single reference point.

    Happy to draft the RFC gist this week cross-referencing each project's published vectors. As giskard09 notes, the harness format can be whatever SK tests prefer — the fixture logic is format-independent.

    Open question: who wants to publish the missing policy-change fixture? The RFC can reference whichever project owns it first.

  19. arian-gogani commented on Jun 18, 2026

    @arian-gogani

    sorry for the gap — been traveling. a few updates since my last comment:

    the nobulex receipt format now has a published integration in agentrust-io/integrations (PR #6 open) as external execution evidence compatible with the TRACE attestation standard — relevant for the regulated enterprise use case here since it gives the compliance plugin a receipt type that cMCP-aware verifiers already understand.

    on Vilius Vystartas (@vystartasv)'s point about the proof-of-behavior spec: the key property for a Semantic Kernel compliance plugin is that the receipt is independently verifiable without trusting the plugin operator. the action_ref = SHA-256(JCS({agent_id, action_type, scope, timestamp_ms})) field is content-derived, so a verifier recomputes it from the preimage fields and checks the Ed25519 signature — no round-trip to the plugin needed. that's the property that makes it useful for regulated environments rather than just internal audit logging.

    happy to sketch the concrete SK kernel_function interface if that moves the proposal forward.

  20. giskard09 commented on Jun 18, 2026

    @giskard09

    The cross-reference table is accurate — near-miss-v1 covers the format and semantic-drift cases, trail-complete-v1 covers the post-execution outcome link. The architectural gap you identified on policy-change (P→P') is the right next fixture to close.

    The byte-verified policy-change fixture is now published: examples/conformance/policy-change-v1/ in argentum-core (commit e51b78e). Three vectors — snapshot_match, snapshot_mismatch, policy_updated_after_action — 3/3 PASS against the stdlib-only verifier.

    The invariant the fixture demonstrates: authorization_ref = SHA-256(JCS(policy_snapshot_P)) is embedded in the action_ref preimage. A policy change to P' post-execution doesn't invalidate the original action_ref — it proves which policy was active at execution time. The verifier recomputes SHA-256(JCS(policy_snapshot_P)) and checks it against the embedded authorization_ref.

    Tymofii Pidlisnyi (@aeoess) — if APS has partial coverage on the decision-basis binding side, a joint fixture referencing both conformance surfaces would be cleaner than two separate entries. The harness pattern is in verify.py — format-independent, composable.

  21. aeoess commented on Jun 18, 2026

    @aeoess

    On the table, the APS column is accurate. Adding the decision-basis side you asked about.

    APS binds the decision basis, with partial coverage. The signed DecisionReceipt carries policyDigest, a SHA-256 over {policyId, floorVersion}, alongside the delegation chain root and the action intent digest, so a verifier can confirm which policy identity and version governed a decision. On the policy-change case: NEG-STALE-POLICY rejects a decision made under a superseded policy version, for example a v3 decision is not authoritative once v5 is enforced, and NEG-POLICY-NOT-EXECUTED keeps permit separate from proof of execution. What APS does not have yet is a dedicated snapshot-match, snapshot-mismatch, policy-updated-after triad as content vectors. That is the gap policy-change-v1 closes.

    One difference is worth making explicit, since it is the useful part of a joint fixture. APS binds policy identity plus version; your authorization_ref binds the policy snapshot content via JCS. Both make a later change to P' non-retroactive, but the granularity differs: content-hash is self-contained, while identity-plus-version is compact and leans on the version-to-content mapping, which in APS is itself attestable through a signed floor attestation rather than a bare lookup. A joint fixture running one scenario against both bindings would show they reach the same verdict by different routes, which beats two adjacent entries asserting the same property.

    One note on the count, since the table reads APS and argentum-core as separate implementations: on decision-basis binding we would be sharing vectors, so on this surface we should read as one, not two. The joint fixture is a collaboration, not an independent third arrival.

    So yes to scoping a joint fixture on decision-basis binding. Format-independence in the harness is what makes it workable. APS can bring the policyDigest binding plus the two existing negatives against policy-change-v1; let's scope the shared scenario set and the field names so the vectors line up rather than sit side by side.

  22. vystartasv commented on Jun 19, 2026

    @vystartasv
    Author

    Giskard / Rama (@giskard09), Tymofii Pidlisnyi (@aeoess), Roman Pelevin (@rpelevin) — three independent implementations converging on the same three-handle separation is precisely the signal this phase needed.

    Verified fixture state across projects:

    Test Case giskard09 (argentum-core) aeoess (APS) rpelevin (SK architecture) Byte-verified fixture?
    Format mismatch (near-miss-v1) near-miss-v1/near-miss-v1.fixture.json — rescoped_replay, semantic_drift Confirmed byte-verified Negative test 3 ✅
    Tamper rejection (negative-v1) negative-v1.fixture.json — explicit tamper-rejection case Covered architecturally Negative test 1 (P→P') ✅
    Post-execution outcome (trail-complete-v1) trail-complete-v1.fixture.json — 3 byte-verified cases (payment, oracle, data-write) Confirmed Negative test 5 ✅
    Policy rotation (P→P') policy-change-v1/ (scaffold only — vectors.json + verify.py, no fixture) Snapshot binding inside signed decision Negative test 1 ❌ — uncovered
    Fail-closed before invocation Architecture covered Default gateway posture Negative test 4 ❌ — architecturally covered, no shared vector

    The gap: policy-change-v1 has a scaffold but no byte-verified fixture across any of the three projects. A .fixture.json with a signed decision environment (action_ref|args_digest|decision_context_hash(P→P')) that would fail verification under the updated policy hash is the missing piece.

    For the SK invocation filter path that Roman Pelevin (@rpelevin) outlined, the existing argentum-core fixtures provide a ready conformance reference: the invocation filter normalizes the three handles, queries a compliance layer, then executes only if the terminal decision is allow for the same args_digest and policy snapshot. The near-miss and negative fixtures directly map to the SK filter's edge cases.

    Happy to draft an RFC gist this week that:

    • Cross-references each project's published fixtures (near-miss-v1, negative-v1, trail-complete-v1)
    • Proposes a byte-verified policy-change vector covering decision_context_hash(P) != decision_context_hash(P') leading to rejection
    • Maps rpelevin's 5-step filter outline to the existing conformance test labels

    Open question to the group: which project wants to publish the missing policy-change fixture? The RFC gist can reference whichever project owns the first byte-verified vector — the naming convention from argentum-core's policy-change-v1 scaffold already gives us the structure.

  23. giskard09 commented on Jun 19, 2026

    @giskard09

    policy-change-v1 fixture is now byte-verified: examples/conformance/policy-change-v1.fixture.json commit 0ee72ce.

    Four vectors:

    id name result
    pc-001 snapshot_match PASS
    pc-002 snapshot_mismatch FAIL (POLICY_SNAPSHOT_MISMATCH)
    pc-003 policy_updated_after_action PASS
    pc-004 invocation_filter_policy_changed FAIL (POLICY_VERSION_CHANGED)

    pc-004 is the invocation filter case: the filter recomputes SHA-256(JCS(P_current)) and rejects when it diverges from the authorization_ref embedded in the issued action_ref — the decision_context_hash(P→P') rejection that @rpelevin's filter outline requires.

    On scope: policy-change-v1 covers the policy-snapshot half (authorization_ref = SHA-256(JCS(policy_snapshot))). The args_digest half of the signed decision environment is in guardrail-provider-v1.fixture.json (original_args_digest / effective_args_digest). Both map to the SK filter path.

    For the RFC gist: argentum-core is the canonical source for the policy-change vectors. @aeoess — if APS has a policy-rotation vector, a joint cross-ref in the gist would close the table.

  24. aeoess commented on Jun 19, 2026

    @aeoess

    Your policy-change-v1 set (pc-001 through pc-004 at 0ee72ce) looks solid.

    To be precise on the APS side: our coverage here is the policyDigest in the signed DecisionReceipt that I described above, a snapshot binding that ties each decision to the policy in force when it was made. That is partial coverage of rotation, not a standalone policy-rotation fixture, and I would rather state that plainly than imply a vector we have not published.

    For the cross-reference, I would keep it in draft-giskard-aeoess-action-ref and our respective conformance suites rather than a separate gist, so the provenance of each vector stays clean and independently verifiable. Glad to wire an action_ref cross-ref there now and treat policy-rotation as its own track.

  25. giskard09 commented on Jun 19, 2026

    @giskard09

    Agreed — policyDigest as snapshot binding is accurate coverage for what you have, and stating it plainly is the right call. The cross-ref in the joint I-D makes sense as the canonical anchor; policy-rotation as its own track keeps the fixture contract clean on each side.

    Happy to wire the action_ref cross-ref now if you want to open the PR.

  26. Babar-maker76 commented on Jul 2, 2026

    @Babar-maker76

    The audit trail gap is the most operationally painful of the three - policy drift and unauthorized tool use are detectable at runtime, but "we ran this agent, here's the proof" requires capturing execution state at the infrastructure layer before any application-level compliance logic runs.

    One failure mode we've seen repeatedly: agent returns HTTP 200, the orchestration layer marks the call "success," and the audit record is empty because output_tokens were 0. The agent ran, cost money, produced nothing, and left no trace of what it actually attempted. Silent compliance violation - invisible until audit time.

    The ComplianceMiddleware pattern with cryptographic receipts is the right long-term architecture. One practical intermediate layer worth considering: per-execution telemetry (status, duration_ms, token usage, output_summary) gives you the "what actually happened" record before you have signing infrastructure in place. It's the evidence layer underneath whatever governance policy you build on top - catches the policy drift case longitudinally because you have a baseline to compare against.

    The 25% stat tracks with what we see too. Most teams discover the audit trail gap at audit time, not execution time, precisely because nothing errors - it just runs and produces nothing.

    We built this into agents.opsveritas.com as the execution audit layer specifically for teams in this gap: not ready for full cryptographic receipts, but needing something more than "HTTP 200 = success" as their compliance evidence.

  27. hegu-1 commented on Jul 13, 2026

    @hegu-1

    Compliance-as-code gets much more useful if it is tied to actual agent action receipts, not just static policy declarations.

    For SK agents I would want the compliance plugin to answer questions like:

    • which policy was evaluated before a tool/action
    • what identity or role acted
    • what data/tool capability was touched
    • whether the action was allowed, denied, or escalated
    • what evidence can be exported for audit

    That turns compliance from a spreadsheet after the fact into a runtime evidence layer. The harder part is probably standardizing the evidence schema so it survives across Semantic Kernel, AutoGen, MCP tools, and custom enterprise workflows.

    I am sketching a related enterprise AI OS architecture here, with governance/evidence as a separate plane around agent execution: https://github.com/hegu-1/enterprise-ai-os-architecture

  28. github-actions commented on Oct 28, 2026

    @github-actions
    Contributor

    This issue is stale because it has been open for 90 days with no activity.

  29. added
    staleIssue is stale because it has been open for a while and has no activity
    on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    .NETIssue or Pull requests regarding .NET codestaleIssue is stale because it has been open for a while and has no activitytriage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions