specsmith 0.17.1.dev684__tar.gz → 0.18.0.dev686__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.dev684/src/specsmith.egg-info → specsmith-0.18.0.dev686}/PKG-INFO +1 -1
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/pyproject.toml +1 -1
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/__init__.py +1 -1
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/runner.py +5 -4
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/auditor.py +8 -1
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/cli.py +142 -171
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compliance/evidence.py +11 -7
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compliance/regulations.py +2 -1
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/config.py +2 -2
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/context_orchestrator.py +27 -8
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/esdb_writer.py +184 -118
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/governance_logic.py +14 -7
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/phase.py +15 -24
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/project_metrics.py +6 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/retrieval.py +49 -5
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/session_store.py +7 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/sync.py +8 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/trace.py +89 -29
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/wi_store.py +10 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686/src/specsmith.egg-info}/PKG-INFO +1 -1
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith.egg-info/SOURCES.txt +5 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_cli.py +29 -3
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_compliance.py +24 -18
- specsmith-0.18.0.dev686/tests/test_deprecation_registry.py +90 -0
- specsmith-0.18.0.dev686/tests/test_esdb_status_integrity.py +130 -0
- specsmith-0.18.0.dev686/tests/test_esdb_status_output.py +89 -0
- specsmith-0.18.0.dev686/tests/test_sqlite_parity.py +124 -0
- specsmith-0.18.0.dev686/tests/test_trace_vault_esdb.py +87 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/LICENSE +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/README.md +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/setup.cfg +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/belief.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/certainty.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/failure_graph.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/py.typed +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/recovery.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/session.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/stress_tester.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/epistemic/trace.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/__main__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/broker.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/chat_runner.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/cleanup.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/context_seed.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/core.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/dispatch/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/dispatch/_status.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/dispatch/dag.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/dispatch/events.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/dispatch/result.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/endpoints.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/events.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/execution_profiles.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/fallback.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/hf_leaderboard.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/hf_sync.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/indexer.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/llm_client.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/mcp.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/memory.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/model_intelligence.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/model_profiles.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/model_router.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/orchestrator.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/permissions.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/profiles.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/provider_registry.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/repl.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/router.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/rules.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/safety.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/spawner.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/suggester.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/teams.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/token_pricing.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/tools.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/verifier.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/agent/voice.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/approvals.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/architect.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/auth.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/block_export.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/channel.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/ci_manager.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/commands/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/commands/intelligence.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/commands/issues_policy.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/commands/reporting.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compliance/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compliance/_compat.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compliance/checker.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compliance/reporter.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/compressor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/console_utils.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/context_window.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/credit_analyzer.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/credits.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/dashboard.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/base.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/citations.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/fpd.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/odp.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/patentsview.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/pfw.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/ppubs.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/datasources/ptab.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/differ.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/doctor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/drive.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/editor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/efficiency.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/epistemic/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/epistemic/belief.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/epistemic/certainty.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/epistemic/failure_graph.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/epistemic/recovery.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/epistemic/stress_tester.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/esdb/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/esdb/_license.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/esdb/bridge.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/esdb/sqlite_store.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/esdb_sweep.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/eval/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/eval/builtins.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/eval/runner.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/executor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/exporter.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/governance_store.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/governance_yaml.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/governed_pr.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/app.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/main_window.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/session_tab.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/theme.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/chat_view.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/input_bar.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/provider_bar.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/token_meter.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/tool_panel.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/widgets/update_checker.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/gui/worker.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/history_search.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/importer.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/instinct.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/agent_skill.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/aider.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/base.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/claude_code.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/codity.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/copilot.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/cursor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/gemini.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/integrations/windsurf.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/issue_reporter.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/languages.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/ledger.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/local_model.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/mcp_generator.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/mcp_server.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m002_agents_slim.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m003_compliance_init.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m006_session_governance.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m007_yaml_first.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m008_esdb_full_coverage.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m009_esdb_first.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/m010_post_esdb_cleanup.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/migrations/runner.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/ollama_cmds.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/patent.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/paths.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/plugins.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/policy.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/profiles.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/quality_report.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/rate_limits.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/recover.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/releaser.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/requirements.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/requirements_parser.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/risk.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/safe_write.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/scaffolder.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/serve.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/session.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/session_init.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/ai_agents.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/cloud.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/corporate.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/cross_platform.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/data_engineering.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/devops.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/docs.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/embedded.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/governance.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/hardware.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/mobile.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/platform_engineering.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/productivity.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/software_engineering.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/specsmith_skills.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/ssh.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills/web_backend.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/skills_builder.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/agents.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/contributing.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/license-MIT.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/community/security.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/editorconfig.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/gitattributes.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/gitignore.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/go/go.mod.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/go/main.go.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/roles.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/rules.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/governance/verification.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/js/package.json.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/ledger.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/python/cli.py.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/python/init.py.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/readme.md.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/rust/main.rs.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/tool_installer.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/toolrules.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/tools.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/transcripts.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/updater.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/upgrader.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/validator.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/vcs/__init__.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/vcs/base.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/vcs/bitbucket.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/vcs/github.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/vcs/gitlab.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/vcs_commands.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/wireframes.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith/workspace.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith.egg-info/dependency_links.txt +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith.egg-info/entry_points.txt +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith.egg-info/requires.txt +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/src/specsmith.egg-info/top_level.txt +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_CMD_001.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_agent_profiles.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_agent_run_feedback.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_agent_runner_ready.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_ai_client.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_ai_intelligence.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_architect_interview.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_architect_v2.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_architecture.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_auditor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_benchmark_harness.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_channel.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_chat_diff_decision.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_chat_runner_openai_compat.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_chat_stdin_protocol.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_cleanup_cmd.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_cli_regressions.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_cli_workflows_history_drive.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_compliance_governance.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_compressor.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_dispatch.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_dual_write.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_e2e_nexus.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_efficiency.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_endpoints_cli.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_endpoints_store.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_epistemic.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_backend_switch.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_enforcement.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_integration.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_license.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_sqlite.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_sweep.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_verify_chain_cli.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_esdb_writer.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_fallback_chain.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_golden_path.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_importer.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_init_modes.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_integrations.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_integrations_codity.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_intelligence.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_issue_policy_features.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_issue_reporter.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_issues_263_264.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_local_model.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_markdown_deprecation.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_mcp_client.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_mcp_server.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_migration_direction.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_model_router.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_new_modules.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_nexus.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_parallel_agents.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_permissions.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_phase1_4_new.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_phase34_completion.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_project_metrics.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_quality_report.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_rate_limits.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_repl.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_repl_extended.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_reporting_commands.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_req_248_262.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_req_358_359.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_resume_command.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_scaffolder.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_schema_migrations.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_skill_marketplace.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_skills_mcp.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_smoke.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_suggester.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_token_cost.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_tools.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_typing_guardrails.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_validator.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_vcs.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_warp_parity.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_warp_parity_followup.py +0 -0
- {specsmith-0.17.1.dev684 → specsmith-0.18.0.dev686}/tests/test_wi_lifecycle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specsmith
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0.dev686
|
|
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.
|
|
7
|
+
version = "0.18.0.dev686"
|
|
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"
|
|
@@ -8,4 +8,4 @@ from importlib.metadata import version as _pkg_version
|
|
|
8
8
|
try:
|
|
9
9
|
__version__: str = _pkg_version("specsmith")
|
|
10
10
|
except PackageNotFoundError: # running from source without install
|
|
11
|
-
__version__ = "0.
|
|
11
|
+
__version__ = "0.18.0" # fallback: keep in sync with pyproject.toml
|
|
@@ -798,10 +798,11 @@ class AgentRunner:
|
|
|
798
798
|
def _seal_profile_pin(self, profile_id: str) -> None:
|
|
799
799
|
"""Append a TraceVault decision seal recording the ``/agent`` pin (G4).
|
|
800
800
|
|
|
801
|
-
Wrapped in best-effort try/except so an unwriteable
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
a profile pin is an explicit governance
|
|
801
|
+
Wrapped in best-effort try/except so an unwriteable ESDB store
|
|
802
|
+
(read-only fs, missing project root, etc.) never breaks the chat loop.
|
|
803
|
+
The seal is persisted as an ESDB ``seal_record`` (REQ-420). The seal
|
|
804
|
+
type is ``decision`` because a profile pin is an explicit governance
|
|
805
|
+
choice the user made.
|
|
805
806
|
"""
|
|
806
807
|
try:
|
|
807
808
|
from specsmith.trace import SealType, TraceVault
|
|
@@ -930,7 +930,14 @@ def check_type_mismatch(root: Path) -> list[AuditResult]:
|
|
|
930
930
|
|
|
931
931
|
|
|
932
932
|
def check_trace_chain_integrity(root: Path) -> list[AuditResult]:
|
|
933
|
-
"""Check trace vault chain integrity if it exists.
|
|
933
|
+
"""Check trace vault chain integrity if it exists.
|
|
934
|
+
|
|
935
|
+
DEPRECATED(REQ-421): this verifies the legacy ``epistemic.trace`` flat-file
|
|
936
|
+
vault (``.specsmith/trace.jsonl``). The current trace vault is ESDB-only
|
|
937
|
+
(``specsmith.trace``; REQ-420). Retained so legacy projects that still carry
|
|
938
|
+
a trace.jsonl keep getting an integrity signal; remove at teardown.
|
|
939
|
+
See docs/DEPRECATIONS.md.
|
|
940
|
+
"""
|
|
934
941
|
trace_path = root / ".specsmith" / "trace.jsonl"
|
|
935
942
|
if not trace_path.exists():
|
|
936
943
|
return [] # No trace vault configured — skip silently
|
|
@@ -771,174 +771,81 @@ def preflight_cmd(
|
|
|
771
771
|
) -> None:
|
|
772
772
|
"""Classify a natural-language utterance under Specsmith governance (REQ-085).
|
|
773
773
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
774
|
+
REQ-418: this command delegates to ``governance_logic.run_preflight`` so the
|
|
775
|
+
CLI decision matches the in-process broker — explicit ``REQ-NNN`` references
|
|
776
|
+
and ``.specsmith/requirements.json`` are honored, the REQ-098 floor is applied
|
|
777
|
+
once, and the work item / ESDB ``preflight_decision`` record are persisted
|
|
778
|
+
(unless ``--predict-only``). The command then layers on presentation-only
|
|
779
|
+
extras (``predicted_refinement``, ``stress_warnings``, ``narration``) and the
|
|
780
|
+
REQ-093/099 LEDGER.md events, and exits 0/2/3 per the decision (REQ-092).
|
|
779
781
|
"""
|
|
780
782
|
import json as _json
|
|
781
|
-
import uuid
|
|
782
783
|
|
|
783
|
-
from specsmith.
|
|
784
|
-
Intent,
|
|
785
|
-
PreflightDecision,
|
|
786
|
-
classify_intent,
|
|
787
|
-
infer_scope,
|
|
788
|
-
narrate_plan,
|
|
789
|
-
)
|
|
784
|
+
from specsmith.governance_logic import run_preflight
|
|
790
785
|
|
|
791
786
|
root = Path(project_dir).resolve()
|
|
792
|
-
|
|
793
|
-
|
|
787
|
+
# REQ-418: delegate the decision to the authoritative broker so explicit
|
|
788
|
+
# REQ-NNN ids and .specsmith/requirements.json drive the result. run_preflight
|
|
789
|
+
# also applies the REQ-098 floor, allocates/persists the work item (unless
|
|
790
|
+
# predict_only), writes the ESDB preflight_decision record, and attaches the
|
|
791
|
+
# ai_disclosure + REG-004 escalation fields. Do NOT re-apply the floor here.
|
|
792
|
+
payload = run_preflight(
|
|
794
793
|
utterance,
|
|
795
|
-
root
|
|
796
|
-
|
|
794
|
+
str(root),
|
|
795
|
+
predict_only=predict_only,
|
|
796
|
+
escalate_threshold=escalate_threshold,
|
|
797
797
|
)
|
|
798
|
+
decision_str = str(payload.get("decision", ""))
|
|
799
|
+
work_item_id = str(payload.get("work_item_id", ""))
|
|
800
|
+
requirement_ids = list(payload.get("requirement_ids", []))
|
|
801
|
+
confidence_target = float(payload.get("confidence_target", 0.0))
|
|
798
802
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
# REQ-088: resolve test_case_ids from machine state by joining
|
|
802
|
-
# `requirement_ids` against `.specsmith/testcases.json` (or `TESTS.md`
|
|
803
|
-
# when the JSON is unavailable). Never invent ids.
|
|
804
|
-
test_case_ids: list[str] = []
|
|
805
|
-
if requirement_ids:
|
|
806
|
-
testcases_json = root / ".specsmith" / "testcases.json"
|
|
807
|
-
if testcases_json.is_file():
|
|
808
|
-
try:
|
|
809
|
-
records = _json.loads(testcases_json.read_text(encoding="utf-8"))
|
|
810
|
-
except (OSError, ValueError):
|
|
811
|
-
records = []
|
|
812
|
-
req_set = set(requirement_ids)
|
|
813
|
-
for record in records:
|
|
814
|
-
if (
|
|
815
|
-
isinstance(record, dict)
|
|
816
|
-
and record.get("requirement_id") in req_set
|
|
817
|
-
and isinstance(record.get("id"), str)
|
|
818
|
-
):
|
|
819
|
-
test_case_ids.append(record["id"])
|
|
820
|
-
else:
|
|
821
|
-
tests_md = root / "TESTS.md"
|
|
822
|
-
if tests_md.is_file():
|
|
823
|
-
import re as _re
|
|
824
|
-
|
|
825
|
-
text = tests_md.read_text(encoding="utf-8")
|
|
826
|
-
# Match each test block: a `TEST-NNN` id paired with a
|
|
827
|
-
# `REQ-NNN` requirement-id reference within the same block.
|
|
828
|
-
req_set = set(requirement_ids)
|
|
829
|
-
for block in _re.split(r"\n## ", text):
|
|
830
|
-
test_match = _re.search(r"\*\*ID:\*\*\s+(TEST-\d+)", block)
|
|
831
|
-
req_match = _re.search(r"\*\*Requirement ID:\*\*\s+(REQ-\d+)", block)
|
|
832
|
-
if test_match and req_match and req_match.group(1) in req_set:
|
|
833
|
-
test_case_ids.append(test_match.group(1))
|
|
834
|
-
|
|
835
|
-
# Heuristic decision policy. Specsmith governance owns the contract; the
|
|
836
|
-
# CLI implementation is intentionally simple and deterministic so the
|
|
837
|
-
# broker (and tests) can rely on it without an LLM.
|
|
838
|
-
decision_str = "accepted"
|
|
839
|
-
instruction = ""
|
|
840
|
-
confidence_target = 0.7
|
|
841
|
-
|
|
842
|
-
if intent == Intent.READ_ONLY_ASK:
|
|
843
|
-
decision_str = "accepted"
|
|
844
|
-
instruction = "Read-only ask; no governance changes required."
|
|
845
|
-
elif intent == Intent.DESTRUCTIVE:
|
|
846
|
-
decision_str = "needs_clarification"
|
|
847
|
-
instruction = (
|
|
848
|
-
"Destructive operation detected. "
|
|
849
|
-
"Confirm explicitly which paths or resources should be removed."
|
|
850
|
-
)
|
|
851
|
-
confidence_target = 0.9
|
|
852
|
-
elif intent == Intent.RELEASE:
|
|
853
|
-
decision_str = "needs_clarification"
|
|
854
|
-
instruction = (
|
|
855
|
-
"Release operations require explicit confirmation. "
|
|
856
|
-
"Specify the target version and channel."
|
|
857
|
-
)
|
|
858
|
-
confidence_target = 0.9
|
|
859
|
-
else: # CHANGE
|
|
860
|
-
if scope.is_known:
|
|
861
|
-
decision_str = "accepted"
|
|
862
|
-
instruction = (
|
|
863
|
-
"Change request matched existing governance scope. Proceed under "
|
|
864
|
-
"Specsmith verification."
|
|
865
|
-
)
|
|
866
|
-
confidence_target = max(0.7, scope.confidence)
|
|
867
|
-
else:
|
|
868
|
-
decision_str = "needs_clarification"
|
|
869
|
-
instruction = (
|
|
870
|
-
"This change does not match an existing requirement. "
|
|
871
|
-
"Could you say in one sentence which behavior you expect?"
|
|
872
|
-
)
|
|
873
|
-
confidence_target = 0.7
|
|
874
|
-
|
|
875
|
-
# REQ-098: respect epistemic.confidence_threshold from .specsmith/config.yml
|
|
876
|
-
# as a floor for confidence_target (heuristic default still applies when
|
|
877
|
-
# the configured value is lower or the file is missing).
|
|
878
|
-
config_threshold = _read_confidence_threshold_floor(root)
|
|
879
|
-
if config_threshold is not None and config_threshold > confidence_target:
|
|
880
|
-
confidence_target = config_threshold
|
|
881
|
-
|
|
882
|
-
work_item_id = f"WI-{uuid.uuid4().hex[:8].upper()}" if decision_str == "accepted" else ""
|
|
883
|
-
|
|
884
|
-
# REQ-117: predict-only mode does not allocate a work_item_id and does
|
|
885
|
-
# not write a ledger event; instead it adds a `predicted_refinement`
|
|
886
|
-
# field for IDE autocomplete.
|
|
803
|
+
# REQ-117: predict-only adds a `predicted_refinement` hint for IDE autocomplete.
|
|
804
|
+
# run_preflight already withholds the work item and the ESDB/ledger writes here.
|
|
887
805
|
if predict_only:
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
payload = {
|
|
891
|
-
"decision": decision_str,
|
|
892
|
-
"work_item_id": work_item_id,
|
|
893
|
-
"requirement_ids": requirement_ids,
|
|
894
|
-
"test_case_ids": test_case_ids,
|
|
895
|
-
"confidence_target": round(confidence_target, 3),
|
|
896
|
-
"instruction": instruction,
|
|
897
|
-
"intent": intent.value,
|
|
898
|
-
}
|
|
899
|
-
if predict_only:
|
|
900
|
-
if not scope.is_known and intent == Intent.CHANGE:
|
|
806
|
+
if decision_str == "needs_clarification":
|
|
901
807
|
payload["predicted_refinement"] = (
|
|
902
|
-
f"{utterance} (please name the component or
|
|
808
|
+
f"{utterance} (please name the component, file, or REQ id to change)"
|
|
903
809
|
)
|
|
904
|
-
elif intent == Intent.DESTRUCTIVE:
|
|
905
|
-
payload["predicted_refinement"] = f"{utterance} (specify the exact paths or resources)"
|
|
906
810
|
else:
|
|
907
811
|
payload["predicted_refinement"] = utterance
|
|
908
812
|
|
|
909
|
-
# REQ-100
|
|
910
|
-
#
|
|
911
|
-
if stress
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
if payload.get("stress_warnings"):
|
|
920
|
-
payload["narration"] += "\nNote: stress-test surfaced one or more critical failures."
|
|
921
|
-
|
|
922
|
-
# REG-009: AI disclosure metadata (FTC Operation AI Comply, Utah SB149 2024).
|
|
923
|
-
# Every governed output must disclose the AI system producing it.
|
|
924
|
-
import os as _os
|
|
925
|
-
|
|
926
|
-
payload["ai_disclosure"] = {
|
|
927
|
-
"governed_by": "specsmith",
|
|
928
|
-
"governance_gated": True,
|
|
929
|
-
"provider": _os.environ.get("SPECSMITH_PROVIDER", "local/heuristic"),
|
|
930
|
-
"model": _os.environ.get("SPECSMITH_MODEL", "deterministic-broker"),
|
|
931
|
-
"spec_version": __version__,
|
|
932
|
-
}
|
|
813
|
+
# REQ-100 (--stress) and --verbose (narration) need the broker's scope/intent
|
|
814
|
+
# view. Re-derive it best-effort; failures never affect the decision payload.
|
|
815
|
+
if stress or verbose:
|
|
816
|
+
try:
|
|
817
|
+
from specsmith.agent.broker import (
|
|
818
|
+
PreflightDecision,
|
|
819
|
+
classify_intent,
|
|
820
|
+
infer_scope,
|
|
821
|
+
narrate_plan,
|
|
822
|
+
)
|
|
933
823
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
824
|
+
intent = classify_intent(utterance)
|
|
825
|
+
# Mirror run_preflight's requirements-path resolution (REQ-418 parity):
|
|
826
|
+
# prefer docs/REQUIREMENTS.md, fall back to the project-root file so the
|
|
827
|
+
# stress/verbose scope view matches the authoritative decision's scope.
|
|
828
|
+
req_md = root / "docs" / "REQUIREMENTS.md"
|
|
829
|
+
if not req_md.is_file():
|
|
830
|
+
req_md = root / "REQUIREMENTS.md"
|
|
831
|
+
scope = infer_scope(
|
|
832
|
+
utterance,
|
|
833
|
+
req_md,
|
|
834
|
+
repo_index_path=root / ".repo-index" / "files.json",
|
|
835
|
+
)
|
|
836
|
+
if stress and scope.matched_requirements:
|
|
837
|
+
warnings = _stress_test_warnings(root, scope.matched_requirements)
|
|
838
|
+
if warnings:
|
|
839
|
+
payload["stress_warnings"] = warnings
|
|
840
|
+
if verbose:
|
|
841
|
+
decision_obj = PreflightDecision.from_json(payload)
|
|
842
|
+
payload["narration"] = narrate_plan(intent, scope, decision_obj, verbose=True)
|
|
843
|
+
if payload.get("stress_warnings"):
|
|
844
|
+
payload["narration"] += (
|
|
845
|
+
"\nNote: stress-test surfaced one or more critical failures."
|
|
846
|
+
)
|
|
847
|
+
except Exception: # noqa: BLE001 - presentation extras are best-effort
|
|
848
|
+
pass
|
|
942
849
|
|
|
943
850
|
# Bypass rich's renderer to keep the JSON intact (same pattern as clean).
|
|
944
851
|
click.echo(_json.dumps(payload, indent=2))
|
|
@@ -11592,39 +11499,99 @@ def esdb_status_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
11592
11499
|
raise SystemExit(1)
|
|
11593
11500
|
return
|
|
11594
11501
|
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
console.print(f" Records: {record_count}")
|
|
11598
|
-
for kind, count in counts.items():
|
|
11599
|
-
console.print(f" {kind}: {count}")
|
|
11502
|
+
# REQ-417: report the actual chain-verification result, not a hardcoded label.
|
|
11503
|
+
integrity_label = "Integrity OK" if chain_ok else "Integrity FAILED"
|
|
11600
11504
|
chain_icon = "[green]\u2714[/green]" if chain_ok else "[red]\u2717[/red]"
|
|
11601
|
-
|
|
11505
|
+
|
|
11506
|
+
# Issue #263 / REQ-419: build both a colored (Rich markup) and a plain ASCII
|
|
11507
|
+
# rendering. The Rich render is attempted first for healthy consoles; on the
|
|
11508
|
+
# Windows legacy console it can raise a spurious KeyboardInterrupt (which Click
|
|
11509
|
+
# turns into Abort/exit 1), so ANY failure falls back to a resilient plain-text
|
|
11510
|
+
# stdout writer that mirrors the --json branch and never aborts.
|
|
11511
|
+
markup_lines: list[str] = [
|
|
11512
|
+
f"[green]\u25cf[/green] ESDB \u2014 {backend_label}",
|
|
11513
|
+
f" Records: {record_count}",
|
|
11514
|
+
]
|
|
11515
|
+
plain_lines: list[str] = [
|
|
11516
|
+
f"ESDB - {backend_label}",
|
|
11517
|
+
f" Records: {record_count}",
|
|
11518
|
+
]
|
|
11519
|
+
for kind, count in counts.items():
|
|
11520
|
+
markup_lines.append(f" {kind}: {count}")
|
|
11521
|
+
plain_lines.append(f" {kind}: {count}")
|
|
11522
|
+
markup_lines.append(f" {chain_icon} {integrity_label}")
|
|
11523
|
+
plain_lines.append(f" {integrity_label}")
|
|
11602
11524
|
if store_error:
|
|
11603
|
-
|
|
11525
|
+
markup_lines.append(f" [red]\u2717[/red] Store error: {store_error}")
|
|
11526
|
+
plain_lines.append(f" Store error: {store_error}")
|
|
11604
11527
|
# License line
|
|
11605
11528
|
if not sys.modules["specsmith.esdb"].CHRONO_AVAILABLE:
|
|
11606
|
-
|
|
11529
|
+
markup_lines.append(
|
|
11607
11530
|
" [dim]chronomemory not installed \u2014 run "
|
|
11608
11531
|
"'pip install specsmith[esdb]' for ChronoStore[/dim]"
|
|
11609
11532
|
)
|
|
11533
|
+
plain_lines.append(
|
|
11534
|
+
" chronomemory not installed - run 'pip install specsmith[esdb]' for ChronoStore"
|
|
11535
|
+
)
|
|
11610
11536
|
elif lic_status and lic_status.valid:
|
|
11611
|
-
|
|
11537
|
+
markup_lines.append(
|
|
11612
11538
|
f" [green]\u2714[/green] License: {lic_status.customer} "
|
|
11613
11539
|
f"(expires {lic_status.expires_at})"
|
|
11614
11540
|
)
|
|
11541
|
+
plain_lines.append(f" License: {lic_status.customer} (expires {lic_status.expires_at})")
|
|
11615
11542
|
else:
|
|
11616
11543
|
reason = lic_status.reason if lic_status else "no license file"
|
|
11617
|
-
|
|
11618
|
-
|
|
11544
|
+
markup_lines.append(f" [yellow]\u26a0[/yellow] ESDB license: {reason}")
|
|
11545
|
+
markup_lines.append(
|
|
11619
11546
|
" [dim]Use 'specsmith esdb enable --key-file <path>' to activate ChronoStore.[/dim]"
|
|
11620
11547
|
)
|
|
11548
|
+
plain_lines.append(f" ESDB license: {reason}")
|
|
11549
|
+
plain_lines.append(
|
|
11550
|
+
" Use 'specsmith esdb enable --key-file <path>' to activate ChronoStore."
|
|
11551
|
+
)
|
|
11621
11552
|
if auto_counts:
|
|
11622
|
-
|
|
11553
|
+
markup_lines.append(
|
|
11623
11554
|
" [cyan]\u27f3[/cyan] Auto-migrated from legacy JSON: "
|
|
11624
11555
|
f"{auto_counts.get('requirements', 0)} requirements + "
|
|
11625
11556
|
f"{auto_counts.get('testcases', 0)} testcases "
|
|
11626
11557
|
f"({auto_counts.get('skipped', 0)} skipped)"
|
|
11627
11558
|
)
|
|
11559
|
+
plain_lines.append(
|
|
11560
|
+
" Auto-migrated from legacy JSON: "
|
|
11561
|
+
f"{auto_counts.get('requirements', 0)} requirements + "
|
|
11562
|
+
f"{auto_counts.get('testcases', 0)} testcases "
|
|
11563
|
+
f"({auto_counts.get('skipped', 0)} skipped)"
|
|
11564
|
+
)
|
|
11565
|
+
|
|
11566
|
+
def _emit_plain() -> None:
|
|
11567
|
+
"""Resiliently write the plain-text status block (mirrors the --json branch)."""
|
|
11568
|
+
plain_text = "\n".join(plain_lines)
|
|
11569
|
+
try:
|
|
11570
|
+
sys.stdout.write(plain_text + "\n")
|
|
11571
|
+
sys.stdout.flush()
|
|
11572
|
+
except Exception as out_exc: # noqa: BLE001
|
|
11573
|
+
try:
|
|
11574
|
+
sys.stderr.write(
|
|
11575
|
+
_json.dumps(
|
|
11576
|
+
{
|
|
11577
|
+
"ok": False,
|
|
11578
|
+
"error": "esdb status: stdout write failed",
|
|
11579
|
+
"reason": str(out_exc),
|
|
11580
|
+
"backend": active_backend,
|
|
11581
|
+
"record_count": record_count,
|
|
11582
|
+
}
|
|
11583
|
+
)
|
|
11584
|
+
+ "\n"
|
|
11585
|
+
)
|
|
11586
|
+
sys.stderr.flush()
|
|
11587
|
+
except Exception: # noqa: BLE001
|
|
11588
|
+
pass
|
|
11589
|
+
raise SystemExit(1) from out_exc
|
|
11590
|
+
|
|
11591
|
+
try:
|
|
11592
|
+
console.print("\n".join(markup_lines))
|
|
11593
|
+
except (KeyboardInterrupt, Exception): # noqa: BLE001
|
|
11594
|
+
_emit_plain()
|
|
11628
11595
|
|
|
11629
11596
|
|
|
11630
11597
|
@esdb_group.command(name="verify-chain")
|
|
@@ -11888,12 +11855,13 @@ def esdb_migrate_cmd(project_dir: str, as_json: bool) -> None:
|
|
|
11888
11855
|
@click.option("--project-dir", type=click.Path(exists=True), default=".")
|
|
11889
11856
|
@click.option("--json", "as_json", is_flag=True, default=False)
|
|
11890
11857
|
def esdb_replay_cmd(project_dir: str, as_json: bool) -> None:
|
|
11891
|
-
"""Replay the trace vault
|
|
11858
|
+
"""Replay the trace vault and verify SHA-256 hash chain integrity.
|
|
11892
11859
|
|
|
11893
|
-
Reads
|
|
11894
|
-
each entry_hash from its stored content_hash +
|
|
11895
|
-
to the stored value. Any mismatch indicates tampering
|
|
11896
|
-
Also reports ledger.jsonl entry count as a secondary
|
|
11860
|
+
Reads seal records from the ESDB (``seal_record`` kind; REQ-420) and walks
|
|
11861
|
+
every seal entry, recomputing each entry_hash from its stored content_hash +
|
|
11862
|
+
prev_hash and comparing to the stored value. Any mismatch indicates tampering
|
|
11863
|
+
or corruption. Also reports ledger.jsonl entry count as a secondary
|
|
11864
|
+
consistency signal.
|
|
11897
11865
|
"""
|
|
11898
11866
|
import json as _json
|
|
11899
11867
|
|
|
@@ -14002,9 +13970,12 @@ def resume_cmd(
|
|
|
14002
13970
|
with contextlib.suppress(Exception):
|
|
14003
13971
|
bridge = EsdbBridge(str(root))
|
|
14004
13972
|
status = bridge.status()
|
|
13973
|
+
# REQ-417: the leading ESDB indicator must reflect the real chain state,
|
|
13974
|
+
# not a hardcoded green check.
|
|
14005
13975
|
chain_icon = "\u2713" if status.chain_valid else "\u2717"
|
|
13976
|
+
chain_color = "green" if status.chain_valid else "red"
|
|
14006
13977
|
console.print(
|
|
14007
|
-
f" [
|
|
13978
|
+
f" [{chain_color}]{chain_icon}[/{chain_color}] ESDB: {status.backend} "
|
|
14008
13979
|
f"({status.record_count} records, chain {chain_icon})"
|
|
14009
13980
|
)
|
|
14010
13981
|
|
|
@@ -163,17 +163,21 @@ class EvidenceCollector:
|
|
|
163
163
|
)
|
|
164
164
|
)
|
|
165
165
|
|
|
166
|
-
# Trace vault
|
|
167
|
-
|
|
166
|
+
# Trace vault (REQ-420: seals are ESDB ``seal_record`` entries, no
|
|
167
|
+
# longer a .specsmith/trace.jsonl flat file).
|
|
168
|
+
from specsmith.trace import count_seal_records
|
|
169
|
+
|
|
170
|
+
seal_count = count_seal_records(self.root)
|
|
168
171
|
items.append(
|
|
169
172
|
EvidenceItem(
|
|
170
173
|
control_id="Art.12",
|
|
171
174
|
regulation_id="*",
|
|
172
|
-
description="SHA-256 chained trace vault (decision seals)",
|
|
173
|
-
source=".specsmith/
|
|
174
|
-
source_type="
|
|
175
|
-
confidence=0.9 if
|
|
176
|
-
present=
|
|
175
|
+
description="SHA-256 chained trace vault (decision seals, ESDB seal_record)",
|
|
176
|
+
source="ESDB seal_record (.specsmith/esdb.sqlite3 | .chronomemory/)",
|
|
177
|
+
source_type="esdb",
|
|
178
|
+
confidence=0.9 if seal_count > 0 else 0.1,
|
|
179
|
+
present=seal_count > 0,
|
|
180
|
+
detail=f"{seal_count} seal(s) in ESDB",
|
|
177
181
|
)
|
|
178
182
|
)
|
|
179
183
|
|
|
@@ -127,7 +127,8 @@ _EU_AI_ACT = Regulation(
|
|
|
127
127
|
category="logging",
|
|
128
128
|
specsmith_controls=[
|
|
129
129
|
"specsmith trace (SHA-256 chain)",
|
|
130
|
-
|
|
130
|
+
# DEPRECATED(REQ-421): legacy trace.jsonl replaced by ESDB seal_record.
|
|
131
|
+
"ESDB seal_record (.specsmith/esdb.sqlite3 | .chronomemory/)",
|
|
131
132
|
"ChronoStore WAL (.chronomemory/events.wal)",
|
|
132
133
|
".specsmith/ledger.jsonl",
|
|
133
134
|
"specsmith trace verify",
|
|
@@ -141,7 +141,7 @@ class ProjectConfig(BaseModel):
|
|
|
141
141
|
),
|
|
142
142
|
)
|
|
143
143
|
language: str = Field(default="python", description="Primary language/runtime")
|
|
144
|
-
spec_version: str = Field(default="0.
|
|
144
|
+
spec_version: str = Field(default="0.18.0", description="Spec version to scaffold from")
|
|
145
145
|
description: str = Field(default="", description="Short project description")
|
|
146
146
|
|
|
147
147
|
# Options
|
|
@@ -451,7 +451,7 @@ class ProjectConfig(BaseModel):
|
|
|
451
451
|
)
|
|
452
452
|
enable_trace_vault: bool = Field(
|
|
453
453
|
default=False,
|
|
454
|
-
description="Enable cryptographic trace vault (
|
|
454
|
+
description="Enable cryptographic trace vault (ESDB seal_record; REQ-420)",
|
|
455
455
|
)
|
|
456
456
|
|
|
457
457
|
@property
|
|
@@ -360,18 +360,37 @@ class ContextOrchestrator:
|
|
|
360
360
|
return 0
|
|
361
361
|
|
|
362
362
|
def _count_critical_records(self) -> int:
|
|
363
|
-
"""Count records that qualify as critical (must be protected).
|
|
363
|
+
"""Count records that qualify as critical (must be protected).
|
|
364
|
+
|
|
365
|
+
REQ-422: parity across backends — prefer the ChronoStore WAL when present,
|
|
366
|
+
otherwise count active high-confidence records from the free SQLite ESDB
|
|
367
|
+
backend so the protection path behaves identically without ChronoStore.
|
|
368
|
+
"""
|
|
369
|
+
# --- ChronoStore first (commercial backend) -------------------------
|
|
364
370
|
wal = self.root / ".chronomemory" / "events.wal"
|
|
365
|
-
if
|
|
366
|
-
|
|
371
|
+
if wal.exists():
|
|
372
|
+
try:
|
|
373
|
+
from chronomemory import ChronoStore
|
|
374
|
+
|
|
375
|
+
with ChronoStore(self.root) as store:
|
|
376
|
+
return sum(
|
|
377
|
+
1
|
|
378
|
+
for r in store.query()
|
|
379
|
+
if r.confidence >= CRITICAL_CONFIDENCE and r.status == "active"
|
|
380
|
+
)
|
|
381
|
+
except Exception: # noqa: BLE001
|
|
382
|
+
pass # fall through to SqliteStore
|
|
383
|
+
|
|
384
|
+
# --- Fall back to SqliteStore (free default backend) ----------------
|
|
367
385
|
try:
|
|
368
|
-
from
|
|
386
|
+
from specsmith.esdb import SqliteStore
|
|
369
387
|
|
|
370
|
-
|
|
388
|
+
sqlite_path = self.root / ".specsmith" / "esdb.sqlite3"
|
|
389
|
+
if not sqlite_path.exists():
|
|
390
|
+
return 0
|
|
391
|
+
with SqliteStore(self.root) as store:
|
|
371
392
|
return sum(
|
|
372
|
-
1
|
|
373
|
-
for r in store.query()
|
|
374
|
-
if r.confidence >= CRITICAL_CONFIDENCE and r.status == "active"
|
|
393
|
+
1 for r in store.query(status="active") if r.confidence >= CRITICAL_CONFIDENCE
|
|
375
394
|
)
|
|
376
395
|
except Exception: # noqa: BLE001
|
|
377
396
|
return 0
|