ouroboros-ai 0.31.2.dev16__tar.gz → 0.31.2.dev18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ouroboros-ai might be problematic. Click here for more details.
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/PKG-INFO +1 -1
- ouroboros_ai-0.31.2.dev18/docs/rfc/disposable-memory.md +188 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/_version.py +2 -2
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/lineage.py +31 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/projector.py +43 -2
- ouroboros_ai-0.31.2.dev18/tests/unit/test_lineage.py +39 -0
- ouroboros_ai-0.31.2.dev18/tests/unit/test_projector_directives.py +278 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.claude/settings.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.claude-plugin/.mcp.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.claude-plugin/marketplace.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.claude-plugin/plugin.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.env.example +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/ISSUE_TEMPLATE/question.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/workflows/dev-publish.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/workflows/lint.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/workflows/release.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.github/workflows/test.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.gitignore +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.mcp.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.ouroboros/mechanical.toml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.ouroboros/seeds/seed_73827177a2a3.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.ouroboros/seeds/seed_78c8e6e41813.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.pre-commit-config.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/.python-version +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/CHANGELOG.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/CLAUDE.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/CODE_OF_CONDUCT.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/CONTRIBUTING.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/Code-Review-Claude.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/Code-Review-Codex.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/HANDOFF.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/LICENSE +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/README.ko.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/README.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/SECURITY.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/UNINSTALL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/cancel.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/evaluate.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/evolve.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/help.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/interview.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/ralph.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/run.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/seed.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/setup.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/status.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/tutorial.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/unstuck.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/commands/welcome.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/.gitignore +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/Cargo.lock +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/Cargo.toml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/README.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/db.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/main.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/mock.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/state.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/views/execution.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/views/logs.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/views/mod.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/README.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/api/README.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/api/core.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/api/mcp.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/architecture.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/cli-reference.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/config-reference.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/contributing/agent-os-kernel-terminology.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/contributing/architecture-overview.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/contributing/findings-registry.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/contributing/issue-quality-policy.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/contributing/key-patterns.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/contributing/testing-guide.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/events.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/examples/mcp-config.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/examples/workflows/design-code-verify.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/examples/workflows/research-to-deliverable.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/getting-started.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/evaluation-pipeline.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/evolution-loop.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/mcp-best-practices.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/mcp-bridge.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/ooo-skill-dispatch-router.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/opencode-subagent-bridge.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/qa-backends.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/seed-authoring.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/guides/tui-usage.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/images/PLACEHOLDER_README.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/images/ouroboros.png +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/platform-support.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/rfc/mesh.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/runtime-capability-matrix.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/runtime-guides/claude-code.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/runtime-guides/codex.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/runtime-guides/gemini.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/runtime-guides/hermes.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/docs/runtime-guides/opencode.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/coordinator_test_seed.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/dummy_seed.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/parallel_subac_test_seed.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/subac_test_seed.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/task_manager/README.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/task_manager/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/task_manager/__main__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/task_manager/cli.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/task_manager/models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/task_manager/storage.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/examples/test_display.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/hooks/hooks.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/llms-full.txt +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/llms.txt +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/project-context.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/pyproject.toml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/drift-monitor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/install.sh +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/keyword-detector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/mcp-serve.sh +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/ralph-rewind.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/ralph.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/ralph.sh +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/session-start.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/sync-plugin-version.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/scripts/version-check.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/brownfield/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/cancel/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/evaluate/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/evolve/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/help/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/interview/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/pm/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/publish/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/qa/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/ralph/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/resume-session/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/run/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/seed/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/setup/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/status/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/tutorial/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/unstuck/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/update/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/skills/welcome/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/__main__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/advocate.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/analysis-agent.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/architect.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/breadth-keeper.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/code-executor.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/codebase-explorer.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/consensus-reviewer.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/contrarian.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/evaluator.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/hacker.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/judge.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/loader.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/ontologist.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/ontology-analyst.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/qa-judge.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/research-agent.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/researcher.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/seed-architect.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/seed-closer.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/semantic-evaluator.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/simplifier.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/agents/socratic-interviewer.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/ambiguity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/brownfield.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/explore.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/interview.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/pm_completion.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/pm_document.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/pm_interview.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/pm_seed.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/question_classifier.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/bigbang/seed_generator.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/claude_permissions.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/cancel.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/codex.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/detect.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/init.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/mcp.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/mcp_doctor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/pm.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/resume.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/run.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/setup.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/status.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/tui.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/commands/uninstall.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/formatters/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/formatters/panels.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/formatters/progress.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/formatters/prompting.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/formatters/tables.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/jsonc.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/main.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/cli/opencode_config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/codex/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/codex/artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/codex/cli_policy.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/codex/ouroboros.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/codex_permissions.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/config/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/config/loader.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/config/models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/ac_tree.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/directive.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/errors.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/file_lock.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/git_workflow.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/initial_context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/json_utils.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/ontology_aspect.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/ontology_questions.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/project_paths.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/retry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/security.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/seed.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/seed_contract.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/seed_contract_prompt.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/text.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/ttl_cache.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/types.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/core/worktree.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/artifact_collector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/checklist.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/consensus.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/detector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/json_utils.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/languages.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/mechanical.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/pipeline.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/semantic.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/trigger.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/base.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/control.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/decomposition.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/evaluation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/interview.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/lineage.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/events/ontology.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/convergence.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/loop.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/reflect.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/regression.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/wonder.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/execution/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/execution/atomicity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/execution/decomposition.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/execution/double_diamond.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/execution/subagent.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/hermes/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/hermes/artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/bridge/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/bridge/bridge.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/bridge/config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/bridge/factory.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/client/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/client/adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/client/manager.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/client/protocol.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/errors.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/job_manager.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/resources/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/resources/handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/server/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/server/adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/server/protocol.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/server/security.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/ac_tree_hud_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/ac_tree_hud_render.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/bridge_mixin.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/dashboard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/definitions.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/execution_handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/pm_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/qa.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/tools/subagent.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/mcp/types.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/observability/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/observability/drift.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/observability/logging.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/observability/retrospective.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/plugin/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/plugin/opencode-plugin.d.ts +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/plugin/ouroboros-bridge.test.ts +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/plugin/ouroboros-bridge.ts +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/plugin/package.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/opencode/plugin/tsconfig.json +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/capabilities.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/control_plane.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/coordinator.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/events.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/gemini_cli_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/heartbeat.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/hermes_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/level_context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/mcp_config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/opencode_event_normalizer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/opencode_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/policy.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/rate_limit.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/runner.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/session.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/orchestrator/workflow_state.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/brownfield.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/checkpoint.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/event_store.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/migrations/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/migrations/runner.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/schema.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/persistence/uow.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/agents/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/agents/pool.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/agents/registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/orchestration/router.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/skills/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/skills/docs.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/skills/executor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/skills/keywords.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/plugin/skills/registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/pm/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/pm/handoff.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/pm/renderer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/anthropic_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/base.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/claude_code_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/codex_cli_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/codex_cli_stream.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/factory.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/gemini_cli_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/gemini_event_normalizer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/litellm_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/providers/opencode_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/py.typed +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/resilience/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/resilience/lateral.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/resilience/recovery.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/resilience/stagnation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/router/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/router/command_parser.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/router/dispatch.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/router/registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/router/types.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/routing/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/routing/complexity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/routing/downgrade.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/routing/escalation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/routing/router.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/routing/tiers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/sandbox.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/secondary/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/secondary/scheduler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/secondary/todo_registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/skills/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/skills/artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/strategies/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/strategies/devil_advocate.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/app.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/components/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/components/agents_panel.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/components/event_log.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/components/progress.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/components/token_tracker.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/events.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/dashboard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/debug.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/execution.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/logs.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/screens/session_selector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/verification/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/verification/extractor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/verification/models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/verification/verifier.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/e2e/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/e2e/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/e2e/mcp_bridge_test_config.yaml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/e2e/test_cli_commands.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/e2e/test_full_workflow.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/e2e/test_session_persistence.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/fixtures/router/skills/frontmatter-body/run/SKILL.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/fixtures/test_atomicity_seed.yml +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/bridge/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/bridge/test_bridge_server_to_server.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/test_client_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/test_client_manager.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/mcp/test_server_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/plugin/test_orchestration.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/test_cancel_subprocess_termination.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/test_codex_skill_fallback.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/test_codex_skill_smoke.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/integration/test_entry_point.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/test-execution-plan.md +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/agents/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/agents/test_loader.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_ambiguity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_brownfield.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_classifier_context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_decide_later_items.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_explore.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_interview.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_interview_async_io.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_interview_no_web_search_hint.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_interview_research_prefix.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_completion.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_interview.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_question_classifier.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/bigbang/test_seed_generator.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/commands/test_tui_command.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/test_console.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/test_panels.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/test_progress.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/test_prompting.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/test_tables.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_bridge_plugin_hardening.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_bridge_plugin_lifecycle.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_cancel.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_codex_command.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_doc_commands.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_init_pm_seed_detection.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_init_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_jsonc.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_main.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_mcp_doctor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_mcp_shell_env.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_mcp_validate_transport_stderr.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_opencode_config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_brownfield.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_completion.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_interactive_logging.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_overwrite.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_runtime_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_pm_select_repos.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_resume.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_run_qa.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_setup.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/cli/test_uninstall.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/codex/test_cli_policy.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/config/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/config/test_loader.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/config/test_loader_env.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/config/test_models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_ac_tree.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_directive.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_errors.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_file_lock.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_git_workflow.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_initial_context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_lineage.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_ontology_aspect.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_ontology_questions.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_retry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_security.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_seed.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_ttl_cache.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_types.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/core/test_worktree.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_artifact_collector_file_prefix.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_checklist.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_consensus.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_detector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_json_utils.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_languages.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_mechanical.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_models.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_pipeline_stage1_reuse.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_pipeline_trigger_consensus.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_review_fixes.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_semantic.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_trigger.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_trigger_consensus.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/events/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/events/test_base.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/events/test_control_events.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/events/test_decomposition_events.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/evolution/test_wonder_scope.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/execution/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/execution/test_atomicity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/execution/test_decomposition.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/execution/test_double_diamond.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/execution/test_subagent_isolation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/hermes/test_artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/bridge/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/bridge/test_bridge.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/bridge/test_config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/bridge/test_factory.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/bridge/test_handler_wiring.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/bridge/test_stability.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/client/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/client/test_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/client/test_adapter_transport_lifecycle.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/client/test_manager.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/server/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/server/test_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/server/test_security.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/test_errors.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/test_job_manager.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/test_types.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/conftest.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_footer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_handler_completed.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_handler_cursor_changed.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_handler_invalid_session.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_handler_no_execution.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_handler_waiting.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_max_nodes.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_render_depth2.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_render_depth3.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_status_icons.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_ac_tree_hud_truncation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_checklist_verify.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_definitions.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_evaluate_multi_ac.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_handler_subagent_wiring.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_interview_done_streak.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_interview_reopen_seed_ready.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_lateral_think_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_mcp_manager_wiring.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_pm_handler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_qa_parser.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_round5_fixes.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/mcp/tools/test_subagent.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/observability/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/observability/test_drift.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/observability/test_logging.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/observability/test_retrospective.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_capabilities.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_control_plane.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_coordinator.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_events.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_gemini_cli_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_hermes_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_level_context.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_mcp_config.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_opencode_runtime.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_parallel_executor_atomic_judgment.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_parallel_executor_recursive_depth.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_policy.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_rate_limit.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_runner.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_sandbox_class.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_seed_prompt.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_session.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/orchestrator/test_workflow_state.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/persistence/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/persistence/test_brownfield_store.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/persistence/test_checkpoint.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/persistence/test_event_store.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/persistence/test_schema.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/persistence/test_uow.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/agents/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/agents/test_registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/orchestration/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/skills/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/skills/test_keywords.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/plugin/skills/test_registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/pm/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/pm/test_renderer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_base.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_claude_code_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_codex_cli_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_factory.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_gemini_cli_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_litellm_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/providers/test_opencode_adapter.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/resilience/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/resilience/test_lateral.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/resilience/test_recovery.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/resilience/test_stagnation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_command_parser.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_dispatch.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_dispatch_result_shapes.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_extract_first_argument.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_invalid_dispatch_input_types.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_malformed_unknown_dispatch_errors.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_not_handled_resolution.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_repository_dispatch_guard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_router_resolution_pipeline.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_typed_frontmatter_fields.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/router/test_valid_dispatch_normalization.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/routing/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/routing/test_complexity.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/routing/test_downgrade.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/routing/test_escalation.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/routing/test_router.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/routing/test_tiers.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/scripts/test_keyword_detector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/scripts/test_session_start.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/scripts/test_version_check.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/secondary/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/secondary/test_scheduler.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/secondary/test_todo_registry.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/skills/test_skill_artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_artifact_collector.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_codex_artifacts.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_convergence.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_dashboard.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_dependencies_configured.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_evolve_rewind.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_evolve_step.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_graceful_shutdown.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_main_entry_point.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_module_structure.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_project_initialization.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_projector_rewind.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_ralph_parser.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_ralph_rewind.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_regression.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_tooling_configuration.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/test_verification.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/__init__.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_app.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_cancelled_display.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_events.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_lineage_viewer.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_screens.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_session_selector_replay.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tests/unit/tui/test_widgets.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/tools/sync_github_project.py +0 -0
- {ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/uv.lock +0 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# RFC — Disposable Memory process model and `artifact_ref`
|
|
2
|
+
|
|
3
|
+
> Status: **Accepted** (Phase 2 of #476 Agent OS roadmap).
|
|
4
|
+
> Closes [#512](https://github.com/Q00/ouroboros/issues/512).
|
|
5
|
+
> Related: [#476](https://github.com/Q00/ouroboros/issues/476) M3 (I/O Journal payload policy), [#492](https://github.com/Q00/ouroboros/pull/492) (`agent_process` target_type forward declaration), [#511](https://github.com/Q00/ouroboros/issues/511), [#518](https://github.com/Q00/ouroboros/issues/518) (M6 AgentProcess lifecycle).
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
This RFC specifies how *disposable working memory* is bounded for sub-agent invocations: where their outputs live, how they are referenced from the ledger without leaking back into main session context, when they are reclaimed, and how replay treats them.
|
|
10
|
+
|
|
11
|
+
The RFC narrows itself deliberately. *Lifecycle verbs* (spawn / pause / resume / cancel / replay) belong to [#518](https://github.com/Q00/ouroboros/issues/518). *Wire and failure semantics* belong to [#511](https://github.com/Q00/ouroboros/issues/511). *Persistent cross-session memory* (Hermes Super Memory and the hippocampus / brain-plasticity research track) is **out of scope** — it is a parallel research stream not part of the 1.0 acceptance surface.
|
|
12
|
+
|
|
13
|
+
Disposable Memory is, in one sentence, the discipline that makes the slide promise *"main ledger holds only `contract_id + artifact_ref`"* survive in code.
|
|
14
|
+
|
|
15
|
+
## Scope
|
|
16
|
+
|
|
17
|
+
This document **does** decide:
|
|
18
|
+
- The execution model for sub-agent invocations.
|
|
19
|
+
- The `artifact_ref` backend (storage layout and addressing).
|
|
20
|
+
- The garbage-collection policy.
|
|
21
|
+
- The mechanism that prevents sub-agent transcripts from leaking into main context.
|
|
22
|
+
- The default replay behavior with respect to artifact reuse vs re-execution.
|
|
23
|
+
|
|
24
|
+
This document **does not** decide:
|
|
25
|
+
- AgentProcess lifecycle verbs (deferred to [#518](https://github.com/Q00/ouroboros/issues/518)).
|
|
26
|
+
- Mesh transport, envelope, or failure → Directive mapping (deferred to [#511](https://github.com/Q00/ouroboros/issues/511)).
|
|
27
|
+
- Contract Ledger schema (deferred to [#513](https://github.com/Q00/ouroboros/issues/513)).
|
|
28
|
+
- Hermes Super Memory or any persistent cross-session memory layer — explicitly **out of scope**.
|
|
29
|
+
|
|
30
|
+
## Inherited from earlier RFCs
|
|
31
|
+
|
|
32
|
+
| Decision | Source | What it means here |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| IPC channel | [#511](https://github.com/Q00/ouroboros/issues/511) D1 — streamable-http + stdio multiplex | Sub-agents do not need a separate channel; the Mesh transport is the IPC. |
|
|
35
|
+
| Resource limits | [#511](https://github.com/Q00/ouroboros/issues/511) D7 — `deadline_ms` + `retry_budget` only | CPU/mem caps are RFC #476 Tier-3 C3, gated by usage evidence. |
|
|
36
|
+
| Crash → Directive | [#511](https://github.com/Q00/ouroboros/issues/511) D7 — runtime crash → `CANCEL`; schema fail → `CANCEL` | Disposable failures inherit this mapping unchanged. |
|
|
37
|
+
| `contract_id = ULID` | [#511](https://github.com/Q00/ouroboros/issues/511) D2 | Sub-agent invocations are addressed by the same id space. |
|
|
38
|
+
|
|
39
|
+
## Decisions
|
|
40
|
+
|
|
41
|
+
### C1 — Execution model: harness invocation, no new Python process layer
|
|
42
|
+
|
|
43
|
+
**Decision.** A sub-agent spawn is a **bounded harness invocation** on top of the existing provider/runtime pattern in `providers/{codex,opencode,gemini}_cli_adapter.py` and `orchestrator/hermes_runtime.py`. The disposable boundary is the harness child process; the spawn passes a constrained context, the harness produces a result envelope, and the child exits when the contract completes.
|
|
44
|
+
|
|
45
|
+
This RFC does **not** add a Python `multiprocessing` or `os.fork` layer.
|
|
46
|
+
|
|
47
|
+
**Rationale.** The slide framing of *"each sub-agent forks like an independent process and dies"* is *already true* in the codebase: every harness adapter spawns the harness as a child process. Inventing a Python-level multiprocessing layer on top of that would duplicate the existing isolation, fail on Windows (`os.fork` is POSIX-only, `multiprocessing.spawn` has pickling problems with stateful objects), and add no isolation we do not already have.
|
|
48
|
+
|
|
49
|
+
**Important framing.** Isolation here is in the **cooperative-trust sense** (#476), not the security sense. A misbehaving sub-agent can still emit forged directives in cooperation; the same trust model the rest of the system uses. This RFC does not pretend otherwise.
|
|
50
|
+
|
|
51
|
+
**Risks.**
|
|
52
|
+
- "Isolation" misread as security isolation. Mitigation: this RFC and the implementation explicitly state cooperative-trust framing.
|
|
53
|
+
- Future demand for true sandboxing. Mitigation: the harness pattern allows a sandboxed harness implementation later without changing the disposable contract.
|
|
54
|
+
|
|
55
|
+
### C2 — Backend: content-addressed filesystem
|
|
56
|
+
|
|
57
|
+
**Layout.**
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
.ouroboros/artifacts/
|
|
61
|
+
ab/ # 2-level prefix avoids huge directories
|
|
62
|
+
abc123<sha256>.json # content-addressed result envelope body
|
|
63
|
+
contracts/
|
|
64
|
+
01HXAB.../
|
|
65
|
+
events.json # optional per-contract event dump/manifest
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`artifact_ref = "sha256:abc123..."` (matches the result envelope shape in [#511](https://github.com/Q00/ouroboros/issues/511) D2). Event dumps are keyed by `contract_id`, not by body hash, so content dedup never overwrites per-contract history.
|
|
69
|
+
|
|
70
|
+
**Why content-addressed FS.**
|
|
71
|
+
- **Auto-dedup.** Identical sub-agent results across contracts collapse to one file.
|
|
72
|
+
- **Single-DB pressure relieved.** The EventStore stays focused on events; bodies do not bloat its WAL.
|
|
73
|
+
- **OS tools work.** `du`, `find`, `rsync`, `ls` operate on the artifact tree directly — important for local-first introspection.
|
|
74
|
+
- **Single hashing story.** SHA-256 is also used for `prompt_hash` in [#517](https://github.com/Q00/ouroboros/issues/517) M3 I/O Journal; using the same family keeps the operator mental model small.
|
|
75
|
+
|
|
76
|
+
**Why not external KV (S3 etc.).** RFC #476 Tier-4 Won't (no SaaS).
|
|
77
|
+
|
|
78
|
+
**Why not SQLite blob.** The EventStore's WAL behavior is not designed for large binary payloads; storing artifacts inline degrades append latency for the rest of the journal.
|
|
79
|
+
|
|
80
|
+
### C3 — GC: reachability-first + TTL fallback + explicit CLI
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
ouroboros artifacts prune # dry-run; prints what would be deleted
|
|
84
|
+
ouroboros artifacts prune --apply # actually delete
|
|
85
|
+
ouroboros artifacts prune --ttl 30d # override default TTL of 90 days
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Algorithm.**
|
|
89
|
+
|
|
90
|
+
1. Walk the EventStore once and build a reverse index: `artifact_ref -> set(contract_id)` plus each contract's retention state.
|
|
91
|
+
2. Protect every artifact referenced by an active contract or by a contract still inside the replay-retention window. These are *active reachable* and are never removed by normal prune.
|
|
92
|
+
3. Mark a file under `.ouroboros/artifacts/` for deletion only when its `mtime` exceeds the TTL **and** every referencing contract is outside the artifact-body retention window, or the operator explicitly opts into tombstoning replay bodies with `--allow-replay-tombstone`.
|
|
93
|
+
4. Before deleting a content-addressed blob, write a contract-scoped `artifact.tombstoned` event (or durable per-contract tombstone manifest entry) for **each** referencing contract. This fan-out is required because a single deduplicated hash may be shared by many contracts.
|
|
94
|
+
5. Delete the blob only after those tombstones are durable. Future replay surfaces *"this artifact was pruned; use `--force-rerun` to recompute"* from the contract's own event stream/manifest rather than a silent missing-file error.
|
|
95
|
+
6. Tombstones for still-referenced contracts are retained as part of the replay contract. Tombstones for artifacts whose referencing contracts are also out of retention may be compacted by an explicit ledger-compaction workflow, not by the normal artifact prune path.
|
|
96
|
+
|
|
97
|
+
**Why local-first / opt-in.** Local-first means GC is never on the hot path; users opt in by running the command. Default policy is conservative (data preservation > disk reclaim). `ouroboros artifacts prune` without `--apply` is a dry-run that prints the candidate list — this is the operator's safety net before destructive action.
|
|
98
|
+
|
|
99
|
+
**Risks.**
|
|
100
|
+
- Disk growth before the operator notices. Mitigation: TTL fallback default (90 days) + dry-run-by-default CLI semantics.
|
|
101
|
+
- Tombstone accumulation. Mitigation: only an explicit ledger-compaction workflow may drop tombstones after their referencing contracts are also out of retention; deterministic replay wins over routine GC.
|
|
102
|
+
- Hash collision in the SHA-256 namespace. Mitigation: practically zero. Policy is "never silently overwrite" — if a write attempt observes a different existing payload at the same hash, it raises.
|
|
103
|
+
|
|
104
|
+
### C4 — Context bloat guard: three-layer enforcement
|
|
105
|
+
|
|
106
|
+
This is the slide promise *"main ledger holds only `contract_id + artifact_ref`"* turned into something that **survives regressions**. Three independent layers because any single layer rots over time.
|
|
107
|
+
|
|
108
|
+
**Layer 1 — Envelope types.** The Result envelope from [#511](https://github.com/Q00/ouroboros/issues/511) D2 only exposes `contract_id`, `artifact_ref`, `result.status`, `runtime_id`, `duration_ms`, `events_emitted_count`. Sub-agent transcripts are *not a field*. The orchestrator's caller-facing API returns this typed envelope and nothing else; deeper bodies are reachable only via explicit query. The type system itself blocks accidental leakage at compile time.
|
|
109
|
+
|
|
110
|
+
**Layer 2 — Regression fixture (CI gate).** A test where a sub-agent emits a 1 MB artifact. Assertion: the parent's in-memory context after the call is bounded (e.g., < 4 KB delta, asserted against a high-water-mark probe). This test is wired into CI so that any future PR that quietly enlarges the result envelope fails.
|
|
111
|
+
|
|
112
|
+
**Layer 3 — Explicit-fetch-only API.** Reading a sub-agent's body is a deliberate call:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
events = event_store.get_events_by_contract(contract_id)
|
|
116
|
+
artifact = artifact_store.read(artifact_ref)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
There is *no* implicit accessor that returns a sub-agent's transcript "for free." A grep-able invariant: *no orchestrator code path calls `artifact_store.read` between `spawn` and the next persisted event.* This invariant is testable post-merge by a static check or a runtime assertion in development mode.
|
|
120
|
+
|
|
121
|
+
**Why three layers.** If any single layer is dropped, the slide promise erodes within a few releases. All three are cheap individually; the discipline is treating them as a set. The common alternative — "developers will remember to keep envelopes small" — is exactly the failure mode this RFC is designed to prevent.
|
|
122
|
+
|
|
123
|
+
### C5 — Replay default: read artifact + `--force-rerun` opt-in
|
|
124
|
+
|
|
125
|
+
**Default `replay()` behavior.** Reads from `.ouroboros/artifacts/`. Deterministic, fast, no token spend.
|
|
126
|
+
|
|
127
|
+
**`--force-rerun`.** Allocates a **new `contract_id`** and runs the work again. This is exactly the rule from [#511](https://github.com/Q00/ouroboros/issues/511) D6: intentional re-execution is a new contract, accidental re-execution via retry is the same contract. Replay inherits that rule rather than inventing a third one.
|
|
128
|
+
|
|
129
|
+
**Tombstoned artifact path.** If the artifact has been pruned (C3), the default replay first checks the contract-scoped tombstone event/manifest and surfaces that tombstone before asking the user to opt into rerun. **No silent fallback to rerun** — this would corrupt the *replay* verb's promise of determinism.
|
|
130
|
+
|
|
131
|
+
## Out of scope (explicit)
|
|
132
|
+
|
|
133
|
+
- **Hermes Super Memory** and any persistent cross-session memory layer. The maintainer's parallel research project on hippocampus modeling and brain-plasticity-inspired forgetting is its own track. Disposable Memory is *the opposite of* Super Memory: disposable is "throw away cleanly," Super Memory is "preserve and forget intelligently." Conflating the two would corrupt both abstractions.
|
|
134
|
+
- **CPU/mem resource limits.** RFC #476 Tier-3 C3, gated by usage evidence.
|
|
135
|
+
- **Forking and branching of sub-agent state.** RFC #476 Tier-3 C1, gated by usage evidence.
|
|
136
|
+
|
|
137
|
+
## Sequence diagram — one sub-agent invocation
|
|
138
|
+
|
|
139
|
+
```mermaid
|
|
140
|
+
sequenceDiagram
|
|
141
|
+
participant O as Orchestrator (main session)
|
|
142
|
+
participant H as Harness child (sub-agent)
|
|
143
|
+
participant E as EventStore
|
|
144
|
+
participant A as Artifact store (.ouroboros/artifacts)
|
|
145
|
+
|
|
146
|
+
O->>H: spawn(directive, bounded context, contract_id)
|
|
147
|
+
H->>E: append tool.call.* / llm.call.* / control.directive.* (target=agent_process/<contract_id>)
|
|
148
|
+
H->>A: write sha256(<body>).json
|
|
149
|
+
H-->>O: result envelope { contract_id, artifact_ref, runtime_id, events_emitted_count, ... }
|
|
150
|
+
H-->>H: process exit (disposable boundary)
|
|
151
|
+
O->>O: caller sees only the result envelope (Layer 1 type guard)
|
|
152
|
+
Note over O,A: replay(contract_id) reads E + A, never re-executes
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Cross-RFC consistency
|
|
156
|
+
|
|
157
|
+
| Subject | Source | This RFC's behaviour |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| IPC channel | [#511](https://github.com/Q00/ouroboros/issues/511) D1 | Inherited; no separate Disposable IPC. |
|
|
160
|
+
| Resource limits | [#511](https://github.com/Q00/ouroboros/issues/511) D7 | Inherited; `deadline_ms` and `retry_budget` only. |
|
|
161
|
+
| Crash → Directive | [#511](https://github.com/Q00/ouroboros/issues/511) D7 | Inherited; sub-agent crash → `CANCEL`. |
|
|
162
|
+
| `artifact_ref` URI scheme | this RFC, C2 | Used in [#511](https://github.com/Q00/ouroboros/issues/511) D2 result envelope. |
|
|
163
|
+
| Replay determinism | this RFC, C5 + [#511](https://github.com/Q00/ouroboros/issues/511) D6 | `replay()` reads artifacts; new run = new `contract_id`. |
|
|
164
|
+
| Bloat guard | this RFC, C4 | Enforced at envelope, fixture, and API layers. |
|
|
165
|
+
|
|
166
|
+
## Pre-merge checklist
|
|
167
|
+
|
|
168
|
+
- [ ] All 5 fresh decisions present (C1–C5), each with option, rationale, risks
|
|
169
|
+
- [ ] Inherited-from list explicitly cites [#511](https://github.com/Q00/ouroboros/issues/511) D1 / D7
|
|
170
|
+
- [ ] Out-of-scope statement names Hermes Super Memory and persistent cross-session memory
|
|
171
|
+
- [ ] Mermaid diagram renders and shows the spawn-to-cleanup loop end to end
|
|
172
|
+
- [ ] Cross-references resolve to existing issues / files
|
|
173
|
+
- [ ] At least two maintainer approvals
|
|
174
|
+
- [ ] C4 three-layer enforcement listed with concrete acceptance examples
|
|
175
|
+
- [ ] `artifact_ref = "sha256:..."` linkage matches what [#513](https://github.com/Q00/ouroboros/issues/513) inherits
|
|
176
|
+
- [ ] "Replay default = read artifact" matches [#511](https://github.com/Q00/ouroboros/issues/511) D6 + [#518](https://github.com/Q00/ouroboros/issues/518) M6
|
|
177
|
+
- [ ] No accidental re-decision of items already settled in [#511](https://github.com/Q00/ouroboros/issues/511)
|
|
178
|
+
|
|
179
|
+
## Post-merge checklist
|
|
180
|
+
|
|
181
|
+
- [ ] `docs/rfc/disposable-memory.md` reachable from the docs site (or the README index when it lands)
|
|
182
|
+
- [ ] Issue [#512](https://github.com/Q00/ouroboros/issues/512) closed with a back-link to this PR
|
|
183
|
+
- [ ] At least one Phase E implementation issue opened referencing this RFC (sub-agent migration to disposable model — `qa-judge` is the candidate first migration)
|
|
184
|
+
- [ ] `.ouroboros/artifacts/<prefix>/<sha256>` path layout reflected in `core/project_paths.py` or equivalent
|
|
185
|
+
|
|
186
|
+
## Rollback
|
|
187
|
+
|
|
188
|
+
Docs PR with no runtime impact. Rollback = revert the docs PR. The proposal comment in [#512](https://github.com/Q00/ouroboros/issues/512) remains as the working draft.
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.31.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 31, 2, '
|
|
21
|
+
__version__ = version = '0.31.2.dev18'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 31, 2, 'dev18')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -369,6 +369,24 @@ class RewindRecord(BaseModel, frozen=True):
|
|
|
369
369
|
discarded_generations: tuple[GenerationRecord, ...] = ()
|
|
370
370
|
|
|
371
371
|
|
|
372
|
+
class ControlDirectiveEmission(BaseModel, frozen=True):
|
|
373
|
+
"""One ``control.directive.emitted`` event folded onto a lineage.
|
|
374
|
+
|
|
375
|
+
Captures the audit-level "who/what/why/when" of a control-plane
|
|
376
|
+
decision so it appears in the lineage timeline alongside state events
|
|
377
|
+
(per RFC #476 M2 / sub-RFC #511). The full event row remains in the
|
|
378
|
+
EventStore; this is the projected view used by callers.
|
|
379
|
+
"""
|
|
380
|
+
|
|
381
|
+
directive: str
|
|
382
|
+
reason: str
|
|
383
|
+
emitted_by: str
|
|
384
|
+
timestamp: datetime
|
|
385
|
+
generation_number: int | None = None
|
|
386
|
+
phase: str | None = None
|
|
387
|
+
is_terminal: bool = False
|
|
388
|
+
|
|
389
|
+
|
|
372
390
|
class OntologyLineage(BaseModel, frozen=True):
|
|
373
391
|
"""Tracks O₁ → O₂ → O₃ evolution across generations.
|
|
374
392
|
|
|
@@ -382,6 +400,7 @@ class OntologyLineage(BaseModel, frozen=True):
|
|
|
382
400
|
goal: str
|
|
383
401
|
generations: tuple[GenerationRecord, ...] = Field(default_factory=tuple)
|
|
384
402
|
rewind_history: tuple[RewindRecord, ...] = Field(default_factory=tuple)
|
|
403
|
+
directive_emissions: tuple[ControlDirectiveEmission, ...] = Field(default_factory=tuple)
|
|
385
404
|
status: LineageStatus = LineageStatus.ACTIVE
|
|
386
405
|
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
|
387
406
|
|
|
@@ -410,6 +429,18 @@ class OntologyLineage(BaseModel, frozen=True):
|
|
|
410
429
|
"""Return new lineage with updated status."""
|
|
411
430
|
return self.model_copy(update={"status": status})
|
|
412
431
|
|
|
432
|
+
def with_directive_emission(self, emission: ControlDirectiveEmission) -> OntologyLineage:
|
|
433
|
+
"""Return new lineage with the directive emission appended.
|
|
434
|
+
|
|
435
|
+
Folds one ``control.directive.emitted`` event into the lineage's
|
|
436
|
+
timeline view. Existing emissions are preserved; ordering is
|
|
437
|
+
whatever the projector replayed (timestamp order from the
|
|
438
|
+
EventStore).
|
|
439
|
+
"""
|
|
440
|
+
return self.model_copy(
|
|
441
|
+
update={"directive_emissions": self.directive_emissions + (emission,)}
|
|
442
|
+
)
|
|
443
|
+
|
|
413
444
|
def rewind_to(self, generation_number: int) -> OntologyLineage:
|
|
414
445
|
"""Return lineage truncated to the given generation.
|
|
415
446
|
|
{ouroboros_ai-0.31.2.dev16 → ouroboros_ai-0.31.2.dev18}/src/ouroboros/evolution/projector.py
RENAMED
|
@@ -9,6 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
import logging
|
|
10
10
|
|
|
11
11
|
from ouroboros.core.lineage import (
|
|
12
|
+
ControlDirectiveEmission,
|
|
12
13
|
EvaluationSummary,
|
|
13
14
|
GenerationPhase,
|
|
14
15
|
GenerationRecord,
|
|
@@ -51,6 +52,7 @@ class LineageProjector:
|
|
|
51
52
|
lineage: OntologyLineage | None = None
|
|
52
53
|
generations: dict[int, GenerationRecord] = {}
|
|
53
54
|
rewind_history: list[RewindRecord] = []
|
|
55
|
+
directive_emissions: list[ControlDirectiveEmission] = []
|
|
54
56
|
|
|
55
57
|
for event in events:
|
|
56
58
|
if event.type == "lineage.created":
|
|
@@ -191,20 +193,59 @@ class LineageProjector:
|
|
|
191
193
|
discarded_generations=discarded,
|
|
192
194
|
)
|
|
193
195
|
)
|
|
194
|
-
# Remove generations after the rewind point
|
|
196
|
+
# Remove active generations after the rewind point. Directive
|
|
197
|
+
# emissions remain in the projected audit timeline so reports
|
|
198
|
+
# can still explain discarded branches preserved in
|
|
199
|
+
# rewind_history.
|
|
195
200
|
generations = {k: v for k, v in generations.items() if k <= to_gen}
|
|
196
201
|
if lineage is not None:
|
|
197
202
|
lineage = lineage.with_status(LineageStatus.ACTIVE)
|
|
198
203
|
|
|
204
|
+
elif event.type == "control.directive.emitted":
|
|
205
|
+
# Fold control-plane directives onto the lineage timeline
|
|
206
|
+
# alongside state events, per RFC #476 M2 / sub-RFC #511.
|
|
207
|
+
# The full event row remains in the EventStore; we project
|
|
208
|
+
# the audit-level summary so callers (TUI, reports) can
|
|
209
|
+
# render decisions without a second query.
|
|
210
|
+
data = event.data
|
|
211
|
+
directive_value = data.get("directive")
|
|
212
|
+
if not isinstance(directive_value, str) or not directive_value:
|
|
213
|
+
# Silently skip malformed directive events rather than
|
|
214
|
+
# corrupt the projection; the raw row is still queryable
|
|
215
|
+
# via event_store directly for postmortem.
|
|
216
|
+
continue
|
|
217
|
+
generation_number = data.get("generation_number")
|
|
218
|
+
if generation_number is not None and not isinstance(generation_number, int):
|
|
219
|
+
continue
|
|
220
|
+
phase = data.get("phase")
|
|
221
|
+
if phase is not None and not isinstance(phase, str):
|
|
222
|
+
continue
|
|
223
|
+
is_terminal = data.get("is_terminal", False)
|
|
224
|
+
if not isinstance(is_terminal, bool):
|
|
225
|
+
continue
|
|
226
|
+
directive_emissions.append(
|
|
227
|
+
ControlDirectiveEmission(
|
|
228
|
+
directive=directive_value,
|
|
229
|
+
reason=str(data.get("reason", "")),
|
|
230
|
+
emitted_by=str(data.get("emitted_by", "")),
|
|
231
|
+
timestamp=event.timestamp,
|
|
232
|
+
generation_number=generation_number,
|
|
233
|
+
phase=phase,
|
|
234
|
+
is_terminal=is_terminal,
|
|
235
|
+
)
|
|
236
|
+
)
|
|
237
|
+
|
|
199
238
|
if lineage is None:
|
|
200
239
|
return None
|
|
201
240
|
|
|
202
|
-
# Build final lineage with sorted generations
|
|
241
|
+
# Build final lineage with sorted generations, rewind history, and
|
|
242
|
+
# any control-plane directive emissions that were folded in.
|
|
203
243
|
sorted_records = tuple(generations[k] for k in sorted(generations.keys()))
|
|
204
244
|
return lineage.model_copy(
|
|
205
245
|
update={
|
|
206
246
|
"generations": sorted_records,
|
|
207
247
|
"rewind_history": tuple(rewind_history),
|
|
248
|
+
"directive_emissions": tuple(directive_emissions),
|
|
208
249
|
}
|
|
209
250
|
)
|
|
210
251
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
def test_rewind_to_retains_directives_for_discarded_generation_audit() -> None:
|
|
2
|
+
from datetime import UTC, datetime
|
|
3
|
+
|
|
4
|
+
from ouroboros.core.lineage import ControlDirectiveEmission, GenerationRecord, OntologyLineage
|
|
5
|
+
from ouroboros.core.seed import OntologyField, OntologySchema
|
|
6
|
+
|
|
7
|
+
ontology = OntologySchema(
|
|
8
|
+
name="Test",
|
|
9
|
+
description="test",
|
|
10
|
+
fields=(OntologyField(name="x", field_type="string", description="x"),),
|
|
11
|
+
)
|
|
12
|
+
lineage = OntologyLineage(
|
|
13
|
+
lineage_id="lin_rewind_directives",
|
|
14
|
+
goal="test",
|
|
15
|
+
generations=(
|
|
16
|
+
GenerationRecord(generation_number=1, seed_id="s1", ontology_snapshot=ontology),
|
|
17
|
+
GenerationRecord(generation_number=2, seed_id="s2", ontology_snapshot=ontology),
|
|
18
|
+
),
|
|
19
|
+
directive_emissions=(
|
|
20
|
+
ControlDirectiveEmission(
|
|
21
|
+
directive="evolve",
|
|
22
|
+
reason="gen1",
|
|
23
|
+
emitted_by="test",
|
|
24
|
+
timestamp=datetime.now(UTC),
|
|
25
|
+
generation_number=1,
|
|
26
|
+
),
|
|
27
|
+
ControlDirectiveEmission(
|
|
28
|
+
directive="retry",
|
|
29
|
+
reason="gen2",
|
|
30
|
+
emitted_by="test",
|
|
31
|
+
timestamp=datetime.now(UTC),
|
|
32
|
+
generation_number=2,
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
rewound = lineage.rewind_to(1)
|
|
38
|
+
|
|
39
|
+
assert [e.directive for e in rewound.directive_emissions] == ["evolve", "retry"]
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""Unit tests for LineageProjector folding control.directive.emitted events.
|
|
2
|
+
|
|
3
|
+
Covers (issue #514, closes #473):
|
|
4
|
+
- A `control.directive.emitted` event with `aggregate_type="lineage"` is
|
|
5
|
+
folded onto the projected `OntologyLineage.directive_emissions` view.
|
|
6
|
+
- Multiple directives appear in event-order on the projection.
|
|
7
|
+
- Optional correlation fields (generation_number, phase, is_terminal) are
|
|
8
|
+
preserved when present and tolerate absence.
|
|
9
|
+
- Malformed directive events (missing/empty `directive` payload) are
|
|
10
|
+
skipped silently rather than corrupting the projection.
|
|
11
|
+
- Existing lineage state (generations, status) projects unchanged when
|
|
12
|
+
directive events are interleaved.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from datetime import UTC, datetime
|
|
16
|
+
|
|
17
|
+
from ouroboros.core.lineage import LineageStatus
|
|
18
|
+
from ouroboros.events.base import BaseEvent
|
|
19
|
+
from ouroboros.evolution.projector import LineageProjector
|
|
20
|
+
|
|
21
|
+
LINEAGE_ID = "lin_directive_projector_test"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _event(
|
|
25
|
+
event_type: str,
|
|
26
|
+
data: dict | None = None,
|
|
27
|
+
*,
|
|
28
|
+
timestamp: datetime | None = None,
|
|
29
|
+
) -> BaseEvent:
|
|
30
|
+
"""Build a `BaseEvent` aggregated by the lineage under test."""
|
|
31
|
+
payload: dict = data or {}
|
|
32
|
+
return BaseEvent(
|
|
33
|
+
type=event_type,
|
|
34
|
+
aggregate_type="lineage",
|
|
35
|
+
aggregate_id=LINEAGE_ID,
|
|
36
|
+
data=payload,
|
|
37
|
+
timestamp=timestamp or datetime.now(UTC),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TestDirectiveProjection:
|
|
42
|
+
def test_directive_appears_on_projected_lineage(self) -> None:
|
|
43
|
+
"""A control.directive.emitted event is folded onto directive_emissions."""
|
|
44
|
+
projector = LineageProjector()
|
|
45
|
+
events = [
|
|
46
|
+
_event("lineage.created", {"goal": "intent under test"}),
|
|
47
|
+
_event(
|
|
48
|
+
"control.directive.emitted",
|
|
49
|
+
{
|
|
50
|
+
"directive": "evolve",
|
|
51
|
+
"reason": "Advance generation.",
|
|
52
|
+
"emitted_by": "evolver",
|
|
53
|
+
"lineage_id": LINEAGE_ID,
|
|
54
|
+
"generation_number": 1,
|
|
55
|
+
"phase": "reflecting",
|
|
56
|
+
"is_terminal": False,
|
|
57
|
+
},
|
|
58
|
+
),
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
lineage = projector.project(events)
|
|
62
|
+
|
|
63
|
+
assert lineage is not None
|
|
64
|
+
assert len(lineage.directive_emissions) == 1
|
|
65
|
+
emission = lineage.directive_emissions[0]
|
|
66
|
+
assert emission.directive == "evolve"
|
|
67
|
+
assert emission.reason == "Advance generation."
|
|
68
|
+
assert emission.emitted_by == "evolver"
|
|
69
|
+
assert emission.generation_number == 1
|
|
70
|
+
assert emission.phase == "reflecting"
|
|
71
|
+
assert emission.is_terminal is False
|
|
72
|
+
|
|
73
|
+
def test_directives_preserve_event_order(self) -> None:
|
|
74
|
+
"""Multiple directives arrive on the projection in event-replay order."""
|
|
75
|
+
projector = LineageProjector()
|
|
76
|
+
events = [
|
|
77
|
+
_event("lineage.created", {"goal": "ordered emissions"}),
|
|
78
|
+
_event(
|
|
79
|
+
"control.directive.emitted",
|
|
80
|
+
{
|
|
81
|
+
"directive": "evolve",
|
|
82
|
+
"reason": "First emission.",
|
|
83
|
+
"emitted_by": "evolver",
|
|
84
|
+
},
|
|
85
|
+
),
|
|
86
|
+
_event(
|
|
87
|
+
"control.directive.emitted",
|
|
88
|
+
{
|
|
89
|
+
"directive": "retry",
|
|
90
|
+
"reason": "Second emission.",
|
|
91
|
+
"emitted_by": "evolver",
|
|
92
|
+
"is_terminal": False,
|
|
93
|
+
},
|
|
94
|
+
),
|
|
95
|
+
_event(
|
|
96
|
+
"control.directive.emitted",
|
|
97
|
+
{
|
|
98
|
+
"directive": "converge",
|
|
99
|
+
"reason": "Third emission.",
|
|
100
|
+
"emitted_by": "evolver",
|
|
101
|
+
"is_terminal": True,
|
|
102
|
+
},
|
|
103
|
+
),
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
lineage = projector.project(events)
|
|
107
|
+
|
|
108
|
+
assert lineage is not None
|
|
109
|
+
emitted = [e.directive for e in lineage.directive_emissions]
|
|
110
|
+
assert emitted == ["evolve", "retry", "converge"]
|
|
111
|
+
assert lineage.directive_emissions[-1].is_terminal is True
|
|
112
|
+
|
|
113
|
+
def test_optional_correlation_fields_default_to_none(self) -> None:
|
|
114
|
+
"""generation_number and phase are None when absent from the payload."""
|
|
115
|
+
projector = LineageProjector()
|
|
116
|
+
events = [
|
|
117
|
+
_event("lineage.created", {"goal": "no correlations"}),
|
|
118
|
+
_event(
|
|
119
|
+
"control.directive.emitted",
|
|
120
|
+
{
|
|
121
|
+
"directive": "wait",
|
|
122
|
+
"reason": "External input pending.",
|
|
123
|
+
"emitted_by": "orchestrator",
|
|
124
|
+
},
|
|
125
|
+
),
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
lineage = projector.project(events)
|
|
129
|
+
|
|
130
|
+
assert lineage is not None
|
|
131
|
+
emission = lineage.directive_emissions[0]
|
|
132
|
+
assert emission.generation_number is None
|
|
133
|
+
assert emission.phase is None
|
|
134
|
+
|
|
135
|
+
def test_malformed_directive_event_is_skipped(self) -> None:
|
|
136
|
+
"""A directive event without a usable directive payload is silently skipped."""
|
|
137
|
+
projector = LineageProjector()
|
|
138
|
+
events = [
|
|
139
|
+
_event("lineage.created", {"goal": "malformed input"}),
|
|
140
|
+
_event(
|
|
141
|
+
"control.directive.emitted",
|
|
142
|
+
{
|
|
143
|
+
# 'directive' missing on purpose
|
|
144
|
+
"reason": "Bad event row.",
|
|
145
|
+
"emitted_by": "evolver",
|
|
146
|
+
},
|
|
147
|
+
),
|
|
148
|
+
_event(
|
|
149
|
+
"control.directive.emitted",
|
|
150
|
+
{
|
|
151
|
+
"directive": "", # empty string also rejected
|
|
152
|
+
"reason": "Empty directive value.",
|
|
153
|
+
"emitted_by": "evolver",
|
|
154
|
+
},
|
|
155
|
+
),
|
|
156
|
+
_event(
|
|
157
|
+
"control.directive.emitted",
|
|
158
|
+
{
|
|
159
|
+
"directive": "continue",
|
|
160
|
+
"reason": "Healthy event row.",
|
|
161
|
+
"emitted_by": "evolver",
|
|
162
|
+
},
|
|
163
|
+
),
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
lineage = projector.project(events)
|
|
167
|
+
|
|
168
|
+
assert lineage is not None
|
|
169
|
+
# Only the healthy row survives; malformed rows are absorbed silently.
|
|
170
|
+
assert [e.directive for e in lineage.directive_emissions] == ["continue"]
|
|
171
|
+
|
|
172
|
+
def test_directives_do_not_corrupt_existing_lineage_state(self) -> None:
|
|
173
|
+
"""Lineage state events project unchanged when interleaved with directives."""
|
|
174
|
+
projector = LineageProjector()
|
|
175
|
+
events = [
|
|
176
|
+
_event("lineage.created", {"goal": "interleaved replay"}),
|
|
177
|
+
_event(
|
|
178
|
+
"control.directive.emitted",
|
|
179
|
+
{
|
|
180
|
+
"directive": "evolve",
|
|
181
|
+
"reason": "Pre-converge directive.",
|
|
182
|
+
"emitted_by": "evolver",
|
|
183
|
+
},
|
|
184
|
+
),
|
|
185
|
+
_event(
|
|
186
|
+
"lineage.converged",
|
|
187
|
+
{
|
|
188
|
+
"generation_number": 1,
|
|
189
|
+
"reason": "All ACs passed.",
|
|
190
|
+
"ontology_similarity": 1.0,
|
|
191
|
+
},
|
|
192
|
+
),
|
|
193
|
+
_event(
|
|
194
|
+
"control.directive.emitted",
|
|
195
|
+
{
|
|
196
|
+
"directive": "converge",
|
|
197
|
+
"reason": "Post-converge directive.",
|
|
198
|
+
"emitted_by": "evolver",
|
|
199
|
+
"is_terminal": True,
|
|
200
|
+
},
|
|
201
|
+
),
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
lineage = projector.project(events)
|
|
205
|
+
|
|
206
|
+
assert lineage is not None
|
|
207
|
+
assert lineage.status == LineageStatus.CONVERGED
|
|
208
|
+
assert len(lineage.directive_emissions) == 2
|
|
209
|
+
assert lineage.directive_emissions[-1].directive == "converge"
|
|
210
|
+
|
|
211
|
+
def test_rewind_retains_directives_for_discarded_generation_audit(self) -> None:
|
|
212
|
+
"""Directive audit timeline still explains discarded rewind branches."""
|
|
213
|
+
projector = LineageProjector()
|
|
214
|
+
events = [
|
|
215
|
+
_event("lineage.created", {"goal": "rewind directive pruning"}),
|
|
216
|
+
_event(
|
|
217
|
+
"control.directive.emitted",
|
|
218
|
+
{
|
|
219
|
+
"directive": "evolve",
|
|
220
|
+
"reason": "Gen 1 decision.",
|
|
221
|
+
"emitted_by": "evolver",
|
|
222
|
+
"generation_number": 1,
|
|
223
|
+
},
|
|
224
|
+
),
|
|
225
|
+
_event(
|
|
226
|
+
"control.directive.emitted",
|
|
227
|
+
{
|
|
228
|
+
"directive": "retry",
|
|
229
|
+
"reason": "Discarded Gen 2 decision.",
|
|
230
|
+
"emitted_by": "evolver",
|
|
231
|
+
"generation_number": 2,
|
|
232
|
+
},
|
|
233
|
+
),
|
|
234
|
+
_event(
|
|
235
|
+
"control.directive.emitted",
|
|
236
|
+
{
|
|
237
|
+
"directive": "wait",
|
|
238
|
+
"reason": "Unscoped audit note.",
|
|
239
|
+
"emitted_by": "orchestrator",
|
|
240
|
+
},
|
|
241
|
+
),
|
|
242
|
+
_event("lineage.rewound", {"from_generation": 2, "to_generation": 1}),
|
|
243
|
+
]
|
|
244
|
+
|
|
245
|
+
lineage = projector.project(events)
|
|
246
|
+
|
|
247
|
+
assert lineage is not None
|
|
248
|
+
assert [e.directive for e in lineage.directive_emissions] == ["evolve", "retry", "wait"]
|
|
249
|
+
|
|
250
|
+
def test_invalid_directive_correlation_shape_is_skipped(self) -> None:
|
|
251
|
+
"""Malformed optional fields should not abort lineage projection."""
|
|
252
|
+
projector = LineageProjector()
|
|
253
|
+
events = [
|
|
254
|
+
_event("lineage.created", {"goal": "invalid directive shape"}),
|
|
255
|
+
_event(
|
|
256
|
+
"control.directive.emitted",
|
|
257
|
+
{
|
|
258
|
+
"directive": "retry",
|
|
259
|
+
"reason": "Bad generation number.",
|
|
260
|
+
"emitted_by": "evolver",
|
|
261
|
+
"generation_number": "two",
|
|
262
|
+
},
|
|
263
|
+
),
|
|
264
|
+
_event(
|
|
265
|
+
"control.directive.emitted",
|
|
266
|
+
{
|
|
267
|
+
"directive": "continue",
|
|
268
|
+
"reason": "Healthy row.",
|
|
269
|
+
"emitted_by": "evolver",
|
|
270
|
+
"generation_number": 1,
|
|
271
|
+
},
|
|
272
|
+
),
|
|
273
|
+
]
|
|
274
|
+
|
|
275
|
+
lineage = projector.project(events)
|
|
276
|
+
|
|
277
|
+
assert lineage is not None
|
|
278
|
+
assert [e.directive for e in lineage.directive_emissions] == ["continue"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|