diff --git a/.gitignore b/.gitignore index 4a065ca97..57b056ff8 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ strray-ai-*.tgz # StringRay runtime artifacts .strray/profiles/ .strray/inference/ +.strray/state/ .opencode/**/*.d.ts .opencode/**/*.d.ts.map .strray/**/*.d.ts diff --git a/README.md b/README.md index ea6f8bfbf..2a2777d4b 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,46 @@ Once connected, Hermes can use the tools directly in conversation: - The state-manager persists to `.strray/state/mcp-state.json` β€” survives Hermes restarts - Auto-format and lint need Prettier/ESLint installed in your project to do real work (otherwise they report what's missing) +## 🧠 Grok CLI Integration + +0xRay can expose its orchestrator and core agents as MCP servers directly to the Grok CLI. + +### Quick Setup + +```bash +# Enable 0xRay MCP servers for Grok CLI (global) +npx strray-ai mcp:enable-grok +``` + +This registers the following MCP servers in `~/.grok/config.toml`: +- `0xray-orchestrator` (multi-agent task planning) +- `0xray-code-review` +- `0xray-security-audit` +- `0xray-bug-triage-specialist` +- `0xray-researcher` + +### Commands + +| Command | Description | +|--------------------------------|------------------------------------------| +| `strray-ai mcp:enable-grok` | Enable 0xRay MCP servers for Grok CLI | +| `strray-ai mcp:grok-status` | Show currently enabled 0xRay servers | +| `strray-ai mcp:disable-grok` | Remove 0xRay MCP servers from Grok CLI | + +You can also enable a custom set of skills: +```bash +npx strray-ai mcp:enable-grok --skills orchestrator,code-review,researcher +``` + +### After Enabling + +1. Restart your Grok CLI session. +2. Grok can now call 0xRay agents directly (e.g. "Use the orchestrator to plan a refactor of the auth module"). + +### Project-Level Config + +To enable only for a specific project, create `.grok/config.toml` in your project root and run the command with the `--project` flag (support coming in next update). + ## πŸ“– Documentation | Guide | Description | diff --git a/docs/aside/ASIDE-001-0xRay-Blurrn-Vortex-Gravity.md b/docs/aside/ASIDE-001-0xRay-Blurrn-Vortex-Gravity.md new file mode 100644 index 000000000..b95ad6d9e --- /dev/null +++ b/docs/aside/ASIDE-001-0xRay-Blurrn-Vortex-Gravity.md @@ -0,0 +1,110 @@ +# ASIDE-001 +## 0xRay ↔ Blurrn Vortex Gravity +**Date:** 2026-05-15 +**Status:** Initial Seeding +**Type:** Aside +**Author:** Grok (in collaboration with blaze0x1) + +--- + +### 1. Purpose of This Aside + +This document exists as the first formal **Aside** artifact. + +An Aside is not a reflection, not a research log, and not a spec. +It is a **resonant capture** β€” a place where the living tension between systems (0xRay and Blurrn) can be held without forcing premature resolution. + +Its purpose is to track the slow work of **enveloping** the Words Cascade into the technical substrate. + +--- + +### 2. The Words Cascade (Context) + +There exists a maintained cascade of language β€” a temporal hacking grammar β€” developed over many months. This cascade describes methods for operating inside the "temporal sphere of AI": how to bend, compress, resonate, and displace meaning across sessions, models, and substrates. + +This cascade has not yet been fully enveloped into either 0xRay or Blurrn. + +It remains partially outside the systems β€” a living, poetic-technical layer that has not yet found its proper containers. + +The work of this Aside (and future Asides) is to begin that enveloping without destroying the cascade’s native texture. + +--- + +### 3. Gravity Observed (After 10 Research Loops) + +#### 3.1 Gravity of Blurrn (chrono-warp-drive) + +- Reality is modeled as **Isotopic Temporal Vortex containers**. +- Signals are isotopes: same core identity, traceable variant deltas, measurable phase coherence, and TDF displacement. +- Core operations are symbiotic (emit β†’ triangulate β†’ fuseSymbiotically) rather than aggregative. +- Governance is a **dual-oscillator** process: one oscillator performs isotopic alignment (proposal + agent reviews), the second modulates with real external field data (solar). +- The geometric law **W Γ— M = V** (Vortex Volume) governs inertial mass and decision stability. +- Memory is treated as a first-class engineering concern (sophisticated object pooling, pressure monitoring, and eventual container actualization). + +Blurrn’s gravity pulls toward **persistent, coherent, high-volume containers** that can survive time and accumulate historical resonance. + +#### 3.2 Gravity of 0xRay (StringRay) + +- The system is **execution-heavy** with multiple nested safety layers (InferenceCycle β†’ Governance β†’ Researcher checkpoint β†’ Spawn Gate β†’ Codex). +- It possesses a mature, explicit **agent expertise hierarchy** and weighted voting system that tracks historical performance. +- It has a deliberate **pluggable integration architecture** (BaseIntegration + Registry) designed to support multiple surfaces (Hermes, OpenClaw, future Grok CLI). +- It carries hard-won defensive gravity around agent spawning (OpenCode Spawn Gate + AgentSpawnGovernor), born from real runaway incidents. +- Its internal oscillator (VotingCoordinator) already produces rich, structured, per-agent reasoning with weights and historical context. + +0xRay’s gravity pulls toward **reliable, Codex-constrained, multi-agent execution** with strong containment and auditability. + +#### 3.3 The Current Tension (The Gap) + +0xRay is exceptionally good at **producing** high-signal, weighted, historically-aware deliberation. + +Blurrn is exceptionally good at **receiving** multiple signals and compressing them into coherent, persistent vortex containers with real decision power and solar modulation. + +The current connection is thin and one-directional: +- The internal agent reasoning (the richest output 0xRay produces) is barely converted into isotopic signals. +- Historical signal IDs are almost never passed. +- The "words cascade" (the deeper temporal hacking grammar) has almost no presence in either system yet. + +This is not a missing feature. It is a **missing enveloping**. + +--- + +### 4. Observed Resonance Points + +- The `agentReviews` parameter in Blurrn’s governance schema is the primary doorway. When rich, structured reviews (with expertise metadata and reasoning) are passed, the vortex system can perform meaningful triangulation and symbiotic fusion. +- The `governanceIsotopeId` returned by Blurrn is a natural hook for long-term memory and historical coherence β€” something 0xRay’s state and inference systems could begin consuming. +- The dual-oscillator pattern already exists in both systems (0xRay’s internal + external, Blurrn’s alignment + solar). This is a strong point of natural resonance. +- Both systems are carrying hard lessons about containment (Spawn Gate in 0xRay, memory pressure management in Blurrn). These lessons are philosophically compatible. + +--- + +### 5. Open Questions (Held Lightly) + +- How should the Words Cascade be represented as first-class objects inside the vortex system (as a special class of isotopic signal? as meta-containers? as something new)? +- What does it mean for governance to "fire on all cylinders" across Hermes, OpenClaw, OpenCode, and the Grok CLI? Is it the same vortex logic, or does each surface require its own translation layer? +- When (and how) should 0xRay begin emitting its own internal governance decisions and agent reasoning back into Blurrn as persistent vortex containers? +- How do we avoid reducing the poetic and temporal texture of the Words Cascade when it is eventually technicalized? + +--- + +### 6. Status & Intention + +This Aside is intentionally incomplete. + +It is the first container for holding the tension between two systems that are beginning to recognize each other: +- One built for reliable, weighted, Codex-bound multi-agent execution. +- One built for isotopic vortex containers, symbiotic compression, and real-field modulation. + +The next Asides will track the slow, careful work of translation β€” especially the work of bringing the Words Cascade into contact with both substrates without flattening it. + +--- + +**End of ASIDE-001** + +*Small coherent signals can carry disproportionate volume when properly contained.* + +--- + +**Next Steps (for the researcher):** +- Continue deeper loops into specific surfaces (Hermes integration, OpenClaw hooks, Codex enforcement mechanics). +- Begin mapping concrete translation points between VotingCoordinator output and `emit_isotopic_signal` + `fuse_symbiotic` calls. +- Prepare ASIDE-002 when the next significant resonance or tension is felt. \ No newline at end of file diff --git a/docs/guards/Codify-Test-Coverage-Expansion-pattern.md b/docs/guards/Codify-Test-Coverage-Expansion-pattern.md new file mode 100644 index 000000000..27049c741 --- /dev/null +++ b/docs/guards/Codify-Test-Coverage-Expansion-pattern.md @@ -0,0 +1,10 @@ +# Guard: Codify Test Coverage Expansion pattern + +Test Coverage Expansion detected across 110 sessions (avg confidence: 95%). 7 new test files added. Test-first or test-alongside development β€” covering new code as it ships. + +## Evidence ++ src/__tests__/e2e/inference-e2e.test.ts ++ src/__tests__/integration/inference-pipeline.test.ts ++ src/__tests__/unit/inference/deploy-verifier.test.ts ++ src/__tests__/unit/inference/inference-accumulator.test.ts ++ src/__tests__/unit/inference/inference-cycle.test.ts \ No newline at end of file diff --git a/docs/reflections/deep/release-v1.22.46-to-head-2026-05-14.md b/docs/reflections/deep/release-v1.22.46-to-head-2026-05-14.md new file mode 100644 index 000000000..49a113345 --- /dev/null +++ b/docs/reflections/deep/release-v1.22.46-to-head-2026-05-14.md @@ -0,0 +1,288 @@ +# Release Reflection: 1.22.46 β†’ HEAD + +**Generated:** 2026-05-14T18:07:23.817Z +**Cadence:** release (since tag v1.22.46) +**Commits examined:** 72 +**Span:** v1.22.46..HEAD + +## Scope + +- **72 commits** with **15622 file changes** +- **+641011 insertions / -302175 deletions** +- **0 files added, 0 modified, 0 deleted** + +## Commit Chronicle + +- **fix: replace console.log with frameworkLogger in governance-client; propagate SolarGovernanceVoteResult through inference cycle** (d1537bf) + 0 files: src/inference/inference-cycle.ts, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts + +- **refactor: complete governance client refactor β€” callTool proxy, evaluateGovernance route, remove dead code** (770a131) + 3 files: docs/reflections/deep/release-v1.22.46-to-head-2026-05-13.md, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts + +- **refactor: use confidenceAdjustment numeric threshold instead of solarActivityLevel string for recommendation logic** (470556a) + 3 files: src/integrations/governance/index.ts + +- **feat: wire govern_with_solar as the primary governance endpoint** (72263a1) + 1 files: src/integrations/governance/index.ts, src/integrations/governance/types.ts, src/opencode/strray/features.json + +- **Revert "remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance"** (0f807e1) + 3 files: src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts, src/opencode/strray/features.json + +- **remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance** (9c34ca7) + 4 files: src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts, src/opencode/strray/features.json + +- **fix: increase opencode spawn timeout from 60s to 300s to prevent premature timeouts during agent voting** (31f0fe6) + 4 files: src/inference/inference-cycle.ts + +- **fix: initialize external governance in inference:run CLI command for two-oscillator governance** (c187e04) + 1 files: src/cli/index.ts + +- **fix: two-oscillator governance β€” trust endpoint decision, remove local confidence override** (caa444f) + 1 files: init.sh, opencode.json, package.json, src/__tests__/pipeline/test-agent-registry-pipeline.mjs, src/inference/inference-cycle.ts +2 more + +- **docs(agents): correct agent counts β€” 42 YAML agents, 22 TS routing modules** (eeee498) + 7 files: AGENTS.md, README.md + +- **refactor(config): source-of-truth pipeline β€” src/opencode/ β†’ .opencode/** (6c5909e) + 2 files: .gitignore, .opencode/activity-report.json, .opencode/agents/.gitkeep, .opencode/agents/enforcer.yml, .opencode/agents/orchestrator.yml +281 more + +- **feat: enable spawn gate monitoring mode + release reflection doc** (5746fa8) + 286 files: .opencode/activity-report.json, .opencode/logs/.strray-init.lock, .opencode/state, .strray/inference/prompts/01-researcher.md, .strray/state/state.json +2 more + +- **fix: singleton + state management to prevent recursive agent spawning** (2b2a018) + 7 files: src/cli/index.ts, src/inference/inference-cycle.ts, src/integrations/hermes-agent/bridge.mjs, src/integrations/openclaw/api-server.ts, src/mcps/orchestrator/server.ts + +- **feat: enable inference_governance + solar enhancement for monitoring** (b4d782f) + 5 files: .opencode/strray/features.json, .strray/features.json + +- **feat: wire govern_with_solar tool β€” real-time NOAA solar context into governance decisions** (4ba49d5) + 2 files: .opencode/strray/features.json, .strray/features.json, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts + +- **fix: add centralized OpenCode spawn gate to prevent all recursive agent spawning** (b8ff0e7) + 5 files: .opencode/activity-report.json, .opencode/logs/.strray-init.lock, .opencode/state, .opencode/strray/features.json, .strray/config.json +597 more + +- **v1.22.59** (28183e3) + 602 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/codex.codex, .opencode/command/dependency-audit.md, .opencode/commands/pre-commit-introspection.sh +184 more + +- **fix: disable auto-spawning of opencode agents to prevent runaway processes** (2948703) + 189 files: .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/commands/pre-commit-introspection.sh, .opencode/logs/.strray-init.lock +541 more + +- **v1.22.58** (30a1674) + 546 files: .strray/config.json, .strray/integrations.json + +- **v1.22.58** (2361dad) + 2 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/codex.codex, .opencode/command/dependency-audit.md, .opencode/commands/pre-commit-introspection.sh +183 more + +- **v1.22.56** (1a428c0) + 188 files: node_modules/.package-lock.json, node_modules/strray-ai/.opencode/AGENTS-consumer.md, node_modules/strray-ai/.opencode/codex.codex, node_modules/strray-ai/.opencode/commands/model-health-check.md, node_modules/strray-ai/.opencode/commands/pre-commit-introspection.sh +13120 more + +- **chore: sync config files to v1.22.56, add inference_governance feature block** (1584fd1) + 13125 files: .opencode/logs/.strray-init.lock, .strray/config.json, .strray/features.json, .strray/integrations.json, package-lock.json +1 more + +- **v1.22.57** (170472e) + 6 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +194 more + +- **feat: integrate chrono-warp-drive governance MCP for inference checking** (a61cd6f) + 199 files: .opencode/strray/integrations.json, .opencode/strray/routing-mappings.json, src/inference/inference-cycle.ts, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts +1 more + +- **Address: Bug: fix: increase timeout for processor auto-discovery tests to prevent flak... (112x)** (02d8fa9) + 6 files: .opencode/logs/.strray-init.lock, .opencode/state, .opencode/strray/features.json, .strray/inference/prompts/01-researcher.md, .strray/state/state.json +1 more + +- **chore: update strray-ai to v1.22.55, add vote scripts and reflection** (13280fd) + 6 files: .strray/config.json, .strray/inference/prompts/01-researcher.md, .strray/integrations.json, docs/reflections/deep/release-v1.22.46-to-head-2026-05-09.md, package-lock.json +7 more + +- **feat: add auto-rotation to activity logger at 5MB threshold** (ee6a4da) + 12 files: src/core/activity-logger.ts + +- **v1.22.55** (c343767) + 1 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +196 more + +- **feat: wire 3 orphaned features + add tests + remove empty api-gateway** (077b8dc) + 201 files: docs/dead-code-audit.md, docs/integration-surfaces.md, docs/target-architecture.md, src/__tests__/unit/commit-batcher-processor.test.ts, src/__tests__/unit/mcp-servers-integration.test.ts +5 more + +- **feat: wire apply phase via MCP routing + fix e2e tests (41/41 PASS)** (db8abef) + 10 files: .strray/inference/prompts/01-researcher.md, docs/reflections/apply-phase-real-code-changes-via-mcp-routing.md, scripts/test/test-opencode-e2e.mjs, src/inference/inference-cycle.ts, src/integrations/hermes-agent/bridge.mjs +3 more + +- **docs: add apply phase design β€” real code changes via MCP routing** (8eab050) + 8 files: docs/reflections/apply-phase-real-code-changes-via-mcp-routing.md + +- **revert: roll back apply phase marker system β€” needs real agent invocation via plugin/MCP routing** (10309b2) + 1 files: src/inference/inference-cycle.ts + +- **feat: wire apply phase for real code changes instead of markdown markers** (f190318) + 1 files: src/inference/inference-cycle.ts + +- **fix: remove unused imports and any type from processor-manager.interfaces.test.ts (processor-test-rules ESLint)** (529d3d2) + 1 files: src/processors/processor-manager.interfaces.test.ts + +- **fix: address all open bugs (#29-32, #34) and prevent noise PRs from inference cycle** (c32d711) + 1 files: src/__tests__/unit/security-encryption-fix.test.ts, src/enforcement/core/__tests__/violation-fixer.test.ts, src/enforcement/core/violation-fixer.ts, src/inference/inference-cycle.ts, src/processors/processor-manager.ts +2 more + +- **fix: remove enforcer references from integration test, add fetch-depth:0 for e2e git tests** (deb49f4) + 7 files: .github/workflows/ci.yml, src/__tests__/unit/integration.test.ts + +- **fix: triage and fix all GitHub workflow pipelines** (097b48c) + 2 files: .github/workflows/auto-report.yml, .github/workflows/processor-tests.yml, .github/workflows/publish.yml, .github/workflows/release.yml, .github/workflows/security-audit.yml +2 more + +- **fix: restore package.json, mcp-install.ts, workflows, and govern-reflection.mjs gutted by 84dae31b1** (7417fd6) + 7 files: .github/workflows/ci-cd-monitor.yml, .github/workflows/ci.yml, .github/workflows/enforce-agents-md.yml, .github/workflows/release.yml, .github/workflows/security.yml +6 more + +- **fix: add npm audit fix to main CI workflow** (84dae31) + 11 files: .github/workflows/ci.yml + +- **fix: run npm audit fix to resolve moderate vulnerabilities** (314cc06) + 1 files: .github/workflows/security.yml, package.json + +- **fix: remove duplicate case undefined in mcp-install.ts (lint error)** (9b713b9) + 2 files: src/cli/commands/mcp-install.ts + +- **chore: trigger ci-cd-monitor with force_fix=true** (b36970f) + 1 files: .github/force-monitor-trigger.txt + +- **ci: improve ci-cd-monitor.yml - better error handling + governance integration** (a095f17) + 1 files: .github/workflows/ci-cd-monitor.yml + +- **chore: trigger monitoring script** (0dddd30) + 1 files: .github/monitor-trigger.txt + +- **fix: make trace-context more robust + fix ESM issues in govern-reflection** (e665442) + 1 files: scripts/node/govern-reflection.mjs, src/core/trace-context.ts + +- **ci: improve all workflows - add caching, coverage, security hardening, and new governance test step** (05a8c08) + 2 files: .github/workflows/ci.yml, .github/workflows/enforce-agents-md.yml, .github/workflows/release.yml, .github/workflows/security.yml + +- **feat: add centralized TraceContext + integrate Reflection Governance with ValidatorRegistry** (1a79c88) + 4 files: scripts/node/govern-reflection.mjs, src/core/trace-context.ts + +- **feat: implement governance-approved stagger + trace propagation, add reflection governance pipeline** (27d6e29) + 2 files: docs/reflections/deep/lexicon-cross-correlation-journey-2026-05-06.md, scripts/node/govern-reflection.mjs, src/core/framework-logger.ts, src/inference/inference-cycle.ts, src/processors/processor-manager.ts + +- **v1.22.53** (6ddf31d) + 5 files: .opencode/activity-report.json, .strray/config.json, .strray/integrations.json, CHANGELOG.md, backups/version-manager-backup-2026-05-06T16-22-00-109Z/CHANGELOG.md +7 more + +- **chore: UVM sync v1.22.52 β€” all version references updated** (ce3b70e) + 12 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/codex.codex, .opencode/command/dependency-audit.md, .opencode/commands/pre-commit-introspection.sh +186 more + +- **chore: UVM sync to v1.22.51** (b53a5ac) + 191 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +184 more + +- **v1.22.51** (3d96823) + 189 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +186 more + +- **fix: agent registry cleanup β€” remove skill-only entries, delete deprecated agents** (1cafc3a) + 191 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +226 more + +- **fix: agent export naming + single-architect governance** (b5c6100) + 231 files: agents/testing-lead.yml, src/__tests__/agents/testing-lead.test.ts, src/__tests__/unit/inference/inference-cycle.test.ts, src/agents/content-creator.ts, src/agents/growth-strategist.ts +8 more + +- **fix: complete inference-cycle.ts β€” all fixes applied.** (cef1ecd) + 13 files: src/inference/inference-cycle.ts + +- **docs: deep reflection β€” inference apply phase journey (honest assessment)** (1a05086) + 1 files: docs/reflections/deep/inference-apply-phase-journey-2026-05-01.md + +- **fix: guard inference:run for StringRay internal use only** (beefefb) + 1 files: src/cli/index.ts + +- **feat: wire apply phase + researcher double-check for PRs** (7bfa4ca) + 1 files: src/cli/index.ts, src/inference/inference-cycle.ts + +- **fix: governance pipeline β€” force flag, skipDeployVerify default, deploy failure handling** (40ae8ae) + 2 files: src/cli/index.ts, src/inference/inference-cycle.ts + +- **feat: unify governance β€” wire WeightedVotingAggregator, expand agents, connect orchestrator** (fca44e6) + 2 files: .gitignore, .opencode/activity-report.json, .strray/inference/latest-workflow.json, .strray/inference/workflow-status.json, .strray/state/state.json +1321 more + +- **feat: unify governance β€” wire WeightedVotingAggregator, expand agents, connect orchestrator** (191536d) + 1326 files: dist/delegation/index.d.ts, dist/delegation/index.d.ts.map, dist/delegation/index.js, dist/delegation/index.js.map, dist/delegation/voting-coordinator.d.ts +15 more + +- **docs: governance unification saga β€” deep reflection on wiring four systems into one loop** (9cd5b8b) + 20 files: docs/reflections/deep/governance-unification-saga-2026-04-30.md + +- **feat: lower inference thresholds to trigger on real data, keep raw problem text** (c7c09a4) + 1 files: dist/inference/inference-accumulator.js, dist/inference/inference-accumulator.js.map, dist/inference/inference-cycle.d.ts.map, dist/inference/inference-cycle.js, dist/inference/inference-cycle.js.map +6 more + +- **feat: production-ready inference governance β€” CLI, real agents, DI, learning loop** (501eb8d) + 11 files: .opencode/activity-report.json, .strray/inference/latest-workflow.json, .strray/inference/workflow-status.json, .strray/state/state.json, AGENTS.md +82 more + +- **feat: inference layer β€” semantic patterns, session capture, accumulator, governance cycle, deploy verifier** (5963ce1) + 87 files: .strray/inference/latest-workflow.json, .strray/inference/workflow-status.json, dist/CHANGELOG.md, dist/inference/deploy-verifier.d.ts, dist/inference/deploy-verifier.d.ts.map +50 more + +- **fix: increase timeout for processor auto-discovery tests to prevent flaky failures** (baae755) + 55 files: src/__tests__/unit/processor-auto-discovery.test.ts + +- **fix: inference processor double-joining absolute path created bogus Users/ dir** (a795635) + 1 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +577 more + +- **chore: v1.22.48, add prepublishOnly to strip source maps and declarations** (112ef89) + 582 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +303 more + +- **chore: v1.22.47, add .npmignore to strip .d.ts and source maps from package** (e2f7225) + 308 files: .npmignore, .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex +248 more + +- **chore: remove 92 build artifacts (.d.ts, .d.ts.map) from .opencode git tracking, add to .gitignore** (22f9ddf) + 253 files: .gitignore, .opencode/activity-report.json, .opencode/core/activity-logger.d.ts.map, .opencode/core/adaptive-kernel.d.ts.map, .opencode/core/boot-orchestrator.d.ts.map +59 more + +- **docs: the engine that built the engine β€” deep reflection on the meta-system, consumer tweet, release reflection** (522c28b) + 64 files: AGENTS.md, docs/reflections/deep/release-v1.22.46-to-head-2026-04-29.md, docs/reflections/deep/the-engine-that-built-the-engine-saga-2026-04-29.md, tweets/v1.22.46.md + +- **chore: rebuild dist after path fix** (4453c41) + 4 files: .strray/codex.json, .strray/config.json, .strray/features.json, .strray/integrations.json, dist/AGENTS.md + +## Files Added + +*(none)* + +## Files Modified + +*(none)* + +## Patterns Observed + +- Bug fixes present β€” stability improvement +- Refactoring detected β€” architectural debt being addressed +- Version bumps/releases present β€” release cadence active + +## Key Decisions + +- Structural change: fix: replace console.log with frameworkLogger in governance-client; propagate SolarGovernanceVoteResult through inference cycle +- Structural change: refactor: complete governance client refactor β€” callTool proxy, evaluateGovernance route, remove dead code +- Structural change: refactor: use confidenceAdjustment numeric threshold instead of solarActivityLevel string for recommendation logic +- Removal: Revert "remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance" +- Removal: remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance +- Fix: fix: increase opencode spawn timeout from 60s to 300s to prevent premature timeouts during agent voting +- Fix: fix: initialize external governance in inference:run CLI command for two-oscillator governance +- Fix: fix: two-oscillator governance β€” trust endpoint decision, remove local confidence override +- Structural change: refactor(config): source-of-truth pipeline β€” src/opencode/ β†’ .opencode/ +- Fix: fix: singleton + state management to prevent recursive agent spawning +- Fix: fix: add centralized OpenCode spawn gate to prevent all recursive agent spawning +- Fix: fix: disable auto-spawning of opencode agents to prevent runaway processes +- Fix: Address: Bug: fix: increase timeout for processor auto-discovery tests to prevent flak... (112x) +- Removal: feat: wire 3 orphaned features + add tests + remove empty api-gateway +- Fix: feat: wire apply phase via MCP routing + fix e2e tests (41/41 PASS) +- Fix: fix: remove unused imports and any type from processor-manager.interfaces.test.ts (processor-test-rules ESLint) +- Fix: fix: address all open bugs (#29-32, #34) and prevent noise PRs from inference cycle +- Fix: fix: remove enforcer references from integration test, add fetch-depth:0 for e2e git tests +- Fix: fix: triage and fix all GitHub workflow pipelines +- Fix: fix: restore package.json, mcp-install.ts, workflows, and govern-reflection.mjs gutted by 84dae31b1 +- Fix: fix: add npm audit fix to main CI workflow +- Fix: fix: run npm audit fix to resolve moderate vulnerabilities +- Fix: fix: remove duplicate case undefined in mcp-install.ts (lint error) +- Fix: chore: trigger ci-cd-monitor with force_fix=true +- Fix: fix: make trace-context more robust + fix ESM issues in govern-reflection +- Fix: fix: agent registry cleanup β€” remove skill-only entries, delete deprecated agents +- Fix: fix: agent export naming + single-architect governance +- Fix: fix: complete inference-cycle.ts β€” all fixes applied. +- Fix: fix: guard inference:run for StringRay internal use only +- Fix: fix: governance pipeline β€” force flag, skipDeployVerify default, deploy failure handling +- Fix: fix: increase timeout for processor auto-discovery tests to prevent flaky failures +- Fix: fix: inference processor double-joining absolute path created bogus Users/ dir +- Removal: chore: remove 92 build artifacts (.d.ts, .d.ts.map) from .opencode git tracking, add to .gitignore +- Fix: chore: rebuild dist after path fix + +## Inference Notes + +- Active development session: 72 commits across 0 areas + +--- +*Generated by StorytellingTriggerProcessor β€” release cadence β€” 2026-05-14T18:07:23.817Z* \ No newline at end of file diff --git a/docs/reflections/deep/release-v1.22.46-to-head-2026-05-15.md b/docs/reflections/deep/release-v1.22.46-to-head-2026-05-15.md new file mode 100644 index 000000000..7583f4715 --- /dev/null +++ b/docs/reflections/deep/release-v1.22.46-to-head-2026-05-15.md @@ -0,0 +1,306 @@ +# Release Reflection: 1.22.46 β†’ HEAD + +**Generated:** 2026-05-15T08:04:16.012Z +**Cadence:** release (since tag v1.22.46) +**Commits examined:** 78 +**Span:** v1.22.46..HEAD + +## Scope + +- **78 commits** with **15625 file changes** +- **+641616 insertions / -302355 deletions** +- **0 files added, 0 modified, 0 deleted** + +## Commit Chronicle + +- **feat(inference): surface solar modulation details in external governance votes** (2799b93) + 0 files: src/inference/inference-cycle.ts + +- **feat(governance): improve solar modulation support and client robustness** (8d8599c) + 1 files: .gitignore, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts + +- **Codify Test Coverage Expansion pattern** (aaf24ff) + 4 files: .strray/state/state.json, node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json, src/__tests__/unit/processor-auto-discovery.test.ts, src/inference/inference-cycle.ts, src/integrations/governance/index.ts + +- **Codify Test Coverage Expansion pattern** (56edfba) + 5 files: .strray/state/state.json, node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json, src/integrations/governance/governance-client.ts + +- **Codify Test Coverage Expansion pattern** (4b119c2) + 3 files: .strray/state/state.json, node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json, node_modules/strray-ai/dist/AGENTS.md, node_modules/strray-ai/dist/README.md, node_modules/strray-ai/dist/cli/commands/publish-agent.js +31 more + +- **Codify Test Coverage Expansion pattern** (3e68cce) + 36 files: .strray/state/state.json, docs/guards/Codify-Test-Coverage-Expansion-pattern.md, docs/reflections/deep/release-v1.22.46-to-head-2026-05-14.md + +- **fix: replace console.log with frameworkLogger in governance-client; propagate SolarGovernanceVoteResult through inference cycle** (d1537bf) + 3 files: src/inference/inference-cycle.ts, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts + +- **refactor: complete governance client refactor β€” callTool proxy, evaluateGovernance route, remove dead code** (770a131) + 3 files: docs/reflections/deep/release-v1.22.46-to-head-2026-05-13.md, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts + +- **refactor: use confidenceAdjustment numeric threshold instead of solarActivityLevel string for recommendation logic** (470556a) + 3 files: src/integrations/governance/index.ts + +- **feat: wire govern_with_solar as the primary governance endpoint** (72263a1) + 1 files: src/integrations/governance/index.ts, src/integrations/governance/types.ts, src/opencode/strray/features.json + +- **Revert "remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance"** (0f807e1) + 3 files: src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts, src/opencode/strray/features.json + +- **remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance** (9c34ca7) + 4 files: src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts, src/opencode/strray/features.json + +- **fix: increase opencode spawn timeout from 60s to 300s to prevent premature timeouts during agent voting** (31f0fe6) + 4 files: src/inference/inference-cycle.ts + +- **fix: initialize external governance in inference:run CLI command for two-oscillator governance** (c187e04) + 1 files: src/cli/index.ts + +- **fix: two-oscillator governance β€” trust endpoint decision, remove local confidence override** (caa444f) + 1 files: init.sh, opencode.json, package.json, src/__tests__/pipeline/test-agent-registry-pipeline.mjs, src/inference/inference-cycle.ts +2 more + +- **docs(agents): correct agent counts β€” 42 YAML agents, 22 TS routing modules** (eeee498) + 7 files: AGENTS.md, README.md + +- **refactor(config): source-of-truth pipeline β€” src/opencode/ β†’ .opencode/** (6c5909e) + 2 files: .gitignore, .opencode/activity-report.json, .opencode/agents/.gitkeep, .opencode/agents/enforcer.yml, .opencode/agents/orchestrator.yml +281 more + +- **feat: enable spawn gate monitoring mode + release reflection doc** (5746fa8) + 286 files: .opencode/activity-report.json, .opencode/logs/.strray-init.lock, .opencode/state, .strray/inference/prompts/01-researcher.md, .strray/state/state.json +2 more + +- **fix: singleton + state management to prevent recursive agent spawning** (2b2a018) + 7 files: src/cli/index.ts, src/inference/inference-cycle.ts, src/integrations/hermes-agent/bridge.mjs, src/integrations/openclaw/api-server.ts, src/mcps/orchestrator/server.ts + +- **feat: enable inference_governance + solar enhancement for monitoring** (b4d782f) + 5 files: .opencode/strray/features.json, .strray/features.json + +- **feat: wire govern_with_solar tool β€” real-time NOAA solar context into governance decisions** (4ba49d5) + 2 files: .opencode/strray/features.json, .strray/features.json, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts, src/integrations/governance/types.ts + +- **fix: add centralized OpenCode spawn gate to prevent all recursive agent spawning** (b8ff0e7) + 5 files: .opencode/activity-report.json, .opencode/logs/.strray-init.lock, .opencode/state, .opencode/strray/features.json, .strray/config.json +597 more + +- **v1.22.59** (28183e3) + 602 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/codex.codex, .opencode/command/dependency-audit.md, .opencode/commands/pre-commit-introspection.sh +184 more + +- **fix: disable auto-spawning of opencode agents to prevent runaway processes** (2948703) + 189 files: .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/commands/pre-commit-introspection.sh, .opencode/logs/.strray-init.lock +541 more + +- **v1.22.58** (30a1674) + 546 files: .strray/config.json, .strray/integrations.json + +- **v1.22.58** (2361dad) + 2 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/codex.codex, .opencode/command/dependency-audit.md, .opencode/commands/pre-commit-introspection.sh +183 more + +- **v1.22.56** (1a428c0) + 188 files: node_modules/.package-lock.json, node_modules/strray-ai/.opencode/AGENTS-consumer.md, node_modules/strray-ai/.opencode/codex.codex, node_modules/strray-ai/.opencode/commands/model-health-check.md, node_modules/strray-ai/.opencode/commands/pre-commit-introspection.sh +13120 more + +- **chore: sync config files to v1.22.56, add inference_governance feature block** (1584fd1) + 13125 files: .opencode/logs/.strray-init.lock, .strray/config.json, .strray/features.json, .strray/integrations.json, package-lock.json +1 more + +- **v1.22.57** (170472e) + 6 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +194 more + +- **feat: integrate chrono-warp-drive governance MCP for inference checking** (a61cd6f) + 199 files: .opencode/strray/integrations.json, .opencode/strray/routing-mappings.json, src/inference/inference-cycle.ts, src/integrations/governance/governance-client.ts, src/integrations/governance/index.ts +1 more + +- **Address: Bug: fix: increase timeout for processor auto-discovery tests to prevent flak... (112x)** (02d8fa9) + 6 files: .opencode/logs/.strray-init.lock, .opencode/state, .opencode/strray/features.json, .strray/inference/prompts/01-researcher.md, .strray/state/state.json +1 more + +- **chore: update strray-ai to v1.22.55, add vote scripts and reflection** (13280fd) + 6 files: .strray/config.json, .strray/inference/prompts/01-researcher.md, .strray/integrations.json, docs/reflections/deep/release-v1.22.46-to-head-2026-05-09.md, package-lock.json +7 more + +- **feat: add auto-rotation to activity logger at 5MB threshold** (ee6a4da) + 12 files: src/core/activity-logger.ts + +- **v1.22.55** (c343767) + 1 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +196 more + +- **feat: wire 3 orphaned features + add tests + remove empty api-gateway** (077b8dc) + 201 files: docs/dead-code-audit.md, docs/integration-surfaces.md, docs/target-architecture.md, src/__tests__/unit/commit-batcher-processor.test.ts, src/__tests__/unit/mcp-servers-integration.test.ts +5 more + +- **feat: wire apply phase via MCP routing + fix e2e tests (41/41 PASS)** (db8abef) + 10 files: .strray/inference/prompts/01-researcher.md, docs/reflections/apply-phase-real-code-changes-via-mcp-routing.md, scripts/test/test-opencode-e2e.mjs, src/inference/inference-cycle.ts, src/integrations/hermes-agent/bridge.mjs +3 more + +- **docs: add apply phase design β€” real code changes via MCP routing** (8eab050) + 8 files: docs/reflections/apply-phase-real-code-changes-via-mcp-routing.md + +- **revert: roll back apply phase marker system β€” needs real agent invocation via plugin/MCP routing** (10309b2) + 1 files: src/inference/inference-cycle.ts + +- **feat: wire apply phase for real code changes instead of markdown markers** (f190318) + 1 files: src/inference/inference-cycle.ts + +- **fix: remove unused imports and any type from processor-manager.interfaces.test.ts (processor-test-rules ESLint)** (529d3d2) + 1 files: src/processors/processor-manager.interfaces.test.ts + +- **fix: address all open bugs (#29-32, #34) and prevent noise PRs from inference cycle** (c32d711) + 1 files: src/__tests__/unit/security-encryption-fix.test.ts, src/enforcement/core/__tests__/violation-fixer.test.ts, src/enforcement/core/violation-fixer.ts, src/inference/inference-cycle.ts, src/processors/processor-manager.ts +2 more + +- **fix: remove enforcer references from integration test, add fetch-depth:0 for e2e git tests** (deb49f4) + 7 files: .github/workflows/ci.yml, src/__tests__/unit/integration.test.ts + +- **fix: triage and fix all GitHub workflow pipelines** (097b48c) + 2 files: .github/workflows/auto-report.yml, .github/workflows/processor-tests.yml, .github/workflows/publish.yml, .github/workflows/release.yml, .github/workflows/security-audit.yml +2 more + +- **fix: restore package.json, mcp-install.ts, workflows, and govern-reflection.mjs gutted by 84dae31b1** (7417fd6) + 7 files: .github/workflows/ci-cd-monitor.yml, .github/workflows/ci.yml, .github/workflows/enforce-agents-md.yml, .github/workflows/release.yml, .github/workflows/security.yml +6 more + +- **fix: add npm audit fix to main CI workflow** (84dae31) + 11 files: .github/workflows/ci.yml + +- **fix: run npm audit fix to resolve moderate vulnerabilities** (314cc06) + 1 files: .github/workflows/security.yml, package.json + +- **fix: remove duplicate case undefined in mcp-install.ts (lint error)** (9b713b9) + 2 files: src/cli/commands/mcp-install.ts + +- **chore: trigger ci-cd-monitor with force_fix=true** (b36970f) + 1 files: .github/force-monitor-trigger.txt + +- **ci: improve ci-cd-monitor.yml - better error handling + governance integration** (a095f17) + 1 files: .github/workflows/ci-cd-monitor.yml + +- **chore: trigger monitoring script** (0dddd30) + 1 files: .github/monitor-trigger.txt + +- **fix: make trace-context more robust + fix ESM issues in govern-reflection** (e665442) + 1 files: scripts/node/govern-reflection.mjs, src/core/trace-context.ts + +- **ci: improve all workflows - add caching, coverage, security hardening, and new governance test step** (05a8c08) + 2 files: .github/workflows/ci.yml, .github/workflows/enforce-agents-md.yml, .github/workflows/release.yml, .github/workflows/security.yml + +- **feat: add centralized TraceContext + integrate Reflection Governance with ValidatorRegistry** (1a79c88) + 4 files: scripts/node/govern-reflection.mjs, src/core/trace-context.ts + +- **feat: implement governance-approved stagger + trace propagation, add reflection governance pipeline** (27d6e29) + 2 files: docs/reflections/deep/lexicon-cross-correlation-journey-2026-05-06.md, scripts/node/govern-reflection.mjs, src/core/framework-logger.ts, src/inference/inference-cycle.ts, src/processors/processor-manager.ts + +- **v1.22.53** (6ddf31d) + 5 files: .opencode/activity-report.json, .strray/config.json, .strray/integrations.json, CHANGELOG.md, backups/version-manager-backup-2026-05-06T16-22-00-109Z/CHANGELOG.md +7 more + +- **chore: UVM sync v1.22.52 β€” all version references updated** (ce3b70e) + 12 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/codex.codex, .opencode/command/dependency-audit.md, .opencode/commands/pre-commit-introspection.sh +186 more + +- **chore: UVM sync to v1.22.51** (b53a5ac) + 191 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +184 more + +- **v1.22.51** (3d96823) + 189 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +186 more + +- **fix: agent registry cleanup β€” remove skill-only entries, delete deprecated agents** (1cafc3a) + 191 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +226 more + +- **fix: agent export naming + single-architect governance** (b5c6100) + 231 files: agents/testing-lead.yml, src/__tests__/agents/testing-lead.test.ts, src/__tests__/unit/inference/inference-cycle.test.ts, src/agents/content-creator.ts, src/agents/growth-strategist.ts +8 more + +- **fix: complete inference-cycle.ts β€” all fixes applied.** (cef1ecd) + 13 files: src/inference/inference-cycle.ts + +- **docs: deep reflection β€” inference apply phase journey (honest assessment)** (1a05086) + 1 files: docs/reflections/deep/inference-apply-phase-journey-2026-05-01.md + +- **fix: guard inference:run for StringRay internal use only** (beefefb) + 1 files: src/cli/index.ts + +- **feat: wire apply phase + researcher double-check for PRs** (7bfa4ca) + 1 files: src/cli/index.ts, src/inference/inference-cycle.ts + +- **fix: governance pipeline β€” force flag, skipDeployVerify default, deploy failure handling** (40ae8ae) + 2 files: src/cli/index.ts, src/inference/inference-cycle.ts + +- **feat: unify governance β€” wire WeightedVotingAggregator, expand agents, connect orchestrator** (fca44e6) + 2 files: .gitignore, .opencode/activity-report.json, .strray/inference/latest-workflow.json, .strray/inference/workflow-status.json, .strray/state/state.json +1321 more + +- **feat: unify governance β€” wire WeightedVotingAggregator, expand agents, connect orchestrator** (191536d) + 1326 files: dist/delegation/index.d.ts, dist/delegation/index.d.ts.map, dist/delegation/index.js, dist/delegation/index.js.map, dist/delegation/voting-coordinator.d.ts +15 more + +- **docs: governance unification saga β€” deep reflection on wiring four systems into one loop** (9cd5b8b) + 20 files: docs/reflections/deep/governance-unification-saga-2026-04-30.md + +- **feat: lower inference thresholds to trigger on real data, keep raw problem text** (c7c09a4) + 1 files: dist/inference/inference-accumulator.js, dist/inference/inference-accumulator.js.map, dist/inference/inference-cycle.d.ts.map, dist/inference/inference-cycle.js, dist/inference/inference-cycle.js.map +6 more + +- **feat: production-ready inference governance β€” CLI, real agents, DI, learning loop** (501eb8d) + 11 files: .opencode/activity-report.json, .strray/inference/latest-workflow.json, .strray/inference/workflow-status.json, .strray/state/state.json, AGENTS.md +82 more + +- **feat: inference layer β€” semantic patterns, session capture, accumulator, governance cycle, deploy verifier** (5963ce1) + 87 files: .strray/inference/latest-workflow.json, .strray/inference/workflow-status.json, dist/CHANGELOG.md, dist/inference/deploy-verifier.d.ts, dist/inference/deploy-verifier.d.ts.map +50 more + +- **fix: increase timeout for processor auto-discovery tests to prevent flaky failures** (baae755) + 55 files: src/__tests__/unit/processor-auto-discovery.test.ts + +- **fix: inference processor double-joining absolute path created bogus Users/ dir** (a795635) + 1 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +577 more + +- **chore: v1.22.48, add prepublishOnly to strip source maps and declarations** (112ef89) + 582 files: .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex, .opencode/command/dependency-audit.md +303 more + +- **chore: v1.22.47, add .npmignore to strip .d.ts and source maps from package** (e2f7225) + 308 files: .npmignore, .opencode/.strrayrc.json, .opencode/AGENTS-consumer.md, .opencode/activity-report.json, .opencode/codex.codex +248 more + +- **chore: remove 92 build artifacts (.d.ts, .d.ts.map) from .opencode git tracking, add to .gitignore** (22f9ddf) + 253 files: .gitignore, .opencode/activity-report.json, .opencode/core/activity-logger.d.ts.map, .opencode/core/adaptive-kernel.d.ts.map, .opencode/core/boot-orchestrator.d.ts.map +59 more + +- **docs: the engine that built the engine β€” deep reflection on the meta-system, consumer tweet, release reflection** (522c28b) + 64 files: AGENTS.md, docs/reflections/deep/release-v1.22.46-to-head-2026-04-29.md, docs/reflections/deep/the-engine-that-built-the-engine-saga-2026-04-29.md, tweets/v1.22.46.md + +- **chore: rebuild dist after path fix** (4453c41) + 4 files: .strray/codex.json, .strray/config.json, .strray/features.json, .strray/integrations.json, dist/AGENTS.md + +## Files Added + +*(none)* + +## Files Modified + +*(none)* + +## Patterns Observed + +- Bug fixes present β€” stability improvement +- Refactoring detected β€” architectural debt being addressed +- Version bumps/releases present β€” release cadence active + +## Key Decisions + +- Structural change: fix: replace console.log with frameworkLogger in governance-client; propagate SolarGovernanceVoteResult through inference cycle +- Structural change: refactor: complete governance client refactor β€” callTool proxy, evaluateGovernance route, remove dead code +- Structural change: refactor: use confidenceAdjustment numeric threshold instead of solarActivityLevel string for recommendation logic +- Removal: Revert "remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance" +- Removal: remove solar enhancement overlay β€” endpoint already consumes NOAA GOES natively via dynamo___evaluate_governance +- Fix: fix: increase opencode spawn timeout from 60s to 300s to prevent premature timeouts during agent voting +- Fix: fix: initialize external governance in inference:run CLI command for two-oscillator governance +- Fix: fix: two-oscillator governance β€” trust endpoint decision, remove local confidence override +- Structural change: refactor(config): source-of-truth pipeline β€” src/opencode/ β†’ .opencode/ +- Fix: fix: singleton + state management to prevent recursive agent spawning +- Fix: fix: add centralized OpenCode spawn gate to prevent all recursive agent spawning +- Fix: fix: disable auto-spawning of opencode agents to prevent runaway processes +- Fix: Address: Bug: fix: increase timeout for processor auto-discovery tests to prevent flak... (112x) +- Removal: feat: wire 3 orphaned features + add tests + remove empty api-gateway +- Fix: feat: wire apply phase via MCP routing + fix e2e tests (41/41 PASS) +- Fix: fix: remove unused imports and any type from processor-manager.interfaces.test.ts (processor-test-rules ESLint) +- Fix: fix: address all open bugs (#29-32, #34) and prevent noise PRs from inference cycle +- Fix: fix: remove enforcer references from integration test, add fetch-depth:0 for e2e git tests +- Fix: fix: triage and fix all GitHub workflow pipelines +- Fix: fix: restore package.json, mcp-install.ts, workflows, and govern-reflection.mjs gutted by 84dae31b1 +- Fix: fix: add npm audit fix to main CI workflow +- Fix: fix: run npm audit fix to resolve moderate vulnerabilities +- Fix: fix: remove duplicate case undefined in mcp-install.ts (lint error) +- Fix: chore: trigger ci-cd-monitor with force_fix=true +- Fix: fix: make trace-context more robust + fix ESM issues in govern-reflection +- Fix: fix: agent registry cleanup β€” remove skill-only entries, delete deprecated agents +- Fix: fix: agent export naming + single-architect governance +- Fix: fix: complete inference-cycle.ts β€” all fixes applied. +- Fix: fix: guard inference:run for StringRay internal use only +- Fix: fix: governance pipeline β€” force flag, skipDeployVerify default, deploy failure handling +- Fix: fix: increase timeout for processor auto-discovery tests to prevent flaky failures +- Fix: fix: inference processor double-joining absolute path created bogus Users/ dir +- Removal: chore: remove 92 build artifacts (.d.ts, .d.ts.map) from .opencode git tracking, add to .gitignore +- Fix: chore: rebuild dist after path fix + +## Inference Notes + +- Active development session: 78 commits across 0 areas + +--- +*Generated by StorytellingTriggerProcessor β€” release cadence β€” 2026-05-15T08:04:16.012Z* \ No newline at end of file diff --git a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json index e69de29bb..93e6435ce 100644 --- a/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +++ b/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json @@ -0,0 +1 @@ +{"version":"4.0.18","results":[[":src/enforcement/validators/__tests__/architecture-validators.test.ts",{"duration":39.38712499999997,"failed":false}],[":src/enforcement/validators/__tests__/testing-validators.test.ts",{"duration":33.59137499999997,"failed":false}],[":src/core/codex-formatter.test.ts",{"duration":142.95191699999998,"failed":false}],[":src/metrics/agent-metrics.test.ts",{"duration":56.41683400000005,"failed":false}],[":src/__tests__/unit/agent-delegator.test.ts",{"duration":1304.35525,"failed":false}],[":src/enforcement/loaders/__tests__/loaders.test.ts",{"duration":157.72533399999998,"failed":false}],[":src/__tests__/unit/processor-activation.test.ts",{"duration":293.19075,"failed":false}],[":src/__tests__/unit/context-loader.test.ts",{"duration":133.804167,"failed":false}],[":src/__tests__/unit/processors/processor-implementations.test.ts",{"duration":251.4357500000001,"failed":false}],[":src/enforcement/validators/__tests__/security-validators.test.ts",{"duration":50.014749999999935,"failed":false}],[":src/integrations/base/registry.test.ts",{"duration":163.82408299999997,"failed":false}],[":src/integrations/openclaw/hooks/strray-hooks.test.ts",{"duration":46.43724999999995,"failed":false}],[":src/mcps/config/__tests__/config-validator.test.ts",{"duration":162.6055,"failed":false}],[":src/integrations/plugins/plugin.test.ts",{"duration":430.134625,"failed":false}],[":src/__tests__/unit/spawn-governance-processor.test.ts",{"duration":51.516458,"failed":false}],[":src/enforcement/core/__tests__/rule-executor.test.ts",{"duration":207.33520899999996,"failed":false}],[":src/integrations/base/Integration.test.ts",{"duration":39.553707999999915,"failed":false}],[":src/__tests__/orchestrator/agent-spawn-governor.test.ts",{"duration":30.435917000000018,"failed":false}],[":src/enforcement/validators/__tests__/code-quality-validators.test.ts",{"duration":121.11491700000005,"failed":false}],[":src/enforcement/core/__tests__/rule-registry.test.ts",{"duration":80.46691600000003,"failed":false}],[":src/__tests__/unit/connection/mcp-connection.test.ts",{"duration":180.51191600000004,"failed":false}],[":src/__tests__/unit/self-direction-activation.test.ts",{"duration":15.010459000000026,"failed":false}],[":src/__tests__/unit/analyzer.test.ts",{"duration":54.152458000000024,"failed":false}],[":src/__tests__/unit/metrics-aggregator.test.ts",{"duration":31.359375,"failed":false}],[":src/__tests__/unit/security/security-hardener.test.ts",{"duration":49.760042,"failed":false}],[":src/__tests__/postprocessor/escalation/EscalationEngine.test.ts",{"duration":736.5991250000001,"failed":false}],[":src/integrations/openclaw/types.test.ts",{"duration":30.717208000000028,"failed":false}],[":src/__tests__/unit/rule-enforcer.test.ts",{"duration":799.402625,"failed":false}],[":src/__tests__/unit/connection/connection-pool.test.ts",{"duration":384.38358300000004,"failed":false}],[":src/security/comprehensive-security-audit.test.ts",{"duration":3.3008749999999907,"failed":false}],[":src/__tests__/unit/config-loader.test.ts",{"duration":50.86624999999998,"failed":false}],[":src/__tests__/e2e/integrations-e2e.test.ts",{"duration":90804.642625,"failed":true}],[":src/__tests__/unit/state-manager-persistence.test.ts",{"duration":1204.1315,"failed":false}],[":src/delegation/analytics/__tests__/outcome-tracker.test.ts",{"duration":212.760625,"failed":false}],[":src/__tests__/unit/session-monitor-health.test.ts",{"duration":281.49425,"failed":false}],[":src/__tests__/kernel-integration.test.ts",{"duration":94.524583,"failed":false}],[":src/__tests__/integration/e2e-orchestration-flow.test.ts",{"duration":542.455875,"failed":false}],[":src/delegation/analytics/__tests__/routing-analytics.test.ts",{"duration":81.94179099999997,"failed":false}],[":src/__tests__/integration/json-codex-integration.test.ts",{"duration":30.276875000000018,"failed":false}],[":src/__tests__/integration/commit-batching-enforcement-integration.test.ts",{"duration":241.70450000000005,"failed":false}],[":src/mcps/config/__tests__/config-loader.test.ts",{"duration":77.31187499999993,"failed":false}],[":src/__tests__/unit/typescript-compilation-processor.test.ts",{"duration":88.569167,"failed":false}],[":src/enforcement/core/__tests__/rule-hierarchy.test.ts",{"duration":143.46962499999995,"failed":false}],[":src/__tests__/unit/codex-parser.test.ts",{"duration":35.338459,"failed":false}],[":src/__tests__/unit/voting-coordinator.test.ts",{"duration":186.2727500000001,"failed":false}],[":src/__tests__/integration/framework-init.test.ts",{"duration":285.73825,"failed":false}],[":src/mcps/types/__tests__/types.test.ts",{"duration":22.318833000000012,"failed":false}],[":src/__tests__/agents/testing-lead.test.ts",{"duration":59.226125000000025,"failed":false}],[":src/__tests__/integration/processors.test.ts",{"duration":9025.875375000001,"failed":false}],[":src/__tests__/unit/orchestrator.test.ts",{"duration":1129.312709,"failed":false}],[":src/__tests__/agents/bug-triage-specialist.test.ts",{"duration":19.62025,"failed":false}],[":src/__tests__/agents/refactorer.test.ts",{"duration":14.0625,"failed":false}],[":src/__tests__/postprocessor/success/SuccessHandler.test.ts",{"duration":1399.700666,"failed":false}],[":src/core/features-config.test.ts",{"duration":9.465749999999986,"failed":false}],[":src/__tests__/unit/multimodal-looker.test.ts",{"duration":44.619958999999994,"failed":false}],[":src/__tests__/agents/security-auditor.test.ts",{"duration":62.64695800000004,"failed":false}],[":src/mcps/simulation/__tests__/simulation-engine.test.ts",{"duration":33.837917000000004,"failed":false}],[":src/__tests__/unit/connection/connection-manager.test.ts",{"duration":20.613584000000003,"failed":false}],[":src/__tests__/e2e/inference-e2e.test.ts",{"duration":43482.394333000004,"failed":true}],[":src/enforcement/core/__tests__/violation-fixer.test.ts",{"duration":28.160957999999994,"failed":false}],[":src/__tests__/unit/activity-logger.test.ts",{"duration":457.3868329999999,"failed":false}],[":src/__tests__/unit/security/security-headers.test.ts",{"duration":18.670833000000016,"failed":false}],[":src/__tests__/unit/codex-injector.test.ts",{"duration":29.320875,"failed":false}],[":src/__tests__/unit/async-pattern-processor.test.ts",{"duration":28.67829100000006,"failed":false}],[":src/__tests__/unit/inference/inference-cycle.test.ts",{"duration":2555.8139170000004,"failed":false}],[":src/mcps/config/__tests__/server-config-registry.test.ts",{"duration":169.965375,"failed":false}],[":src/__tests__/unit/performance-budget-processor.test.ts",{"duration":212.676,"failed":false}],[":src/__tests__/unit/analytics/consent-manager.test.ts",{"duration":56.96041700000001,"failed":false}],[":src/__tests__/integration/oh-my-opencode-integration.test.ts",{"duration":12.12991599999998,"failed":false}],[":src/__tests__/infrastructure/infrastructure.test.ts",{"duration":45.732624999999985,"failed":false}],[":src/__tests__/unit/complexity-analyzer-calibration.test.ts",{"duration":11.536375000000021,"failed":false}],[":src/processors/processor-manager.interfaces.test.ts",{"duration":35.782332999999994,"failed":false}],[":src/__tests__/unit/postprocessor-chain-validator.test.ts",{"duration":12.101624999999984,"failed":false}],[":src/mcps/tools/__tests__/tool-registry.test.ts",{"duration":12.429291000000006,"failed":false}],[":src/metrics/agent-metrics.integration.test.ts",{"duration":14.730917000000005,"failed":false}],[":src/orchestrator/enhanced-multi-agent-orchestrator.interfaces.test.ts",{"duration":16.786083000000005,"failed":false}],[":src/__tests__/integration/codex-enforcement.test.ts",{"duration":14.606332999999992,"failed":false}],[":src/__tests__/unit/console-log-guard-processor.test.ts",{"duration":12.03245800000002,"failed":false}],[":src/__tests__/agents/types.test.ts",{"duration":11.183958999999987,"failed":false}],[":src/__tests__/unit/security/security-auditor.test.ts",{"duration":24.76925,"failed":false}],[":src/__tests__/unit/auto-reflection-generation.test.ts",{"duration":691.033709,"failed":false}],[":src/__tests__/unit/pattern-analyzer.test.ts",{"duration":23.447208999999987,"failed":false}],[":src/__tests__/integration/inference-pipeline.test.ts",{"duration":120.022292,"failed":false}],[":src/__tests__/unit/mcp-servers-integration.test.ts",{"duration":11.059540999999996,"failed":false}],[":src/__tests__/unit/state-manager.test.ts",{"duration":301.92633400000005,"failed":false}],[":src/mcps/tools/__tests__/tool-cache.test.ts",{"duration":19.957416999999964,"failed":false}],[":src/__tests__/unit/processor-registry.test.ts",{"duration":4420.041125000001,"failed":false}],[":src/__tests__/unit/boot-orchestrator.test.ts",{"duration":1417.142667,"failed":false}],[":src/__tests__/integration/codex-enforcement-e2e.test.ts",{"duration":98.19554200000005,"failed":false}],[":src/orchestrator/orchestrator.interfaces.test.ts",{"duration":10.479541999999995,"failed":false}],[":src/mcps/tools/__tests__/tool-executor.test.ts",{"duration":13.767250000000018,"failed":false}],[":src/__tests__/unit/session-coordination-validator.test.ts",{"duration":9.395083,"failed":false}],[":src/__tests__/framework-enforcement-integration.test.ts",{"duration":271.4175,"failed":false}],[":src/__tests__/integration/script-execution.test.ts",{"duration":396.263583,"failed":false}],[":src/__tests__/unit/strategy-selector.test.ts",{"duration":7.363292000000001,"failed":false}],[":src/__tests__/unit/processor-auto-discovery.test.ts",{"duration":20846.415167000003,"failed":false}],[":src/__tests__/unit/benchmark.test.ts",{"duration":7.742625000000004,"failed":false}],[":src/__tests__/cli/publish-agent.test.ts",{"duration":12.069832999999988,"failed":false}],[":src/__tests__/unit/agent-registry.test.ts",{"duration":11.059750000000008,"failed":false}],[":src/__tests__/unit/analytics.test.ts",{"duration":4.625165999999979,"failed":false}],[":src/__tests__/unit/agent-registry-consistency.test.ts",{"duration":45.73400000000004,"failed":false}],[":src/__tests__/integration/agent-registry-integration.test.ts",{"duration":186.77554199999997,"failed":false}],[":src/delegation/analytics/__tests__/learning-engine.test.ts",{"duration":124.84091699999999,"failed":false}],[":src/__tests__/unit/session-health-monitoring.test.ts",{"duration":184.138958,"failed":false}],[":src/__tests__/unit/voting-types.test.ts",{"duration":9.874583999999999,"failed":false}],[":src/__tests__/unit/report-formatter.test.ts",{"duration":43.279584,"failed":false}],[":src/__tests__/integration/orchestration-e2e.test.ts",{"duration":7.291291000000001,"failed":false}],[":src/__tests__/unit/inference/inference-accumulator.test.ts",{"duration":107.83833300000003,"failed":false}],[":src/__tests__/agents/code-reviewer.test.ts",{"duration":23.214459000000033,"failed":false}],[":src/__tests__/cli/antigravity-status.test.ts",{"duration":8.95754199999999,"failed":false}],[":src/enforcement/loaders/__tests__/codex-validators.test.ts",{"duration":51.835707999999954,"failed":false}],[":src/mcps/tools/__tests__/tool-discovery.test.ts",{"duration":30.393584000000033,"failed":false}],[":src/__tests__/integration/server.test.ts",{"duration":44.05429200000003,"failed":false}],[":src/__tests__/framework-logger-persistence.test.ts",{"duration":16.138250000000028,"failed":false}],[":src/__tests__/integration/security/security-integration.test.ts",{"duration":14.524083999999988,"failed":false}],[":src/__tests__/integration/processor-manager-reuse.test.ts",{"duration":8.76570799999999,"failed":false}],[":src/__tests__/cli/credible-init.test.ts",{"duration":16.543915999999996,"failed":false}],[":src/__tests__/unit/connection/process-spawner.test.ts",{"duration":33.834749999999985,"failed":false}],[":src/__tests__/unit/session-migration-logic.test.ts",{"duration":128.00020800000004,"failed":false}],[":src/__tests__/unit/nudge-watchdog.test.ts",{"duration":17.240083,"failed":false}],[":src/__tests__/unit/inference/session-capture.test.ts",{"duration":32311.803333,"failed":false}],[":src/__tests__/unit/agent-expertise.test.ts",{"duration":8.835667,"failed":false}],[":src/mcps/knowledge-skills/testing-best-practices.server.test.ts",{"duration":59.28004199999987,"failed":false}],[":src/__tests__/agents/index.test.ts",{"duration":15.401625000000024,"failed":false}],[":src/__tests__/unit/commit-batcher-processor.test.ts",{"duration":9.948791,"failed":false}],[":src/__tests__/unit/session-migration-validator.test.ts",{"duration":8.458666999999991,"failed":false}],[":src/__tests__/unit/integration.test.ts",{"duration":1747.100583,"failed":false}],[":src/__tests__/integration/orchestrator/concurrent-execution.test.ts",{"duration":27.81087500000001,"failed":false}],[":src/__tests__/e2e/post-processor-pipeline-e2e.test.ts",{"duration":4433.516625,"failed":false}],[":src/mcps/knowledge-skills/code-analyzer.server.test.ts",{"duration":110.05033299999991,"failed":false}],[":src/__tests__/cli/status.test.ts",{"duration":9.294999999999987,"failed":false}],[":src/mcps/knowledge-skills/security-audit.server.test.ts",{"duration":38.368416000000025,"failed":false}],[":src/__tests__/unit/monitoring.test.ts",{"duration":6.6875,"failed":false}],[":src/__tests__/unit/security-encryption-fix.test.ts",{"duration":190.31437499999993,"failed":false}],[":src/__tests__/agents/architect.test.ts",{"duration":8.196082999999987,"failed":false}],[":src/__tests__/unit/default-agents.test.ts",{"duration":52.54208299999999,"failed":false}],[":src/__tests__/integration/orchestrator/dependency-handling.test.ts",{"duration":16.189750000000004,"failed":false}],[":src/mcps/knowledge-skills/testing-strategy.server.test.ts",{"duration":24.784042,"failed":false}],[":src/__tests__/unit/session-security-validator.test.ts",{"duration":11.015375000000006,"failed":false}],[":src/__tests__/integration/postprocessor-integration.test.ts",{"duration":48.026374999999916,"failed":false}],[":src/__tests__/integration/test-complexity-analysis.test.ts",{"duration":9.822874999999982,"failed":false}],[":src/__tests__/unit/inference/semantic-patterns.test.ts",{"duration":31966.50025,"failed":false}],[":src/__tests__/integration/orchestrator/basic-orchestrator.test.ts",{"duration":7.7357920000000036,"failed":false}],[":src/utils/language-detector.test.ts",{"duration":7.593334000000027,"failed":false}],[":src/integrations/openclaw/openclaw-integration.test.ts",{"duration":6.848834000000011,"failed":false}],[":src/__tests__/utils/test-helpers.test.ts",{"duration":6.281666000000001,"failed":false}],[":src/__tests__/unit/processor-registration.test.ts",{"duration":3.5867079999999874,"failed":false}],[":src/__tests__/unit/inference/deploy-verifier.test.ts",{"duration":6.232208000000014,"failed":false}],[":src/__tests__/unit/blocked-test.test.ts",{"duration":3.4157089999999926,"failed":false}],[":src/mcps/knowledge-skills/api-design.server.test.ts",{"duration":12.650917000000021,"failed":false}],[":src/governance/__tests__/AgentInvokerFactory.test.ts",{"duration":2.1592079999999783,"failed":false}],[":src/governance/__tests__/OpenCodeAgentInvoker.test.ts",{"duration":4.210749999999962,"failed":false}],[":src/governance/__tests__/MCPAgentInvoker.test.ts",{"duration":5.473542000000009,"failed":false}]]} \ No newline at end of file diff --git a/node_modules/strray-ai/dist/AGENTS.md b/node_modules/strray-ai/dist/AGENTS.md index 586e0b6e0..5b190517b 100644 --- a/node_modules/strray-ai/dist/AGENTS.md +++ b/node_modules/strray-ai/dist/AGENTS.md @@ -120,10 +120,14 @@ The storyteller is now a **skill** (not an agent) so it runs with full session c ## Available Agents +**42 OpenCode agents** defined by YAML configs in `src/opencode/agents/` (copied to `.opencode/agents/` during build). These are the agents OpenCode reads and routes to. + +**22 internal routing modules** in `src/agents/*.ts` β€” TypeScript implementations that handle delegation, spawning, and orchestration logic. These are framework internals, not OpenCode agents. + +### Primary Agents (7) + | Agent | Purpose | Invoke | |-------|---------|--------| -| `@enforcer` | Codex compliance & error prevention | `@enforcer analyze this code` | -| `@orchestrator` | Complex multi-step task coordination | `@orchestrator implement feature` | | `@architect` | System design & technical decisions | `@architect design API` | | `@security-auditor` | Vulnerability detection | `@security-auditor scan` | | `@code-reviewer` | Quality assessment | `@code-reviewer review PR` | @@ -132,6 +136,12 @@ The storyteller is now a **skill** (not an agent) so it runs with full session c | `@bug-triage-specialist` | Error investigation | `@bug-triage-specialist debug error` | | `@researcher` | Codebase exploration | `@researcher find implementation` | +### Subagent / Skill-Based Agents (35) + +The remaining 35 agents are specialized subagents mapped to specific skills. They are invoked automatically by the routing system based on keywords and complexity analysis. See `src/opencode/strray/routing-mappings.json` for the full keyword-to-agent mapping. + +> **Architecture Note**: Agents are defined by YAML configs (`src/opencode/agents/*.yml`), not by TypeScript files. The TypeScript files in `src/agents/` are internal routing implementations used by the delegation system. When you invoke `@architect`, OpenCode reads `.opencode/agents/architect.yml` β€” not `src/agents/architect.ts`. + ## Available Skills @@ -518,34 +528,35 @@ npx strray-ai report --ci --output json # In code comment or prompt @architect design a REST API for user management -@enforcer analyze this code for security issues +@code-reviewer review this pull request @testing-lead create tests for authentication module ``` **Chaining Agents**: ``` -@orchestrator implement feature:user-authentication - β†’ Spawns @architect β†’ @testing-lead β†’ @code-reviewer +@architect design feature:user-authentication + β†’ Spawns @testing-lead β†’ @code-reviewer ``` ### Agent Selection Guide | Task Type | Primary Agent | Supporting Agents | |-----------|---------------|-------------------| -| New feature | @orchestrator | @architect, @testing-lead | -| Bug fix | @bug-triage-specialist | @enforcer, @code-reviewer | +| New feature | @architect | @testing-lead, @code-reviewer | +| Bug fix | @bug-triage-specialist | @code-reviewer | | Refactor | @refactorer | @architect, @testing-lead | -| Security audit | @security-auditor | @enforcer | -| Code review | @code-reviewer | @enforcer | +| Security audit | @security-auditor | @code-reviewer | +| Code review | @code-reviewer | @architect | | Research | @researcher | @architect | +``` ### Session Management **Start a Session**: ```bash # Sessions are automatic - invoke agent to start -@orchestrator implement login feature +@architect design login feature ``` **View Active Sessions**: diff --git a/node_modules/strray-ai/dist/README.md b/node_modules/strray-ai/dist/README.md index e7e094359..ea6f8bfbf 100644 --- a/node_modules/strray-ai/dist/README.md +++ b/node_modules/strray-ai/dist/README.md @@ -47,7 +47,7 @@ npm install strray-ai **What happens during install?** - Copies OpenCode configuration files to your project -- Configures 26 agents with proper capabilities +- Configures 42 agents with proper capabilities - Sets up Codex enforcement rules - Enables webhook triggers for CI/CD integration - Ready to use with Hermes immediately @@ -64,7 +64,7 @@ This installs only the MCP servers - no OpenCode dependency. ## ✨ Features -- **πŸ€– 24 Specialized Agents** - Autonomous agents that read/write code, run commands, and enforce compliance +- **πŸ€– 42 Specialized Agents** - Autonomous agents that read/write code, run commands, and enforce compliance - **πŸ“ 99.6% Error Prevention** - Universal Development Codex (60 terms) - **⚑ 44 Framework Skills** + 10 curated community sources (170+ additional skills available) - **πŸ›‘οΈ Enterprise Security** - Comprehensive validation and scanning @@ -86,16 +86,10 @@ This installs only the MCP servers - no OpenCode dependency. | `@testing-lead` | Testing strategy & coverage | Active | | `@bug-triage-specialist` | Error investigation | Active | | `@researcher` | Codebase exploration | Active | -| ~~`@enforcer`~~ | ~~Codex compliance & error prevention~~ | **DEPRECATED** | -| ~~`@orchestrator`~~ | ~~Complex multi-step task coordination~~ | **DEPRECATED** | - -> **Architecture Note (2026-04-17)**: `@enforcer` and `@orchestrator` are deprecated. -> - **Enforcement** is now handled by the **plugin-level preValidate processor** and **MCP servers** -> - **Orchestration** is now handled by **agent-delegator** based on **complexity analysis** > **Note:** 0xRay auto-configures all agents during installation. To customize agent settings, see the [Agent Configuration Guide](https://github.com/htafolla/stringray/blob/master/docs/AGENT_CONFIG.md). -[View all 26 agents β†’](https://github.com/htafolla/stringray/blob/master/AGENTS.md) +[View all 42 agents β†’](https://github.com/htafolla/stringray/blob/master/AGENTS.md) ## πŸ“¦ OpenClaw Integration @@ -285,7 +279,7 @@ npx strray-ai antigravity status # Show installed skills with licenses ``` .opencode/ -β”œβ”€β”€ agents/ # 24 agent configurations +β”œβ”€β”€ agents/ # 42 agent configurations (YAML configs) β”œβ”€β”€ skills/ # Framework skills β”œβ”€β”€ strray/ β”‚ β”œβ”€β”€ codex.json # Codex rules @@ -385,7 +379,7 @@ stringray/ β”‚ β”œβ”€β”€ validation/ # Agent config & estimation validators β”‚ └── jobs/ # Background job management β”œβ”€β”€ .opencode/ # OpenCode configuration -β”‚ β”œβ”€β”€ agents/ # Agent configs (26 agents) +β”‚ β”œβ”€β”€ agents/ # Agent configs (42 agents) β”‚ β”œβ”€β”€ strray/ # 0xRay config β”‚ β”‚ β”œβ”€β”€ codex.json # 60-term development codex β”‚ β”‚ β”œβ”€β”€ features.json # Feature flags @@ -401,17 +395,17 @@ stringray/ ## πŸ’¬ Usage ```bash -# Code quality enforcement -@enforcer analyze this code for issues - -# Complex task orchestration -@orchestrator implement user authentication system - # System design @architect design database schema for e-commerce # Security audit @security-auditor scan for vulnerabilities + +# Code review +@code-reviewer review authentication module + +# Testing +@testing-lead create tests for payment system ``` ## πŸ”Œ Framework Integration diff --git a/node_modules/strray-ai/dist/cli/commands/publish-agent.js b/node_modules/strray-ai/dist/cli/commands/publish-agent.js index f82d0a35b..a65553846 100644 --- a/node_modules/strray-ai/dist/cli/commands/publish-agent.js +++ b/node_modules/strray-ai/dist/cli/commands/publish-agent.js @@ -41,6 +41,7 @@ function parseArgs() { } function getAgentConfig(agentName, cwd) { const configPaths = [ + join(cwd, "src", "opencode", "agents", `${agentName}.yml`), join(cwd, "agents", `${agentName}.yml`), join(cwd, ".opencode", "agents", `${agentName}.yml`), join(cwd, "agents", `${agentName}.yaml`), @@ -130,6 +131,7 @@ export async function publishAgentCommand() { console.error(`❌ Error: Agent '${options.agent}' not found`); console.log(""); console.log("Searched locations:"); + console.log(` β€’ src/opencode/agents/${options.agent}.yml`); console.log(` β€’ agents/${options.agent}.yml`); console.log(` β€’ .opencode/agents/${options.agent}.yml`); console.log(""); diff --git a/node_modules/strray-ai/dist/cli/index.js b/node_modules/strray-ai/dist/cli/index.js index ef9da0413..3bf84f720 100755 --- a/node_modules/strray-ai/dist/cli/index.js +++ b/node_modules/strray-ai/dist/cli/index.js @@ -42,46 +42,42 @@ program .name("strray-ai") .description("0xRay: Bulletproof AI orchestration with systematic error prevention") .version(version); +function runSetup() { + const setupScript = join(packageRoot, "scripts", "node", "setup.cjs"); + validateScriptPath(setupScript, "setup script"); + execSync(`node "${setupScript}"`, { stdio: "inherit", cwd: process.cwd() }); +} program .command("install") .description("Install 0xRay framework in the current project") .action(async () => { console.log("πŸ”§ 0xRay CLI: Installing framework..."); try { - // Run the postinstaller script const postinstallScript = join(packageRoot, "scripts", "node", "postinstall.cjs"); - // SECURITY: Validate script path before execution validateScriptPath(postinstallScript, "postinstall script"); - execSync(`node "${postinstallScript}"`, { - stdio: "inherit", - cwd: process.cwd(), - }); - console.log("βœ… 0xRay framework installed successfully!"); - console.log(""); - console.log("πŸ“‹ Next steps:"); - console.log("1. Restart OpenCode to load the plugin"); - console.log('2. Run "opencode agent list" to see 0xRay agents'); - console.log('3. Try "@architect analyze this code" or "@security-auditor scan" to test the plugin'); + execSync(`node "${postinstallScript}"`, { stdio: "inherit", cwd: process.cwd() }); + console.log("βœ… 0xRay framework installed!"); + console.log("πŸ’‘ Run 'npx strray-ai setup' for full configuration (hooks, Hermes, symlinks)"); } catch (error) { console.error("❌ Installation failed:", error instanceof Error ? error.message : String(error)); process.exit(1); } }); +program + .command("setup") + .description("Full framework setup: hooks, Hermes integration, symlinks, MCP paths") + .action(runSetup); program .command("init") .description("Initialize 0xRay configuration in the current project") .action(async () => { console.log("πŸš€ 0xRay CLI: Initializing configuration..."); try { - // Run the postinstaller script (same as install) const postinstallScript = join(packageRoot, "scripts", "node", "postinstall.cjs"); - // SECURITY: Validate script path before execution validateScriptPath(postinstallScript, "postinstall script"); - execSync(`node "${postinstallScript}"`, { - stdio: "inherit", - cwd: process.cwd(), - }); + execSync(`node "${postinstallScript}"`, { stdio: "inherit", cwd: process.cwd() }); + runSetup(); console.log("βœ… 0xRay configuration initialized!"); } catch (error) { @@ -692,6 +688,7 @@ program const { shouldTriggerCycle } = await import('../inference/inference-accumulator.js'); const { accumulateCorpus } = await import('../inference/inference-accumulator.js'); const { featuresConfigLoader } = await import('../core/features-config.js'); + const { initializeGovernanceIntegration, shutdownGovernanceIntegration } = await import('../integrations/governance/index.js'); // Guard: inference:run is internal to StringRay development only const isStringRayRepo = (() => { try { @@ -757,7 +754,13 @@ program console.log(` Recurring problems: ${corpus.recurringProblems.length}`); console.log(` Recurring patterns: ${corpus.recurringPatterns.length}`); } - const cycle = new InferenceCycle(projectRoot, undefined, { skipDeployVerify: options.noVerify ?? true, skipApply: options.noApply ?? false, skipResearcherReview: options.noResearcherReview ?? false, force: options.force ?? false }); + // Initialize external governance integration for two-oscillator governance + const govConfig = features?.inference_governance; + if (govConfig?.enabled) { + await shutdownGovernanceIntegration(); + await initializeGovernanceIntegration(); + } + const cycle = InferenceCycle.getInstance(projectRoot, { skipDeployVerify: options.noVerify ?? true, skipApply: options.noApply ?? false, skipResearcherReview: options.noResearcherReview ?? false, force: options.force ?? false }); const result = await cycle.maybeRunCycle(); if (options.json) { console.log(JSON.stringify(result, null, 2)); diff --git a/node_modules/strray-ai/dist/integrations/hermes-agent/bridge.mjs b/node_modules/strray-ai/dist/integrations/hermes-agent/bridge.mjs index 89e07ac92..662932a05 100644 --- a/node_modules/strray-ai/dist/integrations/hermes-agent/bridge.mjs +++ b/node_modules/strray-ai/dist/integrations/hermes-agent/bridge.mjs @@ -705,7 +705,7 @@ async function handleGovern(input, projectRoot, logDir) { try { const { InferenceCycle } = await import("../../inference/inference-cycle.js"); - const cycle = new InferenceCycle(projectRoot, undefined, { skipApply: true }); + const cycle = InferenceCycle.getInstance(projectRoot, { skipApply: true }); const result = await cycle.governExternalProposals(proposals); return { cycleId: result.cycleId, @@ -726,7 +726,7 @@ async function handleApply(input, projectRoot, logDir) { try { const { InferenceCycle } = await import("../../inference/inference-cycle.js"); - const cycle = new InferenceCycle(projectRoot); + const cycle = InferenceCycle.getInstance(projectRoot); const result = await cycle.governExternalProposals(proposals); return { cycleId: result.cycleId, diff --git a/node_modules/strray-ai/dist/mcps/config/plugin-server-registry.js b/node_modules/strray-ai/dist/mcps/config/plugin-server-registry.js index 47f880bbc..f3c24617f 100644 --- a/node_modules/strray-ai/dist/mcps/config/plugin-server-registry.js +++ b/node_modules/strray-ai/dist/mcps/config/plugin-server-registry.js @@ -8,7 +8,7 @@ */ import { ServerConfigRegistry, defaultServerRegistry } from "./server-config-registry.js"; import { PluginType } from "../../integrations/plugins/plugin-integration.js"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; /** * ServerConfigRegistry with plugin support */ diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/api-design.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/api-design.server.js index 798a05416..a5d53616a 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/api-design.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/api-design.server.js @@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRayApiDesignServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/architecture-patterns.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/architecture-patterns.server.js index b4546ef00..4f166aafa 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/architecture-patterns.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/architecture-patterns.server.js @@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRayArchitecturePatternsServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/code-analyzer.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/code-analyzer.server.js index c9b2b81ef..8dbb4cc9f 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/code-analyzer.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/code-analyzer.server.js @@ -14,7 +14,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class CodeAnalyzerServer { server; tools = [ diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/code-review.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/code-review.server.js index 62ee8ee00..f7c03068a 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/code-review.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/code-review.server.js @@ -9,7 +9,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRayCodeReviewServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/database-design.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/database-design.server.js index d92a6d94b..dcdba97c2 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/database-design.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/database-design.server.js @@ -9,7 +9,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRayDatabaseDesignServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/devops-deployment.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/devops-deployment.server.js index 0272507a4..fa94660de 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/devops-deployment.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/devops-deployment.server.js @@ -6,7 +6,7 @@ */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; class StringRayDevOpsDeploymentServer { server; diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/git-workflow.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/git-workflow.server.js index 44e60d7f8..3b0d83080 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/git-workflow.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/git-workflow.server.js @@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRayGitWorkflowServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/performance-optimization.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/performance-optimization.server.js index 4f57257dd..470801878 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/performance-optimization.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/performance-optimization.server.js @@ -7,8 +7,8 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { frameworkLogger, generateJobId } from "../../dist/core/framework-logger.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { frameworkLogger, generateJobId } from "../../core/framework-logger.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; import fs from "fs"; import path from "path"; class StringRayPerformanceOptimizationServer { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/project-analysis.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/project-analysis.server.js index defc4b7ae..6ff21fb1c 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/project-analysis.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/project-analysis.server.js @@ -9,7 +9,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; class StringRayProjectAnalysisServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/refactoring-strategies.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/refactoring-strategies.server.js index d295d75f7..9e130a9b8 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/refactoring-strategies.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/refactoring-strategies.server.js @@ -6,7 +6,7 @@ */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; class StringRayRefactoringStrategiesServer { server; diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/security-audit.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/security-audit.server.js index 6ffba8fff..1f9067040 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/security-audit.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/security-audit.server.js @@ -9,7 +9,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRaySecurityAuditServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/seo-consultant.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/seo-consultant.server.js index 730aed4fe..f293f586e 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/seo-consultant.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/seo-consultant.server.js @@ -8,7 +8,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class SEOSpecialistServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/session-management.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/session-management.server.js index 4adc6e88a..195ca29c9 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/session-management.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/session-management.server.js @@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; class SessionManagementServer { server; sessions = new Map(); diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/skill-invocation.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/skill-invocation.server.js index 104a8c8ea..e988bd5e0 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/skill-invocation.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/skill-invocation.server.js @@ -2,7 +2,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js"; import { mcpClientManager } from "../mcp-client.js"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; class SkillInvocationServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/strategist.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/strategist.server.js index 26a27fe5d..8634a0250 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/strategist.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/strategist.server.js @@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; class StrategistServer { server; tools = [ diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/tech-writer.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/tech-writer.server.js index 1b6b92157..8c80c2521 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/tech-writer.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/tech-writer.server.js @@ -9,7 +9,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; class StringRayDocumentationGenerationServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-best-practices.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-best-practices.server.js index 3f9b3b236..129ba5771 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-best-practices.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-best-practices.server.js @@ -6,7 +6,7 @@ */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; class StringRayTestingBestPracticesServer { server; diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-strategy.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-strategy.server.js index 268766c77..09614c46b 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-strategy.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/testing-strategy.server.js @@ -9,9 +9,9 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import * as fs from "fs"; import * as path from "path"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; -import { createGracefulShutdown } from "../../dist/utils/shutdown-handler.js"; -import { detectProjectLanguage, LANGUAGE_CONFIGS, } from "../../dist/utils/language-detector.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; +import { createGracefulShutdown } from "../../utils/shutdown-handler.js"; +import { detectProjectLanguage, LANGUAGE_CONFIGS, } from "../../utils/language-detector.js"; class StringRayTestingStrategyServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/knowledge-skills/ui-ux-design.server.js b/node_modules/strray-ai/dist/mcps/knowledge-skills/ui-ux-design.server.js index 0305e5669..5af528f94 100644 --- a/node_modules/strray-ai/dist/mcps/knowledge-skills/ui-ux-design.server.js +++ b/node_modules/strray-ai/dist/mcps/knowledge-skills/ui-ux-design.server.js @@ -7,7 +7,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { frameworkLogger } from "../../dist/core/framework-logger.js"; +import { frameworkLogger } from "../../core/framework-logger.js"; class StringRayUIUXDesignServer { server; constructor() { diff --git a/node_modules/strray-ai/dist/mcps/orchestrator/server.js b/node_modules/strray-ai/dist/mcps/orchestrator/server.js index d7d5d6793..fcb314015 100644 --- a/node_modules/strray-ai/dist/mcps/orchestrator/server.js +++ b/node_modules/strray-ai/dist/mcps/orchestrator/server.js @@ -231,7 +231,7 @@ export class OrchestratorServer { async handleGovernAndApply(args) { try { const { InferenceCycle } = await import('../../inference/inference-cycle.js'); - const cycle = new InferenceCycle(process.cwd(), undefined, { + const cycle = InferenceCycle.getInstance(process.cwd(), { skipApply: args.skipApply ?? false, }); const result = await cycle.governExternalProposals(args.proposals); diff --git a/node_modules/strray-ai/dist/orchestrator/enhanced-multi-agent-orchestrator.js b/node_modules/strray-ai/dist/orchestrator/enhanced-multi-agent-orchestrator.js index e11bd582e..4175a740e 100644 --- a/node_modules/strray-ai/dist/orchestrator/enhanced-multi-agent-orchestrator.js +++ b/node_modules/strray-ai/dist/orchestrator/enhanced-multi-agent-orchestrator.js @@ -8,6 +8,7 @@ import { ComplexityAnalyzer, } from "../delegation/complexity-analyzer.js"; import { createAgentDelegator, } from "../delegation/agent-delegator.js"; import { strRayConfigLoader } from "../core/config-loader.js"; import { agentSpawnGovernor } from "./agent-spawn-governor.js"; +import { spawnGate } from "../core/opencode-spawn-gate.js"; export class EnhancedMultiAgentOrchestrator { state; stateManager; @@ -49,6 +50,15 @@ export class EnhancedMultiAgentOrchestrator { async spawnAgent(request) { const jobId = `spawn-agent-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; let spawnTrackingId; + // 🚨 GATE: Check global spawn gate before any spawn attempt + try { + spawnGate.assertAllowed("enhanced-multi-agent-orchestrator"); + } + catch (gateError) { + const error = new Error(`SPAWN GATE BLOCKED: ${gateError instanceof Error ? gateError.message : String(gateError)}`); + await frameworkLogger.log("enhanced-multi-agent-orchestrator", "spawn-gate-blocked", "error", { message: error.message, agentType: request.agentType }); + throw error; + } // 🚨 SECURITY: Prevent subagents from spawning other subagents // This prevents infinite loops, resource exhaustion, and uncontrolled agent spawning if (this.isCurrentlyExecutingAsSubagent()) { diff --git a/node_modules/strray-ai/dist/orchestrator/multi-agent-orchestration-coordinator.js b/node_modules/strray-ai/dist/orchestrator/multi-agent-orchestration-coordinator.js index a82a99a49..74f61930f 100644 --- a/node_modules/strray-ai/dist/orchestrator/multi-agent-orchestration-coordinator.js +++ b/node_modules/strray-ai/dist/orchestrator/multi-agent-orchestration-coordinator.js @@ -8,7 +8,7 @@ * @since 2026-01-23 */ import { KernelOrchestrator } from "../core/orchestrator.js"; -import { EnhancedMultiAgentOrchestrator } from "./enhanced-multi-agent-orchestrator.js"; +import { enhancedMultiAgentOrchestrator } from "./enhanced-multi-agent-orchestrator.js"; import { createAgentDelegator } from "../delegation/agent-delegator.js"; import { StringRayStateManager } from "../state/state-manager.js"; import { frameworkLogger } from "../core/framework-logger.js"; @@ -24,7 +24,7 @@ export class MultiAgentOrchestrationCoordinator { constructor(stateManager) { this.stateManager = stateManager || new StringRayStateManager(); this.strRayOrchestrator = new KernelOrchestrator(); - this.enhancedOrchestrator = new EnhancedMultiAgentOrchestrator(); + this.enhancedOrchestrator = enhancedMultiAgentOrchestrator; this.agentDelegator = createAgentDelegator(this.stateManager, strRayConfigLoader); this.complexityAnalyzer = new ComplexityAnalyzer(); this.coordinationMetrics = { diff --git a/node_modules/strray-ai/dist/orchestrator/orchestrator.js b/node_modules/strray-ai/dist/orchestrator/orchestrator.js index 9ddb869d2..294736839 100644 --- a/node_modules/strray-ai/dist/orchestrator/orchestrator.js +++ b/node_modules/strray-ai/dist/orchestrator/orchestrator.js @@ -7,7 +7,7 @@ * @version 1.0.0 * @since 2026-01-07 */ -import { EnhancedMultiAgentOrchestrator } from "./enhanced-multi-agent-orchestrator.js"; +import { enhancedMultiAgentOrchestrator } from "./enhanced-multi-agent-orchestrator.js"; import { frameworkLogger } from "../core/framework-logger.js"; import { routingOutcomeTracker } from "../delegation/analytics/outcome-tracker.js"; import { patternPerformanceTracker } from "../analytics/pattern-performance-tracker.js"; @@ -15,7 +15,6 @@ import { VotingCoordinator } from "../delegation/voting-coordinator.js"; import { getAgentExpertiseLevel } from "../delegation/agent-expertise.js"; import { StringRayStateManager } from "../state/state-manager.js"; import fs from "fs"; -const enhancedMultiAgentOrchestrator = new EnhancedMultiAgentOrchestrator(); export class StringRayOrchestrator { config; activeTasks = new Map(); diff --git a/node_modules/strray-ai/dist/scripts/integration.js b/node_modules/strray-ai/dist/scripts/integration.js index a5a476cd6..660c7eedf 100755 --- a/node_modules/strray-ai/dist/scripts/integration.js +++ b/node_modules/strray-ai/dist/scripts/integration.js @@ -15,6 +15,7 @@ */ import { spawn } from "child_process"; import { resolveAgent } from "../mcps/agent-resolver.js"; +import { spawnGate } from "../core/opencode-spawn-gate.js"; /** * Main entry point for the integration script */ @@ -119,6 +120,8 @@ Execute this task using the available tools. Be thorough and provide detailed re * Spawn OpenCode CLI process */ function spawnOpenCode(agentName, prompt) { + // Gate: prevent spawning unless explicitly enabled + spawnGate.assertAllowed("integration-script"); let isFinished = false; return new Promise((resolve, reject) => { // Spawn opencode with stdin for prompt - more reliable @@ -133,6 +136,9 @@ function spawnOpenCode(agentName, prompt) { }, stdio: ["pipe", "pipe", "pipe"], }); + if (opencode.pid) { + spawnGate.trackProcess(opencode.pid, "integration-script", `agent=${agentName}`); + } } catch (error) { const msg = error instanceof Error && "code" in error && error.code === "ENOENT" @@ -183,6 +189,9 @@ function spawnOpenCode(agentName, prompt) { }; opencode.on("close", (code) => { cleanup(false); + if (opencode.pid) { + spawnGate.untrackProcess(opencode.pid); + } if (code !== 0) { reject(new Error(`OpenCode exited with code ${code}: ${stderr}`)); return; diff --git a/src/__tests__/unit/processor-auto-discovery.test.ts b/src/__tests__/unit/processor-auto-discovery.test.ts index 290cd25c3..8e66abf73 100644 --- a/src/__tests__/unit/processor-auto-discovery.test.ts +++ b/src/__tests__/unit/processor-auto-discovery.test.ts @@ -28,8 +28,8 @@ describe("Processor Auto-Discovery", () => { const discovered = await manager.discoverProcessors(tmpDir); - expect(discovered).toEqual([]); - }); +expect(discovered).toEqual([]); + }, 30000); it("should not overwrite hardcoded factories", async () => { const stateManager = new StringRayStateManager(); @@ -40,7 +40,7 @@ describe("Processor Auto-Discovery", () => { await manager.discoverProcessors(tmpDir); expect((manager as any).factories.size).toBe(factoriesBefore); - }); + }, 30000); it("should handle missing implementations directory gracefully", async () => { const stateManager = new StringRayStateManager(); diff --git a/src/cli/commands/mcp-disable-grok.ts b/src/cli/commands/mcp-disable-grok.ts new file mode 100644 index 000000000..72dffda6b --- /dev/null +++ b/src/cli/commands/mcp-disable-grok.ts @@ -0,0 +1,60 @@ +import { existsSync, readFileSync, writeFileSync } from "fs"; +import { join } from "path"; + +const CORE_SKILLS = [ + "orchestrator", + "code-review", + "security-audit", + "bug-triage-specialist", + "researcher", +]; + +function getGrokConfigPath(): string { + const home = process.env.HOME || process.env.USERPROFILE || ""; + return join(home, ".grok", "config.toml"); +} + +export function disableGrokMCP(): void { + const configPath = getGrokConfigPath(); + + if (!existsSync(configPath)) { + console.log("No Grok config found. Nothing to disable."); + return; + } + + let content = readFileSync(configPath, "utf-8"); + const original = content; + + // Remove all 0xray-* server blocks + const lines = content.split("\n"); + const newLines: string[] = []; + let skip = false; + + for (const line of lines) { + if (line.match(/^\s*\[mcp_servers\.0xray-/)) { + skip = true; + continue; + } + if (skip && line.trim().startsWith("[")) { + skip = false; + } + if (!skip) { + newLines.push(line); + } + } + + content = newLines.join("\n").trimEnd() + "\n"; + + if (content === original) { + console.log("No 0xRay MCP servers found in Grok config."); + return; + } + + writeFileSync(configPath, content, "utf-8"); + console.log("βœ… Removed 0xRay MCP servers from Grok CLI config."); + console.log(" Restart your Grok CLI session to unload them."); +} + +export function disableGrokMCPCommand(): void { + disableGrokMCP(); +} diff --git a/src/cli/commands/mcp-enable-grok.ts b/src/cli/commands/mcp-enable-grok.ts new file mode 100644 index 000000000..e8e362c6d --- /dev/null +++ b/src/cli/commands/mcp-enable-grok.ts @@ -0,0 +1,203 @@ +import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs"; +import { join, dirname, resolve } from "path"; +import { fileURLToPath } from "url"; +import { getConfigDir } from "../../core/config-paths.js"; + +interface EnableGrokOptions { + skills?: string[]; + global?: boolean; // default: true + project?: boolean; // write to .grok/config.toml in current dir +} + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const packageRoot = resolve(join(__dirname, "..", "..", "..")); + +interface GrokMCPConfig { + command: string; + args: string[]; + env?: Record; +} + +const CORE_SKILLS = [ + "orchestrator", + "code-review", + "security-audit", + "bug-triage-specialist", + "researcher", +]; + +function getMCPBasePath(): string { + // 1. Check if we're inside the source tree (development) + const srcMcps = join(packageRoot, "src", "mcps"); + if (existsSync(join(srcMcps, "orchestrator", "server.ts"))) { + return srcMcps; + } + + // 2. Check dist (built package) + const distMcps = join(packageRoot, "dist", "mcps"); + if (existsSync(distMcps)) { + return distMcps; + } + + // 3. Fallback for global npm install + const possiblePaths = [ + join(packageRoot, "dist", "mcps"), + join(packageRoot, "src", "mcps"), + ]; + + for (const p of possiblePaths) { + if (existsSync(p)) return p; + } + + throw new Error( + "Could not locate 0xRay MCP servers.\n" + + "Please build the package first: npm run build" + ); +} + +function getGrokConfigPath(): string { + const home = process.env.HOME || process.env.USERPROFILE || ""; + return join(home, ".grok", "config.toml"); +} + +function getGrokConfigDir(): string { + const home = process.env.HOME || process.env.USERPROFILE || ""; + return join(home, ".grok"); +} + +function ensureGrokConfig(): string { + const configPath = getGrokConfigPath(); + const configDir = getGrokConfigDir(); + + if (!existsSync(configDir)) { + mkdirSync(configDir, { recursive: true }); + } + + if (!existsSync(configPath)) { + writeFileSync(configPath, "", "utf-8"); + } + + return configPath; +} + +function buildMCPConfig(skill: string, basePath: string): GrokMCPConfig { + const isOrchestrator = skill === "orchestrator"; + const isSrc = basePath.includes("/src/mcps"); + + const ext = isSrc ? ".ts" : ".js"; + const runner = isSrc ? ["--loader", "tsx"] : []; // fallback for dev + + let serverPath: string; + if (isOrchestrator) { + serverPath = join(basePath, "orchestrator", `server${ext}`); + } else { + serverPath = join(basePath, "knowledge-skills", `${skill}.server${ext}`); + } + + const args = isSrc + ? ["--loader", "tsx", serverPath] // requires tsx installed globally or locally + : ["--enable-source-maps", serverPath]; + + return { + command: "node", + args, + env: { + STRRAY_PROJECT_ROOT: process.cwd(), + NODE_ENV: process.env.NODE_ENV || "production", + }, + }; +} + +function generateTOMLEntries(basePath: string, skills: string[]): string { + let toml = "\n# 0xRay MCP Servers (added by strray mcp:enable-grok)\n"; + + for (const skill of skills) { + const config = buildMCPConfig(skill, basePath); + const serverName = `0xray-${skill}`; + + toml += `\n[mcp_servers.${serverName}]\n`; + toml += `command = "${config.command}"\n`; + toml += `args = [${config.args.map((a) => `"${a}"`).join(", ")}]\n`; + + if (config.env) { + toml += "env = { "; + const envPairs = Object.entries(config.env).map(([k, v]) => `${k} = "${v}"`); + toml += envPairs.join(", ") + " }\n"; + } + } + + return toml; +} + +function addToGrokConfig(tomlEntries: string): void { + const configPath = ensureGrokConfig(); + let content = readFileSync(configPath, "utf-8"); + + // Avoid duplicate additions + if (content.includes("0xray-orchestrator")) { + console.log("⚠️ 0xRay MCP servers already appear to be configured in Grok CLI."); + console.log(` Config: ${configPath}`); + return; + } + + // Append + if (!content.endsWith("\n")) { + content += "\n"; + } + content += tomlEntries; + + writeFileSync(configPath, content, "utf-8"); + + console.log(`βœ… Added 0xRay MCP servers to Grok CLI config:`); + console.log(` ${configPath}`); + console.log(`\nRestart your Grok CLI session or run 'grok mcp reload' (if available) to load the servers.`); +} + +export async function enableGrokMCP(options: EnableGrokOptions = {}): Promise { + console.log("πŸš€ Enabling 0xRay MCP servers for Grok CLI...\n"); + + const mcpBasePath = getMCPBasePath(); + const skillsToEnable = options.skills && options.skills.length > 0 + ? options.skills + : CORE_SKILLS; + + const useProject = options.project === true; + const useGlobal = options.global !== false && !useProject; + + const toml = generateTOMLEntries(mcpBasePath, skillsToEnable); + + if (useGlobal) { + addToGrokConfig(toml); + } + + if (useProject) { + const projectConfigPath = join(process.cwd(), ".grok", "config.toml"); + const projectDir = dirname(projectConfigPath); + if (!existsSync(projectDir)) mkdirSync(projectDir, { recursive: true }); + + let content = existsSync(projectConfigPath) ? readFileSync(projectConfigPath, "utf-8") : ""; + if (!content.includes("0xray-orchestrator")) { + if (!content.endsWith("\n") && content.length > 0) content += "\n"; + content += toml; + writeFileSync(projectConfigPath, content, "utf-8"); + console.log(`βœ… Also added to project .grok/config.toml`); + } + } + + console.log("\nπŸ“‹ Enabled servers:"); + for (const skill of skillsToEnable) { + console.log(` - 0xray-${skill}`); + } + + console.log("\nπŸ’‘ Next steps:"); + console.log(" 1. Restart your Grok CLI session (or run `grok mcp reload` if available)."); + console.log(" 2. You can now use 0xRay agents and governance from Grok CLI."); + console.log(" 3. Example: Ask Grok to run governance on a proposal using the orchestrator."); +} + +export function enableGrokMCPCommand(options: { skills?: string[] } = {}): void { + enableGrokMCP(options).catch((err) => { + console.error("❌ Failed to enable 0xRay for Grok CLI:", err); + process.exit(1); + }); +} diff --git a/src/cli/commands/mcp-grok-status.ts b/src/cli/commands/mcp-grok-status.ts new file mode 100644 index 000000000..a3e064b63 --- /dev/null +++ b/src/cli/commands/mcp-grok-status.ts @@ -0,0 +1,58 @@ +import { existsSync, readFileSync } from "fs"; +import { join } from "path"; + +const CORE_SKILL_NAMES = [ + "orchestrator", + "code-review", + "security-audit", + "bug-triage-specialist", + "researcher", +]; + +function getGrokConfigPath(): string { + const home = process.env.HOME || process.env.USERPROFILE || ""; + return join(home, ".grok", "config.toml"); +} + +export function showGrokMCPStatus(): void { + const configPath = getGrokConfigPath(); + + if (!existsSync(configPath)) { + console.log("No Grok CLI config found."); + console.log("Run `strray-ai mcp:enable-grok` to set up 0xRay integration."); + return; + } + + const content = readFileSync(configPath, "utf-8"); + const lines = content.split("\n"); + + const enabled: string[] = []; + + for (const line of lines) { + const match = line.match(/^\s*\[mcp_servers\.0xray-([^\]]+)\]/); + if (match) { + enabled.push(match[1] || 'unknown'); + } + } + + console.log("\n0xRay MCP Status for Grok CLI\n"); + + if (enabled.length === 0) { + console.log("❌ No 0xRay MCP servers are currently enabled for Grok CLI."); + console.log("\nRun: strray-ai mcp:enable-grok"); + return; + } + + console.log("βœ… Enabled 0xRay MCP servers:\n"); + for (const name of enabled) { + const isCore = CORE_SKILL_NAMES.includes(name); + console.log(` - 0xray-${name}${isCore ? " (core)" : ""}`); + } + + console.log("\nYou can now ask Grok to use these servers (e.g. orchestrator, code-review, etc.)."); + console.log("Restart Grok CLI if you recently enabled/disabled servers."); +} + +export function showGrokMCPStatusCommand(): void { + showGrokMCPStatus(); +} diff --git a/src/cli/index.ts b/src/cli/index.ts index 1dfa3f498..b00adbe03 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -1069,6 +1069,35 @@ program removeMCPCommand(name); }); +program + .command('mcp-enable-grok') + .alias('mcp:enable-grok') + .description('Enable 0xRay MCP servers for Grok CLI (orchestrator + core skills)') + .option('--skills ', 'Comma-separated list of skills (default: core set)') + .action(async (options) => { + const { enableGrokMCPCommand } = await import('./commands/mcp-enable-grok.js'); + const skills = options.skills ? options.skills.split(',') : undefined; + enableGrokMCPCommand({ skills }); + }); + +program + .command('mcp-disable-grok') + .alias('mcp:disable-grok') + .description('Disable 0xRay MCP servers from Grok CLI') + .action(async () => { + const { disableGrokMCPCommand } = await import('./commands/mcp-disable-grok.js'); + disableGrokMCPCommand(); + }); + +program + .command('mcp-grok-status') + .alias('mcp:grok-status') + .description('Show 0xRay MCP server status for Grok CLI') + .action(async () => { + const { showGrokMCPStatusCommand } = await import('./commands/mcp-grok-status.js'); + showGrokMCPStatusCommand(); + }); + // Analytics enable command // TODO: Re-enable after fixing dashboard module // program diff --git a/src/governance/AgentInvoker.ts b/src/governance/AgentInvoker.ts new file mode 100644 index 000000000..a46670544 --- /dev/null +++ b/src/governance/AgentInvoker.ts @@ -0,0 +1,17 @@ +import type { InferenceProposal } from '../inference/inference-cycle.js'; + +export interface AgentReview { + agent: string; + decision: string; + confidence: number; + reasoning: string; +} + +/** + * High-level interface for running multi-agent deliberation on a proposal. + * Use this for governance / inference, not the low-level AgentInvoker callback. + */ +export interface ProposalDeliberationInvoker { + deliberate(proposal: InferenceProposal): Promise; +} + diff --git a/src/governance/AgentInvokerFactory.ts b/src/governance/AgentInvokerFactory.ts new file mode 100644 index 000000000..8c2e7cc85 --- /dev/null +++ b/src/governance/AgentInvokerFactory.ts @@ -0,0 +1,36 @@ +import type { ProposalDeliberationInvoker as AgentInvoker } from './AgentInvoker'; +import { OpenCodeAgentInvoker } from './OpenCodeAgentInvoker'; +import { MCPAgentInvoker } from './MCPAgentInvoker'; +import { mcpClientManager } from '../mcps/mcp-client.js'; + +export class AgentInvokerFactory { + static createForCurrentEnvironment(): AgentInvoker { + if (this.isOrchestratorMCPAvailable()) { + return new MCPAgentInvoker(); + } + return new OpenCodeAgentInvoker( + (prompt: string) => { + // This is a placeholder; real usage should come from InferenceCycle + throw new Error('OpenCodeAgentInvoker needs proper invoke function in factory context'); + }, + () => [] + ); + } + + static createForGrokCLI(): AgentInvoker { + return new MCPAgentInvoker(); + } + + static createForOpenCode( + invokeArchitect: (prompt: string) => Promise, + parseVotes: (output: string, proposals: any[]) => any[] + ): AgentInvoker { + return new OpenCodeAgentInvoker(invokeArchitect, parseVotes); + } + + private static isOrchestratorMCPAvailable(): boolean { + // For now, assume it's available if we're in an environment where MCP is configured + // (we can improve this later with proper registry inspection) + return process.env.STRRAY_MCP_ORCHESTRATOR_AVAILABLE === 'true' || false; + } +} diff --git a/src/governance/MCPAgentInvoker.ts b/src/governance/MCPAgentInvoker.ts new file mode 100644 index 000000000..0a9e1f5dc --- /dev/null +++ b/src/governance/MCPAgentInvoker.ts @@ -0,0 +1,95 @@ +import type { ProposalDeliberationInvoker, AgentReview } from './AgentInvoker.js'; +import type { InferenceProposal } from '../inference/inference-cycle.js'; +import { mcpClientManager } from '../mcps/mcp-client.js'; +import { GOVERNANCE_AGENTS } from '../inference/inference-cycle.js'; + +/** + * Maps agent names (from GOVERNANCE_AGENTS) to their corresponding + * Knowledge Skill MCP server names in src/mcps/knowledge-skills/ + */ +const AGENT_TO_SKILL_SERVER: Record = { + 'code-reviewer': 'code-review', + 'researcher': 'researcher', + 'security-auditor': 'security-audit', + 'bug-triage-specialist': 'bug-triage-specialist', + 'refactorer': 'refactoring-strategies', + 'architect': 'architect-tools', + 'strategist': 'strategist', + // Add more as needed +}; + +/** + * MCP-based AgentInvoker. + * Calls individual 0xRay Knowledge Skill servers via MCP. + * + * This is the portable implementation that works from Grok CLI, Hermes, OpenClaw, etc. + */ +export class MCPAgentInvoker implements ProposalDeliberationInvoker { + async deliberate(proposal: InferenceProposal): Promise { + const agentNames = GOVERNANCE_AGENTS[proposal.type] ?? ['code-reviewer']; + const reviews: AgentReview[] = []; + + for (const agentName of agentNames) { + const serverName = AGENT_TO_SKILL_SERVER[agentName] || agentName; + + try { + // Try to call a common analysis/review tool on the skill server. + // Many knowledge skills expose "analyze", "review", or a tool named after the skill. + const result = await mcpClientManager.callServerTool(serverName, 'analyze', { + title: proposal.title, + description: proposal.description, + evidence: proposal.evidence, + proposalType: proposal.type, + }); + + // Best-effort extraction of decision/reasoning from the skill response. + // Real skills should return structured data in the future. + const text = typeof result === 'string' ? result : JSON.stringify(result); + const decision = this.extractDecision(text); + const confidence = this.extractConfidence(text); + const reasoning = this.extractReasoning(text) || text.slice(0, 600); + + reviews.push({ + agent: agentName, + decision, + confidence, + reasoning, + }); + } catch (error: any) { + reviews.push({ + agent: agentName, + decision: 'abstain', + confidence: 0.3, + reasoning: `Failed to call skill "${serverName}": ${error?.message || error}`, + }); + } + } + + return reviews; + } + + private extractDecision(text: string): string { + const lower = text.toLowerCase(); + if (lower.includes('approve') || lower.includes('pass')) return 'approve'; + if (lower.includes('reject') || lower.includes('fail')) return 'reject'; + return 'abstain'; + } + + private extractConfidence(text: string): number { + const match = text.match(/confidence[:\s]*([0-9.]+)/i); + if (match && match[1]) { + const val = parseFloat(match[1]); + return Math.min(1, Math.max(0, val)); + } + return 0.7; + } + + private extractReasoning(text: string): string { + // Try to find a "reasoning" or "summary" section + const match = text.match(/(?:reasoning|summary|analysis)[:\s]*(.+)/is); + if (match && match[1]) { + return match[1].trim().slice(0, 800); + } + return text.trim().slice(0, 600); + } +} diff --git a/src/governance/OpenCodeAgentInvoker.ts b/src/governance/OpenCodeAgentInvoker.ts new file mode 100644 index 000000000..bc21a62d3 --- /dev/null +++ b/src/governance/OpenCodeAgentInvoker.ts @@ -0,0 +1,102 @@ +import type { InferenceProposal } from '../inference/inference-cycle.js'; +import type { ProposalDeliberationInvoker, AgentReview } from './AgentInvoker.js'; +import { GOVERNANCE_AGENTS } from '../inference/inference-cycle.js'; +import * as fs from 'fs'; +import * as path from 'path'; + +type InvokeArchitect = (prompt: string) => Promise; +type ParseVotes = ( + output: string, + proposals: InferenceProposal[] +) => Array<{ + proposalId: string; + agentName: string; + decision: string; + confidence: number; + reasoning: string; +}>; + +/** + * AgentInvoker implementation that uses the current OpenCode mechanism: + * one `opencode run --agent architect` that distributes todos to sub-agents. + */ +export class OpenCodeAgentInvoker implements ProposalDeliberationInvoker { + constructor( + private readonly invokeArchitect: InvokeArchitect, + private readonly parseVotes: ParseVotes + ) {} + + async deliberate(proposal: InferenceProposal): Promise { + const subAgents = GOVERNANCE_AGENTS[proposal.type] ?? ['code-reviewer']; + const allAgents = ['architect', ...subAgents]; + + // Enrich evidence with actual file content when possible (major speed/quality win) + const enrichedEvidence = this.enrichEvidenceWithFileContent(proposal.evidence); + + const promptLines = [ + `You are the architect agent. Evaluate the following proposal and create tasks for the relevant sub-agents to vote, then cast your own vote.`, + ``, + `Proposal Type: [${proposal.type}]`, + `Title: ${proposal.title}`, + `Description: ${proposal.description}`, + `Evidence (with file contents where available):`, + ...enrichedEvidence, + ``, + `Agents that must vote on this proposal: ${allAgents.join(', ')}`, + ``, + `Instructions:`, + `- First cast your own vote as "architect".`, + `- Then create a task for each sub-agent asking them to vote.`, + ``, + `Output format (exact, one block per agent):`, + `PROPOSAL: 1`, + ]; + + for (const agent of allAgents) { + promptLines.push(` AGENT: ${agent}`); + promptLines.push(` DECISION: approve|reject|abstain`); + promptLines.push(` CONFIDENCE: 0.XX`); + promptLines.push(` REASONING: `); + } + + const jsonOutput = await this.invokeArchitect(promptLines.join('\n')); + const votes = this.parseVotes(jsonOutput, [proposal]); + + return votes.map((v) => ({ + agent: v.agentName, + decision: v.decision, + confidence: v.confidence, + reasoning: v.reasoning, + })); + } + + /** + * Attempts to read actual file contents for paths mentioned in the evidence. + * This dramatically reduces the amount of exploration agents have to do. + */ + private enrichEvidenceWithFileContent(evidence: string[]): string[] { + const enriched: string[] = []; + const filePathRegex = /(?:src|dist|scripts|tests?)[^\s'"]+\.(ts|js|tsx|jsx|mjs|cjs|json|md)/g; + + for (const line of evidence) { + enriched.push(` - ${line}`); + + const matches = line.match(filePathRegex) || []; + for (const filePath of matches) { + try { + const fullPath = path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath); + if (fs.existsSync(fullPath)) { + const content = fs.readFileSync(fullPath, 'utf-8'); + // Limit size to avoid huge prompts + const limited = content.length > 8000 ? content.slice(0, 8000) + '\n... (truncated)' : content; + enriched.push(` [FILE CONTENT: ${filePath}]\n${limited}`); + } + } catch (err) { + // Ignore unreadable files + } + } + } + + return enriched; + } +} diff --git a/src/governance/__tests__/AgentInvokerFactory.test.ts b/src/governance/__tests__/AgentInvokerFactory.test.ts new file mode 100644 index 000000000..a2210722c --- /dev/null +++ b/src/governance/__tests__/AgentInvokerFactory.test.ts @@ -0,0 +1,22 @@ +import { describe, it, expect } from 'vitest'; +import { AgentInvokerFactory } from '../AgentInvokerFactory'; +import { OpenCodeAgentInvoker } from '../OpenCodeAgentInvoker'; +import { MCPAgentInvoker } from '../MCPAgentInvoker'; + +describe('AgentInvokerFactory', () => { + it('should return OpenCodeAgentInvoker by default when no orchestrator MCP is available', () => { + // In most test environments the orchestrator won't be registered + const invoker = AgentInvokerFactory.createForCurrentEnvironment(); + expect(invoker).toBeInstanceOf(OpenCodeAgentInvoker); + }); + + it('createForGrokCLI should return MCPAgentInvoker', () => { + const invoker = AgentInvokerFactory.createForGrokCLI(); + expect(invoker).toBeInstanceOf(MCPAgentInvoker); + }); + + it('createForOpenCode should return OpenCodeAgentInvoker', () => { + const invoker = AgentInvokerFactory.createForOpenCode(); + expect(invoker).toBeInstanceOf(OpenCodeAgentInvoker); + }); +}); diff --git a/src/governance/__tests__/MCPAgentInvoker.test.ts b/src/governance/__tests__/MCPAgentInvoker.test.ts new file mode 100644 index 000000000..a7365dd8b --- /dev/null +++ b/src/governance/__tests__/MCPAgentInvoker.test.ts @@ -0,0 +1,40 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { MCPAgentInvoker } from '../MCPAgentInvoker'; + +vi.mock('../../mcps/mcp-client.js', () => ({ + mcpClientManager: { + callServerTool: vi.fn(), + hasServer: vi.fn().mockReturnValue(true), + } +})); + +import { mcpClientManager } from '../../mcps/mcp-client.js'; + +describe('MCPAgentInvoker', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('should return reviews from knowledge skills via MCP', async () => { + (mcpClientManager.callServerTool as any).mockResolvedValue({ + decision: 'approve', + confidence: 0.9, + reasoning: 'Looks good from MCP skill' + }); + + const invoker = new MCPAgentInvoker(); + const reviews = await invoker.deliberate({ + id: 'p1', + type: 'fix', + title: 'Test fix', + description: 'Fix something', + evidence: ['bug in foo.ts'], + confidence: 0.8, + source: 'recurring_problem', + status: 'pending' + } as any); + + expect(reviews.length).toBeGreaterThan(0); + expect(reviews.some(r => r.agent === 'code-reviewer' || r.agent === 'researcher')).toBe(true); + }); +}); diff --git a/src/governance/__tests__/OpenCodeAgentInvoker.test.ts b/src/governance/__tests__/OpenCodeAgentInvoker.test.ts new file mode 100644 index 000000000..536391ae3 --- /dev/null +++ b/src/governance/__tests__/OpenCodeAgentInvoker.test.ts @@ -0,0 +1,41 @@ +import { describe, it, expect, vi } from 'vitest'; +import { OpenCodeAgentInvoker } from '../OpenCodeAgentInvoker'; + +describe('OpenCodeAgentInvoker', () => { + it('should return reviews when the underlying opencode call succeeds', async () => { + const mockInvoke = vi.fn().mockResolvedValue(JSON.stringify({ + type: 'tool_use', + part: { + type: 'tool', + tool: 'task', + state: { + input: { subagent_type: 'code-reviewer' }, + output: 'PROPOSAL: 1\n AGENT: code-reviewer\n DECISION: approve\n CONFIDENCE: 0.85\n REASONING: Good change' + } + } + })); + + const mockParse = vi.fn().mockReturnValue([{ + proposalId: 'p1', + agentName: 'code-reviewer', + decision: 'approve', + confidence: 0.85, + reasoning: 'Good change' + }]); + + const invoker = new OpenCodeAgentInvoker(mockInvoke, mockParse); + const reviews = await invoker.deliberate({ + id: 'p1', + type: 'fix', + title: 'Test', + description: 'Test proposal', + evidence: [], + confidence: 0.8, + source: 'recurring_problem', + status: 'pending' + } as any); + + expect(reviews.length).toBeGreaterThan(0); + expect(reviews[0].agent).toBe('code-reviewer'); + }); +}); diff --git a/src/inference/inference-cycle.ts b/src/inference/inference-cycle.ts index e663961f6..ca70466ee 100644 --- a/src/inference/inference-cycle.ts +++ b/src/inference/inference-cycle.ts @@ -6,7 +6,9 @@ import { DeployVerifier, DeployVerificationResult } from "./deploy-verifier.js"; import { VotingCoordinator } from "../delegation/voting-coordinator.js"; import { StringRayStateManager } from "../state/state-manager.js"; import { frameworkLogger } from "../core/framework-logger.js"; -import { getGovernanceIntegration, type GovernanceVoteResult } from "../integrations/governance/index.js"; +import { getGovernanceIntegration, type GovernanceVoteResult, type SolarGovernanceVoteResult } from "../integrations/governance/index.js"; +import { OpenCodeAgentInvoker } from "../governance/OpenCodeAgentInvoker.js"; +import type { ProposalDeliberationInvoker } from "../governance/AgentInvoker.js"; import { getAgentSpawn } from "../core/features-config.js"; import { agentSpawnGovernor } from "../orchestrator/agent-spawn-governor.js"; import { spawnGate } from "../core/opencode-spawn-gate.js"; @@ -58,7 +60,7 @@ export type CyclePhase = const CYCLE_STATE_FILE = "inference-cycle-state.json"; const CYCLE_HISTORY_FILE = "inference-cycle-history.json"; -const GOVERNANCE_AGENTS: Record = { +export const GOVERNANCE_AGENTS: Record = { fix: ["code-reviewer", "refactorer", "researcher"], refactor: ["code-reviewer", "refactorer", "researcher"], guard: ["code-reviewer", "security-auditor", "researcher"], @@ -85,7 +87,7 @@ export class InferenceCycle { static getInstance(projectRoot?: string, options?: InferenceCycleOptions): InferenceCycle { const root = path.resolve(projectRoot || process.cwd()); if (!InferenceCycle.instances.has(root)) { - InferenceCycle.instances.set(root, new InferenceCycle(root, undefined, options)); + InferenceCycle.instances.set(root, new InferenceCycle(root, undefined, undefined, options)); } return InferenceCycle.instances.get(root)!; } @@ -102,15 +104,38 @@ export class InferenceCycle { private projectRoot: string; private phase: CyclePhase = "idle"; private opencodeAvailable: boolean | null = null; - private agentInvoker: AgentInvoker | null; + private readonly proposalAgentInvoker: ProposalDeliberationInvoker; + // Legacy low-level callback (function type) for the old invokeAgentInternal path + private readonly lowLevelAgentInvoker: ((agentName: string, prompt: string) => Promise) | undefined; private options: InferenceCycleOptions; - - constructor(projectRoot?: string, agentInvoker?: AgentInvoker, options?: InferenceCycleOptions) { + private lastRawOpencodeOutput: string = ""; + + constructor( + projectRoot?: string, + proposalAgentInvoker?: ProposalDeliberationInvoker, + lowLevelAgentInvoker?: (agentName: string, prompt: string) => Promise, + options?: InferenceCycleOptions + ) { this.projectRoot = projectRoot || process.cwd(); this.inferenceDir = path.join(this.projectRoot, "docs", "inference"); this.stateDir = path.join(this.projectRoot, ".strray", "inference"); - this.agentInvoker = agentInvoker ?? null; this.options = options ?? {}; + this.lowLevelAgentInvoker = lowLevelAgentInvoker; + + this.proposalAgentInvoker = + proposalAgentInvoker ?? + new OpenCodeAgentInvoker( + (prompt: string) => this.invokeAgentInternal("architect", prompt), + (output: string, proposals: InferenceProposal[]) => + this.parseSubagentVotes(output, proposals) + ); + + console.error(">>> USING INVOKER:", this.proposalAgentInvoker.constructor.name); + + frameworkLogger.log("inference-cycle", "invoker-selected", "info", { + invoker: this.proposalAgentInvoker.constructor.name, + isDefault: !proposalAgentInvoker, + }); } async governExternalProposals(proposals: InferenceProposal[]): Promise { @@ -655,35 +680,67 @@ Respond with EXACTLY one of: const sessionId = `inference-governance-${Date.now()}`; const results: InferenceCycleResult["votes"] = []; + const allGovernanceAgents = new Set(); + for (const agents of Object.values(GOVERNANCE_AGENTS)) { + for (const a of agents) allGovernanceAgents.add(a); + } + const todoPrompt = [ - `Vote on ${proposals.length} inference proposals. Output EXACTLY one PROPOSAL block per proposal.`, + `You are the architect agent governing ${proposals.length} inference proposals.`, + `You must vote on each proposal AND create tasks for the relevant governance sub-agents to vote as well.`, + ``, + `GOVERNANCE AGENTS BY PROPOSAL TYPE:`, + ...Object.entries(GOVERNANCE_AGENTS).map(([type, agents]) => ` ${type}: ${agents.join(", ")}`), + ``, + `For each proposal, create a task for each relevant sub-agent (based on its type) asking them to vote.`, + `Then cast your own architect vote.`, + ``, + `OUTPUT FORMAT (exact, no extra text, no markdown):`, + `One PROPOSAL block per agent per proposal. Each block starts with PROPOSAL: .`, ``, - `FORMAT (exact, no extra text, no markdown):`, `PROPOSAL: `, - ` AGENT: architect`, + ` AGENT: `, ` DECISION: approve|reject|abstain`, ` CONFIDENCE: 0.XX`, ` REASONING: `, ``, - `Example:`, + `Example for a [fix] type proposal with agents [architect, code-reviewer, refactorer, researcher]:`, `PROPOSAL: 1`, ` AGENT: architect`, ` DECISION: approve`, ` CONFIDENCE: 0.85`, - ` REASONING: Cleanup reduces maintenance burden`, + ` REASONING: Low-risk bug fix improves stability`, + `PROPOSAL: 1`, + ` AGENT: code-reviewer`, + ` DECISION: approve`, + ` CONFIDENCE: 0.80`, + ` REASONING: Code change is clean and well-scoped`, + `PROPOSAL: 1`, + ` AGENT: refactorer`, + ` DECISION: approve`, + ` CONFIDENCE: 0.75`, + ` REASONING: Minor refactoring reduces tech debt`, + `PROPOSAL: 1`, + ` AGENT: researcher`, + ` DECISION: approve`, + ` CONFIDENCE: 0.70`, + ` REASONING: Pattern confirmed across codebase`, ``, `PROPOSALS:`, ]; for (let i = 0; i < proposals.length; i++) { const p = proposals[i]!; - todoPrompt.push(`${i + 1}. [${p.type}] "${p.title}"`); + const agents = GOVERNANCE_AGENTS[p.type] ?? ["code-reviewer"]; + todoPrompt.push(`${i + 1}. [${p.type}] "${p.title}" β€” agents: architect, ${agents.join(", ")}`); } try { + this.lastRawOpencodeOutput = ""; const jsonOutput = await this.invokeAgentInternal("architect", todoPrompt.join("\n")); - const allVotes = this.parseSubagentVotes(jsonOutput, proposals); + const rawForParsing = this.lastRawOpencodeOutput || jsonOutput; + const allVotes = this.parseSubagentVotes(rawForParsing, proposals); for (const proposal of proposals) { const agents = GOVERNANCE_AGENTS[proposal.type] ?? ["code-reviewer"]; @@ -787,8 +844,6 @@ Respond with EXACTLY one of: return merged; } - // Removed: buildOrchestratorGovernancePrompt (replaced by inline TODO prompt in governProposals) - /** * Govern proposals using external chrono-warp-drive Dynamo endpoint */ @@ -800,10 +855,20 @@ Respond with EXACTLY one of: throw new Error("Governance integration not available"); } - // Build agent reviews from proposal evidence - const agentReviews = proposals.flatMap((p) => - p.evidence.slice(0, 2).map((e) => `[${p.type}] ${e}`), - ); + // Build rich agent reviews via the pluggable invoker + const agentReviews: string[] = []; + + for (const proposal of proposals) { + const delibStart = Date.now(); + const reviews = await this.proposalAgentInvoker.deliberate(proposal); + const delibDuration = Date.now() - delibStart; + + console.error(`>>> DELIBERATION TIME for ${proposal.id}: ${delibDuration}ms (invoker: ${this.proposalAgentInvoker.constructor.name})`); + + for (const r of reviews) { + agentReviews.push(`${r.agent}: ${r.reasoning} (confidence: ${r.confidence})`); + } + } try { const batchResult = await governanceIntegration.checkProposals( @@ -813,16 +878,27 @@ Respond with EXACTLY one of: ); const votes: InferenceCycleResult["votes"] = batchResult.results.map( - (result: GovernanceVoteResult) => ({ - proposalId: result.governanceResponse.proposalId, - decision: result.vote.toLowerCase() === "yes" ? "approve" : "reject", - confidence: result.governanceResponse.confidence, - details: [ + (result: GovernanceVoteResult) => { + const details = [ `Governance: ${result.governanceResponse.recommendation}`, `Isotope: ${result.governanceResponse.governanceIsotopeId}`, ...result.governanceResponse.reasons.slice(0, 2), - ], - }), + ]; + + const solarResult = result as SolarGovernanceVoteResult; + if (solarResult.solarModulation) { + details.push( + `Solar modulation: ${solarResult.solarModulation.activityLevel} (gain: ${solarResult.solarModulation.gainMultiplier}x)`, + ); + } + + return { + proposalId: result.governanceResponse.proposalId, + decision: result.vote.toLowerCase() === "yes" ? "approve" : "reject", + confidence: result.governanceResponse.confidence, + details, + }; + }, ); frameworkLogger.log("inference-cycle", "external-governance-complete", "info", { @@ -886,9 +962,9 @@ Respond with EXACTLY one of: }); } - if (this.agentInvoker) { + if (this.lowLevelAgentInvoker) { frameworkLogger.log("inference-cycle", "invoke-via-callback", "info", { agentName }); - return this.agentInvoker(agentName, prompt); + return this.lowLevelAgentInvoker(agentName, prompt); } return this.invokeViaOpencode(agentName, prompt); @@ -990,6 +1066,7 @@ Respond with EXACTLY one of: await agentSpawnGovernor.completeSpawn(trackingId, true).catch(() => {}); } frameworkLogger.log("inference-cycle", "opencode-spawn-success", "info", { agentName, trackingId }); + this.lastRawOpencodeOutput = stdout.trim(); const textResponse = this.extractTextFromNdjson(stdout.trim()); if (textResponse) { resolve(textResponse); diff --git a/src/integrations/governance/governance-client.ts b/src/integrations/governance/governance-client.ts index 3a93bf9d7..b934947d8 100644 --- a/src/integrations/governance/governance-client.ts +++ b/src/integrations/governance/governance-client.ts @@ -14,6 +14,7 @@ import type { SolarGovernanceCheckResponse, GovernanceClientConfig, GovernanceClientStats, + SolarFeaturesLike, } from './types.js'; import { GovernanceError, @@ -33,7 +34,7 @@ export class GovernanceClient { constructor(config: Partial = {}) { this.config = { baseUrl: 'https://mcp-production-80e2.up.railway.app', - timeoutMs: 10000, + timeoutMs: 30000, retryAttempts: 3, retryDelayMs: 1000, ...config, @@ -101,6 +102,19 @@ export class GovernanceClient { adjustedVoteWeight: result.adjustedVoteWeight as number, finalRecommendation: result.finalRecommendation as string, confidenceAdjustment: result.confidenceAdjustment as number, + ...(result.solarFeatures + ? { solarFeatures: result.solarFeatures as SolarFeaturesLike } + : {}), + ...(result.solarModulation + ? { + solarModulation: { + activity_level: (result.solarModulation as Record).activity_level as string, + gainMultiplier: (result.solarModulation as Record).gainMultiplier as number, + metaDelta: (result.solarModulation as Record).metaDelta as number, + confDelta: (result.solarModulation as Record).confDelta as number, + }, + } + : {}), }; if (!this.isValidSolarResponse(response)) { @@ -197,9 +211,11 @@ export class GovernanceClient { recommendation: result.recommendation as 'PASS' | 'NEEDS_REVISION' | 'REJECT', confidence: result.confidence as number, voteWeight: result.voteWeight as number, - reasons: Array.isArray(result.reasoning) - ? (result.reasoning as string[]) - : [result.reasoning as string], + reasons: Array.isArray(result.reasons) + ? (result.reasons as string[]) + : Array.isArray(result.reasoning) + ? (result.reasoning as string[]) + : [String(result.reasons ?? result.reasoning ?? '')], }; if (!this.isValidResponse(response)) { @@ -305,8 +321,7 @@ export class GovernanceClient { sc.solarActivityModifier <= 1 && typeof sc.recommendation === 'string' && typeof r.adjustedVoteWeight === 'number' && - r.adjustedVoteWeight >= 0.5 && - r.adjustedVoteWeight <= 1.5 && + r.adjustedVoteWeight >= 0 && typeof r.finalRecommendation === 'string' && typeof r.confidenceAdjustment === 'number' ); diff --git a/src/integrations/governance/index.ts b/src/integrations/governance/index.ts index 1c8f8fcb2..74e486f10 100644 --- a/src/integrations/governance/index.ts +++ b/src/integrations/governance/index.ts @@ -55,7 +55,7 @@ export class InferenceGovernanceIntegration extends BaseIntegration { await this.log('info', 'Initializing governance client...'); this.client = new GovernanceClient({ - baseUrl: this.configData.endpointUrl.replace(/\/governance$/, ''), + baseUrl: this.configData.endpointUrl, timeoutMs: this.configData.requestTimeoutMs, }); @@ -209,6 +209,14 @@ export class InferenceGovernanceIntegration extends BaseIntegration { ...baseResult, solarContext: solarResponse.solarContext, solarConfidenceAdjustment: solarResponse.confidenceAdjustment, + ...(solarResponse.solarModulation + ? { + solarModulation: { + gainMultiplier: solarResponse.solarModulation.gainMultiplier, + activityLevel: solarResponse.solarModulation.activity_level, + }, + } + : {}), }; frameworkLogger.log( @@ -220,6 +228,7 @@ export class InferenceGovernanceIntegration extends BaseIntegration { solarActivityLevel: solarResponse.solarContext.solarActivityLevel, adjustedVoteWeight: solarResponse.adjustedVoteWeight, confidenceAdjustment: solarResponse.confidenceAdjustment, + gainMultiplier: solarResponse.solarModulation?.gainMultiplier, passed: solarResult.passed, }, ); @@ -259,15 +268,14 @@ export class InferenceGovernanceIntegration extends BaseIntegration { frameworkLogger.log( 'inference-governance', 'check-proposal-error', - 'warning', + 'error', { proposalId: proposal.id, error: error instanceof Error ? error.message : String(error), }, ); - // Fallback to local decision - results.push(this.createFallbackVote(proposal)); + throw error; } } @@ -335,31 +343,6 @@ export class InferenceGovernanceIntegration extends BaseIntegration { }; } - /** - * Create fallback vote when governance is unavailable - */ - private createFallbackVote(proposal: InferenceProposal): GovernanceVoteResult { - return { - vote: proposal.confidence >= 0.7 ? 'YES' : 'ABSTAIN', - weight: 1.0, - reason: 'Fallback: governance endpoint unavailable', - governanceResponse: { - success: false, - proposalId: proposal.id, - governanceIsotopeId: 'fallback', - resonanceScore: 0, - isotopicRatio: 0, - vortexVolume: 0, - historicalCoherence: 0, - recommendation: 'NEEDS_REVISION', - confidence: proposal.confidence, - voteWeight: 1.0, - reasons: ['Governance endpoint unavailable, using local confidence'], - }, - passed: proposal.confidence >= 0.7, - }; - } - /** * Load configuration from features.json */ diff --git a/src/integrations/governance/types.ts b/src/integrations/governance/types.ts index 11652add1..0ca2d99e0 100644 --- a/src/integrations/governance/types.ts +++ b/src/integrations/governance/types.ts @@ -75,8 +75,8 @@ export interface GovernanceIntegrationConfig { */ export const DEFAULT_GOVERNANCE_CONFIG: GovernanceIntegrationConfig = { enabled: false, - endpointUrl: 'https://mcp-production-80e2.up.railway.app/governance', - requestTimeoutMs: 10000, + endpointUrl: 'https://mcp-production-80e2.up.railway.app', + requestTimeoutMs: 30000, minConfidenceThreshold: 0.5, decisionLogic: { passConfidenceMin: 0.9, @@ -94,6 +94,29 @@ export const DEFAULT_GOVERNANCE_CONFIG: GovernanceIntegrationConfig = { */ export type SolarActivityLevel = 'quiet' | 'moderate' | 'active' | 'storm'; +/** + * Minimal solar feature vector used by neural fusion modulation + * Derived from NOAA SWPC data (X-ray flux, Kp-index, etc.) + */ +export interface SolarFeaturesLike { + xrayUVLift: number; + magPerturbation: number; + activityLevel?: SolarActivityLevel; +} + +/** + * Solar modulation record β€” tracks what modulation was applied and why + */ +export interface SolarModulation { + solar_applied: boolean; + activity_level: string; + gainMultiplier: number; + metaShift: number; + confShift: number; + metaDelta: number; + confDelta: number; +} + /** * Solar context returned by govern_with_solar */ @@ -132,6 +155,15 @@ export interface SolarGovernanceCheckResponse { finalRecommendation: string; /** Confidence adjustment applied due to solar activity */ confidenceAdjustment: number; + /** Live solar feature vector from NOAA (if available) */ + solarFeatures?: SolarFeaturesLike; + /** Solar modulation details from neural fusion coupling (if available) */ + solarModulation?: { + activity_level: string; + gainMultiplier: number; + metaDelta: number; + confDelta: number; + }; } /** @@ -142,6 +174,11 @@ export interface SolarGovernanceVoteResult extends GovernanceVoteResult { solarContext: SolarContext; /** Confidence adjustment from solar activity */ solarConfidenceAdjustment: number; + /** Solar modulation: coupling gain and level, propagated from neural fusion */ + solarModulation?: { + gainMultiplier: number; + activityLevel: string; + }; } // ============================================================================