diff --git a/Makefile b/Makefile index 8856a65..0397cbc 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -.PHONY: validate test validate-agent-cycle-health validate-authority-dependency-evidence validate-prometheus-sr validate-reasoning-failure-traces validate-governance-context validate-lattice-data-governai-execution-refs validate-lattice-runtime-profile-refs validate-network-native-assistant-evidence validate-guardrail-evidence-artifacts validate-stop-gate-evaluator validate-guarded-workcell-artifact validate-guarded-workcell-executor validate-guarded-invocation-artifact validate-guarded-invocation validate-agentic-pr-work-order validate-semantic-enterprise-agent-boundary validate-ops-history-contracts validate-action-contracts validate-agent-operation-contract validate-superconscious-reasoning-import validate-agent-harness-runtime-contracts validate-bounded-action-loop agentplane-evidence-receipt-composition-tier2-binding-ci lawful-learning-phase9-contract-ci validate-evidence-receipt-binding validate-semantic-activation-receipt validate-governed-run-contract validate-preflight-receipt validate-attempt-admission-receipt validate-verification-execution-receipt validate-synthetic-verification-receipt validate-governed-runner-v0-2-contract-chain validate-budget-settlement-receipt validate-rollback-receipts validate-run-dossier validate-governed-runner-readonly validate-workroom-context-evidence validate-wallguard-collaboration-admission validate-prophet-mesh-agentplane-adapter +.PHONY: validate test validate-agent-cycle-health validate-authority-dependency-evidence validate-prometheus-sr validate-reasoning-failure-traces validate-governance-context validate-lattice-data-governai-execution-refs validate-lattice-runtime-profile-refs validate-network-native-assistant-evidence validate-guardrail-evidence-artifacts validate-stop-gate-evaluator validate-guarded-workcell-artifact validate-guarded-workcell-executor validate-guarded-invocation-artifact validate-guarded-invocation validate-agentic-pr-work-order validate-semantic-enterprise-agent-boundary validate-ops-history-contracts validate-action-contracts validate-agent-operation-contract validate-superconscious-reasoning-import validate-agent-harness-runtime-contracts validate-bounded-action-loop agentplane-evidence-receipt-composition-tier2-binding-ci lawful-learning-phase9-contract-ci validate-evidence-receipt-binding validate-semantic-activation-receipt validate-governed-run-contract validate-preflight-receipt validate-attempt-admission-receipt validate-verification-execution-receipt validate-synthetic-verification-receipt validate-governed-runner-v0-2-contract-chain validate-budget-settlement-receipt validate-rollback-receipts validate-run-dossier validate-governed-runner-readonly validate-workroom-context-evidence validate-wallguard-collaboration-admission validate-prophet-mesh-agentplane-adapter validate-source-control-intent-bridge -validate: validate-agent-cycle-health validate-authority-dependency-evidence validate-prometheus-sr validate-reasoning-failure-traces validate-governance-context validate-lattice-data-governai-execution-refs validate-lattice-runtime-profile-refs validate-network-native-assistant-evidence validate-guardrail-evidence-artifacts validate-stop-gate-evaluator validate-guarded-workcell-artifact validate-guarded-workcell-executor validate-guarded-invocation-artifact validate-guarded-invocation validate-agentic-pr-work-order validate-semantic-enterprise-agent-boundary validate-ops-history-contracts validate-action-contracts validate-agent-operation-contract validate-superconscious-reasoning-import validate-agent-harness-runtime-contracts validate-bounded-action-loop agentplane-evidence-receipt-composition-tier2-binding-ci lawful-learning-phase9-contract-ci validate-evidence-receipt-binding validate-semantic-activation-receipt validate-governed-run-contract validate-preflight-receipt validate-attempt-admission-receipt validate-verification-execution-receipt validate-synthetic-verification-receipt validate-governed-runner-v0-2-contract-chain validate-budget-settlement-receipt validate-rollback-receipts validate-run-dossier validate-governed-runner-readonly validate-workroom-context-evidence validate-wallguard-collaboration-admission validate-prophet-mesh-agentplane-adapter +validate: validate-agent-cycle-health validate-authority-dependency-evidence validate-prometheus-sr validate-reasoning-failure-traces validate-governance-context validate-lattice-data-governai-execution-refs validate-lattice-runtime-profile-refs validate-network-native-assistant-evidence validate-guardrail-evidence-artifacts validate-stop-gate-evaluator validate-guarded-workcell-artifact validate-guarded-workcell-executor validate-guarded-invocation-artifact validate-guarded-invocation validate-agentic-pr-work-order validate-semantic-enterprise-agent-boundary validate-ops-history-contracts validate-action-contracts validate-agent-operation-contract validate-superconscious-reasoning-import validate-agent-harness-runtime-contracts validate-bounded-action-loop agentplane-evidence-receipt-composition-tier2-binding-ci lawful-learning-phase9-contract-ci validate-evidence-receipt-binding validate-semantic-activation-receipt validate-governed-run-contract validate-preflight-receipt validate-attempt-admission-receipt validate-verification-execution-receipt validate-synthetic-verification-receipt validate-governed-runner-v0-2-contract-chain validate-budget-settlement-receipt validate-rollback-receipts validate-run-dossier validate-governed-runner-readonly validate-workroom-context-evidence validate-wallguard-collaboration-admission validate-prophet-mesh-agentplane-adapter validate-source-control-intent-bridge python3 tools/validate_execution_timing.py validate-governance-context: @@ -248,6 +248,9 @@ validate-prophet-mesh-agentplane-adapter: python3 -m json.tool contracts/prophet-mesh/prophet-mesh-agentplane-adapter.v0.1.json >/dev/null python3 tools/validate_prophet_mesh_agentplane_adapter.py +validate-source-control-intent-bridge: + python3 tools/validate_source_control_intent_bridge.py + validate-agent-cycle-health: python3 tools/validate_agent_cycle_health.py diff --git a/schemas/source-control-intent-bridge.schema.v0.1.json b/schemas/source-control-intent-bridge.schema.v0.1.json new file mode 100644 index 0000000..5f75039 --- /dev/null +++ b/schemas/source-control-intent-bridge.schema.v0.1.json @@ -0,0 +1,108 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://socioprophet.io/schemas/agentplane/source-control-intent-bridge/v0.1", + "title": "SourceControlIntentBridgeArtifact", + "description": "AgentPlane bridge artifact for source-control intent registration and post-execution evidence emitted by gitea-sovereign. AgentPlane remains canonical execution admission authority; gitea-sovereign registers intent surfaces and consumes AgentPlane semantics.", + "type": "object", + "required": [ + "kind", + "artifact_id", + "captured_at", + "scaffold_baseline", + "service_id", + "operation", + "intent_status", + "agentplane_admission_ref", + "policy_decision", + "replay_eligible" + ], + "additionalProperties": false, + "properties": { + "kind": { "type": "string", "const": "SourceControlIntentBridgeArtifact" }, + "artifact_id": { "type": "string", "minLength": 1 }, + "captured_at": { "type": "string", "format": "date-time" }, + "scaffold_baseline": { + "type": "string", + "description": "git commit SHA of the gitea-sovereign scaffold baseline", + "pattern": "^[a-f0-9]{40}$" + }, + "service_id": { + "type": "string", + "description": "Service identity; must match svc.substrate.source-control for gitea-sovereign" + }, + "operation": { + "type": "string", + "enum": [ + "intent_registration", + "branch_create", + "branch_protect", + "pr_open", + "pr_merge", + "pr_close", + "commit_push", + "tag_create", + "webhook_emit", + "divergence_check" + ] + }, + "intent_status": { + "type": "string", + "enum": ["registered", "admitted", "blocked", "diverged", "replayed", "pending_review"] + }, + "agentplane_admission_ref": { + "type": "string", + "description": "Reference to the AgentPlane admission record that authorized this operation. Must be non-null for admitted and replayed status." + }, + "policy_decision": { + "type": "string", + "enum": ["allow", "allow_with_audit", "block", "escalate", "pending"] + }, + "policy_ref": { "type": "string" }, + "replay_eligible": { "type": "boolean" }, + "replay_artifact_ref": { + "type": "string", + "description": "Reference to non-mutating replay artifact, if replay has been performed" + }, + "divergence_evidence": { "$ref": "#/$defs/DivergenceEvidence" }, + "evidence_refs": { + "type": "array", + "items": { "type": "string" } + }, + "runtime_ready": { + "type": "boolean", + "const": false, + "description": "Scaffold baseline does not imply runtime readiness; this field must remain false until runtime prerequisites are satisfied" + }, + "pr_ref": { "type": "string" }, + "actor_ref": { "type": "string" } + }, + "if": { + "properties": { "intent_status": { "enum": ["admitted", "replayed"] } } + }, + "then": { + "required": ["agentplane_admission_ref"], + "properties": { + "agentplane_admission_ref": { "type": "string", "minLength": 1 } + } + }, + "$defs": { + "DivergenceEvidence": { + "type": "object", + "required": ["detected_at", "divergence_type", "baseline_ref", "observed_ref"], + "additionalProperties": false, + "properties": { + "detected_at": { "type": "string", "format": "date-time" }, + "divergence_type": { + "type": "string", + "enum": ["branch_diverged", "policy_drift", "scaffold_mismatch", "replay_hash_mismatch"] + }, + "baseline_ref": { "type": "string", "minLength": 1 }, + "observed_ref": { "type": "string", "minLength": 1 }, + "resolution_status": { + "type": "string", + "enum": ["unresolved", "escalated", "resolved", "accepted_as_known"] + } + } + } + } +} diff --git a/tests/fixtures/source-control-intent/allowed-operation.json b/tests/fixtures/source-control-intent/allowed-operation.json new file mode 100644 index 0000000..bb4b5b7 --- /dev/null +++ b/tests/fixtures/source-control-intent/allowed-operation.json @@ -0,0 +1,20 @@ +{ + "kind": "SourceControlIntentBridgeArtifact", + "artifact_id": "scib_pr_open_20260611_001", + "captured_at": "2026-06-11T10:00:00Z", + "scaffold_baseline": "5d85ab6a24502f60f15ef829235b6288a289d47e", + "service_id": "svc.substrate.source-control", + "operation": "pr_open", + "intent_status": "admitted", + "agentplane_admission_ref": "agentplane://admission/scib_admission_20260611_001", + "policy_decision": "allow_with_audit", + "policy_ref": "policy://platform/source-control-pr-open-v1", + "replay_eligible": true, + "evidence_refs": [ + "ev://agentplane/run-receipt/scib_run_20260611_001", + "ev://sourceos/state-integrity/scib_20260611_001" + ], + "runtime_ready": false, + "pr_ref": "github://SocioProphet/gitea-sovereign/pull/2", + "actor_ref": "actor://agent/governed-runner-001" +} diff --git a/tests/fixtures/source-control-intent/blocked-operation.json b/tests/fixtures/source-control-intent/blocked-operation.json new file mode 100644 index 0000000..2c45c87 --- /dev/null +++ b/tests/fixtures/source-control-intent/blocked-operation.json @@ -0,0 +1,19 @@ +{ + "kind": "SourceControlIntentBridgeArtifact", + "artifact_id": "scib_commit_push_blocked_20260611_001", + "captured_at": "2026-06-11T11:00:00Z", + "scaffold_baseline": "5d85ab6a24502f60f15ef829235b6288a289d47e", + "service_id": "svc.substrate.source-control", + "operation": "commit_push", + "intent_status": "blocked", + "agentplane_admission_ref": "agentplane://admission/scib_admission_blocked_20260611_001", + "policy_decision": "block", + "policy_ref": "policy://platform/source-control-commit-push-v1", + "replay_eligible": false, + "evidence_refs": [ + "ev://agentplane/block-receipt/scib_block_20260611_001" + ], + "runtime_ready": false, + "pr_ref": "github://SocioProphet/gitea-sovereign/pull/3", + "actor_ref": "actor://agent/governed-runner-002" +} diff --git a/tests/fixtures/source-control-intent/divergence-evidence.json b/tests/fixtures/source-control-intent/divergence-evidence.json new file mode 100644 index 0000000..7c9e58b --- /dev/null +++ b/tests/fixtures/source-control-intent/divergence-evidence.json @@ -0,0 +1,25 @@ +{ + "kind": "SourceControlIntentBridgeArtifact", + "artifact_id": "scib_divergence_20260611_001", + "captured_at": "2026-06-11T12:00:00Z", + "scaffold_baseline": "5d85ab6a24502f60f15ef829235b6288a289d47e", + "service_id": "svc.substrate.source-control", + "operation": "divergence_check", + "intent_status": "diverged", + "agentplane_admission_ref": "agentplane://admission/scib_admission_diverge_20260611_001", + "policy_decision": "escalate", + "policy_ref": "policy://platform/source-control-divergence-v1", + "replay_eligible": false, + "divergence_evidence": { + "detected_at": "2026-06-11T12:00:00Z", + "divergence_type": "scaffold_mismatch", + "baseline_ref": "git://SocioProphet/gitea-sovereign@5d85ab6a24502f60f15ef829235b6288a289d47e", + "observed_ref": "git://SocioProphet/gitea-sovereign@deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + "resolution_status": "escalated" + }, + "evidence_refs": [ + "ev://agentplane/divergence-receipt/scib_diverge_20260611_001" + ], + "runtime_ready": false, + "actor_ref": "actor://agent/governed-runner-003" +} diff --git a/tests/fixtures/source-control-intent/reject_admitted-missing-admission-ref.json b/tests/fixtures/source-control-intent/reject_admitted-missing-admission-ref.json new file mode 100644 index 0000000..1be716c --- /dev/null +++ b/tests/fixtures/source-control-intent/reject_admitted-missing-admission-ref.json @@ -0,0 +1,14 @@ +{ + "_reject_reason": "intent_status=admitted but agentplane_admission_ref is empty — conditional requires non-empty admission ref for admitted status", + "kind": "SourceControlIntentBridgeArtifact", + "artifact_id": "scib_reject_admitted_no_ref_001", + "captured_at": "2026-06-11T13:00:00Z", + "scaffold_baseline": "5d85ab6a24502f60f15ef829235b6288a289d47e", + "service_id": "svc.substrate.source-control", + "operation": "pr_open", + "intent_status": "admitted", + "agentplane_admission_ref": "", + "policy_decision": "allow", + "replay_eligible": true, + "runtime_ready": false +} diff --git a/tools/validate_source_control_intent_bridge.py b/tools/validate_source_control_intent_bridge.py new file mode 100644 index 0000000..7874373 --- /dev/null +++ b/tools/validate_source_control_intent_bridge.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +"""Validate SourceControlIntentBridgeArtifact fixtures. + +Validates fixtures against source-control-intent-bridge.schema.v0.1.json. +Enforces: +- AgentPlane admission ref is non-empty for admitted/replayed status +- runtime_ready must be false (scaffold baseline != runtime readiness) +""" +from __future__ import annotations + +import json +import sys +from pathlib import Path + +try: + import jsonschema +except ImportError: + print("ERROR: jsonschema not installed", file=sys.stderr) + sys.exit(1) + +ROOT = Path(__file__).resolve().parent.parent +SCHEMA_PATH = ROOT / "schemas" / "source-control-intent-bridge.schema.v0.1.json" +FIXTURES = ROOT / "tests" / "fixtures" / "source-control-intent" + +SCHEMA = json.loads(SCHEMA_PATH.read_text()) + +errors: list[str] = [] +results: list[bool] = [] + + +def ok(label: str) -> None: + print(f"PASS {label}") + results.append(True) + + +def fail(label: str, reason: str) -> None: + errors.append(f"FAIL {label}: {reason}") + results.append(False) + + +for path in sorted(FIXTURES.glob("*.json")): + is_reject = path.name.startswith("reject_") + label = path.name + + try: + data = json.loads(path.read_text()) + except json.JSONDecodeError as e: + fail(f"json-parse {label}", str(e)) + continue + + ok(f"json-parse {label}") + + v = jsonschema.Draft202012Validator(SCHEMA) + schema_errs = list(v.iter_errors(data)) + + # Extra gate: runtime_ready must be false + runtime_err = None + if data.get("runtime_ready") is True: + runtime_err = "runtime_ready must be false — scaffold baseline does not imply runtime readiness" + + has_errors = bool(schema_errs) or bool(runtime_err) + + if is_reject: + if has_errors: + ok(f"reject-expected {label}") + else: + fail(f"reject-fixture {label}", "expected failure but fixture appears valid") + else: + if schema_errs: + for e in schema_errs: + fail(f"schema {label}", e.message) + elif runtime_err: + fail(f"runtime-ready-gate {label}", runtime_err) + else: + ok(f"schema {label}") + +passed = sum(results) +if errors: + print(file=sys.stderr) + for e in errors: + print(e, file=sys.stderr) + print(f"\n{passed} passed, {len(errors)} failed", file=sys.stderr) + sys.exit(1) + +print(f"\n{passed} source-control-intent-bridge checks passed")