Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
doofus/dumbmoney/interop_fixtures/*.json text eol=lf
200 changes: 200 additions & 0 deletions doofus/dumbmoney/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
"""DumbMoney proof-carrying research plane.

This package produces candidate evidence. It deliberately exposes no broker,
credential, financial-signature, order, transfer, or capital-authority API.
"""
from .assurance import assurance_rank, required_assurance
from .authority import (
ResearchAuthorityDenied,
assert_research_capabilities,
capability_manifest,
)
from .budget import (
CATEGORY_LIMITS_MICROUSD,
DAILY_LIMIT_MICROUSD,
BudgetExceeded,
DailyExternalBudget,
ExternalBudgetLeaseV1,
)
from .canonical import (
CanonicalModel,
CanonicalizationError,
canonical_json,
canonical_json_bytes,
content_hash,
)
from .contracts import (
AlphaPassportV1,
AssuranceLevel,
ConsequenceProfileV1,
CourtFindingV1,
EvidenceVerdictV1,
MetricObservationV1,
ResearchMandateV1,
TrialReceiptV1,
TrialStatus,
)
from .courts import (
AdversarialOperationsCourt,
AdversarialOperationsEvidenceV1,
CourtContext,
EconomicEvidenceV1,
EconomicsCourt,
EvidenceCourt,
EvidenceCourtSuite,
IntegrityCourt,
StatisticalEvidenceV1,
StatisticsCourt,
)
from .fixtures import (
alpha_passport_fixture,
evidence_verdict_fixture,
export_interoperability_fixtures,
fund_interop_fixture_bundle,
interoperability_fixture_bundle,
)
from .fund_interop import (
FundAlphaPassportV1,
FundEvidenceClass,
FundEvidenceDecision,
FundEvidenceVerdictV1,
FundInteropBundleV1,
FundVenue,
export_fund_interop,
export_fund_interop_files,
fund_digest,
raw_digest,
)
from .lineage import (
ArchiveDimensionV1,
CandidateRecordV1,
LineageArchive,
QualityDiversityArchive,
)
from .loop import (
AutonomousResearchLoop,
BudgetedModelGateway,
CandidateGovernanceV1,
CandidateProposalV1,
ObservationRequestV1,
ObservationSource,
ProposalRequestV1,
ResearchCycleJournal,
ResearchCycleRequestV1,
ResearchCycleResultV1,
ResearchObservationV1,
SealedTrialRunner,
TrialExecutionV1,
TrialRunRequestV1,
)
from .mutation_subprocess import MutationSubprocessResult, run_mutation_subprocess
from .model_spool import (
FileSpoolModelGateway,
ModelSpoolAmbiguousError,
ModelSpoolBoundArtifactV1,
ModelSpoolConflictError,
ModelSpoolContextArtifactV1,
ModelSpoolError,
ModelSpoolIntegrityError,
ModelSpoolOutcomeV1,
ModelSpoolParentContextV1,
ModelSpoolProtocolError,
ModelSpoolRejectedError,
ModelSpoolRequestV1,
ModelSpoolResponseV1,
ModelSpoolTimeoutError,
publish_research_artifact,
)
from .proof_credit import ProofCreditLedger, ProofCreditWalletV1
from .registry import IncompleteDisclosureError, TrialRegistry

__all__ = [
"AdversarialOperationsCourt",
"AdversarialOperationsEvidenceV1",
"AlphaPassportV1",
"ArchiveDimensionV1",
"AssuranceLevel",
"AutonomousResearchLoop",
"BudgetExceeded",
"CATEGORY_LIMITS_MICROUSD",
"CanonicalModel",
"CanonicalizationError",
"CandidateRecordV1",
"CandidateGovernanceV1",
"CandidateProposalV1",
"ConsequenceProfileV1",
"CourtContext",
"CourtFindingV1",
"DAILY_LIMIT_MICROUSD",
"DailyExternalBudget",
"EconomicEvidenceV1",
"EconomicsCourt",
"EvidenceCourt",
"EvidenceCourtSuite",
"EvidenceVerdictV1",
"ExternalBudgetLeaseV1",
"FundAlphaPassportV1",
"FundEvidenceClass",
"FundEvidenceDecision",
"FundEvidenceVerdictV1",
"FundInteropBundleV1",
"FundVenue",
"FileSpoolModelGateway",
"IncompleteDisclosureError",
"IntegrityCourt",
"LineageArchive",
"MetricObservationV1",
"ModelSpoolAmbiguousError",
"ModelSpoolBoundArtifactV1",
"ModelSpoolConflictError",
"ModelSpoolContextArtifactV1",
"ModelSpoolError",
"ModelSpoolIntegrityError",
"ModelSpoolOutcomeV1",
"ModelSpoolParentContextV1",
"ModelSpoolProtocolError",
"ModelSpoolRejectedError",
"ModelSpoolRequestV1",
"ModelSpoolResponseV1",
"ModelSpoolTimeoutError",
"MutationSubprocessResult",
"ObservationRequestV1",
"ObservationSource",
"ProofCreditLedger",
"ProofCreditWalletV1",
"ProposalRequestV1",
"QualityDiversityArchive",
"ResearchAuthorityDenied",
"ResearchCycleJournal",
"ResearchCycleRequestV1",
"ResearchCycleResultV1",
"ResearchMandateV1",
"ResearchObservationV1",
"BudgetedModelGateway",
"SealedTrialRunner",
"StatisticalEvidenceV1",
"StatisticsCourt",
"TrialReceiptV1",
"TrialExecutionV1",
"TrialRunRequestV1",
"TrialRegistry",
"TrialStatus",
"alpha_passport_fixture",
"assert_research_capabilities",
"assurance_rank",
"canonical_json",
"canonical_json_bytes",
"capability_manifest",
"content_hash",
"evidence_verdict_fixture",
"export_interoperability_fixtures",
"export_fund_interop",
"export_fund_interop_files",
"fund_digest",
"fund_interop_fixture_bundle",
"interoperability_fixture_bundle",
"required_assurance",
"raw_digest",
"run_mutation_subprocess",
"publish_research_artifact",
]
44 changes: 44 additions & 0 deletions doofus/dumbmoney/assurance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Consequence-proportional assurance policy for research candidates."""
from __future__ import annotations

from .contracts import AssuranceLevel, ConsequenceProfileV1

ASSURANCE_ORDER = (
AssuranceLevel.IDEA,
AssuranceLevel.REPLAY,
AssuranceLevel.SHADOW,
AssuranceLevel.EXPLORATORY_LIVE,
AssuranceLevel.SCALED_LIVE,
)


def assurance_rank(level: AssuranceLevel) -> int:
return ASSURANCE_ORDER.index(level)


def minimum_assurance(
left: AssuranceLevel,
right: AssuranceLevel,
) -> AssuranceLevel:
return left if assurance_rank(left) <= assurance_rank(right) else right


def required_assurance(profile: ConsequenceProfileV1) -> AssuranceLevel:
"""Map possible consequence to evidence strength without granting authority."""

loss = profile.maximum_external_loss_cents
if profile.irreversible_change or loss > 100_000:
return AssuranceLevel.SCALED_LIVE
if profile.live_execution_relevance:
return (
AssuranceLevel.EXPLORATORY_LIVE
if loss <= 25_000
else AssuranceLevel.SCALED_LIVE
)
if profile.external_side_effects:
return AssuranceLevel.SHADOW if loss <= 25_000 else AssuranceLevel.EXPLORATORY_LIVE
if loss == 0:
return AssuranceLevel.IDEA
if loss <= 2_500:
return AssuranceLevel.REPLAY
return AssuranceLevel.SHADOW
82 changes: 82 additions & 0 deletions doofus/dumbmoney/authority.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""Structural capability boundary for the Doofus DumbMoney slice."""
from __future__ import annotations

from typing import Iterable, Literal

from .canonical import CanonicalModel

ResearchCapability = Literal[
"artifact_read",
"artifact_write",
"budgeted_model_gateway",
"public_data_read",
"sandbox_compute",
]

ALLOWED_RESEARCH_CAPABILITIES: frozenset[str] = frozenset(
{
"artifact_read",
"artifact_write",
"budgeted_model_gateway",
"public_data_read",
"sandbox_compute",
}
)

FORBIDDEN_TERMS: tuple[str, ...] = (
"broker",
"credential",
"api_key",
"apikey",
"token",
"oauth",
"cookie",
"password",
"secret",
"robinhood",
"kalshi",
"order_submit",
"order_cancel",
"capital",
"signing",
"withdraw",
"transfer",
)


class ResearchAuthorityDenied(PermissionError):
pass


class ResearchCapabilityManifestV1(CanonicalModel):
schema_id: Literal["dumbmoney.research_capability_manifest.v1"] = (
"dumbmoney.research_capability_manifest.v1"
)
allowed: tuple[ResearchCapability, ...]
broker_authority: Literal["none"] = "none"
credential_access: Literal["none"] = "none"
capital_signing_authority: Literal["none"] = "none"
proof_credits_redeemable: Literal[False] = False


def assert_research_capabilities(requested: Iterable[str]) -> tuple[ResearchCapability, ...]:
normalized = tuple(sorted(set(requested)))
denied = [
capability
for capability in normalized
if capability not in ALLOWED_RESEARCH_CAPABILITIES
or any(term in capability.lower() for term in FORBIDDEN_TERMS)
]
if denied:
raise ResearchAuthorityDenied(f"research plane denies capabilities: {','.join(denied)}")
return normalized # type: ignore[return-value]


def capability_manifest() -> ResearchCapabilityManifestV1:
allowed = assert_research_capabilities(ALLOWED_RESEARCH_CAPABILITIES)
return ResearchCapabilityManifestV1(allowed=allowed)


def is_sensitive_environment_key(key: str) -> bool:
upper = key.upper()
return any(term.upper() in upper for term in FORBIDDEN_TERMS)
Loading