Skip to content

Merge proxy into compose + agentic hardening + genesis paths#61

Open
jbcupps wants to merge 16 commits intomainfrom
merge-proxy-into-compose
Open

Merge proxy into compose + agentic hardening + genesis paths#61
jbcupps wants to merge 16 commits intomainfrom
merge-proxy-into-compose

Conversation

@jbcupps
Copy link
Copy Markdown
Owner

@jbcupps jbcupps commented Feb 20, 2026

Summary

  • Dual-proxy egress boundary: Merged proxy infrastructure into base docker-compose for single-command full-stack startup with SSRF deny rules and allowlist/allow_all modes
  • Modular Genesis paths: Added genesis-core trait + 4 pluggable birth paths (Quick Start, Direct Discovery, Soul Crystallization, Soul Forge) with unified step protocol and registry
  • Soul Forge engine: 14 TOML ethical scenarios, 16 combinatorial archetypes, 4-dim Compass Ethic calibration, SHA-256 soul hash, and visual sigil generation
  • Agentic hardening: Circuit breaker + Ego gate to kill death-spiral loops, structured tool extraction, inline task monitor, SSE streaming hooks
  • Frontend overhaul: Mission Control dashboard, GenesisStepView (replaces per-path components), ErrorBoundary, focus trap hook, enhanced AgenticPanel with streaming timeline
  • Tier model orchestration: Per-provider Fast/Standard/Pro model selection with catalog validation, refresh, and reset endpoints
  • Pro council (MoA DAG): Rust-native multi-provider draft → critique → synthesis with 90s timeout and graceful degradation
  • Docs & Soul Contract: Updated Agent Soul Contract with personality.md (Superego-modifiable), added Superego enterprise deployment section, agent archetype standard, skill troubleshooting playbook
  • CI fixes: Rustfmt/clippy install for any stable toolchain, pre-existing lint cleanup, test race fix on ORION_MASTER_KEY
  • Dependency bumps: rand, mail-parser, anyhow, uuid, tower-http, and frontend deps (react-dom, typescript-eslint, eslint-plugin-react-refresh, globals, @eslint/js)

Test plan

  • .\scripts\run-uat.ps1 -Fast passes (fmt, clippy, unit tests, frontend build)
  • .\scripts\run-uat.ps1 full UAT passes (full-stack probes + postgres tests)
  • .\scripts\dev-stack.ps1 starts cleanly; web UI loads at http://localhost:3000
  • Birth flow: create agent through all 4 Genesis paths (Quick Start, Direct Discovery, Soul Crystallization, Soul Forge)
  • Proxy smoke test: .\scripts\proxy-smoke-test.ps1 validates egress rules
  • Agentic run: start a task, verify SSE timeline streams, confirm circuit breaker triggers on runaway loops

🤖 Generated with Claude Code

jbcupps and others added 16 commits February 16, 2026 20:30
…tack

- Add x-proxy-env anchor, orion_internal/orion_proxy_chain/orion_egress networks
- Add proxy_internal, proxy_external, nettest, frontend_ingress, ollama_ingress, postgres_ingress
- Attach full-profile services to orion_internal; remove direct ports (ingress sidecars)
- Delete docker-compose.proxy.yml
- Update README, HOW_TO_RUN_LOCALLY, ARCHITECTURE, example.env, docker/proxy/README
- Use single-file in proxy-smoke-test scripts
- Ignore .orion/ runtime proxy logs in .gitignore

Co-authored-by: Cursor <cursoragent@cursor.com>
Align runtime identity terminology to 'entity', add proxy observability/manageability APIs and tooling, improve chat-to-agentic follow-through reliability, and upgrade startup/documentation for predictable full-stack operations.

Co-authored-by: Cursor <cursoragent@cursor.com>
… conflicts

Co-authored-by: Cursor <cursoragent@cursor.com>
…, and 16 archetypes

Transform the genesis system into a community-contributable library with:
- genesis-core crate: GenesisStrategy trait, SoulManifest contract, CompassEthicWeights (4-dim), StepRequest/StepResponse protocol, GenesisRegistry
- 14 TOML-defined ethical scenarios with difficulty stratification and session selection
- 16 combinatorial archetypes (4 pure + 12 compound) via primary/secondary dimension system
- 4 genesis-path wrapper crates (quick-start, direct-discovery, soul-crystallization, soul-forge)
- Unified /api/agents/:id/genesis/step endpoint replacing per-path routes
- 4-dimension Compass Ethic (duty/virtue/outcome/welfare) replacing Triangle Ethic
- Improved 8x32 sigil generation with dimension-blended character sets
- Frontend GenesisStepView unified component and mentor name integration
- Updated soul-crystallization ethics calibrator for 4 dimensions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Batch 1 — Critical fixes:
- Re-enable CI pipeline (remove `if: false`)
- Parameterize Postgres credentials in docker-compose
- Enforce API auth in containers (ORION_API_TOKEN required)
- Move private key from HTTP header to POST body (export endpoint)
- Replace EventSource with fetch-based SSE (token out of query string)
- Add agentic task cleanup loop (memory leak fix)

Batch 2 — Quality improvements:
- Extract shared useAgenticStream hook (eliminates ~200 lines duplication)
- Add React ErrorBoundary with fallback UI
- Fix undefined var(--fg) CSS variable → var(--text)
- Add 2-minute timeout on chat stream fetch
- Create centralized ApiError type (error.rs)

