execweave 0.7.2__tar.gz → 0.7.3__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.
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/ci.yml +52 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/publish.yml +11 -3
- execweave-0.7.3/.github/workflows/repair-v073.yml +173 -0
- {execweave-0.7.2 → execweave-0.7.3}/PKG-INFO +1 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.de.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.fr.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.ja.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.ko.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.ru.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.zh-CN.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/docs/codex-hooks.zh-TW.md +0 -1
- {execweave-0.7.2 → execweave-0.7.3}/pyproject.toml +2 -2
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_codex_hook.py +9 -15
- execweave-0.7.3/scripts/check_conversation_records.py +215 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/emit_claude_hook_smoke.py +16 -6
- execweave-0.7.3/scripts/emit_codex_hook_smoke.py +201 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/emit_cursor_hook_smoke.py +3 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/emit_gemini_hook_smoke.py +2 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/emit_opencode_plugin_smoke.py +9 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/__init__.py +1 -1
- execweave-0.7.2/src/execweave/conversation_records.py → execweave-0.7.3/src/execweave/_conversation_records_core.py +247 -55
- execweave-0.7.3/src/execweave/agent_topology.py +313 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/agent_trace.py +7 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_adapter.py +10 -1
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_delegation.py +5 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_full_fidelity.py +10 -1
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_hook_contract.py +5 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_adapter.py +10 -1
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_conversation.py +243 -28
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_full_fidelity.py +43 -8
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_hook_cli.py +102 -10
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/conversation_archive.py +24 -5
- execweave-0.7.3/src/execweave/conversation_message_identity.py +264 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/conversation_preview.py +106 -57
- execweave-0.7.3/src/execweave/conversation_records.py +115 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_full_fidelity.py +5 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/graph.py +7 -1
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_event_contract.py +2 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_full_fidelity.py +2 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_task_linkage.py +23 -2
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_conversation_tree.py +4 -4
- execweave-0.7.3/tests/fixtures/codex_multi_agent/PROVENANCE.md +38 -0
- execweave-0.7.3/tests/fixtures/codex_multi_agent/hook-payloads.json +105 -0
- execweave-0.7.3/tests/fixtures/codex_multi_agent/rollout-main.jsonl +77 -0
- execweave-0.7.3/tests/test_agent_topology_evidence.py +499 -0
- execweave-0.7.3/tests/test_codex_hook_partial_capture.py +248 -0
- execweave-0.7.3/tests/test_codex_real_multi_agent_conversation.py +475 -0
- execweave-0.7.3/tests/test_codex_routing_native_identity.py +44 -0
- execweave-0.7.3/tests/test_conversation_identity_merge.py +440 -0
- execweave-0.7.3/tests/test_conversation_message_observation_dedupe.py +346 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_conversation_provider_parity.py +13 -8
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_v069_dashboard_release.py +4 -4
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/cleanup-workflow-history.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/i18n.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/package-benchmark.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/package-smoke.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/scalability.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/wheel-smoke.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.github/workflows/windows-launcher.yml +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/.gitignore +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/LICENSE +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/README.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/benchmarks/phase1_overhead.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/antigravity-hooks.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/assets/codex.gif +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/benchmarks/README.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/benchmarks/v0.6.0-github-actions.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/benchmarks/v0.6.0-github-actions.svg +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/claude-code-hooks.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/cursor-hooks.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/evidence-grades.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/gemini-hooks.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/inference-gateway.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/live-graph.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/model-runtime.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/opencode-plugin.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-1-runtime-collection.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/phase-2-execution-graph.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/rule-packs.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/run-integrity.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/runtime-threat-model.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/security-analysis.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.de.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.fr.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.ja.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.ko.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.ru.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.zh-CN.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/semantic-telemetry.zh-TW.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/docs/v0.6.5-hardening-decisions.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/audit_i18n_parity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_claude_hook.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_claude_record_graph.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_correlation_graph.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_inference_gateway_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_model_runtime_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_openai_compatible_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_semantic_graph.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_viewer_js.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_wheel_install.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/check_windows_launchers.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/make_semantic_smoke.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/scripts/sync_i18n_nav.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/__main__.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/agent_bootstrap.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/analysis.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/anthropic.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/anthropic_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/anthropic_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_adapter_base.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_full_fidelity_base.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_full_fidelity_collaboration_base.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_hook_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_subagent_linkage.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/antigravity_trace_capability.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/auto_specialized.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/backends.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/benchmark.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_hook_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_model_observer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/claude_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_hook_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_message_diagnostics.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_message_transport_diagnostics.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_rollout_structures.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_rollout_trace.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/codex_rollout_trace_base.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/collector.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/command.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/content_evidence.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/content_store.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/correlation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_delegation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_delegation_base.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_hook_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_hook_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/cursor_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/entry.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/evidence_grade.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/filesystem.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/focus.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/gemini_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/gemini_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/gemini_hook_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/gemini_hook_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/gemini_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/graph_ops.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/http_proxy.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/http_proxy_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/inference_gateway.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/inference_gateway_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/inference_gateway_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/inference_identity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/inference_identity_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/integrity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/integrity_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/litellm_callback.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/litellm_callback_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_core.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_extra_style.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_markup.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_script_a.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_script_b.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_script_c.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_script_d.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/live_view_style.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/model_runtime.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/model_runtime_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/model_runtime_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/openai_compatible.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/openai_compatible_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/openai_compatible_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_hook_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_plugin_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/opencode_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/overhead_benchmark.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/provider_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/provider_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/rule_pack.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/rule_pack_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/scalability_benchmark.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/schema.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/scope.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/semantic.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/sink.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/strace_backend.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/theme.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/top.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/top_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/validate.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/view_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_antigravity_linkage_inspector.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_content_inspector.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_conversation_panel.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_dashboard_clean.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_dashboard_focus.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_execution_inspector.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_live_layout.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_projection.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/viewer_projection_base.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/src/execweave/workflow.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/README.md +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/claude.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/codex.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/cursor.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/gemini.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/manifest.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/fixtures/hooks/opencode.json +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_agent_bootstrap.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_agent_message_viewer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_agent_trace_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_agent_trace_viewer_visibility.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_analysis.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_anthropic.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_agent_collaboration.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_cursor_launch.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_linkage_projection.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_official_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_subagent_transcript_linkage.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_antigravity_trace_capability_cli.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_auto_specialized.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_backends.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_delegation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_hook_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_hook_metadata.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_hook_viewer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_model_observer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_claude_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_archive_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_conversation_isolation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_hook_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_message_diagnostics.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_message_transport_diagnostics.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_reducer_command.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_rollout_structures.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_codex_rollout_trace.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_collector.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_command.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_condense.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_conversation_access.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_conversation_agent_isolation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_correlation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_correlation_canonical_path.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_correlation_checker.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_correlation_process_exe.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cross_provider_agent_trace.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_delegation.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_hook_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_hook_fail_open.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_cursor_task_linkage.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_dashboard_information_architecture.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_dashboard_simplification.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_dashboard_ux_and_hook_projection.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_delegation_viewer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_evidence_grade.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_execution_viewer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_filesystem_resilience.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_focus.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_gemini_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_gemini_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_gemini_hook_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_gemini_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_gemini_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_graph.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_graph_ops.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_hook_fixture_corpus.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_http_proxy.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_inference_gateway.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_inference_gateway_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_inference_identity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_integrity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_litellm_callback.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live_auth.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live_dashboard.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live_dashboard_js.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live_delta.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live_logs_export.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_live_theme.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_lmstudio_auto_specialized.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_model_runtime.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_model_runtime_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_openai_compatible.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_adapter.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_event_contract.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_event_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_full_fidelity.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_plugin.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_record.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_opencode_task_session_linkage.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_overhead_benchmark.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_provider_conversation_evidence.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_provider_lifecycle.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_rule_pack.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_schema.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_scope.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_semantic.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_strace_backend.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_threat_model.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_top_detached.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_v063_features.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_v064_live_auto_integrations.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_v064_live_evidence.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_validate.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_version.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_viewer.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_viewer_content_inspector.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_viewer_projection.py +0 -0
- {execweave-0.7.2 → execweave-0.7.3}/tests/test_workflow.py +0 -0
|
@@ -150,6 +150,12 @@ jobs:
|
|
|
150
150
|
run: python scripts/check_correlation_graph.py claude-record-smoke/graph.correlated.json
|
|
151
151
|
- name: Check correlated standalone viewer JavaScript syntax
|
|
152
152
|
run: python scripts/check_viewer_js.py claude-record-smoke/viewer.correlated.html --output claude-record-smoke/viewer.correlated.js
|
|
153
|
+
- name: Verify Claude materialized conversations
|
|
154
|
+
run: >
|
|
155
|
+
python scripts/check_conversation_records.py claude-record-smoke
|
|
156
|
+
--expect-agent /root
|
|
157
|
+
--expect-root-text "CI CLAUDE PROMPT"
|
|
158
|
+
--expect-root-text "CI CLAUDE FINAL ANSWER"
|
|
153
159
|
- name: Gemini run-bound semantic and correlation smoke
|
|
154
160
|
run: execweave-gemini-record --backend auto --no-files --no-network --output-dir gemini-record-smoke -- python scripts/emit_gemini_hook_smoke.py
|
|
155
161
|
- name: Validate Gemini runtime stream
|
|
@@ -162,6 +168,12 @@ jobs:
|
|
|
162
168
|
run: python scripts/check_correlation_graph.py gemini-record-smoke/graph.correlated.json
|
|
163
169
|
- name: Check Gemini correlated viewer JavaScript syntax
|
|
164
170
|
run: python scripts/check_viewer_js.py gemini-record-smoke/viewer.correlated.html --output gemini-record-smoke/viewer.correlated.js
|
|
171
|
+
- name: Verify Gemini materialized conversations
|
|
172
|
+
run: >
|
|
173
|
+
python scripts/check_conversation_records.py gemini-record-smoke
|
|
174
|
+
--expect-agent /root
|
|
175
|
+
--expect-root-text "CI GEMINI PROMPT"
|
|
176
|
+
--expect-root-text "CI GEMINI FINAL ANSWER"
|
|
165
177
|
- name: Cursor run-bound semantic and correlation smoke
|
|
166
178
|
run: execweave-cursor-record --backend auto --no-files --no-network --output-dir cursor-record-smoke -- python scripts/emit_cursor_hook_smoke.py
|
|
167
179
|
- name: Validate Cursor runtime stream
|
|
@@ -174,6 +186,12 @@ jobs:
|
|
|
174
186
|
run: python scripts/check_correlation_graph.py cursor-record-smoke/graph.correlated.json
|
|
175
187
|
- name: Check Cursor correlated viewer JavaScript syntax
|
|
176
188
|
run: python scripts/check_viewer_js.py cursor-record-smoke/viewer.correlated.html --output cursor-record-smoke/viewer.correlated.js
|
|
189
|
+
- name: Verify Cursor materialized conversations
|
|
190
|
+
run: >
|
|
191
|
+
python scripts/check_conversation_records.py cursor-record-smoke
|
|
192
|
+
--expect-agent /root
|
|
193
|
+
--expect-root-text "CI CURSOR PROMPT"
|
|
194
|
+
--expect-root-text "CI CURSOR FINAL ANSWER"
|
|
177
195
|
- name: OpenCode plugin installer smoke
|
|
178
196
|
run: execweave-opencode-plugin --install --root opencode-plugin-smoke
|
|
179
197
|
- name: OpenCode run-bound semantic and correlation smoke
|
|
@@ -188,6 +206,40 @@ jobs:
|
|
|
188
206
|
run: python scripts/check_correlation_graph.py opencode-record-smoke/graph.correlated.json
|
|
189
207
|
- name: Check OpenCode correlated viewer JavaScript syntax
|
|
190
208
|
run: python scripts/check_viewer_js.py opencode-record-smoke/viewer.correlated.html --output opencode-record-smoke/viewer.correlated.js
|
|
209
|
+
- name: Verify OpenCode materialized conversations
|
|
210
|
+
run: >
|
|
211
|
+
python scripts/check_conversation_records.py opencode-record-smoke
|
|
212
|
+
--expect-agent /root
|
|
213
|
+
--expect-root-text "CI OPENCODE FINAL ANSWER"
|
|
214
|
+
--forbid-agent /root/ci-opencode-session
|
|
215
|
+
- name: Codex hook command smoke
|
|
216
|
+
run: python scripts/check_codex_hook.py
|
|
217
|
+
- name: Codex run-bound semantic and correlation smoke
|
|
218
|
+
run: execweave-codex-record --backend auto --no-files --no-network --output-dir codex-record-smoke -- python scripts/emit_codex_hook_smoke.py
|
|
219
|
+
- name: Validate Codex runtime stream
|
|
220
|
+
run: execweave validate codex-record-smoke/events.jsonl
|
|
221
|
+
- name: Validate Codex merged stream
|
|
222
|
+
run: execweave validate codex-record-smoke/events.semantic.jsonl
|
|
223
|
+
- name: Validate Codex correlated stream
|
|
224
|
+
run: execweave validate codex-record-smoke/events.correlated.jsonl
|
|
225
|
+
- name: Verify Codex conservative correlation edge
|
|
226
|
+
run: python scripts/check_correlation_graph.py codex-record-smoke/graph.correlated.json
|
|
227
|
+
- name: Check Codex correlated viewer JavaScript syntax
|
|
228
|
+
run: python scripts/check_viewer_js.py codex-record-smoke/viewer.correlated.html --output codex-record-smoke/viewer.correlated.js
|
|
229
|
+
# Codex reports a subagent stop with the child rollout on agent_transcript_path
|
|
230
|
+
# and the parent rollout on transcript_path. Archiving the parent is the
|
|
231
|
+
# v0.7.2 regression, so assert the child conversation survives end to end.
|
|
232
|
+
- name: Verify Codex agent-local subagent conversations
|
|
233
|
+
run: >
|
|
234
|
+
python scripts/check_conversation_records.py codex-record-smoke
|
|
235
|
+
--min-entries 2
|
|
236
|
+
--expect-agent /root
|
|
237
|
+
--expect-agent /root/explorer
|
|
238
|
+
--expect-root-text "CI ROOT PROMPT"
|
|
239
|
+
--expect-root-text "CI ROOT FINAL ANSWER"
|
|
240
|
+
--expect-owned "/root=CI ROOT COMMENTARY"
|
|
241
|
+
--expect-owned "/root/explorer=CI CHILD PRIVATE REASONING"
|
|
242
|
+
--forbid-agent /root/01a04cea-67b2-7683-9f6b-cd644497b862
|
|
191
243
|
- name: Model runtime CLI smoke
|
|
192
244
|
run: python scripts/check_model_runtime_cli.py
|
|
193
245
|
- name: Inference gateway CLI smoke
|
|
@@ -3,21 +3,30 @@ name: Publish to PyPI
|
|
|
3
3
|
on:
|
|
4
4
|
release:
|
|
5
5
|
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
release_tag:
|
|
9
|
+
description: Release tag to publish
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
6
12
|
|
|
7
13
|
permissions:
|
|
8
14
|
contents: read
|
|
9
15
|
|
|
16
|
+
env:
|
|
17
|
+
RELEASE_TAG: ${{ github.event.release.tag_name || inputs.release_tag }}
|
|
18
|
+
|
|
10
19
|
jobs:
|
|
11
20
|
build:
|
|
12
21
|
runs-on: ubuntu-latest
|
|
13
22
|
steps:
|
|
14
23
|
- uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
ref: ${{ env.RELEASE_TAG }}
|
|
15
26
|
- uses: actions/setup-python@v5
|
|
16
27
|
with:
|
|
17
28
|
python-version: "3.12"
|
|
18
29
|
- name: Verify release tag matches package version
|
|
19
|
-
env:
|
|
20
|
-
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
21
30
|
run: |
|
|
22
31
|
python - <<'PY'
|
|
23
32
|
import os
|
|
@@ -75,5 +84,4 @@ jobs:
|
|
|
75
84
|
- name: Attach distributions to GitHub Release
|
|
76
85
|
env:
|
|
77
86
|
GH_TOKEN: ${{ github.token }}
|
|
78
|
-
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
79
87
|
run: gh release upload "$RELEASE_TAG" dist/* --clobber --repo "$GITHUB_REPOSITORY"
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
name: Repair v0.7.3 Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: ["CI"]
|
|
6
|
+
types: [completed]
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
actions: write
|
|
11
|
+
contents: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
repair:
|
|
15
|
+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
env:
|
|
18
|
+
GH_TOKEN: ${{ github.token }}
|
|
19
|
+
RELEASE_TAG: v0.7.3
|
|
20
|
+
EXPECTED_VERSION: 0.7.3
|
|
21
|
+
STALE_TAG_SHA: 25321ec325ecf871ec2a56b55b593fcac854ffcf
|
|
22
|
+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
ref: ${{ env.HEAD_SHA }}
|
|
27
|
+
|
|
28
|
+
- name: Verify repaired release candidate
|
|
29
|
+
run: |
|
|
30
|
+
set -euo pipefail
|
|
31
|
+
current_main="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/main" --jq '.object.sha')"
|
|
32
|
+
if [[ "$current_main" != "$HEAD_SHA" ]]; then
|
|
33
|
+
echo "main moved from $HEAD_SHA to $current_main; refusing release repair" >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
python - <<'PY'
|
|
37
|
+
import os
|
|
38
|
+
import tomllib
|
|
39
|
+
from pathlib import Path
|
|
40
|
+
|
|
41
|
+
version = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))["project"]["version"]
|
|
42
|
+
expected = os.environ["EXPECTED_VERSION"]
|
|
43
|
+
if version != expected:
|
|
44
|
+
raise SystemExit(f"package version {version!r} does not match expected {expected!r}")
|
|
45
|
+
print(f"Release candidate version: {version}")
|
|
46
|
+
PY
|
|
47
|
+
|
|
48
|
+
- name: Wait for all release gates
|
|
49
|
+
run: |
|
|
50
|
+
set -euo pipefail
|
|
51
|
+
required=("CI" "Package Smoke" "Wheel Install Smoke" "Windows Launcher Compatibility")
|
|
52
|
+
for attempt in $(seq 1 60); do
|
|
53
|
+
runs="$(gh api "repos/$GITHUB_REPOSITORY/actions/runs?head_sha=$HEAD_SHA&per_page=100")"
|
|
54
|
+
pending=0
|
|
55
|
+
for gate in "${required[@]}"; do
|
|
56
|
+
state="$(jq -r --arg name "$gate" '
|
|
57
|
+
.workflow_runs
|
|
58
|
+
| map(select(.name == $name and .event == "push"))
|
|
59
|
+
| sort_by(.created_at)
|
|
60
|
+
| reverse
|
|
61
|
+
| .[0]
|
|
62
|
+
| if . == null then "missing"
|
|
63
|
+
else ((.status // "") + ":" + (.conclusion // "")) end
|
|
64
|
+
' <<<"$runs")"
|
|
65
|
+
echo "$gate => $state"
|
|
66
|
+
case "$state" in
|
|
67
|
+
completed:success) ;;
|
|
68
|
+
completed:*) echo "$gate failed: $state" >&2; exit 1 ;;
|
|
69
|
+
*) pending=1 ;;
|
|
70
|
+
esac
|
|
71
|
+
done
|
|
72
|
+
if [[ "$pending" -eq 0 ]]; then
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
sleep 5
|
|
76
|
+
done
|
|
77
|
+
echo "release gates did not all complete successfully" >&2
|
|
78
|
+
exit 1
|
|
79
|
+
|
|
80
|
+
- name: Replace stale v0.7.3 tag and release
|
|
81
|
+
run: |
|
|
82
|
+
set -euo pipefail
|
|
83
|
+
tag_sha="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$RELEASE_TAG" --jq '.object.sha' 2>/dev/null || true)"
|
|
84
|
+
release_exists=0
|
|
85
|
+
asset_count=0
|
|
86
|
+
if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
|
87
|
+
release_exists=1
|
|
88
|
+
asset_count="$(gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets | length')"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
if [[ -n "$tag_sha" && "$tag_sha" != "$STALE_TAG_SHA" && "$tag_sha" != "$HEAD_SHA" ]]; then
|
|
92
|
+
echo "v0.7.3 tag unexpectedly points to $tag_sha; refusing to overwrite" >&2
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
if [[ "$asset_count" -gt 0 && "$tag_sha" != "$HEAD_SHA" ]]; then
|
|
96
|
+
echo "existing v0.7.3 release already has assets; refusing destructive replacement" >&2
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
if [[ "$tag_sha" != "$HEAD_SHA" ]]; then
|
|
101
|
+
if [[ "$release_exists" -eq 1 ]]; then
|
|
102
|
+
gh release delete "$RELEASE_TAG" --cleanup-tag --yes --repo "$GITHUB_REPOSITORY"
|
|
103
|
+
elif [[ -n "$tag_sha" ]]; then
|
|
104
|
+
gh api --method DELETE "repos/$GITHUB_REPOSITORY/git/refs/tags/$RELEASE_TAG"
|
|
105
|
+
fi
|
|
106
|
+
gh release create "$RELEASE_TAG" \
|
|
107
|
+
--target "$HEAD_SHA" \
|
|
108
|
+
--title "ExecWeave v0.7.3" \
|
|
109
|
+
--generate-notes \
|
|
110
|
+
--repo "$GITHUB_REPOSITORY"
|
|
111
|
+
else
|
|
112
|
+
echo "v0.7.3 tag already points to repaired release candidate"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
- name: Dispatch canonical publish workflow
|
|
116
|
+
run: |
|
|
117
|
+
set -euo pipefail
|
|
118
|
+
gh workflow run publish.yml \
|
|
119
|
+
--ref main \
|
|
120
|
+
-f release_tag="$RELEASE_TAG" \
|
|
121
|
+
--repo "$GITHUB_REPOSITORY"
|
|
122
|
+
|
|
123
|
+
run_id=""
|
|
124
|
+
for attempt in $(seq 1 30); do
|
|
125
|
+
run_id="$(gh run list \
|
|
126
|
+
--workflow publish.yml \
|
|
127
|
+
--event workflow_dispatch \
|
|
128
|
+
--branch main \
|
|
129
|
+
--limit 20 \
|
|
130
|
+
--json databaseId,headSha,createdAt \
|
|
131
|
+
--jq ".[] | select(.headSha == \"$HEAD_SHA\") | .databaseId" \
|
|
132
|
+
--repo "$GITHUB_REPOSITORY" | head -n 1)"
|
|
133
|
+
if [[ -n "$run_id" ]]; then
|
|
134
|
+
break
|
|
135
|
+
fi
|
|
136
|
+
sleep 2
|
|
137
|
+
done
|
|
138
|
+
if [[ -z "$run_id" ]]; then
|
|
139
|
+
echo "could not locate dispatched publish workflow" >&2
|
|
140
|
+
exit 1
|
|
141
|
+
fi
|
|
142
|
+
echo "publish_run_id=$run_id" >> "$GITHUB_ENV"
|
|
143
|
+
|
|
144
|
+
- name: Wait for publish workflow
|
|
145
|
+
run: gh run watch "$publish_run_id" --exit-status --repo "$GITHUB_REPOSITORY"
|
|
146
|
+
|
|
147
|
+
- name: Verify release assets and PyPI
|
|
148
|
+
run: |
|
|
149
|
+
set -euo pipefail
|
|
150
|
+
assets="$(gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[].name')"
|
|
151
|
+
grep -Fx "execweave-0.7.3-py3-none-any.whl" <<<"$assets"
|
|
152
|
+
grep -Fx "execweave-0.7.3.tar.gz" <<<"$assets"
|
|
153
|
+
|
|
154
|
+
python - <<'PY'
|
|
155
|
+
import json
|
|
156
|
+
import time
|
|
157
|
+
import urllib.error
|
|
158
|
+
import urllib.request
|
|
159
|
+
|
|
160
|
+
url = "https://pypi.org/pypi/execweave/0.7.3/json"
|
|
161
|
+
for _ in range(60):
|
|
162
|
+
try:
|
|
163
|
+
with urllib.request.urlopen(url, timeout=10) as response:
|
|
164
|
+
payload = json.load(response)
|
|
165
|
+
if payload.get("info", {}).get("version") == "0.7.3":
|
|
166
|
+
print("PyPI ExecWeave 0.7.3 verified")
|
|
167
|
+
break
|
|
168
|
+
except (urllib.error.URLError, json.JSONDecodeError):
|
|
169
|
+
pass
|
|
170
|
+
time.sleep(5)
|
|
171
|
+
else:
|
|
172
|
+
raise SystemExit("PyPI did not expose ExecWeave 0.7.3")
|
|
173
|
+
PY
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: execweave
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: Turn AI-agent runtime behavior into a local interactive execution graph.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Irish-kw/ExecWeave
|
|
6
6
|
Project-URL: Repository, https://github.com/Irish-kw/ExecWeave
|
|
@@ -30,7 +30,6 @@ ExecWeave zeichnet Evidenz aus Codex-Lifecycle-Hooks neben unabhängig erfasster
|
|
|
30
30
|
- `SubagentStart`
|
|
31
31
|
- `SubagentStop`
|
|
32
32
|
- `Stop`
|
|
33
|
-
- `Interrupt`
|
|
34
33
|
|
|
35
34
|
Unbekannte oder upstream nicht verfügbare Ereignisse werden nicht erfunden. Hook-Schemata und Dispatch-Abdeckung können sich zwischen Codex-Versionen ändern.
|
|
36
35
|
|
|
@@ -30,7 +30,6 @@ ExecWeave enregistre les preuves issues des hooks de cycle de vie Codex à côt
|
|
|
30
30
|
- `SubagentStart`
|
|
31
31
|
- `SubagentStop`
|
|
32
32
|
- `Stop`
|
|
33
|
-
- `Interrupt`
|
|
34
33
|
|
|
35
34
|
ExecWeave n'invente pas les événements absents ou indisponibles côté fournisseur. Les schémas et la couverture peuvent changer selon les versions de Codex.
|
|
36
35
|
|
|
@@ -30,7 +30,6 @@ ExecWeave records Codex lifecycle-hook evidence beside independent OS runtime te
|
|
|
30
30
|
- `SubagentStart`
|
|
31
31
|
- `SubagentStop`
|
|
32
32
|
- `Stop`
|
|
33
|
-
- `Interrupt`
|
|
34
33
|
|
|
35
34
|
Unknown or unavailable upstream events are not invented. Hook schemas and dispatch coverage can change between Codex versions.
|
|
36
35
|
|
|
@@ -30,7 +30,6 @@ ExecWeave записывает evidence из lifecycle hooks Codex рядом с
|
|
|
30
30
|
- `SubagentStart`
|
|
31
31
|
- `SubagentStop`
|
|
32
32
|
- `Stop`
|
|
33
|
-
- `Interrupt`
|
|
34
33
|
|
|
35
34
|
Неизвестные или недоступные upstream events не выдумываются. Hook schemas и dispatch coverage могут меняться между версиями Codex.
|
|
36
35
|
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "execweave"
|
|
7
|
-
# ExecWeave v0.7.
|
|
8
|
-
version = "0.7.
|
|
7
|
+
# ExecWeave v0.7.3 release metadata
|
|
8
|
+
version = "0.7.3"
|
|
9
9
|
description = "Turn AI-agent runtime behavior into a local interactive execution graph."
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -65,22 +65,16 @@ def main() -> int:
|
|
|
65
65
|
check=True,
|
|
66
66
|
)
|
|
67
67
|
parsed = json.loads(config.stdout)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"PostCompact",
|
|
74
|
-
"SessionStart",
|
|
75
|
-
"SessionEnd",
|
|
76
|
-
"UserPromptSubmit",
|
|
77
|
-
"SubagentStart",
|
|
78
|
-
"SubagentStop",
|
|
79
|
-
"Stop",
|
|
80
|
-
"Interrupt",
|
|
81
|
-
}
|
|
68
|
+
# Bound to the shipped event set rather than a second hardcoded copy, which had
|
|
69
|
+
# drifted to expect an "Interrupt" hook ExecWeave does not register.
|
|
70
|
+
from execweave.codex_hook_lifecycle import OFFICIAL_CODEX_HOOK_EVENTS
|
|
71
|
+
|
|
72
|
+
required = set(OFFICIAL_CODEX_HOOK_EVENTS)
|
|
82
73
|
if set(parsed.get("hooks", {})) != required:
|
|
83
|
-
raise SystemExit(
|
|
74
|
+
raise SystemExit(
|
|
75
|
+
"generated Codex hook config does not match the official event set: "
|
|
76
|
+
f"{sorted(set(parsed.get('hooks', {})) ^ required)}"
|
|
77
|
+
)
|
|
84
78
|
for event_name in {"PreToolUse", "PermissionRequest", "PostToolUse"}:
|
|
85
79
|
if parsed["hooks"][event_name][0].get("matcher") != "*":
|
|
86
80
|
raise SystemExit(f"Codex {event_name} hook is not configured for all tools")
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""Assert that a recorded run actually materialized the conversations it observed.
|
|
2
|
+
|
|
3
|
+
CI previously ran every provider's record pipeline end to end and never looked at
|
|
4
|
+
``conversations.json``. All four provider smokes were producing ``entry_count: 0``
|
|
5
|
+
while reporting success, which is how a total conversation collapse reached a tagged
|
|
6
|
+
release with green CI.
|
|
7
|
+
|
|
8
|
+
This checker closes that gap. It reads the final artifact — not an intermediate
|
|
9
|
+
preview object — and fails when a run that observed conversational evidence published
|
|
10
|
+
none, when an expected agent is missing, when one agent execution is published as
|
|
11
|
+
several conversations, or when a message landed in the wrong agent's thread.
|
|
12
|
+
|
|
13
|
+
Every check walks the real entry list. An earlier version keyed previews by agent path
|
|
14
|
+
before running the ownership checks, so a duplicate silently overwrote its twin and the
|
|
15
|
+
isolation assertions only ever saw one of them.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
import json
|
|
22
|
+
import sys
|
|
23
|
+
from collections import defaultdict
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _fail(message: str) -> None:
|
|
29
|
+
print(f"conversation record check FAILED: {message}", file=sys.stderr)
|
|
30
|
+
raise SystemExit(1)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _load(run_dir: Path) -> dict[str, Any]:
|
|
34
|
+
path = run_dir / "conversations.json"
|
|
35
|
+
if not path.is_file():
|
|
36
|
+
_fail(f"{path} does not exist")
|
|
37
|
+
try:
|
|
38
|
+
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
39
|
+
except json.JSONDecodeError as exc:
|
|
40
|
+
_fail(f"{path} is not valid JSON: {exc.msg}")
|
|
41
|
+
if not isinstance(payload, dict):
|
|
42
|
+
_fail(f"{path} root must be a JSON object")
|
|
43
|
+
return payload
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _entries_by_agent(document: dict[str, Any]) -> dict[str, list[dict[str, Any]]]:
|
|
47
|
+
"""Group every materialized preview under its agent path, keeping duplicates."""
|
|
48
|
+
grouped: dict[str, list[dict[str, Any]]] = defaultdict(list)
|
|
49
|
+
for entry in document.get("entries") or []:
|
|
50
|
+
if not isinstance(entry, dict):
|
|
51
|
+
continue
|
|
52
|
+
preview = entry.get("conversation_preview")
|
|
53
|
+
if isinstance(preview, dict) and preview.get("agent_path"):
|
|
54
|
+
grouped[str(preview["agent_path"])].append(preview)
|
|
55
|
+
return dict(grouped)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _texts(preview: dict[str, Any]) -> str:
|
|
59
|
+
return "\n".join(
|
|
60
|
+
str(message.get("text") or "") for message in preview.get("messages") or []
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _describe(agent_path: str, previews: list[dict[str, Any]]) -> str:
|
|
65
|
+
threads = [str(preview.get("thread_id")) for preview in previews]
|
|
66
|
+
return f"{agent_path} -> {len(previews)} entries with thread ids {threads}"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def main() -> int:
|
|
70
|
+
parser = argparse.ArgumentParser(
|
|
71
|
+
description="Verify a run's materialized conversations.json"
|
|
72
|
+
)
|
|
73
|
+
parser.add_argument("run_dir", type=Path, help="ExecWeave run artifact directory")
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"--expect-agent",
|
|
76
|
+
action="append",
|
|
77
|
+
default=[],
|
|
78
|
+
metavar="AGENT_PATH",
|
|
79
|
+
help="agent path that must have a conversation entry (repeatable)",
|
|
80
|
+
)
|
|
81
|
+
parser.add_argument(
|
|
82
|
+
"--expect-root-text",
|
|
83
|
+
action="append",
|
|
84
|
+
default=[],
|
|
85
|
+
metavar="TEXT",
|
|
86
|
+
help="text that must appear in the /root thread (repeatable)",
|
|
87
|
+
)
|
|
88
|
+
parser.add_argument(
|
|
89
|
+
"--expect-owned",
|
|
90
|
+
action="append",
|
|
91
|
+
default=[],
|
|
92
|
+
metavar="AGENT_PATH=TEXT",
|
|
93
|
+
help="text that must appear in one agent's thread and nowhere else (repeatable)",
|
|
94
|
+
)
|
|
95
|
+
parser.add_argument(
|
|
96
|
+
"--forbid-agent",
|
|
97
|
+
action="append",
|
|
98
|
+
default=[],
|
|
99
|
+
metavar="AGENT_PATH",
|
|
100
|
+
help="agent path that must NOT exist, e.g. a fabricated child (repeatable)",
|
|
101
|
+
)
|
|
102
|
+
parser.add_argument(
|
|
103
|
+
"--allow-duplicate-agent",
|
|
104
|
+
action="append",
|
|
105
|
+
default=[],
|
|
106
|
+
metavar="AGENT_PATH",
|
|
107
|
+
help=(
|
|
108
|
+
"permit this agent path to hold several conversation entries. Only for a "
|
|
109
|
+
"fixture where one agent genuinely runs several independent conversations; "
|
|
110
|
+
"one execution published twice is a defect, not a configuration choice."
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
parser.add_argument(
|
|
114
|
+
"--min-entries",
|
|
115
|
+
type=int,
|
|
116
|
+
default=1,
|
|
117
|
+
help="minimum number of materialized conversation entries (default: 1)",
|
|
118
|
+
)
|
|
119
|
+
args = parser.parse_args()
|
|
120
|
+
|
|
121
|
+
document = _load(args.run_dir)
|
|
122
|
+
grouped = _entries_by_agent(document)
|
|
123
|
+
entry_count = document.get("entry_count")
|
|
124
|
+
|
|
125
|
+
if not isinstance(entry_count, int) or entry_count < args.min_entries:
|
|
126
|
+
_fail(
|
|
127
|
+
f"entry_count is {entry_count!r}; expected at least {args.min_entries}. "
|
|
128
|
+
"The run observed conversational evidence but published none."
|
|
129
|
+
)
|
|
130
|
+
if len(grouped) < args.min_entries:
|
|
131
|
+
_fail(f"only {len(grouped)} agents carry a conversation; expected {args.min_entries}")
|
|
132
|
+
|
|
133
|
+
# One agent execution must be published exactly once. Evidence that names its
|
|
134
|
+
# thread differently is provenance, not a second conversation.
|
|
135
|
+
allowed_duplicates = set(args.allow_duplicate_agent)
|
|
136
|
+
for agent_path, previews in sorted(grouped.items()):
|
|
137
|
+
if len(previews) > 1 and agent_path not in allowed_duplicates:
|
|
138
|
+
_fail(
|
|
139
|
+
"one agent execution is published as several conversations: "
|
|
140
|
+
+ _describe(agent_path, previews)
|
|
141
|
+
+ ". Evidence describing the same execution must merge into one entry."
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
for agent_path in args.expect_agent:
|
|
145
|
+
if agent_path not in grouped:
|
|
146
|
+
_fail(f"no conversation entry for {agent_path}; found {sorted(grouped)}")
|
|
147
|
+
if not any(preview.get("messages") for preview in grouped[agent_path]):
|
|
148
|
+
_fail(f"{agent_path} materialized an entry with no messages")
|
|
149
|
+
|
|
150
|
+
for agent_path in args.forbid_agent:
|
|
151
|
+
if agent_path in grouped:
|
|
152
|
+
_fail(f"{agent_path} was materialized but no evidence establishes it")
|
|
153
|
+
|
|
154
|
+
if args.expect_root_text and "/root" not in grouped:
|
|
155
|
+
_fail(f"no /root conversation; found {sorted(grouped)}")
|
|
156
|
+
for text in args.expect_root_text:
|
|
157
|
+
if not any(text in _texts(preview) for preview in grouped.get("/root", [])):
|
|
158
|
+
_fail(f"/root thread is missing expected text {text!r}")
|
|
159
|
+
|
|
160
|
+
for spec in args.expect_owned:
|
|
161
|
+
agent_path, separator, text = spec.partition("=")
|
|
162
|
+
if not separator:
|
|
163
|
+
_fail(f"--expect-owned needs AGENT_PATH=TEXT, got {spec!r}")
|
|
164
|
+
if agent_path not in grouped:
|
|
165
|
+
_fail(f"no conversation entry for {agent_path}; found {sorted(grouped)}")
|
|
166
|
+
if not any(text in _texts(preview) for preview in grouped[agent_path]):
|
|
167
|
+
_fail(f"{agent_path} is missing its own content {text!r}")
|
|
168
|
+
# Isolation is checked against every published entry, so a duplicate cannot
|
|
169
|
+
# hide a leak by being overwritten before this runs.
|
|
170
|
+
for other_path, others in grouped.items():
|
|
171
|
+
if other_path == agent_path:
|
|
172
|
+
continue
|
|
173
|
+
for preview in others:
|
|
174
|
+
if text in _texts(preview):
|
|
175
|
+
_fail(
|
|
176
|
+
f"content {text!r} owned by {agent_path} leaked into "
|
|
177
|
+
f"{other_path} (thread {preview.get('thread_id')!r})"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Topology provenance: every parent link must name the evidence behind it, and no
|
|
181
|
+
# entry may claim a parent that has no conversation of its own.
|
|
182
|
+
for agent_path, previews in sorted(grouped.items()):
|
|
183
|
+
for preview in previews:
|
|
184
|
+
parent = preview.get("parent_agent_path")
|
|
185
|
+
if preview.get("is_root"):
|
|
186
|
+
if parent is not None:
|
|
187
|
+
_fail(f"{agent_path} is root but names parent {parent!r}")
|
|
188
|
+
continue
|
|
189
|
+
if parent is None:
|
|
190
|
+
_fail(f"{agent_path} is not root but names no parent")
|
|
191
|
+
if not preview.get("parent_relation_source"):
|
|
192
|
+
_fail(f"{agent_path} claims parent {parent!r} with no evidence recorded")
|
|
193
|
+
if parent not in grouped:
|
|
194
|
+
_fail(f"{agent_path} names parent {parent!r}, which has no conversation")
|
|
195
|
+
|
|
196
|
+
print(
|
|
197
|
+
f"conversation record check passed for {args.run_dir}: "
|
|
198
|
+
f"{entry_count} entries, agents {sorted(grouped)}"
|
|
199
|
+
)
|
|
200
|
+
for agent_path, previews in sorted(grouped.items()):
|
|
201
|
+
for preview in previews:
|
|
202
|
+
evidence = preview.get("evidence_thread_ids") or [preview.get("thread_id")]
|
|
203
|
+
print(
|
|
204
|
+
f" {agent_path}: {len(preview.get('messages') or [])} messages, "
|
|
205
|
+
f"completeness={preview.get('conversation_completeness')}, "
|
|
206
|
+
f"path_source={preview.get('agent_path_source')}, "
|
|
207
|
+
f"topology={preview.get('topology_state')}, "
|
|
208
|
+
f"thread={preview.get('thread_id')}, "
|
|
209
|
+
f"evidence_threads={len(evidence)}"
|
|
210
|
+
)
|
|
211
|
+
return 0
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
if __name__ == "__main__":
|
|
215
|
+
raise SystemExit(main())
|
|
@@ -30,12 +30,22 @@ def main() -> int:
|
|
|
30
30
|
}
|
|
31
31
|
if not os.environ.get("EXECWEAVE_SEMANTIC_SIDECAR"):
|
|
32
32
|
raise SystemExit("run-bound semantic sidecar environment was not inherited")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
|
|
34
|
+
def send(body: dict) -> None:
|
|
35
|
+
subprocess.run(
|
|
36
|
+
["execweave-claude-hook"], input=json.dumps(body), text=True, check=True
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
base = {key: payload[key] for key in ("session_id", "cwd", "permission_mode")}
|
|
40
|
+
# Conversation evidence, so the run materializes a conversations.json CI can check.
|
|
41
|
+
send({**base, "hook_event_name": "UserPromptSubmit", "prompt": "CI CLAUDE PROMPT"})
|
|
42
|
+
send(payload)
|
|
43
|
+
send({
|
|
44
|
+
**base,
|
|
45
|
+
"hook_event_name": "Stop",
|
|
46
|
+
"stop_hook_active": False,
|
|
47
|
+
"last_assistant_message": "CI CLAUDE FINAL ANSWER",
|
|
48
|
+
})
|
|
39
49
|
child = subprocess.Popen(child_argv)
|
|
40
50
|
# Keep the emitter alive while the child is running so the portable sampler
|
|
41
51
|
# gets many observation opportunities on slower hosted runners.
|