Skip to content

Harden MGTP determinism and enforce boundary isolation#6

Open
Copilot wants to merge 3 commits intofeat/mgtp-scaffold-v0.1from
copilot/harden-mgtp-determinism
Open

Harden MGTP determinism and enforce boundary isolation#6
Copilot wants to merge 3 commits intofeat/mgtp-scaffold-v0.1from
copilot/harden-mgtp-determinism

Conversation

Copy link

Copilot AI commented Feb 28, 2026

Introduces deterministic canonicalisation, cross-version stability, and boundary isolation for the MGTP layer — all changes confined to mgtp/** and tests/**. No upstream files (authority_gate.py, stop_machine.py, commit_gate/**) are touched.

mgtp/types.py

  • Added DecisionRecord frozen dataclass with explicit canonical_bytes() / canonical_hash() methods: sorted keys, compact separators, UTF-8, no __repr__, no sets
  • Added provided_evidence: Optional[Evidence] = None to AuthorityContext for MGTP-local authority mapping (defaults None)

mgtp/evaluate.py (new)

  • Deterministic evaluate(request, context) -> DecisionRecord that maps authority_basis string → Evidence enum via Evidence[name] (explicit, no implicit ordering)
  • Fails cleanly with ValueError when provided_evidence is None or authority_basis is unrecognised
ctx_no_evidence = AuthorityContext(actor_id="alice", authority_basis="OWNER", tenant_id="t1")
evaluate(request, ctx_no_evidence)  # raises ValueError: "provided_evidence is required"

tests/test_mgtp_determinism.py (new, 18 tests)

Group Coverage
T1 — Canonicalisation canonical_bytes() stable ×20, sorted keys, no whitespace, UTF-8
T2 — Cross-version Pinned known-value SHA-256 digest; explicit dict construction avoids implicit ordering
T3 — Authority isolation Missing/unknown evidence raises; APPROVED / REFUSED / SUPERVISED paths; default None
T4 — Boundary integrity AuthorityGate behaviour unchanged post-import; commit_gate not introduced into sys.modules by mgtp

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 28, 2026 13:38
Co-authored-by: LalaSkye <228581229+LalaSkye@users.noreply.github.com>
Co-authored-by: LalaSkye <228581229+LalaSkye@users.noreply.github.com>
Copilot AI changed the title [WIP] Harden MGTP determinism and enforce boundary isolation Harden MGTP determinism and enforce boundary isolation Feb 28, 2026
@LalaSkye LalaSkye marked this pull request as ready for review February 28, 2026 18:50
@LalaSkye LalaSkye requested a review from Copilot February 28, 2026 18:50
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds deterministic decision canonicalisation/hashing and a deterministic MGTP evaluation entrypoint while introducing tests to enforce cross-version stability and boundary isolation.

Changes:

  • Add DecisionRecord with deterministic canonical_bytes() / canonical_hash() and extend AuthorityContext with optional provided_evidence.
  • Introduce mgtp.evaluate.evaluate() to deterministically map authority_basis to Evidence and produce a DecisionRecord.
  • Add a new determinism/boundary-focused test suite for MGTP, plus a root .gitignore.

Reviewed changes

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

File Description
mgtp/types.py Adds canonical, deterministic serialization/hashing on DecisionRecord; extends AuthorityContext with MGTP-local evidence.
mgtp/evaluate.py Implements deterministic evaluation logic and explicit authority mapping via Evidence[...].
tests/test_mgtp_determinism.py Adds determinism, cross-version stability, and boundary isolation tests for MGTP.
.gitignore Ignores common Python build/test artefacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

def test_canonical_bytes_no_whitespace():
"""T1d: canonical_bytes uses compact separators (no extra whitespace)."""
raw = SAMPLE_RECORD.canonical_bytes().decode("utf-8")
assert " " not in raw, "Unexpected whitespace in canonical bytes"
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The assertion " " not in raw is overly strict: canonical JSON can legitimately contain spaces inside string values (e.g., actor_id="Alice Smith"). This test should instead assert that JSON separators are compact (e.g., no occurrences of ": " or ", "), or use a regex that checks for whitespace outside quoted strings.

Suggested change
assert " " not in raw, "Unexpected whitespace in canonical bytes"
assert '": ' not in raw, "Unexpected space after ':' separator in canonical bytes"
assert '", ' not in raw, "Unexpected space after ',' separator in canonical bytes"

Copilot uses AI. Check for mistakes.
f"mgtp import introduced commit_gate modules: {new_commit_gate}"
)
finally:
# Restore mgtp modules so other tests are unaffected
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The cleanup in the finally block restores any previously-cached mgtp* modules, but it does not remove the newly imported mgtp / mgtp.* entries that were added during the test run. This can leak imported modules/state into subsequent tests. Consider popping current mgtp keys again before restoring saved_mgtp (or use a helper/context manager that fully restores sys.modules for the prefix).

Suggested change
# Restore mgtp modules so other tests are unaffected
# Remove any mgtp modules imported during this test and restore previous ones
current_mgtp_keys = [k for k in sys.modules if k == "mgtp" or k.startswith("mgtp.")]
for k in current_mgtp_keys:
sys.modules.pop(k, None)

Copilot uses AI. Check for mistakes.
Comment on lines +247 to +252
def test_mgtp_import_does_not_modify_authority_gate():
"""T4a: Importing mgtp does not alter AuthorityGate behaviour."""
gate = AuthorityGate(Evidence.OWNER)
assert gate.check(Evidence.ADMIN) is Decision.ALLOW
assert gate.check(Evidence.USER) is Decision.DENY
assert gate.required_level is Evidence.OWNER
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

This test’s docstring says it verifies behavior “after importing mgtp”, but the test never imports mgtp (it imports mgtp.evaluate at module import time). Either import mgtp explicitly in the test (or rename the docstring) so the claim matches what’s actually being exercised.

Copilot uses AI. Check for mistakes.
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