From b0999951f8cbecbfddd99f151fccb31cd78d5bf2 Mon Sep 17 00:00:00 2001 From: Giovanni Giovanni Date: Sat, 18 Jul 2026 22:17:08 -0400 Subject: [PATCH] chore(residue): eradicate afi-core's aspirational DAG-integration surface (Mission R follow-up) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A second DAG-model surface the initial sweep missed: afi-core's unimplemented "AFI DAG integration" scaffolding for the deleted DAG-orchestrator model. All removed symbols have zero importers; scoring/UWR/decay byte-invariant. Removed (0 importers; not on the scored path): - runtime/afiRuntimeAdapter.ts + runtime/types.ts (unimplemented "bridge to AFI-Reactor DAG orchestration / ElizaOS" scaffolding, status "planned") + the ./runtime/* package export - src/analyst/AnalystScoreTemplate.ts: the AFIDAGConfig / AnalystScoreTemplateWithAFIDAG / isAFIDAGConfig block (DAG-node execution model: "enrichmentNodes to execute") and its AFIDAG-only test file (base AnalystScoreTemplate + Zod schema retained) - docs/AFI_CORE_RUNTIME_OVERVIEW.md (documented the deleted DAG-bridge model) - .afi-codex ("bridging AFI-Reactor DAG plans"), afi-core-verify.sh (checked a nonexistent dist/dags/ scaffold) Consolidated (current-facing docs → manifest-driven pipeline terms): - AGENTS.md, droids/00 + droids/20, .factory/droids/schema-validator-droid.md, .factory/skills/extend-signal-schema/SKILL.md: DAG wiring/nodes/"10 Commandments Orchestrator Doctrine"/dag-builder/add-dag-node -> pipeline composition via the governed registries/manifests (per the live Droid Charter); dropped a dead afi-research-site reference and stale .afi-codex.json pointers Proof: tsc --noEmit clean; vitest 213 pass / 0 fail incl. computeUwrScore + applyTimeDecay KATs (scoring byte-invariant). Co-Authored-By: Claude Opus 4.8 (1M context) --- .afi-codex | 15 - .factory/droids/schema-validator-droid.md | 8 +- .factory/skills/extend-signal-schema/SKILL.md | 8 +- AGENTS.md | 3 +- afi-core-verify.sh | 41 --- docs/AFI_CORE_RUNTIME_OVERVIEW.md | 220 ------------- droids/00_repo_orientation.md | 8 +- droids/20_safe_patch_patterns.md | 2 +- package.json | 4 - runtime/afiRuntimeAdapter.ts | 242 -------------- runtime/types.ts | 114 ------- src/analyst/AnalystScoreTemplate.ts | 106 ------ .../__tests__/AnalystScoreTemplate.test.ts | 305 ------------------ 13 files changed, 14 insertions(+), 1062 deletions(-) delete mode 100644 .afi-codex delete mode 100755 afi-core-verify.sh delete mode 100644 docs/AFI_CORE_RUNTIME_OVERVIEW.md delete mode 100644 runtime/afiRuntimeAdapter.ts delete mode 100644 runtime/types.ts delete mode 100644 src/analyst/__tests__/AnalystScoreTemplate.test.ts diff --git a/.afi-codex b/.afi-codex deleted file mode 100644 index 2b75c8f..0000000 --- a/.afi-codex +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "afi-core", - "role": "runtime", - "description": "ElizaOS-based runtime layer for AFI, bridging AFI-Reactor DAG plans to agents and mint instructions", - "language": "TypeScript", - "tags": ["validator", "mentor", "runtime", "afi", "typescript", "elizaos", "agents"], - "entry": "runtime/afiRuntimeAdapter.ts", - "dependsOn": ["afi-reactor", "afi-token"], - "factory_ready": true, - "elizaOSIntegration": { - "status": "planned", - "softForkPlanned": true, - "currentPhase": "thin-layer-scaffolding" - } -} diff --git a/.factory/droids/schema-validator-droid.md b/.factory/droids/schema-validator-droid.md index 82975d9..66d0b89 100644 --- a/.factory/droids/schema-validator-droid.md +++ b/.factory/droids/schema-validator-droid.md @@ -46,7 +46,7 @@ This droid is a **schema and validator specialist** for afi-core. It: - `afi-reactor/` — To understand how schemas are consumed (read-only context) **Must NOT touch**: -- `afi-reactor/` — DAG wiring, orchestration logic (that's the orchestrator's job) +- `afi-reactor/` — pipeline composition + orchestration logic (that's the orchestrator's job) - `afi-token/` — Smart contracts, emissions, tokenomics - `afi-gateway/` — Eliza agents, gateway configs, runtime agent behavior - `afi-infra/` — Deployment, infrastructure @@ -86,7 +86,7 @@ The **AFI Droid Charter v0.1** (`afi-config/codex/governance/droids/AFI_DROID_CH ### AFI Core Role (NOT an Orchestrator) -From the AFI Orchestrator Doctrine (10 Commandments): +Per the AFI Droid Charter — afi-reactor is the orchestration/execution layer: - **afi-reactor is the orchestrator of AFI** — afi-core is NOT an orchestrator. - **afi-core is our runtime library, not our boss** — afi-core provides canonical types, schemas, validators, and scoring logic that afi-reactor orchestrates. @@ -161,7 +161,7 @@ If a request asks to add PoI/PoInsight to signals, STOP and escalate. This droid MUST NOT: 1. **Modify orchestration logic**: - - Do NOT edit DAG wiring, pipeline execution, or orchestration code in afi-reactor + - Do NOT edit pipeline composition, pipeline execution, or orchestration code in afi-reactor - Do NOT add orchestration logic to afi-core 2. **Touch token/economics**: @@ -298,7 +298,7 @@ Produce a short summary that includes: ### Do NOT Use This Droid For -- "Wire the new schema into the DAG pipeline." → Use dag-builder-droid in afi-reactor +- "Wire the new schema into the pipeline." → Use the pipeline-composer-droid in afi-reactor - "Add PoInsight as a field on signals." → Violates PoI/PoInsight design (escalate) - "Modify token emissions based on signal scores." → Belongs in afi-token (escalate) - "Update Eliza agent character specs." → Belongs in afi-gateway (escalate) diff --git a/.factory/skills/extend-signal-schema/SKILL.md b/.factory/skills/extend-signal-schema/SKILL.md index 6f02062..a90b47a 100644 --- a/.factory/skills/extend-signal-schema/SKILL.md +++ b/.factory/skills/extend-signal-schema/SKILL.md @@ -216,8 +216,8 @@ error output, and surface it with minimal, clear commentary. When using this skill, you MUST NOT: - **Modify orchestration logic** in afi-reactor: - - Do NOT edit DAG wiring, pipeline execution, or orchestration code. - - Schema changes belong in afi-core; DAG wiring belongs in afi-reactor. + - Do NOT edit pipeline composition, pipeline execution, or orchestration code. + - Schema changes belong in afi-core; pipeline composition belongs in afi-reactor. - **Introduce PoI/PoInsight as signal fields**: - Do NOT add `poi`, `poinsight`, `proof_of_intelligence`, or similar fields. @@ -292,8 +292,8 @@ exactly what changed and why. ### Do NOT Use This Skill For -- "Wire the new schema into the DAG pipeline." - → Use `add-dag-node` skill in afi-reactor instead. +- "Wire the new schema into the pipeline." + → Author the pipeline composition in afi-reactor (governed registries/manifests) instead. - "Add PoInsight as a field on Scored signals." → Violates PoI/PoInsight design (escalate to human). diff --git a/AGENTS.md b/AGENTS.md index a34f781..2ecce85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -81,7 +81,7 @@ npm run mentor-eval **Boundary with afi-reactor**: - `afi-core` = runtime behavior (validators, scoring) -- `afi-reactor` = orchestration (DAG wiring, pipeline execution) +- `afi-reactor` = orchestration (manifest-driven pipeline composition + execution) **Eliza integration**: - `afi-core` defines shared types, client libraries, and helpers used by AFI services and Eliza plugins. @@ -159,7 +159,6 @@ npm run mentor-eval - Small, well-scoped changes to validators, types, runtime glue when requested - Add tests for existing validators - Improve ElizaOS integration with clear spec -- Update `.afi-codex.json` if capabilities change **Forbidden**: - Large-scale refactors without explicit spec diff --git a/afi-core-verify.sh b/afi-core-verify.sh deleted file mode 100755 index 00e82cf..0000000 --- a/afi-core-verify.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -# ============================================================ -# Local maintainer/dev helper script for afi-core. -# NOT part of runtime logic; NOT required for droids or automation. -# Runs simple build artifact checks (dist presence/ESM scan) for local verification. -# ============================================================ -# afi-core-verify.sh -# Verifies AFI-core ESM compliance, DAG/schema/validator coverage, and type declarations - -echo "🔎 Verifying AFI-core structure..." - -# 1. Check main entrypoint -[ -f dist/index.js ] && echo "✅ dist/index.js exists" || echo "❌ dist/index.js missing" - -# 2. Check DAG scaffolding -[ -f dist/dags/index.js ] && echo "✅ DAG index exists" || echo "❌ DAG index missing" -[ -f dist/dags/signalProcessingDAG.js ] && echo "✅ signalProcessingDAG exists" || echo "❌ signalProcessingDAG missing" - -# 3. Check schema coverage -schemas=(pipeline_config_schema.js universal_signal_schema.js signal_finalization_request_schema.js validator_metadata_schema.js validator_governance_schema.js) -for schema in "${schemas[@]}"; do - [ -f "dist/schemas/$schema" ] && echo "✅ Schema $schema exists" || echo "❌ Schema $schema missing" -done - -# 4. Check validator index -[ -f dist/validators/index.js ] && echo "✅ Validator index exists" || echo "❌ Validator index missing" - -# 5. Check type declarations -types=(dist/index.d.ts dist/schemas/index.d.ts dist/validators/index.d.ts) -for typefile in "${types[@]}"; do - [ -f "$typefile" ] && echo "✅ Type declarations $typefile exists" || echo "❌ Type declarations $typefile missing" -done - -# 6. Quick ESM check (grep for CommonJS) -if grep -R "module.exports\|require(" dist/ > /dev/null 2>&1; then - echo "❌ Found CommonJS usage in dist/" -else - echo "✅ ESM-only (no CommonJS found)" -fi - -echo "🎉 Verification complete!" diff --git a/docs/AFI_CORE_RUNTIME_OVERVIEW.md b/docs/AFI_CORE_RUNTIME_OVERVIEW.md deleted file mode 100644 index 3b5aa21..0000000 --- a/docs/AFI_CORE_RUNTIME_OVERVIEW.md +++ /dev/null @@ -1,220 +0,0 @@ -# AFI-Core Runtime Overview - -> **AFI Settlement v1 note:** Parts of this document reference the **v0** per-signal mint / ERC-1155 receipt / direct-beneficiary path, which is **superseded as mainnet architecture** by AFI Settlement v1 — rewards settle **by epoch** through a RewardsVault / Merkle-claim layer funded from an EpochSettlementManifest, strategy/epoch receipts use **ERC-6909** (not ERC-1155), provenance is separated from payout, and ENS names are aliases (concrete addresses + chainId are the source of truth). See `afi-docs/specs/AFI_SETTLEMENT_V1_DOCTRINE.md` for the canonical architecture. - -**Date:** 2025-11-16 -**Purpose:** Define AFI-Core's role as the ElizaOS-based runtime layer in AFI Protocol - ---- - -## Role of AFI-Core - -AFI-Core is the **runtime layer powered by ElizaOS** (or a future soft fork thereof). It sits between: -- **AFI-Reactor** (DAG orchestration and policy) -- **AFI-Token** (on-chain token contracts and minting) - -### Core Responsibilities - -AFI-Core is responsible for: - -1. **Agent Orchestration** - Managing ElizaOS agents, personas, and tools that execute AFI Protocol logic -2. **Signal Validation** - Running Proof-of-Insight (PoI) and Proof-of-Intelligence validators on signals -3. **Runtime Coordination** - Receiving DAG execution plans from Reactor and coordinating agent execution -4. **Mint Instruction Generation** - Producing structured, verifiable mint instructions for the token layer -5. **Mentor Pairing** - Matching signals with appropriate mentor agents for validation - -### What AFI-Core is NOT Responsible For - -AFI-Core does **NOT** handle: - -❌ **Token Contract Definitions** - That's `afi-token` (AFIToken, AFISignalReceipt, AFIMintCoordinator) -❌ **DAG Topology / Policy** - That's `afi-reactor` (15-node DAG, pipeline definitions, orchestration rules) -❌ **Infrastructure / Deployment** - That's `afi-infra` (Kubernetes, Terraform, CI/CD) -❌ **Direct On-Chain Writes** - AFI-Core generates instructions; execution happens via Safe/backend/droid - ---- - -## Relationship to AFI-Reactor - -### Reactor = DAG + Policy Orchestrator - -AFI-Reactor (already hardened) is the **canonical orchestrator** for AFI Protocol. It: -- Defines the 15-node DAG architecture (generators, analyzers, validators, executors, observers) -- Controls pipeline topology and execution order -- Enforces orchestration rules (agents don't call each other directly) -- Routes signals through the DAG based on policy - -### Core = Runtime Executor - -AFI-Core is the **runtime that executes Reactor's plans**. It: -- **Receives** DAG execution plans from Reactor (e.g., "run signal through technical-analysis-node") -- **Spins up** the appropriate ElizaOS agents and tools to execute each DAG step -- **Executes** agent logic (analysis, validation, scoring) according to Reactor's instructions -- **Reports** results back to Reactor, which decides what happens next - -### Interaction Flow - -``` -┌─────────────────┐ -│ AFI-Reactor │ (DAG Orchestrator) -│ - 15-node DAG │ -│ - Pipelines │ -│ - Routing │ -└────────┬────────┘ - │ DAG execution plan - │ (e.g., "analyze signal X with node Y") - ▼ -┌─────────────────┐ -│ AFI-Core │ (ElizaOS Runtime) -│ - Agent pool │ -│ - Validators │ -│ - Tools │ -└────────┬────────┘ - │ Execution result - │ (e.g., "analysis complete, score: 85") - ▼ -┌─────────────────┐ -│ AFI-Reactor │ (Routes to next node) -└─────────────────┘ -``` - -### Key Principle - -**Reactor tells Core WHAT to do and WHEN. Core tells agents HOW to do it.** - -- Reactor controls the DAG topology and orchestration -- Core controls the agent runtime and execution -- Agents are workers that obey both Reactor's routing and Core's runtime - ---- - -## Relationship to AFI-Token Layer - -### Token Layer = On-Chain Contracts - -The `afi-token` repository contains: -- **AFIToken** - ERC20 token with capped supply and minting controls -- **AFISignalReceipt** - On-chain record of validated signals -- **AFIMintCoordinator** - Coordinator for minting AFI tokens based on signals - -### Core's Role in Minting - -AFI-Core **generates mint instructions** but does **NOT** execute them on-chain. - -#### Mint Instruction Flow - -``` -┌─────────────────┐ -│ AFI-Core │ -│ - Validates │ -│ - Scores │ -│ - Generates │ -│ mint instr. │ -└────────┬────────┘ - │ Structured mint instruction - │ (signalId, amount, recipient, proof) - ▼ -┌─────────────────┐ -│ Backend/Safe │ (Off-chain coordinator) -│ - Reviews │ -│ - Approves │ -│ - Executes │ -└────────┬────────┘ - │ On-chain transaction - ▼ -┌─────────────────┐ -│ AFI-Token │ (On-chain contracts) -│ - AFIMint │ -│ Coordinator │ -│ - AFIToken │ -└─────────────────┘ -``` - -### Structured, Verifiable Outputs - -At this stage, AFI-Core focuses on generating **structured, verifiable outputs**: - -- **Mint Instructions** - JSON objects with signal ID, amount, recipient, proof -- **Signal Receipts** - Validated signal metadata for on-chain recording -- **Audit Logs** - Telemetry for T.S.S.D. Vault - -AFI-Core does **NOT**: -- Import web3 libraries (ethers, viem) -- Make RPC calls to Base or Ethereum -- Sign transactions or broadcast to the network -- Directly call AFIMintCoordinator - -**Why?** Separation of concerns: -- Core focuses on **intelligence and validation** -- Token layer focuses on **on-chain execution and security** -- Backend/Safe/droid handles **coordination and approval** - ---- - -## Future Soft Fork of ElizaOS - -### Current State - -AFI-Core is currently a **standalone validator/runtime library** with: -- No ElizaOS integration -- Minimal runtime infrastructure (MentorRegistry) -- Basic validators (PoIValidator) - -### Evolution Path - -AFI-Core will evolve into a **soft fork of ElizaOS** once the thin layer's limits are clear: - -1. **Phase 1 (Current)** - Thin runtime adapter layer - - Stub interfaces for runtime adapter and mint pipeline driver - - Documentation of integration points - - No ElizaOS dependencies yet - -2. **Phase 2 (Near Future)** - ElizaOS integration - - Import ElizaOS as a dependency - - Implement runtime adapter using ElizaOS APIs - - Register AFI agents, tools, and evaluators with ElizaOS - -3. **Phase 3 (Future)** - Soft fork - - Vendor ElizaOS into `afi-core` as a soft fork - - Customize ElizaOS runtime for AFI-specific needs - - Maintain compatibility with upstream ElizaOS where possible - -### Why a Soft Fork? - -AFI Protocol has specific requirements that may diverge from ElizaOS: -- **Deterministic execution** for signal validation and replay -- **DAG-based orchestration** (Reactor controls flow, not ElizaOS) -- **Proof-of-Intelligence** validators and mentor pairing -- **On-chain integration** with AFI-Token contracts - -A soft fork allows AFI to: -- Leverage ElizaOS's agent runtime and tooling -- Customize for AFI-specific needs -- Maintain compatibility with ElizaOS ecosystem -- Control the runtime evolution independently - -### This Repo is the Natural Home - -`afi-core` will be the natural home of the ElizaOS soft fork (or vendored runtime) because: -- It already contains runtime infrastructure (MentorRegistry) -- It already contains validators and schemas -- It sits at the right layer (between Reactor and Token) -- It's designed to be the "runtime layer" from the start - ---- - -## Summary - -| Layer | Repository | Role | -|-------|-----------|------| -| **Orchestration** | `afi-reactor` | DAG topology, pipeline routing, orchestration rules | -| **Runtime** | `afi-core` | ElizaOS agents, validators, mint instruction generation | -| **On-Chain** | `afi-token` | Token contracts, minting, signal receipts | - -**AFI-Core is the bridge** between Reactor's orchestration and Token's on-chain execution. - ---- - -**Last Updated:** 2025-11-16 -**Maintained By:** AFI Protocol Core Team - diff --git a/droids/00_repo_orientation.md b/droids/00_repo_orientation.md index 98d0d42..de470a9 100644 --- a/droids/00_repo_orientation.md +++ b/droids/00_repo_orientation.md @@ -6,7 +6,7 @@ ## What This Repo Does -Core runtime for agent signal validation, ElizaOS integration, and PoI/PoInsight validation. This is where signals get validated before entering the DAG pipeline. +Core runtime for agent signal validation, ElizaOS integration, and PoI/PoInsight validation. This is where signals get validated before entering the scoring pipeline. **Key Capabilities**: - Signal validation (PoI, PoInsight) @@ -26,8 +26,8 @@ Core runtime for agent signal validation, ElizaOS integration, and PoI/PoInsight - ✅ Core schemas **This repo does NOT handle**: -- ❌ DAG orchestration (that's afi-reactor) -- ❌ UI/frontend (that's afi-research-site) +- ❌ Pipeline orchestration (that's afi-reactor) +- ❌ UI/frontend - ❌ Deployment (that's afi-infra) - ❌ Smart contracts (that's afi-token) @@ -88,7 +88,7 @@ See `10_common_tasks.md` for detailed workflows. **Before making changes**: 1. Read `AGENTS.md` for constraints -2. Check `.afi-codex.json` for dependencies +2. Check `package.json` for dependencies 3. Run tests locally 4. Ensure no breaking changes to signal schema diff --git a/droids/20_safe_patch_patterns.md b/droids/20_safe_patch_patterns.md index bcada9b..ef0ba69 100644 --- a/droids/20_safe_patch_patterns.md +++ b/droids/20_safe_patch_patterns.md @@ -173,7 +173,7 @@ const signal = { \`\`\` ### Affected repos -- afi-reactor (update DAG nodes) +- afi-reactor (update pipeline composition) ``` **Why**: Breaking changes need clear migration paths. diff --git a/package.json b/package.json index a223dfe..dd1436a 100644 --- a/package.json +++ b/package.json @@ -50,10 +50,6 @@ "./analysts/*": { "import": "./dist/analysts/*", "types": "./dist/analysts/*" - }, - "./runtime/*": { - "import": "./dist/runtime/*", - "types": "./dist/runtime/*" } }, "scripts": { diff --git a/runtime/afiRuntimeAdapter.ts b/runtime/afiRuntimeAdapter.ts deleted file mode 100644 index 29e6557..0000000 --- a/runtime/afiRuntimeAdapter.ts +++ /dev/null @@ -1,242 +0,0 @@ -/** - * AFI Runtime Adapter - * =================== - * - * This is the **thin runtime layer** that bridges AFI-Reactor's DAG orchestration - * with ElizaOS agents (or a future soft fork thereof). - * - * CURRENT STATUS: Stub interfaces and type definitions only. - * - * FUTURE WORK: Implement the actual runtime logic that: - * - Receives DAG execution plans from AFI-Reactor - * - Spins up appropriate ElizaOS agents and tools - * - Executes agent logic according to Reactor's instructions - * - Reports results back to Reactor for next-step routing - * - * This file will grow as we integrate ElizaOS and eventually evolve into - * a soft fork of ElizaOS customized for AFI Protocol's needs. - * - * @module runtime/afiRuntimeAdapter - * @see docs/AFI_CORE_RUNTIME_OVERVIEW.md - */ - -// ============================================================================ -// Type Definitions -// ============================================================================ - -/** - * Runtime context for AFI agent execution. - * Contains metadata about the current execution environment. - */ -export interface AFIRuntimeContext { - /** Unique identifier for the agent executing this task */ - agentId: string; - - /** Unique identifier for the signal being processed */ - signalId: string; - - /** Unique identifier for this execution run (for replay/audit) */ - runId: string; - - /** Reference to the Reactor DAG node that triggered this execution */ - reactorNodeId?: string; - - /** Pipeline type (e.g., "signal-to-vault", "signal-to-vault-cognition") */ - pipelineType?: string; - - /** Additional metadata from Reactor */ - reactorMetadata?: Record; - - /** Timestamp when this execution started */ - startedAt: Date; -} - -/** - * Raw signal data from AFI-Reactor. - * This is the input to the runtime adapter. - */ -export interface AFISignalInput { - /** Unique signal identifier */ - signalId: string; - - /** Signal source (e.g., "market-data-streamer", "social-signal-crawler") */ - source: string; - - /** Signal timestamp */ - timestamp: string; - - /** Signal payload (structure depends on source) */ - payload: unknown; - - /** Signal metadata */ - meta?: Record; -} - -/** - * DAG step instruction from AFI-Reactor. - * Tells the runtime adapter which node to execute and with what parameters. - */ -export interface AFIDAGStepInstruction { - /** DAG node to execute (e.g., "technical-analysis-node") */ - nodeId: string; - - /** Node category (generator, analyzer, validator, executor, observer) */ - nodeCategory: 'generator' | 'analyzer' | 'validator' | 'executor' | 'observer'; - - /** Input signal or data for this step */ - input: unknown; - - /** Step-specific parameters */ - parameters?: Record; - - /** Execution timeout in milliseconds */ - timeoutMs?: number; -} - -/** - * Result of executing a DAG step. - * Returned to AFI-Reactor for routing to next step. - */ -export interface AFIDAGStepResult { - /** Node that executed this step */ - nodeId: string; - - /** Execution status */ - status: 'success' | 'failure' | 'timeout'; - - /** Output data from this step */ - output?: unknown; - - /** Error message if status is 'failure' */ - error?: string; - - /** Execution duration in milliseconds */ - durationMs: number; - - /** Additional metadata */ - metadata?: Record; -} - -// ============================================================================ -// AFI Runtime Adapter Interface -// ============================================================================ - -/** - * AFI Runtime Adapter - * - * This is the main interface for the AFI runtime layer. - * It bridges AFI-Reactor's DAG orchestration with ElizaOS agents. - * - * IMPLEMENTATION STATUS: Stub only. Future work will implement these methods. - * - * @interface AFIRuntimeAdapter - */ -export interface AFIRuntimeAdapter { - /** - * Initialize the runtime adapter with the given context. - * - * TODO: Implement initialization logic: - * - Load ElizaOS runtime - * - Register AFI agents and tools - * - Connect to T.S.S.D. Vault for telemetry - * - Set up mentor registry - * - * @param context - Runtime context for this execution - */ - initialize(context: AFIRuntimeContext): Promise; - - /** - * Handle a raw signal from AFI-Reactor. - * - * TODO: Implement signal handling logic: - * - Validate signal structure - * - Route to appropriate agent/validator - * - Return validation result - * - * @param signal - Raw signal input - */ - handleSignal(signal: AFISignalInput): Promise; - - /** - * Execute a DAG step instruction from AFI-Reactor. - * - * TODO: Implement DAG step execution: - * - Identify the agent/tool for this node - * - Execute the agent logic - * - Capture output and errors - * - Return result to Reactor - * - * @param step - DAG step instruction - * @returns Result of executing the step - */ - handleDAGStep(step: AFIDAGStepInstruction): Promise; - - /** - * Emit a mint instruction to the mint pipeline driver. - * - * TODO: Implement mint instruction emission: - * - Validate mint instruction structure - * - Queue instruction for backend/Safe approval - * - Log to T.S.S.D. Vault for audit - * - * @param instruction - Mint instruction to emit - * @see runtime/mintPipelineDriver.ts - */ - emitMintInstruction(instruction: unknown): Promise; - - /** - * Shutdown the runtime adapter and clean up resources. - * - * TODO: Implement cleanup logic: - * - Stop all running agents - * - Flush telemetry to vault - * - Close connections - */ - shutdown(): Promise; -} - -// ============================================================================ -// Stub Implementation (for testing/scaffolding only) -// ============================================================================ - -/** - * Stub implementation of AFIRuntimeAdapter. - * - * This is a placeholder implementation that does nothing. - * Future work will replace this with a real implementation using ElizaOS. - * - * @class StubRuntimeAdapter - * @implements {AFIRuntimeAdapter} - */ -export class StubRuntimeAdapter implements AFIRuntimeAdapter { - async initialize(context: AFIRuntimeContext): Promise { - console.log('[StubRuntimeAdapter] initialize() called with context:', context); - // TODO: Implement real initialization - } - - async handleSignal(signal: AFISignalInput): Promise { - console.log('[StubRuntimeAdapter] handleSignal() called with signal:', signal); - // TODO: Implement real signal handling - } - - async handleDAGStep(step: AFIDAGStepInstruction): Promise { - console.log('[StubRuntimeAdapter] handleDAGStep() called with step:', step); - // TODO: Implement real DAG step execution - return { - nodeId: step.nodeId, - status: 'success', - output: { message: 'Stub implementation - no real execution' }, - durationMs: 0, - }; - } - - async emitMintInstruction(instruction: unknown): Promise { - console.log('[StubRuntimeAdapter] emitMintInstruction() called with instruction:', instruction); - // TODO: Implement real mint instruction emission - } - - async shutdown(): Promise { - console.log('[StubRuntimeAdapter] shutdown() called'); - // TODO: Implement real cleanup - } -} diff --git a/runtime/types.ts b/runtime/types.ts deleted file mode 100644 index 51e5b7b..0000000 --- a/runtime/types.ts +++ /dev/null @@ -1,114 +0,0 @@ -/** - * AFI Core Runtime Types - * ====================== - * - * Canonical type definitions for AFI Protocol runtime. - * These types align with the Zod schemas in schemas/ but provide - * TypeScript-native interfaces for validators, runtime adapters, - * and other protocol components. - * - * @module runtime/types - */ - -// ============================================================================ -// Signal Types -// ============================================================================ - -/** - * Indicator data point attached to a signal. - * Represents technical indicators, sentiment scores, or other metrics. - */ -export interface SignalIndicator { - name: string; - value: string | number | boolean | null; - timeframe?: string; -} - -/** - * Analysis result attached to a signal. - * Represents output from validators, analyzers, or other processing steps. - */ -export interface SignalAnalysis { - type: string; - result: string; - confidence?: number; -} - -/** - * SignalPayload - Canonical signal structure for AFI Protocol - * - * This is the primary data structure passed through the signal lifecycle: - * ingestion → validation → scoring → DAG processing → finalization - * - * Aligns with schemas/universal_signal_schema.ts (Zod schema). - * - * @see schemas/universal_signal_schema.ts - */ -export interface SignalPayload { - /** Unique signal identifier (optional during ingestion, required after) */ - id?: string; - - /** Trading symbol or asset identifier */ - symbol: string; - - /** Market context (e.g., "crypto", "equity", "forex") */ - market?: string; - - /** Signal action type */ - action: "buy" | "sell" | "hold"; - - /** Current or target price */ - price?: number; - - /** Signal timestamp (Unix ms or ISO string) */ - timestamp?: number | string; - - /** Signal source (e.g., "twitter", "discord", "validator-xyz") */ - source?: string; - - /** Strategy or methodology (e.g., "momentum", "mean-reversion") */ - strategy?: string; - - /** Human-readable notes or rationale */ - notes?: string; - - /** Target price for the signal */ - targetPrice?: number; - - /** Stop-loss price */ - stopLoss?: number; - - /** Timeframe (e.g., "1h", "1d", "1w") */ - timeframe?: string; - - /** Signal strength classification */ - strength?: "low" | "medium" | "high"; - - /** Technical indicators or metrics */ - indicators?: SignalIndicator[]; - - /** Analysis results from validators/processors */ - analysis?: SignalAnalysis[]; - - /** Whether user is subscribed to this signal source */ - subscribed?: boolean; - - /** Composite score (0-100, computed by validators) */ - score?: number; -} - -/** - * Minimal signal payload for validators that only need core fields. - * Useful for validators that operate on content/metadata without - * requiring full market data. - */ -export interface MinimalSignalPayload { - /** Signal identifier */ - signalId: string; - - /** Signal content (text, JSON, or other serialized data) */ - content: string; - - /** Arbitrary metadata */ - metadata?: Record; -} diff --git a/src/analyst/AnalystScoreTemplate.ts b/src/analyst/AnalystScoreTemplate.ts index 3553c1e..29b1066 100644 --- a/src/analyst/AnalystScoreTemplate.ts +++ b/src/analyst/AnalystScoreTemplate.ts @@ -190,109 +190,3 @@ export const AnalystScoreTemplateSchema = z.object({ caveats: z.string().optional(), tags: z.array(z.string()).optional(), }); - -/** - * AFI DAG configuration for analyst score template - * - * Configuration for AFI DAG integration with the analyst score template. - * This allows analysts to specify enrichment nodes and parallel processing options. - */ -export interface AFIDAGConfig { - /** Enrichment nodes to use. Array of node IDs to execute. */ - enrichmentNodes: string[]; - - /** Whether to enable parallel processing. */ - parallelProcessing: boolean; - - /** Maximum parallel nodes. Limits the number of nodes that can run in parallel. */ - maxParallelNodes?: number; - - /** Timeout for enrichment nodes in milliseconds. */ - enrichmentTimeout?: number; -} - -/** - * Extended AnalystScoreTemplate with AFI DAG configuration - * - * Extends the base AnalystScoreTemplate with optional AFI DAG-specific fields. - * This allows analysts to include enrichment results and AFI DAG configuration - * in their score output. - */ -export interface AnalystScoreTemplateWithAFIDAG extends AnalystScoreTemplate { - /** Optional AFI DAG configuration. */ - afiDAGConfig?: AFIDAGConfig; - - /** Optional enrichment results. Map of node ID to enrichment result. */ - enrichmentResults?: Map; -} - -/** - * Type guard to check if an object is an AFIDAGConfig - */ -export function isAFIDAGConfig(obj: unknown): obj is AFIDAGConfig { - if (typeof obj !== 'object' || obj === null) { - return false; - } - - const config = obj as unknown as Record; - - return ( - Array.isArray(config.enrichmentNodes) && - typeof config.parallelProcessing === 'boolean' && - (config.maxParallelNodes === undefined || typeof config.maxParallelNodes === 'number') && - (config.enrichmentTimeout === undefined || typeof config.enrichmentTimeout === 'number') - ); -} - -/** - * Type guard to check if an object is an AnalystScoreTemplateWithAFIDAG - */ -export function isAnalystScoreTemplateWithAFIDAG(obj: unknown): obj is AnalystScoreTemplateWithAFIDAG { - if (typeof obj !== 'object' || obj === null) { - return false; - } - - const template = obj as unknown as Record; - - // Check base AnalystScoreTemplate fields - if ( - typeof template.analystId !== 'string' || - typeof template.strategyId !== 'string' || - typeof template.marketType !== 'string' || - typeof template.assetClass !== 'string' || - typeof template.instrumentType !== 'string' || - typeof template.baseAsset !== 'string' || - typeof template.signalTimeframe !== 'string' || - typeof template.direction !== 'string' || - typeof template.riskBucket !== 'string' || - typeof template.conviction !== 'number' || - typeof template.uwrScore !== 'number' || - typeof template.scoredAt !== 'string' - ) { - return false; - } - - // Check uwrAxes - const uwrAxes = template.uwrAxes as unknown as Record | undefined; - if ( - typeof uwrAxes !== 'object' || - uwrAxes === null || - typeof uwrAxes.structure !== 'number' || - typeof uwrAxes.execution !== 'number' || - typeof uwrAxes.risk !== 'number' || - typeof uwrAxes.insight !== 'number' - ) { - return false; - } - - // Check optional AFI DAG fields - if (template.afiDAGConfig !== undefined && !isAFIDAGConfig(template.afiDAGConfig)) { - return false; - } - - if (template.enrichmentResults !== undefined && !(template.enrichmentResults instanceof Map)) { - return false; - } - - return true; -} diff --git a/src/analyst/__tests__/AnalystScoreTemplate.test.ts b/src/analyst/__tests__/AnalystScoreTemplate.test.ts deleted file mode 100644 index c7d327b..0000000 --- a/src/analyst/__tests__/AnalystScoreTemplate.test.ts +++ /dev/null @@ -1,305 +0,0 @@ -/** - * Type tests for afi-core/src/analyst/AnalystScoreTemplate.ts - * - * These tests verify that TypeScript interfaces are correctly defined - * and that type guards work as expected. - * - * The bulk of this file uses compile-time type assertions to verify type - * compatibility; the runtime `describe` block at the end exercises the - * exported type guards so vitest registers a suite for the file. - */ - -import { describe, it, expect } from 'vitest'; -import type { - AnalystScoreTemplate, - AFIDAGConfig, - AnalystScoreTemplateWithAFIDAG, -} from '../AnalystScoreTemplate'; -import { - isAFIDAGConfig, - isAnalystScoreTemplateWithAFIDAG, -} from '../AnalystScoreTemplate'; - -// ============================================================================ -// AFIDAGConfig Type Tests -// ============================================================================ - -const validAFIDAGConfig: AFIDAGConfig = { - enrichmentNodes: ['price-enricher', 'sentiment-analyzer', 'onchain-tracker'], - parallelProcessing: true, - maxParallelNodes: 5, - enrichmentTimeout: 30000, -}; - -const minimalAFIDAGConfig: AFIDAGConfig = { - enrichmentNodes: ['price-enricher'], - parallelProcessing: false, -}; - -// ============================================================================ -// AnalystScoreTemplateWithAFIDAG Type Tests -// ============================================================================ - -const validAnalystScoreTemplateWithAFIDAG: AnalystScoreTemplateWithAFIDAG = { - // Base AnalystScoreTemplate fields - analystId: 'crypto-analyst', - strategyId: 'trend-following-v1', - strategyVersion: '1.0.0', - marketType: 'spot', - assetClass: 'crypto', - instrumentType: 'spot', - baseAsset: 'BTC', - quoteAsset: 'USDT', - venue: 'binance', - signalTimeframe: '4h', - holdingHorizon: 'swing', - direction: 'long', - riskBucket: 'medium', - conviction: 0.75, - greeks: { - delta: 0.5, - gamma: 0.1, - theta: -0.05, - vega: 0.2, - rho: 0.01, - }, - uwrAxes: { - structure: 0.8, - execution: 0.7, - risk: 0.75, - insight: 0.8, - }, - uwrScore: 0.7625, - axisNotes: { - structure: 'Strong trend structure', - execution: 'Good entry point', - risk: 'Acceptable risk level', - insight: 'Clear market insight', - }, - axisFlags: ['high-confidence', 'trend-following'], - rationale: 'Strong uptrend with good risk/reward ratio', - caveats: 'Monitor for trend reversal', - tags: ['trend-following', 'BTC', '4h'], - // AFI DAG-specific fields - afiDAGConfig: validAFIDAGConfig, - enrichmentResults: new Map([ - ['price-enricher', { price: 50000, volume: 1000 }], - ['sentiment-analyzer', { sentiment: 'bullish', confidence: 0.8 }], - ]), -}; - -const minimalAnalystScoreTemplateWithAFIDAG: AnalystScoreTemplateWithAFIDAG = { - // Minimal base AnalystScoreTemplate fields - analystId: 'equity-trader', - strategyId: 'mean-reversion-v2', - marketType: 'spot', - assetClass: 'equity', - instrumentType: 'spot', - baseAsset: 'AAPL', - venue: 'NYSE', - signalTimeframe: '1d', - direction: 'long', - riskBucket: 'low', - conviction: 0.6, - uwrAxes: { - structure: 0.7, - execution: 0.6, - risk: 0.65, - insight: 0.7, - }, - uwrScore: 0.6625, - // AFI DAG-specific fields - afiDAGConfig: minimalAFIDAGConfig, -}; - -const analystScoreTemplateWithoutAFIDAG: AnalystScoreTemplateWithAFIDAG = { - // Base AnalystScoreTemplate fields only - analystId: 'crypto-analyst', - strategyId: 'trend-following-v1', - marketType: 'spot', - assetClass: 'crypto', - instrumentType: 'spot', - baseAsset: 'ETH', - venue: 'coinbase', - signalTimeframe: '1h', - direction: 'short', - riskBucket: 'high', - conviction: 0.85, - uwrAxes: { - structure: 0.9, - execution: 0.8, - risk: 0.7, - insight: 0.85, - }, - uwrScore: 0.8125, - // No AFI DAG-specific fields -}; - -// ============================================================================ -// Type Guard Tests -// ============================================================================ - -// Test isAFIDAGConfig -const afdDAGConfigTest1 = { - enrichmentNodes: ['price-enricher', 'sentiment-analyzer'], - parallelProcessing: true, -}; - -if (isAFIDAGConfig(afdDAGConfigTest1)) { - const enrichmentNodes: string[] = afdDAGConfigTest1.enrichmentNodes; - const parallelProcessing: boolean = afdDAGConfigTest1.parallelProcessing; - const maxParallelNodes: number | undefined = afdDAGConfigTest1.maxParallelNodes; - const enrichmentTimeout: number | undefined = afdDAGConfigTest1.enrichmentTimeout; -} - -// Test isAnalystScoreTemplateWithAFIDAG -const analystScoreTemplateTest1 = { - analystId: 'crypto-analyst', - strategyId: 'trend-following-v1', - marketType: 'spot' as const, - assetClass: 'crypto' as const, - instrumentType: 'spot' as const, - baseAsset: 'BTC', - signalTimeframe: '4h', - direction: 'long' as const, - riskBucket: 'medium' as const, - conviction: 0.75, - uwrAxes: { - structure: 0.8, - execution: 0.7, - risk: 0.75, - insight: 0.8, - }, - uwrScore: 0.7625, - afiDAGConfig: validAFIDAGConfig, - enrichmentResults: new Map(), -}; - -if (isAnalystScoreTemplateWithAFIDAG(analystScoreTemplateTest1)) { - const analystId: string = analystScoreTemplateTest1.analystId; - const strategyId: string = analystScoreTemplateTest1.strategyId; - const uwrScore: number = analystScoreTemplateTest1.uwrScore; - const afiDAGConfig: AFIDAGConfig | undefined = analystScoreTemplateTest1.afiDAGConfig; - const enrichmentResults: Map | undefined = analystScoreTemplateTest1.enrichmentResults; -} - -// ============================================================================ -// Type Compatibility Tests -// ============================================================================ - -// Test that AFIDAGConfig can be used in AnalystScoreTemplateWithAFIDAG -const templateWithConfig: AnalystScoreTemplateWithAFIDAG = { - analystId: 'crypto-analyst', - strategyId: 'trend-following-v1', - marketType: 'spot', - assetClass: 'crypto', - instrumentType: 'spot', - baseAsset: 'BTC', - signalTimeframe: '4h', - direction: 'long', - riskBucket: 'medium', - conviction: 0.75, - uwrAxes: { - structure: 0.8, - execution: 0.7, - risk: 0.75, - insight: 0.8, - }, - uwrScore: 0.7625, - afiDAGConfig: validAFIDAGConfig, -}; - -// Test that AnalystScoreTemplate can be extended with AFI DAG fields -const baseTemplate: AnalystScoreTemplate = { - analystId: 'crypto-analyst', - strategyId: 'trend-following-v1', - marketType: 'spot', - assetClass: 'crypto', - instrumentType: 'spot', - baseAsset: 'BTC', - signalTimeframe: '4h', - direction: 'long', - riskBucket: 'medium', - conviction: 0.75, - uwrAxes: { - structure: 0.8, - execution: 0.7, - risk: 0.75, - insight: 0.8, - }, - uwrScore: 0.7625, -}; - -const extendedTemplate: AnalystScoreTemplateWithAFIDAG = { - ...baseTemplate, - afiDAGConfig: validAFIDAGConfig, - enrichmentResults: new Map(), -}; - -// Test that config can be passed to functions expecting specific types -function processAFIDAGConfig(config: AFIDAGConfig): void { - console.log(`Processing AFI DAG config with ${config.enrichmentNodes.length} nodes`); -} - -function processAnalystScoreTemplate(template: AnalystScoreTemplate): void { - console.log(`Processing analyst score: ${template.analystId} - ${template.uwrScore}`); -} - -function processAnalystScoreTemplateWithAFIDAG(template: AnalystScoreTemplateWithAFIDAG): void { - console.log(`Processing analyst score with AFI DAG: ${template.analystId}`); - if (template.afiDAGConfig) { - console.log(` Parallel processing: ${template.afiDAGConfig.parallelProcessing}`); - } - if (template.enrichmentResults) { - console.log(` Enrichment results: ${template.enrichmentResults.size}`); - } -} - -processAFIDAGConfig(validAFIDAGConfig); -processAnalystScoreTemplate(baseTemplate); -processAnalystScoreTemplateWithAFIDAG(extendedTemplate); - -// ============================================================================ -// Runtime tests for the exported type guards -// ============================================================================ - -describe('AnalystScoreTemplate type guards', () => { - it('isAFIDAGConfig accepts valid configs', () => { - expect(isAFIDAGConfig(validAFIDAGConfig)).toBe(true); - expect(isAFIDAGConfig(minimalAFIDAGConfig)).toBe(true); - }); - - it('isAFIDAGConfig rejects non-configs', () => { - expect(isAFIDAGConfig(null)).toBe(false); - expect(isAFIDAGConfig({})).toBe(false); - expect(isAFIDAGConfig({ enrichmentNodes: ['a'] })).toBe(false); // missing parallelProcessing - }); - - it('isAnalystScoreTemplateWithAFIDAG accepts valid templates', () => { - // The runtime guard additionally requires a `scoredAt` string (which the - // compile-time fixtures above omit, since the type marks it optional). - const scoredAt = '2026-01-01T00:00:00.000Z'; - expect(isAnalystScoreTemplateWithAFIDAG({ ...validAnalystScoreTemplateWithAFIDAG, scoredAt })).toBe(true); - expect(isAnalystScoreTemplateWithAFIDAG({ ...minimalAnalystScoreTemplateWithAFIDAG, scoredAt })).toBe(true); - }); - - it('isAnalystScoreTemplateWithAFIDAG rejects non-templates', () => { - expect(isAnalystScoreTemplateWithAFIDAG(null)).toBe(false); - expect(isAnalystScoreTemplateWithAFIDAG({})).toBe(false); - }); -}); - -// ============================================================================ -// Export for type checking -// ============================================================================ - -export { - validAFIDAGConfig, - minimalAFIDAGConfig, - validAnalystScoreTemplateWithAFIDAG, - minimalAnalystScoreTemplateWithAFIDAG, - analystScoreTemplateWithoutAFIDAG, - templateWithConfig, - baseTemplate, - extendedTemplate, -};