Skip to content

Resolve evaluate/evaluate_transition ambiguity and unify DecisionRecord#13

Merged
LalaSkye merged 6 commits intomainfrom
copilot/process-pr-7-decision-record
Mar 2, 2026
Merged

Resolve evaluate/evaluate_transition ambiguity and unify DecisionRecord#13
LalaSkye merged 6 commits intomainfrom
copilot/process-pr-7-decision-record

Conversation

Copy link
Contributor

Copilot AI commented Mar 1, 2026

Post-PR#6 conflict resolution left mgtp/evaluate.py with two evaluation functions and two competing DecisionRecord implementations across mgtp/types.py and mgtp/decision_record.py. This PR enforces a single canonical path for each.

DecisionRecord — one implementation

  • mgtp/types.py is the sole DecisionRecord definition: unified class with 5 core fields plus optional audit fields (actor_id, tenant_id, context_hash, gate_version, timestamp).
  • mgtp/decision_record.py becomes a re-export shim only (from mgtp.types import DecisionRecord). No competing class.
  • Computed properties (canonical_bytes, canonical_hash, content_hash, decision_id, reason_code) replace stored duplicates. build() classmethod retained for audit-trail construction.

evaluate() / evaluate_transition() — Option A (thin wrapper)

  • mgtp/evaluate.py exposes only evaluate() (__all__ = ["evaluate"]); the registry-free canonical entrypoint from PR#6.
  • mgtp/evaluate_transition.py exposes only evaluate_transition() (__all__ = ["evaluate_transition"]); a thin wrapper that adds registry pre-check then delegates the gate decision to evaluate():
# evaluate_transition pipeline:
# 1. Registry membership → REFUSED if absent
# 2. Map (registry.required_authority, context.authority_basis)
#    → (authority_basis=required, provided_evidence=actual)
# 3. Call evaluate() for APPROVED / REFUSED / SUPERVISED decision
# 4. Reconstruct DecisionRecord with actor's original authority_basis + audit fields
eval_context = AuthorityContext(
    authority_basis=entry["required_authority"],   # required level
    provided_evidence=Evidence[context.authority_basis],  # actual
    ...
)
gate_result = evaluate(request, eval_context)

No divergent gate behaviour

tests/test_evaluate_coherence.py asserts that for every equivalent authority configuration (APPROVED, REFUSED, SUPERVISED), both evaluate() and evaluate_transition() produce the same outcome. The __all__ guard on each module is also tested to prevent a third entrypoint from silently appearing.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…ition() with no ambiguity

Co-authored-by: LalaSkye <228581229+LalaSkye@users.noreply.github.com>
Copilot AI changed the title [WIP] Prepare for PR #7 with decision record Resolve evaluate/evaluate_transition ambiguity and unify DecisionRecord Mar 1, 2026
LalaSkye added 4 commits March 2, 2026 07:20
Remove import yaml, use import json instead.
Replace yaml.safe_load with json.load.
Require schema_version top-level key.
No new external dependencies.
Replace YAML fixture content with json.dumps equivalents.
Point _REAL_REGISTRY to .json file.
Remove textwrap import, add json import.
Use schema_version key instead of version.
@LalaSkye LalaSkye marked this pull request as ready for review March 2, 2026 07:27
@LalaSkye LalaSkye merged commit 1e4d39c into main Mar 2, 2026
6 checks passed
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.

2 participants