Batch 3 — Infrastructure & migration:
- Pin Ollama base image to 0.16.2
- Fix Object URL memory leak on OperationalChat unmount
- Add React.lazy() code splitting for 9 components
- Convert agent_runs.rs and skills.rs to ApiError

Batch 4 — Accessibility & API consistency:
- Add Forbidden variant to ApiError, fix 403 vs 401 semantics
- Add frontend health check in Docker compose
- Add ARIA labels + aria-expanded to interactive elements
- Add focus trap on modal dialogs (useFocusTrap hook)
- Complete ApiError migration: 45 handlers in main.rs converted
- Extract route modules: identity.rs, agent_runs.rs, skills.rs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Id vs Ego Responsibility Matrix to CLAUDE.md, README.md, and
docs/ARCHITECTURE.md. Updates CLAUDE.md Terminology with explicit
Id/Ego definitions. Id must never be used for tool-calling or
autonomous loops — only birth, heartbeat cron, and privacy flows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pre-flight: reject agentic tasks when no cloud Ego provider is configured.
Id (local LLM) is heartbeat-only and must never run autonomous tool-calling loops.

Circuit breaker (inside the turn loop):
- no_tool_streak: counts consecutive turns where the LLM produced no tool calls.
  At 3 consecutive no-tool turns, aborts with actionable error message.
  Nudge messages now show streak progress (e.g. "1/3 no-tool turns").
- seen_states: HashSet of response content hashes. If the LLM produces an
  identical response twice (loop/death-spiral), aborts immediately.

Both triggers emit AgenticEvent::Warning before the Done/Failed event so the
frontend can surface the reason. The SSE route now handles the new Warning variant.

Adds ego_available_for_agentic() to IdEgoRouter as a semantic gate method.

Tests: 5 new tests (3 in orion-api, 2 in orion-router) all passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rust-toolchain.toml specifies channel = "stable" which causes rustup to
sync to the latest stable inside Docker containers. The Dockerfile only
installed components for the base image's Rust 1.75, so cargo fmt/clippy
failed when the toolchain upgraded to 1.93.1. Adding components to
rust-toolchain.toml ensures they're always available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Describe Orion Dock's place in the three-part identity ecosystem
(Abigail, Orion Dock, SAO) with agent soul contract details and
visual reference placeholders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Define the canonical agent archetype covering soul, ethics, org-map,
skills contract, and birth ceremony across the ecosystem.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Keep reportedTaskResultsRef and BirthChatMessageItem type from
feature branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove duplicate proxy endpoint functions in main.rs, fix missing
config_path scope in quick-start path, add spawn_agentic_loop wrapper
to satisfy Send bound for tokio::spawn, update deprecated rand/rand
APIs (gen_range→random_range, thread_rng→rng), fix explicit auto-deref
clippy warnings, make postgres integration test skip gracefully when
DB is unreachable, remove stale agenticLaunchInfo polling and duplicate
useEffect/API definitions from frontend, and run cargo fmt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add shared MASTER_KEY_ENV_LOCK mutex across all orion-core tests that
read or mutate the ORION_MASTER_KEY env var (dpapi, encrypted_storage,
email_auth, provider_keyring, secrets, skill_keychain) to prevent
parallel test races when the key is set in the Docker environment.
Also add --legacy-peer-deps to docker-test-suite.sh npm fallback to
handle @eslint/js peer dependency conflict.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add personality.md as Superego-modifiable document to the Agent Soul
Contract, and document Superego behavior in enterprise deployments
(CRITICALITY-based monitoring, hot-reload, SAO audit trail).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 02f5f24c55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1724 to +1728
let providers: Vec<String> = state
.resolved_ego
.read()
.unwrap()
.all_provider_names
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Scope provider listing to the requested agent

This handler now ignores id and always returns state.resolved_ego.all_provider_names, so every /api/agents/{id}/connectivity/providers call reports the same provider set regardless of which agent is requested. In a multi-agent Hive this leaks cross-agent connectivity state and breaks per-agent configuration flows (tier models, connectivity UI), because the response no longer reflects the target agent’s keyring.

Useful? React with 👍 / 👎.

Comment on lines 3565 to +3567
let (ego_name, ego_key) = {
let keyring = ProviderKeyring::load(config.data_dir.clone())
.unwrap_or_else(|_| ProviderKeyring::new(config.data_dir.clone()));
resolve_ego_credentials_with_preference(
&keyring,
config.active_provider_preference.as_deref(),
)
let resolved = state.resolved_ego.read().unwrap();
(resolved.provider_name.clone(), resolved.api_key.clone())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Recompute Ego credentials from current agent config

Operational chat now pulls provider/key only from the cached resolved_ego pair, but that cache is refreshed on keyring mutations, not when /api/agents/{id}/active-provider changes active_provider_preference. The result is that switching active provider can be silently ignored for subsequent chats until an unrelated key mutation or restart, routing requests with stale credentials.

Useful? React with 👍 / 👎.

Comment on lines +4522 to +4526
// Write mutated keyring back to shared state.
if kr_mutated {
let mut shared_kr = shared_keyring.write().unwrap();
*shared_kr = keyring.clone();
if let Err(e) = shared_kr.save() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Sync skill keychain even without provider-key mutations

The cloned skill_kc is written back to shared state only inside if kr_mutated, but store_vault_secret updates skill_kc without setting kr_mutated. That means vault-secret writes can succeed on disk while state.skill_keychain stays stale in memory, so later skill executions in the same process may not see newly stored secrets until another keyring mutation happens.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant