Skip to content

feat: add external evaluator handoff example - #3419

Open
zhangbin (joy7758) wants to merge 4 commits into
microsoft:mainfrom
joy7758:agent/external-evaluator-handoff
Open

feat: add external evaluator handoff example#3419
zhangbin (joy7758) wants to merge 4 commits into
microsoft:mainfrom
joy7758:agent/external-evaluator-handoff

Conversation

@joy7758

@joy7758 zhangbin (joy7758) commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds an experimental, community-driven example that converts AGT
DecisionBOM observations into a deterministic, strict-JSON request for an
external post-execution evaluator.

The boundary remains intentionally narrow:

  • AGT remains the runtime governance and observation source.
  • Optional BOM fields cross the boundary only through an exact caller-provided
    allowlist; the default exports none.
  • The handoff is read-only and cannot authorize execution, override policy,
    mutate source records, or turn an evaluator result into a governance
    decision.
  • The sample is offline and uses only synthetic data.
  • The deterministic identifier uses AGT's public sha256_jcs SDK helper, not a
    raw cryptographic primitive.

This provides an integration-first interoperability surface without adding an
external evaluator, a second audit model, or a new runtime dependency to AGT
core.

Maintainer-review update

This branch is rebased onto current main and addresses the three requested
repository gates:

  • replaces direct hashlib use with the public sha256_jcs SDK API and adds a
    regression test for the identifier binding;
  • adds file-local cspell directives for SAEE and utcoffset;
  • adds the required dependency audit under docs/dependency-audits/.

The standalone requirements now use
agent-governance-toolkit-core>=5.0.0,<6.0, because the public digest helper is
part of the v5 supported surface.

Relationship to existing merged work

This PR continues an existing upstream interoperability path rather than
introducing a parallel evidence model:

User and developer impact

The implementation is limited to examples/external-evaluator-handoff/, with
one repository-required record under docs/dependency-audits/. It does not
change a published API, core runtime behavior, policy enforcement, or existing
package dependencies. Developers can run the example locally and adapt the
request at an explicit external-evaluator boundary.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Maintenance (dependency audit and review fixes)
  • Security fix

Package(s) Affected

  • agent-os-kernel
  • agent-mesh
  • agent-runtime
  • agent-sre
  • agent-governance
  • docs / root

Checklist

  • My code follows the project style guidelines (ruff check)
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass (pytest)
  • I have updated documentation as needed
  • I have signed the Microsoft CLA

The full monorepo test matrix was not run locally. The scoped checks below pass;
the repository CI remains authoritative for the full matrix.

Validation

  • PyPI agent-governance-toolkit-core>=5.0.0,<6.0: example tests — 7 passed
  • current agent-mesh source: example tests — 7 passed
  • Ruff E/F/W lint and Ruff format check — passed
  • runnable example plus strict JSON output validation — passed
  • python -m compileall -q examples/external-evaluator-handoff — passed
  • README and dependency-audit link checks — 0 broken links
  • strict dependency-audit frontmatter check — 0 findings
  • cspell 8.17.3 on changed lines — passed
  • No Unauthorized Crypto — passed
  • Dependency Audit Trail — passed
  • No Stubs/TODOs — passed
  • Security Audit Required — passed
  • No Unauthenticated Registration — passed
  • git diff --check — passed

The consolidated package emits existing deprecation warnings for legacy Python
import namespaces; this example does not introduce those warnings.

Attribution & Prior Art

  • This contribution does not contain code copied or derived from other projects without attribution
  • Any external projects that inspired this design are credited in code comments or documentation
  • If this PR implements functionality similar to an existing open-source project, I have listed it below

Prior art / related projects:

  • SAEE informed the separation between
    runtime governance and longitudinal external evaluation. No SAEE source code,
    engine implementation, or runtime dependency is included.

AI Assistance

  • I can explain every meaningful change in this PR: what it does, why, and what tradeoffs were considered
  • I have run tests and verification appropriate for this change
  • No part of this PR was autonomously submitted by an AI agent without my review
  • I have not used AI to generate review comments on others' PRs

Codex assisted with implementation, tests, documentation, validation, and the
PR update under the contributor's direction. The contributor reviewed the
original candidate and explicitly authorized this maintainer-requested update.

IP, Patents, and Licensing

  • This contribution does not implement patent-pending or patent-encumbered techniques
  • This contribution does not require an NDA or licensing agreement to understand or use
  • Any AI tools used have terms compatible with the MIT License

