diff --git a/.claude.json b/.claude.json index 6e81048ff..0c4eebd4a 100644 --- a/.claude.json +++ b/.claude.json @@ -9,7 +9,7 @@ "provenance": { "generator": "scripts/build-cognitive-manifest.py", "repository": "Aegis-Omega/AEGIS-OMEGA", - "source_ref": "fix/claude-artifact-discovery-v1", + "source_ref": "feat/company-brain-v1", "parent_state_hash": "e9f0ec153b0b320a1e791092f73209442ec43a982e503203d9c101ec40949cba", "signature_mode": "GITHUB_OIDC_ATTESTATION" }, @@ -494,5 +494,5 @@ "on_success": "broadcast-attested-verified-event-stream" } }, - "state_hash": "37a6aed7eb08ac8fd74f4363ca362f969e67734f20d11bab7dede0622b0fe270" + "state_hash": "a68c249b1c9fb9cc83ae65ba5cd9afe2b09d688df5a169e60fb2162a100946da" } diff --git a/.github/workflows/company-brain-v1.yml b/.github/workflows/company-brain-v1.yml new file mode 100644 index 000000000..bd04b242a --- /dev/null +++ b/.github/workflows/company-brain-v1.yml @@ -0,0 +1,50 @@ +name: Company Brain v1 + +on: + pull_request: + paths: + - "harness/sdk/company_brain.py" + - "harness/sdk/metacognitive_executive.py" + - "harness/sdk/proof_trace.py" + - "sovereign-omega-v2/python/tests/test_company_brain.py" + - ".github/workflows/company-brain-v1.yml" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: company-brain-v1-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + PYTHONPATH: ${{ github.workspace }} + +jobs: + company-brain: + name: aegis / company-brain-v1 + runs-on: ubuntu-24.04 + timeout-minutes: 12 + steps: + - name: Checkout exact candidate + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 + with: + python-version: "3.12" + + - name: Install exact test dependency + run: python -m pip install --disable-pip-version-check pytest==8.4.1 + + - name: Compile company brain contract + run: python -m py_compile harness/sdk/company_brain.py sovereign-omega-v2/python/tests/test_company_brain.py + + - name: Run company brain falsifiers + run: pytest -q sovereign-omega-v2/python/tests/test_company_brain.py + + - name: Re-run metacognitive executive falsifiers + run: pytest -q sovereign-omega-v2/python/tests/test_metacognitive_executive.py + + - name: Re-run proof trace falsifiers + run: pytest -q sovereign-omega-v2/python/tests/test_proof_trace_sdk.py diff --git a/harness/sdk/company_brain.py b/harness/sdk/company_brain.py new file mode 100644 index 000000000..70a209ceb --- /dev/null +++ b/harness/sdk/company_brain.py @@ -0,0 +1,238 @@ +"""AEGIS Company Brain v1. + +Policy-bound front door from an operator/company objective into the existing +MetacognitiveExecutive. This module is deliberately not a scheduler and not an +authority root. It narrows company policy into one GoalEnvelope, executes the +existing bounded executive, and emits an evidence-only receipt. + +Raw objective text is never copied into the receipt; only a domain-separated +digest crosses the execution/evidence boundary. +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Literal + +from harness.sdk.metacognitive_executive import ( + GoalEnvelopeV1, + MetacognitiveExecutive, + MetacognitiveExecutiveOutcomeV1, +) +from harness.sdk.sovereign_execution import canonical_hash + +CONSEQUENCE_ORDER = {"D0": 0, "D1": 1, "D2": 2, "D3": 3, "D4": 4} + + +class CompanyBrainError(ValueError): + """Fail-closed Company Brain error with stable machine-readable code.""" + + def __init__(self, code: str): + super().__init__(code) + self.code = code + + +@dataclass(frozen=True) +class CompanyPolicyV1: + policy_id: str + policy_commitment: str + allowed_capabilities: tuple[str, ...] + allowed_providers: tuple[str, ...] + allowed_tools: tuple[str, ...] + max_cost_microunits: int + max_tokens: int + max_steps: int + consequence_ceiling: str + + +@dataclass(frozen=True) +class CompanyGoalRequestV1: + goal_id: str + objective: str + source_commit: str + authority_epoch: int + pre_state_root: str + requested_capabilities: tuple[str, ...] + requested_providers: tuple[str, ...] + requested_tools: tuple[str, ...] + max_cost_microunits: int + max_tokens: int + max_steps: int + consequence_ceiling: str + deterministic_nonce: str + + +@dataclass(frozen=True) +class CompanyBrainReceiptV1: + receipt_kind: Literal["COMPANY_BRAIN_RUN_RECEIPT_V1"] + goal_id: str + objective_digest: str + policy_commitment: str + status: Literal["DONE", "WAITING_OPERATOR", "HALTED"] + executive_status: Literal["COMPLETE", "ESCALATE", "HALT"] + operator_attention_required: bool + total_cost_microunits: int + total_tokens: int + autonomy_mode: str + executive_receipt_digest: str + trace_bundle_root: str + authority: Literal["EVIDENCE_ONLY"] + receipt_digest: str + + +@dataclass(frozen=True) +class CompanyBrainOutcomeV1: + receipt: CompanyBrainReceiptV1 + executive_outcome: MetacognitiveExecutiveOutcomeV1 + + +class CompanyBrain: + """Narrow company policy into a bounded metacognitive execution. + + The Company Brain may only contract the operator-provided policy envelope. + It cannot add providers, tools, capabilities, budget, steps or consequence + authority. D4 is structurally unavailable. + """ + + def __init__(self, policy: CompanyPolicyV1, executive: MetacognitiveExecutive) -> None: + self._validate_policy(policy) + self._policy = policy + self._executive = executive + + @property + def policy(self) -> CompanyPolicyV1: + return self._policy + + def run(self, request: CompanyGoalRequestV1) -> CompanyBrainOutcomeV1: + self._validate_request(request) + + objective_digest = canonical_hash( + "AEGIS_COMPANY_OBJECTIVE_V1", + {"goal_id": request.goal_id, "objective": request.objective}, + ) + + goal = GoalEnvelopeV1( + goal_id=request.goal_id, + objective_digest=objective_digest, + source_commit=request.source_commit, + policy_commitment=self._policy.policy_commitment, + authority_epoch=request.authority_epoch, + pre_state_root=request.pre_state_root, + allowed_capabilities=request.requested_capabilities, + allowed_providers=request.requested_providers, + allowed_tools=request.requested_tools, + max_cost_microunits=request.max_cost_microunits, + max_tokens=request.max_tokens, + max_steps=request.max_steps, + consequence_ceiling=request.consequence_ceiling, + deterministic_nonce=request.deterministic_nonce, + ) + + executive_outcome = self._executive.run(goal) + executive_receipt = executive_outcome.receipt + + if executive_receipt.status == "COMPLETE": + status = "DONE" + operator_attention_required = False + elif executive_receipt.status == "ESCALATE": + status = "WAITING_OPERATOR" + operator_attention_required = True + else: + status = "HALTED" + operator_attention_required = False + + body = { + "receipt_kind": "COMPANY_BRAIN_RUN_RECEIPT_V1", + "goal_id": request.goal_id, + "objective_digest": objective_digest, + "policy_commitment": self._policy.policy_commitment, + "status": status, + "executive_status": executive_receipt.status, + "operator_attention_required": operator_attention_required, + "total_cost_microunits": executive_receipt.total_cost_microunits, + "total_tokens": executive_receipt.total_tokens, + "autonomy_mode": executive_receipt.autonomy_mode, + "executive_receipt_digest": executive_receipt.receipt_digest, + "trace_bundle_root": executive_receipt.trace_bundle_root, + "authority": "EVIDENCE_ONLY", + } + receipt_digest = canonical_hash("AEGIS_COMPANY_BRAIN_RUN_RECEIPT_V1", body) + + receipt = CompanyBrainReceiptV1( + receipt_kind="COMPANY_BRAIN_RUN_RECEIPT_V1", + goal_id=request.goal_id, + objective_digest=objective_digest, + policy_commitment=self._policy.policy_commitment, + status=status, # type: ignore[arg-type] + executive_status=executive_receipt.status, + operator_attention_required=operator_attention_required, + total_cost_microunits=executive_receipt.total_cost_microunits, + total_tokens=executive_receipt.total_tokens, + autonomy_mode=executive_receipt.autonomy_mode, + executive_receipt_digest=executive_receipt.receipt_digest, + trace_bundle_root=executive_receipt.trace_bundle_root, + authority="EVIDENCE_ONLY", + receipt_digest=receipt_digest, + ) + return CompanyBrainOutcomeV1(receipt=receipt, executive_outcome=executive_outcome) + + @staticmethod + def _validate_policy(policy: CompanyPolicyV1) -> None: + if not policy.policy_id: + raise CompanyBrainError("POLICY_ID_REQUIRED") + if policy.consequence_ceiling not in CONSEQUENCE_ORDER: + raise CompanyBrainError("POLICY_CONSEQUENCE_CEILING_UNSUPPORTED") + if policy.consequence_ceiling == "D4": + raise CompanyBrainError("POLICY_D4_FORBIDDEN") + if not policy.allowed_capabilities: + raise CompanyBrainError("POLICY_CAPABILITIES_EMPTY") + if not policy.allowed_providers: + raise CompanyBrainError("POLICY_PROVIDERS_EMPTY") + if not policy.allowed_tools: + raise CompanyBrainError("POLICY_TOOLS_EMPTY") + for name, values in ( + ("POLICY_CAPABILITIES_DUPLICATE", policy.allowed_capabilities), + ("POLICY_PROVIDERS_DUPLICATE", policy.allowed_providers), + ("POLICY_TOOLS_DUPLICATE", policy.allowed_tools), + ): + if len(set(values)) != len(values): + raise CompanyBrainError(name) + if isinstance(policy.max_cost_microunits, bool) or policy.max_cost_microunits < 0: + raise CompanyBrainError("POLICY_COST_BUDGET_INVALID") + if isinstance(policy.max_tokens, bool) or policy.max_tokens < 0: + raise CompanyBrainError("POLICY_TOKEN_BUDGET_INVALID") + if isinstance(policy.max_steps, bool) or policy.max_steps < 1: + raise CompanyBrainError("POLICY_STEP_BUDGET_INVALID") + + def _validate_request(self, request: CompanyGoalRequestV1) -> None: + if not request.goal_id: + raise CompanyBrainError("GOAL_ID_REQUIRED") + if not isinstance(request.objective, str) or not request.objective.strip(): + raise CompanyBrainError("OBJECTIVE_REQUIRED") + if not request.requested_capabilities: + raise CompanyBrainError("REQUEST_CAPABILITIES_EMPTY") + if not request.requested_providers: + raise CompanyBrainError("REQUEST_PROVIDERS_EMPTY") + if not request.requested_tools: + raise CompanyBrainError("REQUEST_TOOLS_EMPTY") + + if any(value not in self._policy.allowed_capabilities for value in request.requested_capabilities): + raise CompanyBrainError("REQUEST_CAPABILITY_NOT_ALLOWED") + if any(value not in self._policy.allowed_providers for value in request.requested_providers): + raise CompanyBrainError("REQUEST_PROVIDER_NOT_ALLOWED") + if any(value not in self._policy.allowed_tools for value in request.requested_tools): + raise CompanyBrainError("REQUEST_TOOL_NOT_ALLOWED") + + if request.max_cost_microunits > self._policy.max_cost_microunits: + raise CompanyBrainError("REQUEST_COST_BUDGET_EXCEEDED") + if request.max_tokens > self._policy.max_tokens: + raise CompanyBrainError("REQUEST_TOKEN_BUDGET_EXCEEDED") + if request.max_steps > self._policy.max_steps: + raise CompanyBrainError("REQUEST_STEP_BUDGET_EXCEEDED") + + if request.consequence_ceiling not in CONSEQUENCE_ORDER: + raise CompanyBrainError("REQUEST_CONSEQUENCE_CEILING_UNSUPPORTED") + if request.consequence_ceiling == "D4" or ( + CONSEQUENCE_ORDER[request.consequence_ceiling] + > CONSEQUENCE_ORDER[self._policy.consequence_ceiling] + ): + raise CompanyBrainError("REQUEST_CONSEQUENCE_CEILING_EXCEEDED") diff --git a/sovereign-omega-v2/python/tests/test_company_brain.py b/sovereign-omega-v2/python/tests/test_company_brain.py new file mode 100644 index 000000000..0d1f154fa --- /dev/null +++ b/sovereign-omega-v2/python/tests/test_company_brain.py @@ -0,0 +1,223 @@ +from __future__ import annotations + +from dataclasses import asdict + +import pytest + +from harness.sdk.company_brain import ( + CompanyBrain, + CompanyBrainError, + CompanyGoalRequestV1, + CompanyPolicyV1, +) +from harness.sdk.metacognitive_executive import ( + AuthorizationResultV1, + MetacognitiveExecutive, + MetacognitiveExecutiveError, + PlanStepV1, + PlanV1, + VerifiedStepObservationV1, + WorkerResultV1, +) + +COMMIT = "a" * 40 +POLICY = "b" * 64 +STATE = "c" * 64 +TARGET = "d" * 64 +TRANSITION = "1" * 64 +DECISION_RECEIPT = "2" * 64 +OUTPUT = "3" * 64 +EVIDENCE = "4" * 64 +VERIFIER_RECEIPT = "5" * 64 + + +def policy(**overrides): + base = dict( + policy_id="company-policy-v1", + policy_commitment=POLICY, + allowed_capabilities=("research", "code"), + allowed_providers=("openai", "anthropic"), + allowed_tools=("web", "repo"), + max_cost_microunits=10_000, + max_tokens=50_000, + max_steps=8, + consequence_ceiling="D3", + ) + base.update(overrides) + return CompanyPolicyV1(**base) + + +def request(**overrides): + base = dict( + goal_id="company-goal-1", + objective="Find and verify the highest-value funding opportunity for AEGIS.", + source_commit=COMMIT, + authority_epoch=7, + pre_state_root=STATE, + requested_capabilities=("research",), + requested_providers=("openai",), + requested_tools=("web",), + max_cost_microunits=1_000, + max_tokens=5_000, + max_steps=2, + consequence_ceiling="D2", + deterministic_nonce="company-goal-1-run-1", + ) + base.update(overrides) + return CompanyGoalRequestV1(**base) + + +def make_executive(*, authorization_outcome="PERMIT", planner_provider="openai", calls=None): + calls = calls if calls is not None else {} + calls.setdefault("planner", 0) + calls.setdefault("worker", 0) + + def planner(goal): + calls["planner"] += 1 + return PlanV1( + goal_id=goal.goal_id, + steps=( + PlanStepV1( + step_id="s1", + objective_digest=goal.objective_digest, + dependency_ids=(), + capability_id="research", + provider=planner_provider, + tool="web", + max_cost_microunits=100, + max_tokens=500, + consequence_class="D1", + target_digest=TARGET, + ), + ), + ) + + def authorizer(step): + return AuthorizationResultV1( + step_id=step.step_id, + outcome=authorization_outcome, + transition_id=TRANSITION, + decision_receipt_root=DECISION_RECEIPT, + authority_basis="POLICY", + ) + + def worker(step, _authorization): + calls["worker"] += 1 + return WorkerResultV1( + step_id=step.step_id, + status="SUCCEEDED", + output_digest=OUTPUT, + actual_cost_microunits=50, + actual_tokens=250, + evidence_roots=(EVIDENCE,), + ) + + def verifier(step, result): + return VerifiedStepObservationV1( + step_id=step.step_id, + worker_output_digest=result.output_digest, + verdict="PASS", + evidence_roots=result.evidence_roots, + verifier_receipt_root=VERIFIER_RECEIPT, + ) + + return MetacognitiveExecutive( + planner=planner, + predictor=lambda _goal, _step, _state: 9000, + authorizer=authorizer, + worker=worker, + verifier=verifier, + ) + + +def test_company_policy_is_a_hard_upper_bound_not_a_model_suggestion(): + brain = CompanyBrain(policy(), make_executive()) + + cases = [ + (request(requested_capabilities=("deploy",)), "REQUEST_CAPABILITY_NOT_ALLOWED"), + (request(requested_providers=("gemini",)), "REQUEST_PROVIDER_NOT_ALLOWED"), + (request(requested_tools=("shell",)), "REQUEST_TOOL_NOT_ALLOWED"), + (request(max_cost_microunits=10_001), "REQUEST_COST_BUDGET_EXCEEDED"), + (request(max_tokens=50_001), "REQUEST_TOKEN_BUDGET_EXCEEDED"), + (request(max_steps=9), "REQUEST_STEP_BUDGET_EXCEEDED"), + (request(consequence_ceiling="D4"), "REQUEST_CONSEQUENCE_CEILING_EXCEEDED"), + ] + + for current_request, code in cases: + with pytest.raises(CompanyBrainError) as exc: + brain.run(current_request) + assert exc.value.code == code + + +def test_company_policy_cannot_enable_d4_even_when_configured_that_way(): + with pytest.raises(CompanyBrainError) as exc: + CompanyBrain(policy(consequence_ceiling="D4"), make_executive()) + assert exc.value.code == "POLICY_D4_FORBIDDEN" + + +def test_successful_company_goal_runs_metacognitive_loop_and_emits_evidence_only_receipt(): + brain = CompanyBrain(policy(), make_executive()) + + outcome = brain.run(request()) + + assert outcome.receipt.status == "DONE" + assert outcome.receipt.authority == "EVIDENCE_ONLY" + assert outcome.receipt.executive_status == "COMPLETE" + assert outcome.receipt.trace_bundle_root == outcome.executive_outcome.trace_bundle.root + assert outcome.executive_outcome.trace_bundle.final_control_state_root == STATE + assert outcome.receipt.total_cost_microunits == 50 + assert outcome.receipt.total_tokens == 250 + + rendered = repr(asdict(outcome.receipt)) + assert request().objective not in rendered + + +def test_deferred_authorization_never_calls_worker_and_routes_to_operator_attention(): + calls = {} + brain = CompanyBrain(policy(), make_executive(authorization_outcome="DEFER", calls=calls)) + + outcome = brain.run(request()) + + assert calls["worker"] == 0 + assert outcome.receipt.status == "WAITING_OPERATOR" + assert outcome.receipt.executive_status == "ESCALATE" + assert outcome.receipt.operator_attention_required is True + + +def test_denied_authorization_halts_without_calling_worker(): + calls = {} + brain = CompanyBrain(policy(), make_executive(authorization_outcome="DENY", calls=calls)) + + outcome = brain.run(request()) + + assert calls["worker"] == 0 + assert outcome.receipt.status == "HALTED" + assert outcome.receipt.executive_status == "HALT" + assert outcome.receipt.operator_attention_required is False + + +def test_provider_planner_cannot_escape_company_request_bounds(): + brain = CompanyBrain(policy(), make_executive(planner_provider="anthropic")) + + with pytest.raises(MetacognitiveExecutiveError) as exc: + brain.run(request(requested_providers=("openai",))) + assert exc.value.code == "PLAN_PROVIDER_NOT_ALLOWED" + + +def test_same_bound_company_run_replays_to_same_receipt_and_trace_root(): + first = CompanyBrain(policy(), make_executive()).run(request()) + second = CompanyBrain(policy(), make_executive()).run(request()) + + assert first.receipt.receipt_digest == second.receipt.receipt_digest + assert first.receipt.trace_bundle_root == second.receipt.trace_bundle_root + + +def test_objective_text_is_digest_bound_but_not_copied_into_receipt(): + brain = CompanyBrain(policy(), make_executive()) + + first = brain.run(request(objective="Research funding option A.")) + second = brain.run(request(objective="Research funding option B.")) + + assert first.receipt.objective_digest != second.receipt.objective_digest + assert "Research funding option A." not in repr(asdict(first.receipt)) + assert "Research funding option B." not in repr(asdict(second.receipt))