specsmith 0.17.1.dev661__tar.gz → 0.17.1.dev664__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.
- {specsmith-0.17.1.dev661/src/specsmith.egg-info → specsmith-0.17.1.dev664}/PKG-INFO +1 -1
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/pyproject.toml +1 -1
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/context_seed.py +131 -33
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/context_orchestrator.py +51 -10
- specsmith-0.17.1.dev664/src/specsmith/esdb_writer.py +226 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governance_logic.py +19 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/__init__.py +2 -0
- specsmith-0.17.1.dev664/src/specsmith/migrations/m008_esdb_full_coverage.py +225 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/governance.py +33 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/wi_store.py +16 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664/src/specsmith.egg-info}/PKG-INFO +1 -1
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/SOURCES.txt +5 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_e2e_nexus.py +110 -0
- specsmith-0.17.1.dev664/tests/test_esdb_integration.py +413 -0
- specsmith-0.17.1.dev664/tests/test_esdb_writer.py +463 -0
- specsmith-0.17.1.dev664/tests/test_repl.py +250 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/LICENSE +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/README.md +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/setup.cfg +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/belief.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/certainty.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/failure_graph.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/py.typed +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/recovery.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/session.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/stress_tester.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/trace.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/__main__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/broker.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/chat_runner.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/cleanup.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/core.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/_status.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/dag.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/events.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/result.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/endpoints.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/events.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/execution_profiles.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/fallback.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/hf_leaderboard.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/hf_sync.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/indexer.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/llm_client.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/mcp.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/memory.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/model_intelligence.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/model_profiles.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/model_router.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/orchestrator.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/permissions.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/profiles.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/provider_registry.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/repl.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/router.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/rules.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/runner.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/safety.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/spawner.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/suggester.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/teams.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/tools.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/verifier.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/voice.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/approvals.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/architect.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/auditor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/auth.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/block_export.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/channel.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/ci_manager.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/cli.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/intelligence.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/issues_policy.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/reporting.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/_compat.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/checker.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/evidence.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/regulations.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/reporter.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compressor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/config.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/console_utils.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/context_window.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/credit_analyzer.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/credits.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/dashboard.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/base.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/citations.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/fpd.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/odp.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/patentsview.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/pfw.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/ppubs.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/ptab.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/differ.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/doctor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/drive.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/editor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/belief.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/certainty.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/failure_graph.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/recovery.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/stress_tester.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/_license.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/bridge.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/sqlite_store.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/eval/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/eval/builtins.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/eval/runner.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/executor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/exporter.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governance_store.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governance_yaml.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governed_pr.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/app.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/main_window.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/session_tab.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/theme.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/chat_view.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/input_bar.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/provider_bar.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/token_meter.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/tool_panel.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/update_checker.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/worker.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/history_search.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/importer.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/instinct.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/agent_skill.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/aider.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/base.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/claude_code.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/codity.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/copilot.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/cursor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/gemini.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/windsurf.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/issue_reporter.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/languages.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/ledger.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/local_model.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/mcp_generator.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/mcp_server.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m002_agents_slim.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m003_compliance_init.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m006_session_governance.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m007_yaml_first.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/runner.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/ollama_cmds.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/patent.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/paths.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/phase.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/plugins.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/policy.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/profiles.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/project_metrics.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/quality_report.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/rate_limits.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/recover.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/releaser.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/requirements.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/requirements_parser.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/retrieval.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/risk.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/safe_write.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/scaffolder.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/serve.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/session.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/session_init.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/session_store.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/ai_agents.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/cloud.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/corporate.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/cross_platform.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/data_engineering.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/devops.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/docs.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/embedded.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/hardware.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/mobile.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/platform_engineering.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/productivity.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/software_engineering.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/specsmith_skills.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/ssh.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/web_backend.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills_builder.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/sync.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/agents.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/contributing.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/license-MIT.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/security.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/editorconfig.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/gitattributes.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/gitignore.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/go/go.mod.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/go/main.go.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/roles.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/rules.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/verification.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/js/package.json.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/ledger.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/python/cli.py.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/python/init.py.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/readme.md.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/rust/main.rs.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/tool_installer.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/toolrules.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/tools.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/trace.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/transcripts.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/updater.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/upgrader.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/validator.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/__init__.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/base.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/bitbucket.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/github.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/gitlab.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs_commands.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/wireframes.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/workspace.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/dependency_links.txt +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/entry_points.txt +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/requires.txt +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/top_level.txt +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_CMD_001.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_agent_profiles.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_agent_run_feedback.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_agent_runner_ready.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_ai_client.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_ai_intelligence.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_architect_interview.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_architect_v2.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_architecture.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_auditor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_channel.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_chat_diff_decision.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_chat_runner_openai_compat.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_chat_stdin_protocol.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cleanup_cmd.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cli.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cli_regressions.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cli_workflows_history_drive.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_compliance.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_compliance_governance.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_compressor.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_dispatch.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_endpoints_cli.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_endpoints_store.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_epistemic.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_backend_switch.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_enforcement.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_license.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_sqlite.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_verify_chain_cli.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_fallback_chain.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_golden_path.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_importer.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_init_modes.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_integrations.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_integrations_codity.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_intelligence.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_issue_policy_features.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_issue_reporter.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_issues_263_264.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_local_model.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_markdown_deprecation.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_mcp_client.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_mcp_server.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_migration_direction.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_model_router.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_new_modules.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_nexus.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_permissions.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_phase1_4_new.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_phase34_completion.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_project_metrics.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_quality_report.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_rate_limits.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_reporting_commands.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_req_248_262.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_req_358_359.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_scaffolder.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_schema_migrations.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_skill_marketplace.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_skills_mcp.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_smoke.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_suggester.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_tools.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_typing_guardrails.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_validator.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_vcs.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_warp_parity.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_warp_parity_followup.py +0 -0
- {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_wi_lifecycle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specsmith
|
|
3
|
-
Version: 0.17.1.
|
|
3
|
+
Version: 0.17.1.dev664
|
|
4
4
|
Summary: AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider.
|
|
5
5
|
Author: Layer1Labs Silicon, Inc.
|
|
6
6
|
License-Expression: MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specsmith"
|
|
7
|
-
version = "0.17.1.
|
|
7
|
+
version = "0.17.1.dev664"
|
|
8
8
|
description = "AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -27,14 +27,17 @@ left off (extended to cover full epistemic continuity).
|
|
|
27
27
|
from __future__ import annotations
|
|
28
28
|
|
|
29
29
|
import json
|
|
30
|
+
from collections.abc import Sequence
|
|
30
31
|
from pathlib import Path
|
|
31
32
|
from typing import Any
|
|
32
33
|
|
|
33
|
-
# Maximum total characters injected as seed context.
|
|
34
|
-
#
|
|
35
|
-
_SEED_CHAR_BUDGET =
|
|
34
|
+
# Maximum total characters injected as seed context. Raised from 8 000 to
|
|
35
|
+
# 12 000 to accommodate the richer per-kind ESDB query output (REQ-399).
|
|
36
|
+
_SEED_CHAR_BUDGET = 12_000
|
|
36
37
|
_MAX_LEDGER_LINES = 30
|
|
37
|
-
|
|
38
|
+
_MAX_PREFLIGHT_RECORDS = 10 # preflight_decision records (conf≥0.6)
|
|
39
|
+
_MAX_VERIFY_RECORDS = 5 # verify_result records (conf≥0.6)
|
|
40
|
+
_MAX_WI_RECORDS = 5 # work_item records (active status only)
|
|
38
41
|
|
|
39
42
|
|
|
40
43
|
def build_context_seed(
|
|
@@ -42,7 +45,9 @@ def build_context_seed(
|
|
|
42
45
|
*,
|
|
43
46
|
char_budget: int = _SEED_CHAR_BUDGET,
|
|
44
47
|
max_ledger: int = _MAX_LEDGER_LINES,
|
|
45
|
-
|
|
48
|
+
max_preflight: int = _MAX_PREFLIGHT_RECORDS,
|
|
49
|
+
max_verify: int = _MAX_VERIFY_RECORDS,
|
|
50
|
+
max_wi: int = _MAX_WI_RECORDS,
|
|
46
51
|
) -> list[dict[str, Any]]:
|
|
47
52
|
"""Return a list of history turns to prepend to a new agent session.
|
|
48
53
|
|
|
@@ -50,11 +55,20 @@ def build_context_seed(
|
|
|
50
55
|
state or missing optional dependency can never prevent the agent from
|
|
51
56
|
starting.
|
|
52
57
|
|
|
58
|
+
The ESDB query is now **relevance-based** (REQ-399): records are fetched by
|
|
59
|
+
kind (preflight_decision, verify_result, work_item) rather than returning
|
|
60
|
+
the last N records by insertion order. Only active records with
|
|
61
|
+
confidence ≥ 0.6 are included. This ensures epistemically low-quality
|
|
62
|
+
records (failed approaches, stale decisions, low-confidence hypotheses) are
|
|
63
|
+
excluded from the context window.
|
|
64
|
+
|
|
53
65
|
Args:
|
|
54
66
|
project_dir: Project root containing ``.specsmith/``.
|
|
55
67
|
char_budget: Maximum total characters across all seed turns.
|
|
56
68
|
max_ledger: Maximum LEDGER.md lines to include.
|
|
57
|
-
|
|
69
|
+
max_preflight: Max preflight_decision records to include.
|
|
70
|
+
max_verify: Max verify_result records to include.
|
|
71
|
+
max_wi: Max active work_item records to include.
|
|
58
72
|
|
|
59
73
|
Returns:
|
|
60
74
|
List of ``{role: str, content: str}`` dicts, oldest first.
|
|
@@ -72,7 +86,7 @@ def build_context_seed(
|
|
|
72
86
|
turns.append({"role": "system", "content": content})
|
|
73
87
|
used += len(content)
|
|
74
88
|
|
|
75
|
-
# ── 2. Prior conversation history
|
|
89
|
+
# ── 2. Prior conversation history ────────────────────────────
|
|
76
90
|
hist_turns = _load_conversation_history(root, budget=char_budget - used)
|
|
77
91
|
for t in hist_turns:
|
|
78
92
|
c = json.dumps(t, ensure_ascii=False)
|
|
@@ -81,7 +95,7 @@ def build_context_seed(
|
|
|
81
95
|
turns.append(t)
|
|
82
96
|
used += len(c)
|
|
83
97
|
|
|
84
|
-
# ── 3. Recent LEDGER entries
|
|
98
|
+
# ── 3. Recent LEDGER entries ─────────────────────────────────
|
|
85
99
|
ledger_block = _load_ledger_snippet(root, max_lines=max_ledger)
|
|
86
100
|
if ledger_block and used + len(ledger_block) <= char_budget:
|
|
87
101
|
turns.append(
|
|
@@ -92,13 +106,21 @@ def build_context_seed(
|
|
|
92
106
|
)
|
|
93
107
|
used += len(ledger_block)
|
|
94
108
|
|
|
95
|
-
# ── 4.
|
|
96
|
-
esdb_block =
|
|
109
|
+
# ── 4. ESDB records — relevance-based by kind (REQ-399) ──────────────
|
|
110
|
+
esdb_block = _load_esdb_by_kind(
|
|
111
|
+
root,
|
|
112
|
+
max_preflight=max_preflight,
|
|
113
|
+
max_verify=max_verify,
|
|
114
|
+
max_wi=max_wi,
|
|
115
|
+
)
|
|
97
116
|
if esdb_block and used + len(esdb_block) <= char_budget:
|
|
98
117
|
turns.append(
|
|
99
118
|
{
|
|
100
119
|
"role": "system",
|
|
101
|
-
"content":
|
|
120
|
+
"content": (
|
|
121
|
+
"[ESDB governance context — active preflight"
|
|
122
|
+
f" decisions, verify results, work items]\n{esdb_block}"
|
|
123
|
+
),
|
|
102
124
|
}
|
|
103
125
|
)
|
|
104
126
|
|
|
@@ -185,31 +207,107 @@ def _load_ledger_snippet(root: Path, *, max_lines: int) -> str:
|
|
|
185
207
|
return ""
|
|
186
208
|
|
|
187
209
|
|
|
188
|
-
def
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
210
|
+
def _load_esdb_by_kind(
|
|
211
|
+
root: Path,
|
|
212
|
+
*,
|
|
213
|
+
max_preflight: int = 10,
|
|
214
|
+
max_verify: int = 5,
|
|
215
|
+
max_wi: int = 5,
|
|
216
|
+
) -> str:
|
|
217
|
+
"""Return a compact, epistemically-filtered ESDB context block (REQ-399).
|
|
218
|
+
|
|
219
|
+
Queries three specific kinds rather than "last N records by insertion
|
|
220
|
+
order" so the context seed is relevant regardless of store size:
|
|
221
|
+
|
|
222
|
+
1. ``preflight_decision`` (active, conf≥0.6) — recent accepted preflights;
|
|
223
|
+
sorted highest-confidence first so the best-evidenced ones appear.
|
|
224
|
+
2. ``verify_result`` (active, conf≥0.6) — recent verify outcomes.
|
|
225
|
+
3. ``work_item`` (active, conf≥0.6) — open/in-progress WIs.
|
|
226
|
+
|
|
227
|
+
Falls back to ``query.what_is_known()`` for ChronoStore when the SqliteStore
|
|
228
|
+
does not have records of the requested kinds (e.g. before the first preflight).
|
|
229
|
+
|
|
230
|
+
Uses ``store.query(kind=..., rag_filter=True)`` which applies the
|
|
231
|
+
confidence≥0.6 filter, honouring H18 (RAG retrieval filtering).
|
|
232
|
+
Infrastructure kinds (edge, rollback_event, token_metric, skill_run) are
|
|
233
|
+
never returned by this function — ESDB spec rule 3 / critical rule §23.
|
|
194
234
|
"""
|
|
235
|
+
lines: list[str] = []
|
|
236
|
+
seen_ids: set[str] = set()
|
|
237
|
+
|
|
238
|
+
def _fmt(rec: object) -> str:
|
|
239
|
+
rid = getattr(rec, "id", "?")
|
|
240
|
+
kind = getattr(rec, "kind", "?")
|
|
241
|
+
label = getattr(rec, "label", "")
|
|
242
|
+
data = getattr(rec, "data", {}) or {}
|
|
243
|
+
conf = getattr(rec, "confidence", 0.0)
|
|
244
|
+
line = f"[{rid}] {kind} (conf={conf:.2f}): {label[:120]}"
|
|
245
|
+
detail = (
|
|
246
|
+
data.get("decision")
|
|
247
|
+
or data.get("equilibrium")
|
|
248
|
+
or data.get("status")
|
|
249
|
+
or data.get("summary")
|
|
250
|
+
)
|
|
251
|
+
if detail:
|
|
252
|
+
line += f" — {str(detail)[:80]}"
|
|
253
|
+
return line
|
|
254
|
+
|
|
255
|
+
def _add_records(records: Sequence[object], max_n: int) -> None:
|
|
256
|
+
added = 0
|
|
257
|
+
for rec in sorted(records, key=lambda r: -getattr(r, "confidence", 0)):
|
|
258
|
+
if added >= max_n:
|
|
259
|
+
break
|
|
260
|
+
rid = getattr(rec, "id", None)
|
|
261
|
+
if rid and rid not in seen_ids:
|
|
262
|
+
lines.append(_fmt(rec))
|
|
263
|
+
seen_ids.add(rid)
|
|
264
|
+
added += 1
|
|
265
|
+
|
|
266
|
+
# --- Try SqliteStore (always available, no external dep) -----------------
|
|
195
267
|
try:
|
|
196
|
-
from
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
268
|
+
from specsmith.esdb import SqliteStore
|
|
269
|
+
|
|
270
|
+
sqlite_path = root / ".specsmith" / "esdb.sqlite3"
|
|
271
|
+
if sqlite_path.exists():
|
|
272
|
+
with SqliteStore(root) as store:
|
|
273
|
+
_add_records(
|
|
274
|
+
store.query(kind="preflight_decision", rag_filter=True),
|
|
275
|
+
max_preflight,
|
|
276
|
+
)
|
|
277
|
+
_add_records(
|
|
278
|
+
store.query(kind="verify_result", rag_filter=True),
|
|
279
|
+
max_verify,
|
|
280
|
+
)
|
|
281
|
+
_add_records(
|
|
282
|
+
store.query(kind="work_item", status="active", rag_filter=True),
|
|
283
|
+
max_wi,
|
|
284
|
+
)
|
|
211
285
|
except Exception: # noqa: BLE001
|
|
212
|
-
|
|
286
|
+
pass
|
|
287
|
+
|
|
288
|
+
# --- Supplement / fall back via ChronoStore ------------------------------
|
|
289
|
+
# Only query ChronoStore when we got fewer records than requested so we
|
|
290
|
+
# don't duplicate records that are in both backends.
|
|
291
|
+
chrono_needed = max_preflight + max_verify + max_wi - len(seen_ids)
|
|
292
|
+
if chrono_needed > 0:
|
|
293
|
+
try:
|
|
294
|
+
from chronomemory import ChronoStore
|
|
295
|
+
from chronomemory import query as _cm_query
|
|
296
|
+
|
|
297
|
+
with ChronoStore(root) as store:
|
|
298
|
+
known = _cm_query.what_is_known(store) # active, conf>=0.6, no infra
|
|
299
|
+
# Group by kind and add missing records
|
|
300
|
+
for kind_key, max_n in (
|
|
301
|
+
("preflight_decision", max_preflight),
|
|
302
|
+
("verify_result", max_verify),
|
|
303
|
+
("work_item", max_wi),
|
|
304
|
+
):
|
|
305
|
+
kind_recs = [r for r in known if getattr(r, "kind", "") == kind_key]
|
|
306
|
+
_add_records(kind_recs, max_n)
|
|
307
|
+
except Exception: # noqa: BLE001
|
|
308
|
+
pass
|
|
309
|
+
|
|
310
|
+
return "\n".join(lines)
|
|
213
311
|
|
|
214
312
|
|
|
215
313
|
__all__ = ["build_context_seed"]
|
|
@@ -220,28 +220,69 @@ class ContextOrchestrator:
|
|
|
220
220
|
min_confidence: float = 0.5,
|
|
221
221
|
source_type_exclude: list[str] | None = None,
|
|
222
222
|
) -> int:
|
|
223
|
-
"""
|
|
223
|
+
"""Tombstone low-confidence records in the ESDB store (REQ-400).
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
Writes back to the store (tombstone via store.delete()) so the eviction
|
|
226
|
+
persists across sessions. Data is never physically removed — tombstone
|
|
227
|
+
only. Infrastructure records (edge, rollback_event, token_metric,
|
|
228
|
+
skill_run) and governance records (requirement, testcase) are exempt.
|
|
227
229
|
|
|
228
|
-
Returns the count of records
|
|
230
|
+
Returns the count of records actually tombstoned.
|
|
229
231
|
"""
|
|
232
|
+
_EXEMPT_KINDS = frozenset(
|
|
233
|
+
{
|
|
234
|
+
"requirement",
|
|
235
|
+
"testcase",
|
|
236
|
+
"edge",
|
|
237
|
+
"rollback_event",
|
|
238
|
+
"token_metric",
|
|
239
|
+
"skill_run",
|
|
240
|
+
}
|
|
241
|
+
)
|
|
230
242
|
|
|
243
|
+
# --- Try ChronoStore first (commercial backend) ----------------------
|
|
231
244
|
wal = self.root / ".chronomemory" / "events.wal"
|
|
232
|
-
if
|
|
233
|
-
|
|
245
|
+
if wal.exists():
|
|
246
|
+
try:
|
|
247
|
+
from chronomemory import ChronoStore
|
|
248
|
+
|
|
249
|
+
with ChronoStore(self.root) as store:
|
|
250
|
+
records = store.query()
|
|
251
|
+
count = 0
|
|
252
|
+
for rec in records:
|
|
253
|
+
if getattr(rec, "kind", "") in _EXEMPT_KINDS:
|
|
254
|
+
continue
|
|
255
|
+
evict = rec.confidence < min_confidence
|
|
256
|
+
if (
|
|
257
|
+
source_type_exclude
|
|
258
|
+
and getattr(rec, "source_type", "") in source_type_exclude
|
|
259
|
+
):
|
|
260
|
+
evict = True
|
|
261
|
+
if evict:
|
|
262
|
+
store.delete(rec.id) # tombstone — never physically removed
|
|
263
|
+
count += 1
|
|
264
|
+
return count
|
|
265
|
+
except Exception: # noqa: BLE001
|
|
266
|
+
pass # fall through to SqliteStore
|
|
267
|
+
|
|
268
|
+
# --- Fall back to SqliteStore (free default backend) -----------------
|
|
234
269
|
try:
|
|
235
|
-
from
|
|
270
|
+
from specsmith.esdb import SqliteStore
|
|
236
271
|
|
|
237
|
-
|
|
238
|
-
|
|
272
|
+
sqlite_path = self.root / ".specsmith" / "esdb.sqlite3"
|
|
273
|
+
if not sqlite_path.exists():
|
|
274
|
+
return 0
|
|
275
|
+
with SqliteStore(self.root) as store:
|
|
276
|
+
records = store.query(status="active")
|
|
239
277
|
count = 0
|
|
240
278
|
for rec in records:
|
|
279
|
+
if rec.kind in _EXEMPT_KINDS:
|
|
280
|
+
continue
|
|
241
281
|
evict = rec.confidence < min_confidence
|
|
242
|
-
if source_type_exclude and rec.
|
|
282
|
+
if source_type_exclude and rec.kind in source_type_exclude:
|
|
243
283
|
evict = True
|
|
244
284
|
if evict:
|
|
285
|
+
store.delete(rec.id) # tombstone
|
|
245
286
|
count += 1
|
|
246
287
|
return count
|
|
247
288
|
except Exception: # noqa: BLE001
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2026 Layer1Labs Silicon, Inc. All rights reserved.
|
|
3
|
+
"""specsmith.esdb_writer — centralised best-effort ESDB write paths (REQ-395..402).
|
|
4
|
+
|
|
5
|
+
This module provides the write paths that were previously missing from ESDB:
|
|
6
|
+
- Preflight decisions (kind="preflight_decision")
|
|
7
|
+
- Verify results (kind="verify_result")
|
|
8
|
+
- Work item records (kind="work_item")
|
|
9
|
+
|
|
10
|
+
All three functions are **best-effort** — they are wrapped in try/except so
|
|
11
|
+
they never block their callers when ESDB is unavailable or the store fails.
|
|
12
|
+
|
|
13
|
+
Backend-agnostic: uses ``open_default_store()`` which dispatches to either
|
|
14
|
+
the free SQLite backend or the commercial ChronoStore backend depending on
|
|
15
|
+
what is installed and licensed.
|
|
16
|
+
|
|
17
|
+
Record confidence mapping:
|
|
18
|
+
preflight_decision → payload["confidence_target"] (0.7–0.9 typical)
|
|
19
|
+
verify_result → 0.85 on equilibrium, 0.4 otherwise
|
|
20
|
+
work_item → wi.confidence_target; tombstone on terminal states
|
|
21
|
+
|
|
22
|
+
REQ-395: ESDBWriter utility module
|
|
23
|
+
REQ-396: Preflight decision ESDB write path
|
|
24
|
+
REQ-397: Verify result ESDB write path
|
|
25
|
+
REQ-398: Work item ESDB synchronisation
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import hashlib
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
from typing import TYPE_CHECKING, Any
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
pass # avoid circular imports at runtime
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
# Internal helpers
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _short_hash(text: str, length: int = 8) -> str:
|
|
44
|
+
"""Return first *length* hex chars of SHA-256 of *text*."""
|
|
45
|
+
return hashlib.sha256(text.encode("utf-8")).hexdigest()[:length].upper()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
# Public write functions — all best-effort (wrapped in try/except by callers)
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def write_preflight_record(
|
|
54
|
+
project_root: str | Path,
|
|
55
|
+
payload: dict[str, Any],
|
|
56
|
+
) -> bool:
|
|
57
|
+
"""Upsert a ``preflight_decision`` ESDB record from a preflight payload.
|
|
58
|
+
|
|
59
|
+
Called by ``run_preflight()`` after the work item is minted.
|
|
60
|
+
|
|
61
|
+
Record shape:
|
|
62
|
+
id = payload["work_item_id"] (e.g. "WI-3A9F1C02")
|
|
63
|
+
kind = "preflight_decision"
|
|
64
|
+
label = utterance extracted from payload
|
|
65
|
+
confidence = payload["confidence_target"]
|
|
66
|
+
source_ids = payload["requirement_ids"]
|
|
67
|
+
status = "active"
|
|
68
|
+
data = {decision, intent, work_item_id, test_case_ids, ...}
|
|
69
|
+
|
|
70
|
+
Returns True on success, False on any error (error is swallowed).
|
|
71
|
+
"""
|
|
72
|
+
try:
|
|
73
|
+
work_item_id = payload.get("work_item_id", "")
|
|
74
|
+
if not work_item_id:
|
|
75
|
+
return False # only persist accepted preflights that minted a WI
|
|
76
|
+
|
|
77
|
+
from specsmith.esdb import SqliteRecord, open_default_store
|
|
78
|
+
|
|
79
|
+
root = Path(project_root)
|
|
80
|
+
pf_id = f"PF-{work_item_id}"
|
|
81
|
+
record = SqliteRecord(
|
|
82
|
+
id=pf_id,
|
|
83
|
+
kind="preflight_decision",
|
|
84
|
+
status="active",
|
|
85
|
+
label=str(payload.get("instruction", payload.get("intent", "")))[:200],
|
|
86
|
+
confidence=float(payload.get("confidence_target", 0.7)),
|
|
87
|
+
data={
|
|
88
|
+
"decision": payload.get("decision", ""),
|
|
89
|
+
"intent": payload.get("intent", ""),
|
|
90
|
+
"work_item_id": work_item_id,
|
|
91
|
+
"test_case_ids": payload.get("test_case_ids", []),
|
|
92
|
+
"instruction": payload.get("instruction", ""),
|
|
93
|
+
"ai_disclosure": payload.get("ai_disclosure", {}),
|
|
94
|
+
},
|
|
95
|
+
source_ids=list(payload.get("requirement_ids", [])),
|
|
96
|
+
)
|
|
97
|
+
with open_default_store(root, warn=False) as store:
|
|
98
|
+
store.upsert(record)
|
|
99
|
+
return True
|
|
100
|
+
except Exception: # noqa: BLE001 — best-effort; never blocks preflight
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def write_verify_record(
|
|
105
|
+
project_root: str | Path,
|
|
106
|
+
result: dict[str, Any],
|
|
107
|
+
) -> bool:
|
|
108
|
+
"""Upsert a ``verify_result`` ESDB record from a verify payload.
|
|
109
|
+
|
|
110
|
+
Called by ``run_verify()`` after the work item is marked implemented.
|
|
111
|
+
|
|
112
|
+
Record shape:
|
|
113
|
+
id = "VERIFY-{work_item_id}"
|
|
114
|
+
kind = "verify_result"
|
|
115
|
+
label = brief summary string
|
|
116
|
+
confidence = 0.85 on equilibrium else 0.4
|
|
117
|
+
source_ids = [work_item_id] (links to preflight_decision record)
|
|
118
|
+
status = "active"
|
|
119
|
+
data = {equilibrium, retry_strategy, files_changed_count, ...}
|
|
120
|
+
|
|
121
|
+
When equilibrium is reached the corresponding ``preflight_decision``
|
|
122
|
+
record is tombstoned (status → "tombstone") to signal completion.
|
|
123
|
+
|
|
124
|
+
Returns True on success, False on any error.
|
|
125
|
+
"""
|
|
126
|
+
try:
|
|
127
|
+
work_item_id = result.get("work_item_id", "")
|
|
128
|
+
equilibrium = bool(result.get("equilibrium", False))
|
|
129
|
+
confidence = 0.85 if equilibrium else 0.4
|
|
130
|
+
|
|
131
|
+
from specsmith.esdb import SqliteRecord, open_default_store
|
|
132
|
+
|
|
133
|
+
root = Path(project_root)
|
|
134
|
+
verify_id = (
|
|
135
|
+
f"VERIFY-{work_item_id}" if work_item_id else f"VERIFY-{_short_hash(str(result))}"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
record = SqliteRecord(
|
|
139
|
+
id=verify_id,
|
|
140
|
+
kind="verify_result",
|
|
141
|
+
status="active",
|
|
142
|
+
label=str(result.get("summary", ""))[:200],
|
|
143
|
+
confidence=confidence,
|
|
144
|
+
data={
|
|
145
|
+
"equilibrium": equilibrium,
|
|
146
|
+
"confidence": result.get("confidence", confidence),
|
|
147
|
+
"retry_strategy": result.get("retry_strategy", ""),
|
|
148
|
+
"files_changed_count": len(result.get("files_changed", [])),
|
|
149
|
+
"work_item_id": work_item_id,
|
|
150
|
+
},
|
|
151
|
+
source_ids=[work_item_id] if work_item_id else [],
|
|
152
|
+
)
|
|
153
|
+
with open_default_store(root, warn=False) as store:
|
|
154
|
+
store.upsert(record)
|
|
155
|
+
# When equilibrium reached, tombstone the preflight_decision record
|
|
156
|
+
# so context seed knows this WI is complete.
|
|
157
|
+
if equilibrium and work_item_id:
|
|
158
|
+
pf_id = f"PF-{work_item_id}"
|
|
159
|
+
existing = store.get(pf_id)
|
|
160
|
+
if existing is not None and existing.kind == "preflight_decision":
|
|
161
|
+
store.delete(pf_id)
|
|
162
|
+
return True
|
|
163
|
+
except Exception: # noqa: BLE001 — best-effort
|
|
164
|
+
return False
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def write_work_item_record(
|
|
168
|
+
project_root: str | Path,
|
|
169
|
+
wi: Any, # WorkItem — avoid circular import; duck-typed
|
|
170
|
+
) -> bool:
|
|
171
|
+
"""Upsert a ``work_item`` ESDB record mirroring a WorkItem.
|
|
172
|
+
|
|
173
|
+
Called by WorkItemStore after create/set_status/mark_implemented/promote.
|
|
174
|
+
|
|
175
|
+
Record shape:
|
|
176
|
+
id = wi.id (e.g. "WI-3A9F1C02")
|
|
177
|
+
kind = "work_item"
|
|
178
|
+
label = wi.intent[:200]
|
|
179
|
+
confidence = wi.confidence_target
|
|
180
|
+
source_ids = wi.requirement_ids + wi.test_case_ids
|
|
181
|
+
status = "active" for open/implemented
|
|
182
|
+
"tombstone" for promoted/closed/archived/rejected
|
|
183
|
+
data = {status, kind, verified, promoted_to_req, blast_radius, ...}
|
|
184
|
+
|
|
185
|
+
Returns True on success, False on any error.
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
from specsmith.esdb import SqliteRecord, open_default_store
|
|
189
|
+
|
|
190
|
+
_TERMINAL = frozenset({"promoted", "closed", "archived", "rejected"})
|
|
191
|
+
esdb_status = "tombstone" if wi.status in _TERMINAL else "active"
|
|
192
|
+
|
|
193
|
+
source_ids = list(getattr(wi, "requirement_ids", []))
|
|
194
|
+
source_ids += list(getattr(wi, "test_case_ids", []))
|
|
195
|
+
|
|
196
|
+
record = SqliteRecord(
|
|
197
|
+
id=wi.id,
|
|
198
|
+
kind="work_item",
|
|
199
|
+
status=esdb_status,
|
|
200
|
+
label=str(wi.intent or wi.id)[:200],
|
|
201
|
+
confidence=float(getattr(wi, "confidence_target", 0.7)),
|
|
202
|
+
data={
|
|
203
|
+
"status": wi.status,
|
|
204
|
+
"kind": getattr(wi, "kind", "feature"),
|
|
205
|
+
"verified": getattr(wi, "verified", False),
|
|
206
|
+
"promoted_to_req": getattr(wi, "promoted_to_req", ""),
|
|
207
|
+
"blast_radius_estimate": getattr(wi, "blast_radius_estimate", ""),
|
|
208
|
+
"created_at": getattr(wi, "created_at", ""),
|
|
209
|
+
"updated_at": getattr(wi, "updated_at", ""),
|
|
210
|
+
"closed_reason": getattr(wi, "closed_reason", ""),
|
|
211
|
+
},
|
|
212
|
+
source_ids=source_ids,
|
|
213
|
+
)
|
|
214
|
+
root = Path(project_root)
|
|
215
|
+
with open_default_store(root, warn=False) as store:
|
|
216
|
+
store.upsert(record)
|
|
217
|
+
return True
|
|
218
|
+
except Exception: # noqa: BLE001 — best-effort
|
|
219
|
+
return False
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
__all__ = [
|
|
223
|
+
"write_preflight_record",
|
|
224
|
+
"write_verify_record",
|
|
225
|
+
"write_work_item_record",
|
|
226
|
+
]
|
|
@@ -271,6 +271,16 @@ def run_preflight(
|
|
|
271
271
|
except Exception: # noqa: BLE001
|
|
272
272
|
pass
|
|
273
273
|
|
|
274
|
+
# ESDB write — persist preflight decision for session resume and RAG (REQ-396).
|
|
275
|
+
# Best-effort: esdb_writer swallows all errors so ESDB is never on the
|
|
276
|
+
# critical path for preflight.
|
|
277
|
+
try:
|
|
278
|
+
from specsmith.esdb_writer import write_preflight_record
|
|
279
|
+
|
|
280
|
+
write_preflight_record(_root_str, payload)
|
|
281
|
+
except Exception: # noqa: BLE001
|
|
282
|
+
pass
|
|
283
|
+
|
|
274
284
|
return payload
|
|
275
285
|
|
|
276
286
|
|
|
@@ -370,6 +380,15 @@ def run_verify(
|
|
|
370
380
|
except Exception: # noqa: BLE001
|
|
371
381
|
pass
|
|
372
382
|
|
|
383
|
+
# ESDB write — persist verify result for session resume and audit (REQ-397).
|
|
384
|
+
# Also tombstones the preflight_decision record on equilibrium.
|
|
385
|
+
try:
|
|
386
|
+
from specsmith.esdb_writer import write_verify_record
|
|
387
|
+
|
|
388
|
+
write_verify_record(root, out)
|
|
389
|
+
except Exception: # noqa: BLE001
|
|
390
|
+
pass
|
|
391
|
+
|
|
373
392
|
return out
|
|
374
393
|
|
|
375
394
|
|
|
@@ -115,6 +115,7 @@ class _MigrationRegistry:
|
|
|
115
115
|
m005_agent_run_tool,
|
|
116
116
|
m006_session_governance,
|
|
117
117
|
m007_yaml_first,
|
|
118
|
+
m008_esdb_full_coverage,
|
|
118
119
|
)
|
|
119
120
|
|
|
120
121
|
instances: list[Migration] = [
|
|
@@ -125,6 +126,7 @@ class _MigrationRegistry:
|
|
|
125
126
|
m005_agent_run_tool.AgentRunToolMigration(),
|
|
126
127
|
m006_session_governance.SessionGovernanceMigration(),
|
|
127
128
|
m007_yaml_first.YamlFirstMigration(),
|
|
129
|
+
m008_esdb_full_coverage.EsdbFullCoverageMigration(),
|
|
128
130
|
]
|
|
129
131
|
instances.sort(key=lambda m: m.version)
|
|
130
132
|
self._migrations = instances
|