Related Issues and Merged Work

  • Discussion: #1314
  • Merged documentation boundary: #1319
  • Merged AuditEntry accountability export: #1370

Copilot AI review requested due to automatic review settings July 22, 2026 16:11
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ⚠️ Missing No current-run comment
🛡️ Security Scan ⚠️ Missing No current-run comment
🔄 Breaking Changes ⚠️ Missing No current-run comment
📝 Docs Sync ⚠️ Missing No current-run comment
🧪 Test Coverage ⚠️ Missing No current-run comment

Verdict: ⚠️ AI review incomplete; ready for human review

AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims.

@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file size/L Large PR (< 500 lines) labels Jul 22, 2026
@github-actions

Copy link
Copy Markdown

🔴 Contributor Check: HIGH

Check Result
Profile HIGH
Credential LOW
Overall HIGH

Automated check by AGT Contributor Check.

@github-actions github-actions Bot added the needs-review:HIGH Contributor reputation check flagged HIGH risk label Jul 22, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

TL;DR: 2 blockers, 0 warnings. Fix #1 and #2 and this ships.

# Sev Issue Where
1 Block assert used for runtime validation (can be stripped with -O) test_external_evaluator_handoff.py
2 Block README claims hash covers emitted “request bytes”, but request_id is computed before it is added README.md

Changes:

  • Add a runnable, offline example that exports DecisionBOM observations into a deterministic strict-JSON external-evaluation request with an explicit allowlist boundary.
  • Add pytest coverage for determinism, immutability, allowlisting behavior, and strict-JSON/timezone validation.
  • Add example documentation and a local requirements file for running/testing the example.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
examples/external-evaluator-handoff/external_evaluator_handoff.py Implements the deterministic strict-JSON handoff request builder and a synthetic runnable demo.
examples/external-evaluator-handoff/test_external_evaluator_handoff.py Adds regression tests covering determinism, allowlisting, immutability, and validation behavior.
examples/external-evaluator-handoff/README.md Documents the boundary, usage, test commands, and security notes for the example.
examples/external-evaluator-handoff/requirements.txt Defines minimal dependencies to run and test the example.

Comment thread examples/external-evaluator-handoff/README.md Outdated
Copilot AI review requested due to automatic review settings July 22, 2026 16:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread examples/external-evaluator-handoff/requirements.txt Outdated
@joy7758
zhangbin (joy7758) marked this pull request as ready for review July 22, 2026 17:01
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI review requested due to automatic review settings July 22, 2026 17:03
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: code-reviewer — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

TL;DR: 0 blockers, 1 warning. Safe experimental feature addition with minor follow-up needed.

# Sev Issue Where
1 W Missing validation for allowed_field_names build_external_evaluation_request

Action items:

  1. Add validation to ensure allowed_field_names contains only valid field names from DecisionBOM.

Warnings:

  • Fine as follow-up PRs.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: breaking-change-detector — API Compatibility

AI-generated review output. Treat it as untrusted analysis and verify before acting.

API Compatibility

No breaking changes detected.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: docs-sync-checker — Docs Sync

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Docs Sync

Documentation is in sync.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: test-generator — `examples/external-evaluator-handoff/external_evaluator_handoff.py`

AI-generated review output. Treat it as untrusted analysis and verify before acting.

examples/external-evaluator-handoff/external_evaluator_handoff.py

  • test_empty_decisions -- Validate that an empty decisions list raises a ValueError.
  • test_timezone_free_generated_at -- Ensure generated_at without a timezone raises a ValueError.
  • test_invalid_field_serialization -- Confirm that non-JSON-serializable fields in allowed_field_names raise a ValueError.
  • test_unallowed_field_exclusion -- Verify that fields not in allowed_field_names are excluded from the output.
  • test_request_id_determinism -- Check that identical inputs produce the same request_id.

@github-actions

Copy link
Copy Markdown
🤖 AI Agent: security-scanner — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

No security issues found.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@liamcrumm

Copy link
Copy Markdown
Contributor

The prior art link in the README, github.com/joy7758/SAEE, returns 404. The example itself is scoped correctly as a standalone with no runtime dependency, which is what the contribution guide asks for. Please point the reference at the right repository or drop it if the project is not public.

@joy7758

Copy link
Copy Markdown
Contributor Author

liamcrumm Thanks for catching this. The SAEE repository was private at the time of submission, which caused the 404. It has now been made public, so the prior art reference at https://github.com/joy7758/SAEE resolves correctly (verified HTTP 200). No content changes were needed — the README link already points at this repository.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Diagnosed all three failing checks rather than the first one, because a partial diagnosis on a PR
with three reds is worse than none. All three are genuine and all three are yours, but they are all
small.

1. No Unauthorized Crypto. The gate reports:

❌ no-custom-crypto: direct crypto usage found outside designated modules:
+import hashlib

From external_evaluator_handoff.py:12, used at line 132:

request["request_id"] = f"eval_{hashlib.sha256(canonical).hexdigest()}"

That is a deterministic content-addressed identifier, not a security primitive, so it is the same
category as the exemption scripts/ci/no-custom-crypto.sh already grants to
agt-policies/.../cli/_migrate_resolution/build.py ("writes a non-security SHA-256 content checksum
of a generated rego bundle").

Two ways out, and I would take the second. You can ask for a per-file exemption on the same grounds.
But this is a runnable example under examples/, and the gate's own comment says "Everything else
should use the SDK's public API, not raw primitives". An example that reaches for hashlib teaches
the pattern the gate exists to discourage, and the next contributor copies it. If a stable
request_id is what you need, deriving it through the SDK, or from the already-canonical JSON with a
non-crypto identifier, keeps the example exemplary and clears the gate with no exemption to maintain.

2. Spell-check changed files. Three unknown words, all in your own added lines, none in
.cspell-repo-terms.txt:

:385:40 - Unknown word (SAEE's)
:386:39 - Unknown word (SAEE)
:414:38 - Unknown word (utcoffset)

SAEE and SAEE's are from the README attribution at lines 105 to 106, utcoffset from
value.utcoffset() in the tz check. A <!-- cspell:ignore SAEE --> in the README and a
# cspell:ignore utcoffset in the module are the lightest fix and keep a project-specific proper
noun out of the repo-wide dictionary. This one is genuine, unlike several other PRs in the queue
right now where the same check is red from a stale-base over-scan.

3. Dependency Audit Trail. "lockfiles changed but no dependency audit doc found". Your new
examples/external-evaluator-handoff/requirements.txt (agent-governance-toolkit-core>=4.1.0,<6.0,
pytest>=8.0.0,<10.0) trips the gate. It wants a matching doc under docs/dependency-audits/; the
files added by #3843 and #3875 are good templates. Both pins look sensible and the doc should be
short.

One more thing, mechanical. This branch is 189 commits behind main. Worth rebasing along
with the three fixes, both so the checks re-run against a current base and because the
agentmesh.governance.decision_bom import surface has had time to move under you.

On the attribution, which I want to say something positive about: naming SAEE as the source of the
interface boundary, with the explicit "No SAEE source code, engine implementation..." disclaimer, is
exactly the right way to handle an externally-inspired design in a Microsoft repository. It is
volunteered rather than extracted, and it makes the provenance question answerable instead of latent.

Nothing blocking on the design.

Signed-off-by: BIN Zhang <joy7759@gmail.com>
Signed-off-by: BIN Zhang <joy7759@gmail.com>
Signed-off-by: BIN Zhang <joy7759@gmail.com>
Signed-off-by: BIN Zhang <joy7759@gmail.com>
@joy7758
zhangbin (joy7758) force-pushed the agent/external-evaluator-handoff branch from 5429e64 to 42f6c39 Compare September 3, 2026 10:37
@joy7758

Copy link
Copy Markdown
Contributor Author

Imran Siddique (@imran-siddique) Thanks for the concrete diagnosis. I have addressed all three items and rebased the branch onto current main (359a2332):

  • replaced direct hashlib use with AGT's public sha256_jcs SDK helper and added a regression test for the request ID binding;
  • added file-local cspell directives for SAEE and utcoffset;
  • added the required dependency audit under docs/dependency-audits/.

Because the public digest helper is a v5 API, the standalone example now requires agent-governance-toolkit-core>=5.0.0,<6.0.

Local verification on 42f6c394:

  • example tests against the published v5 package: 7 passed;
  • example tests against current agent-mesh source: 7 passed;
  • Ruff lint/format, changed-line cspell, strict JSON output, compileall, docs checks, No Unauthorized Crypto, and Dependency Audit Trail: passed.

GitHub currently marks the fork-origin pull_request workflows as action_required with no jobs created, so they still need repository-side approval before the full CI matrix can run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation needs-review:HIGH Contributor reputation check flagged HIGH risk size/L Large PR (< 500 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants