deepstrike 0.2.63__tar.gz → 0.2.65__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.
- {deepstrike-0.2.63 → deepstrike-0.2.65}/Cargo.lock +6 -6
- {deepstrike-0.2.63 → deepstrike-0.2.65}/Cargo.toml +3 -3
- {deepstrike-0.2.63 → deepstrike-0.2.65}/PKG-INFO +1 -1
- deepstrike-0.2.65/crates/deepstrike-core/src/bin/ds-chain-validator.rs +375 -0
- deepstrike-0.2.65/crates/deepstrike-core/src/runtime/chain_validator/mod.rs +3714 -0
- deepstrike-0.2.65/crates/deepstrike-core/src/runtime/kernel/wire/crash_point.rs +1029 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire.rs +3 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/request_plan.py +9 -7
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/execution_evidence.py +93 -7
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/runner.py +185 -4
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/session_log.py +33 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/session_repair.py +11 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/pyproject.toml +1 -1
- deepstrike-0.2.63/crates/deepstrike-core/src/bin/ds-chain-validator.rs +0 -204
- deepstrike-0.2.63/crates/deepstrike-core/src/runtime/chain_validator/mod.rs +0 -1181
- {deepstrike-0.2.63 → deepstrike-0.2.65}/LICENSE +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/README.md +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/Cargo.toml +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/LICENSE +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/benches/kernel_baseline.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/benches/wait_index_baseline.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/benchmark/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/compression.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/config.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/fault.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/manager.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/measurement.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/partitions.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/policy.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/pressure.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/renderer.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/renewal.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/task_state.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/text.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/units.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/utility.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/permission.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/pipeline.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/quota.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/repeat_fuse.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/veto.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/harness/eval.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/harness/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/lexical.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/lib.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/memory/curator.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/memory/durable.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/memory/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/handle.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/memory.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/value.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/tournament.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/proc/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/observation.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/binding.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/checkpoint.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/command.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/config.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/continuation.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/effects.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/events.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/planning.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/projection.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/provider.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/syscall.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/tests.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/effect.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/envelope.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/event.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/fault.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/projection.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/record.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/restore.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/root.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/scalar.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/syscall.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/terminal.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/tests.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/transaction.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/session.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/budget_grant.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/cross_operation.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/entropy.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/mailbox.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/runnable.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/cancellation.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/wait_index.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/attention.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/queue.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/router.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/agent.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/capability.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/contract.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/durable_content.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/error.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/message.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/milestone.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/mod.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/policy.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/result.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/signal.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/skill.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/task.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-py/Cargo.toml +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-py/LICENSE +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-py/src/lib.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-tokenizer/Cargo.toml +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-tokenizer/LICENSE +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-tokenizer/src/lib.rs +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/agent.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/agent_ir.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/contract.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/handoff.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/harness.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/modes.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/pool.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/governance.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/harness/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/harness/harness.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/harness/judge.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/kernel/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/kernel/canonical.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/knowledge/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/knowledge/source.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/agent.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/durable.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/extraction.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/in_memory_store.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/protocols.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/ranking.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/retention.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/working.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/anthropic.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/anthropic_adapter.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/anthropic_compatible.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/base.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/capability_router.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/credentials.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/embedding.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/factories.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/gemini.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/gemini_adapter.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/model_catalog.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/model_registry.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/ollama.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/ollama_adapter.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/openai.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/openai_chat_adapter.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/openai_responses.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/protocol_adapter.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/provider_error.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/qwen.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/replay.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/replay_validator.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/runtime_registry.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/stop_reason.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/stream.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/usage.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/vendor_profiles.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/archive.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/canonical_kernel_step.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/context_policy.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/credential_vault.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/durable_content.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/eval.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/event_stream.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/execution_plane.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/facade.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/filtered_plane.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/kernel_event_log.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/kernel_journal.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/kernel_step.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/loop_driver.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/mcp_proxy_plane.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/os_profile.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/os_snapshot.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/output_schema.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/payload_store.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/process_sandbox_plane.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/provider_replay.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reaction_checkpoint.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reactive_session.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reducers.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reliability.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/remote_vpc_plane.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/replay_fixture.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/replay_provider.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/replay_sanitize.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/run_group.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/sub_agent_orchestrator.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/turn_policy.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/workflow_control_flow.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/workflow_store.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/worktree_plane.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/safety/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/safety/permissions.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/gateway.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/scheduled.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/types.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/loader.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/registry.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/watcher.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/builtin/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/builtin/read_file.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/errors.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/execution.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/registry.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/__init__.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/agent.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/content.py +0 -0
- {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/content_policy.py +0 -0
|
@@ -254,7 +254,7 @@ dependencies = [
|
|
|
254
254
|
|
|
255
255
|
[[package]]
|
|
256
256
|
name = "deepstrike-core"
|
|
257
|
-
version = "0.2.
|
|
257
|
+
version = "0.2.65"
|
|
258
258
|
dependencies = [
|
|
259
259
|
"compact_str",
|
|
260
260
|
"deepstrike-tokenizer",
|
|
@@ -268,7 +268,7 @@ dependencies = [
|
|
|
268
268
|
|
|
269
269
|
[[package]]
|
|
270
270
|
name = "deepstrike-node"
|
|
271
|
-
version = "0.2.
|
|
271
|
+
version = "0.2.65"
|
|
272
272
|
dependencies = [
|
|
273
273
|
"compact_str",
|
|
274
274
|
"deepstrike-core",
|
|
@@ -280,7 +280,7 @@ dependencies = [
|
|
|
280
280
|
|
|
281
281
|
[[package]]
|
|
282
282
|
name = "deepstrike-py"
|
|
283
|
-
version = "0.2.
|
|
283
|
+
version = "0.2.65"
|
|
284
284
|
dependencies = [
|
|
285
285
|
"compact_str",
|
|
286
286
|
"deepstrike-core",
|
|
@@ -291,7 +291,7 @@ dependencies = [
|
|
|
291
291
|
|
|
292
292
|
[[package]]
|
|
293
293
|
name = "deepstrike-sdk"
|
|
294
|
-
version = "0.2.
|
|
294
|
+
version = "0.2.65"
|
|
295
295
|
dependencies = [
|
|
296
296
|
"async-stream",
|
|
297
297
|
"async-trait",
|
|
@@ -327,7 +327,7 @@ dependencies = [
|
|
|
327
327
|
|
|
328
328
|
[[package]]
|
|
329
329
|
name = "deepstrike-tokenizer"
|
|
330
|
-
version = "0.2.
|
|
330
|
+
version = "0.2.65"
|
|
331
331
|
dependencies = [
|
|
332
332
|
"pretty_assertions",
|
|
333
333
|
"tiktoken-rs",
|
|
@@ -335,7 +335,7 @@ dependencies = [
|
|
|
335
335
|
|
|
336
336
|
[[package]]
|
|
337
337
|
name = "deepstrike-wasm"
|
|
338
|
-
version = "0.2.
|
|
338
|
+
version = "0.2.65"
|
|
339
339
|
dependencies = [
|
|
340
340
|
"compact_str",
|
|
341
341
|
"deepstrike-core",
|
|
@@ -3,13 +3,13 @@ resolver = "2"
|
|
|
3
3
|
members = ["crates/deepstrike-core", "crates/deepstrike-tokenizer", "crates/deepstrike-py"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.65"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
repository = "https://github.com/kongusen/deepstrike"
|
|
9
9
|
|
|
10
10
|
[workspace.dependencies]
|
|
11
|
-
deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.
|
|
12
|
-
deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.
|
|
11
|
+
deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.65" }
|
|
12
|
+
deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.65" }
|
|
13
13
|
notify = "6"
|
|
14
14
|
serde = { version = "1", features = ["derive"] }
|
|
15
15
|
serde_json = "1"
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
//! `ds-chain-validator` — the P7-S5 chain validator CLI: rules C1–C4 (batch 1), C6/C8
|
|
2
|
+
//! (batch 3, SessionLog plane), C5 (batch 2, checkpoint plane).
|
|
3
|
+
//!
|
|
4
|
+
//! Host-ops tooling: CI gates and incident triage run the same knife. Input is a journal prefix
|
|
5
|
+
//! — a sequence of kernel record blobs — grouped into per-operation chain segments, each judged
|
|
6
|
+
//! independently. Record bytes are passed through untouched: a verdict is about the bytes the
|
|
7
|
+
//! host durably wrote, never about a re-serialization.
|
|
8
|
+
//!
|
|
9
|
+
//! Exit codes (P7 §3.2): `0` every check green (degraded hops and deferred scope do not count
|
|
10
|
+
//! against green), `1` a violation was proven, `2` the evidence was insufficient (nothing
|
|
11
|
+
//! judgeable, or unparseable blobs and no proven violation). `64` is a usage error.
|
|
12
|
+
//!
|
|
13
|
+
//! Journal input forms, per `--journal` path:
|
|
14
|
+
//! - a directory: every `*.json` file inside (name-sorted), each file one record;
|
|
15
|
+
//! - a file holding one JSON object: one record;
|
|
16
|
+
//! - a file holding a JSON array: its elements, one record each;
|
|
17
|
+
//! - anything else: JSON Lines — one record per non-empty line.
|
|
18
|
+
//!
|
|
19
|
+
//! SessionLog input forms (batch 3), per `--session-log` path:
|
|
20
|
+
//! - a directory: every `*.json`/`*.jsonl` file inside (name-sorted), each file one session
|
|
21
|
+
//! stream — events keep the file's append order, and streams never cross-join;
|
|
22
|
+
//! - a file: one stream — a JSON object (one event), a JSON array (one event per element), or
|
|
23
|
+
//! JSON Lines (one event per non-empty line).
|
|
24
|
+
//!
|
|
25
|
+
//! Checkpoint input forms (batch 2), per `--checkpoint` path — same shapes as the journal:
|
|
26
|
+
//! a directory of `*.json` checkpoints, a JSON object (one checkpoint), a JSON array, or JSON
|
|
27
|
+
//! Lines. A golden-fixture wrapper (a JSON object holding a nested `checkpoint` document
|
|
28
|
+
//! beside its ack/restore metadata) is unwrapped automatically. Without this plane C5 is
|
|
29
|
+
//! deferred, not red; `--strict` arms the re-plan replay.
|
|
30
|
+
|
|
31
|
+
use std::path::{Path, PathBuf};
|
|
32
|
+
use std::process::ExitCode;
|
|
33
|
+
|
|
34
|
+
use deepstrike_core::runtime::chain_validator::{
|
|
35
|
+
ValidationReport, Verdict, validate_journal, validate_with_checkpoint,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const USAGE: &str = "Usage: ds-chain-validator [--journal <path>...] [--session-log <path>...] \
|
|
39
|
+
[--checkpoint <path>...] [--strict] [--format human|json]\n\
|
|
40
|
+
\x20 (at least one evidence plane is required)\n\
|
|
41
|
+
\n\
|
|
42
|
+
Validates a kernel journal prefix against P2 §5 rules C1–C5, marking\n\
|
|
43
|
+
degraded evidence per C7. With --session-log, the batch-3 cross-checks\n\
|
|
44
|
+
(C6/C8) join the SessionLog evidence plane against the journal. With\n\
|
|
45
|
+
--checkpoint, the batch-2 rule (C5) anchors each checkpoint against the\n\
|
|
46
|
+
journal: genesis/covered-head/tail digests (C5a) and the launch-token\n\
|
|
47
|
+
ledger (C5b).\n\
|
|
48
|
+
Exit codes: 0 = all green, 1 = violation proven, 2 = evidence insufficient.\n\
|
|
49
|
+
\n\
|
|
50
|
+
--journal <path> record source: directory of *.json records, a JSON\n\
|
|
51
|
+
\x20 object/array file, or a JSONL file (repeatable)\n\
|
|
52
|
+
--session-log <path> session-log source: a directory (each *.json/*.jsonl\n\
|
|
53
|
+
\x20 file is one append-ordered stream) or a single\n\
|
|
54
|
+
\x20 stream file — object/array/JSONL (repeatable)\n\
|
|
55
|
+
--checkpoint <path> checkpoint source: directory of *.json checkpoints,\n\
|
|
56
|
+
\x20 a JSON object/array file, or a JSONL file\n\
|
|
57
|
+
\x20 (repeatable; golden-fixture wrappers holding a\n\
|
|
58
|
+
\x20 nested `checkpoint` are unwrapped). Omit it and\n\
|
|
59
|
+
\x20 C5 is deferred, not red\n\
|
|
60
|
+
--strict with --checkpoint: re-plan the journal prefix from\n\
|
|
61
|
+
\x20 genesis through the covered step and require the\n\
|
|
62
|
+
\x20 re-derived state digest and launch-token ledger to\n\
|
|
63
|
+
\x20 match the checkpoint (costs one full fold)\n\
|
|
64
|
+
--format <mode> human (default) or json";
|
|
65
|
+
|
|
66
|
+
fn main() -> ExitCode {
|
|
67
|
+
let mut journals: Vec<PathBuf> = Vec::new();
|
|
68
|
+
let mut session_logs: Vec<PathBuf> = Vec::new();
|
|
69
|
+
let mut checkpoints: Vec<PathBuf> = Vec::new();
|
|
70
|
+
let mut strict = false;
|
|
71
|
+
let mut format = "human".to_string();
|
|
72
|
+
let mut args = std::env::args().skip(1);
|
|
73
|
+
while let Some(arg) = args.next() {
|
|
74
|
+
match arg.as_str() {
|
|
75
|
+
"--journal" => {
|
|
76
|
+
let Some(path) = args.next() else {
|
|
77
|
+
return usage("--journal requires a path");
|
|
78
|
+
};
|
|
79
|
+
journals.push(PathBuf::from(path));
|
|
80
|
+
}
|
|
81
|
+
"--session-log" => {
|
|
82
|
+
let Some(path) = args.next() else {
|
|
83
|
+
return usage("--session-log requires a path");
|
|
84
|
+
};
|
|
85
|
+
session_logs.push(PathBuf::from(path));
|
|
86
|
+
}
|
|
87
|
+
"--checkpoint" => {
|
|
88
|
+
let Some(path) = args.next() else {
|
|
89
|
+
return usage("--checkpoint requires a path");
|
|
90
|
+
};
|
|
91
|
+
checkpoints.push(PathBuf::from(path));
|
|
92
|
+
}
|
|
93
|
+
"--strict" => strict = true,
|
|
94
|
+
"--format" => {
|
|
95
|
+
let Some(mode) = args.next() else {
|
|
96
|
+
return usage("--format requires human or json");
|
|
97
|
+
};
|
|
98
|
+
if mode != "human" && mode != "json" {
|
|
99
|
+
return usage("--format requires human or json");
|
|
100
|
+
}
|
|
101
|
+
format = mode;
|
|
102
|
+
}
|
|
103
|
+
"--help" | "-h" => {
|
|
104
|
+
println!("{USAGE}");
|
|
105
|
+
return ExitCode::from(0);
|
|
106
|
+
}
|
|
107
|
+
_ => return usage(&format!("unknown argument: {arg}")),
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if journals.is_empty() && session_logs.is_empty() && checkpoints.is_empty() {
|
|
111
|
+
return usage("at least one --journal, --session-log, or --checkpoint path is required");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let mut blobs: Vec<Vec<u8>> = Vec::new();
|
|
115
|
+
for path in &journals {
|
|
116
|
+
match read_journal(path, &mut blobs) {
|
|
117
|
+
Ok(count) => eprintln!("read {count} record blob(s) from {}", path.display()),
|
|
118
|
+
Err(message) => {
|
|
119
|
+
eprintln!("ds-chain-validator: {message}");
|
|
120
|
+
return ExitCode::from(2);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let mut streams: Vec<Vec<Vec<u8>>> = Vec::new();
|
|
126
|
+
for path in &session_logs {
|
|
127
|
+
let streams_before = streams.len();
|
|
128
|
+
match read_session_log(path, &mut streams) {
|
|
129
|
+
Ok(count) => eprintln!(
|
|
130
|
+
"read {count} session event(s) in {} stream(s) from {}",
|
|
131
|
+
streams.len() - streams_before,
|
|
132
|
+
path.display()
|
|
133
|
+
),
|
|
134
|
+
Err(message) => {
|
|
135
|
+
eprintln!("ds-chain-validator: {message}");
|
|
136
|
+
return ExitCode::from(2);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let mut checkpoint_blobs: Vec<Vec<u8>> = Vec::new();
|
|
142
|
+
for path in &checkpoints {
|
|
143
|
+
match read_checkpoint(path, &mut checkpoint_blobs) {
|
|
144
|
+
Ok(count) => eprintln!("read {count} checkpoint blob(s) from {}", path.display()),
|
|
145
|
+
Err(message) => {
|
|
146
|
+
eprintln!("ds-chain-validator: {message}");
|
|
147
|
+
return ExitCode::from(2);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let report = if session_logs.is_empty() && checkpoints.is_empty() {
|
|
153
|
+
validate_journal(&blobs)
|
|
154
|
+
} else {
|
|
155
|
+
validate_with_checkpoint(&blobs, &streams, &checkpoint_blobs, strict)
|
|
156
|
+
};
|
|
157
|
+
match format.as_str() {
|
|
158
|
+
"json" => match serde_json::to_string_pretty(&report) {
|
|
159
|
+
Ok(json) => println!("{json}"),
|
|
160
|
+
Err(error) => {
|
|
161
|
+
eprintln!("ds-chain-validator: could not serialize the report: {error}");
|
|
162
|
+
return ExitCode::from(2);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
_ => print_human(&report),
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let code = report.exit_code();
|
|
169
|
+
ExitCode::from(u8::try_from(code).unwrap_or(2))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fn usage(message: &str) -> ExitCode {
|
|
173
|
+
eprintln!("ds-chain-validator: {message}\n\n{USAGE}");
|
|
174
|
+
ExitCode::from(64)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// Collect record blobs from one journal source. Byte-exactness is the whole game: directory
|
|
178
|
+
/// entries and whole-file objects pass through raw; array elements and JSONL lines are handed
|
|
179
|
+
/// over exactly as found (array elements are re-emitted compactly — safe because the record's
|
|
180
|
+
/// self-digest is computed from its decoded fields, not its input byte layout).
|
|
181
|
+
fn read_journal(path: &Path, blobs: &mut Vec<Vec<u8>>) -> Result<usize, String> {
|
|
182
|
+
let before = blobs.len();
|
|
183
|
+
if path.is_dir() {
|
|
184
|
+
let mut entries: Vec<PathBuf> = std::fs::read_dir(path)
|
|
185
|
+
.map_err(|error| format!("cannot read directory {}: {error}", path.display()))?
|
|
186
|
+
.filter_map(|entry| entry.ok().map(|entry| entry.path()))
|
|
187
|
+
.filter(|entry| {
|
|
188
|
+
entry
|
|
189
|
+
.extension()
|
|
190
|
+
.is_some_and(|extension| extension == "json")
|
|
191
|
+
})
|
|
192
|
+
.collect();
|
|
193
|
+
entries.sort();
|
|
194
|
+
for entry in entries {
|
|
195
|
+
let bytes = std::fs::read(&entry)
|
|
196
|
+
.map_err(|error| format!("cannot read {}: {error}", entry.display()))?;
|
|
197
|
+
blobs.push(bytes);
|
|
198
|
+
}
|
|
199
|
+
return Ok(blobs.len() - before);
|
|
200
|
+
}
|
|
201
|
+
let bytes =
|
|
202
|
+
std::fs::read(path).map_err(|error| format!("cannot read {}: {error}", path.display()))?;
|
|
203
|
+
split_blob_file(&bytes, blobs);
|
|
204
|
+
Ok(blobs.len() - before)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/// Collect SessionLog event streams from one session-log source. Unlike the journal plane,
|
|
208
|
+
/// append order within one file is meaningful, so **each file becomes one stream** — for a
|
|
209
|
+
/// directory, every `*.json`/`*.jsonl` file inside (name-sorted); for a single path, the file
|
|
210
|
+
/// itself. Event blobs within a stream preserve the file's order.
|
|
211
|
+
fn read_session_log(path: &Path, streams: &mut Vec<Vec<Vec<u8>>>) -> Result<usize, String> {
|
|
212
|
+
let mut added = 0usize;
|
|
213
|
+
if path.is_dir() {
|
|
214
|
+
let mut entries: Vec<PathBuf> = std::fs::read_dir(path)
|
|
215
|
+
.map_err(|error| format!("cannot read directory {}: {error}", path.display()))?
|
|
216
|
+
.filter_map(|entry| entry.ok().map(|entry| entry.path()))
|
|
217
|
+
.filter(|entry| {
|
|
218
|
+
entry.extension().is_some_and(|extension| {
|
|
219
|
+
extension == "json" || extension == "jsonl"
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
.collect();
|
|
223
|
+
entries.sort();
|
|
224
|
+
for entry in entries {
|
|
225
|
+
let bytes = std::fs::read(&entry)
|
|
226
|
+
.map_err(|error| format!("cannot read {}: {error}", entry.display()))?;
|
|
227
|
+
let mut stream = Vec::new();
|
|
228
|
+
split_blob_file(&bytes, &mut stream);
|
|
229
|
+
added += stream.len();
|
|
230
|
+
streams.push(stream);
|
|
231
|
+
}
|
|
232
|
+
return Ok(added);
|
|
233
|
+
}
|
|
234
|
+
let bytes =
|
|
235
|
+
std::fs::read(path).map_err(|error| format!("cannot read {}: {error}", path.display()))?;
|
|
236
|
+
let mut stream = Vec::new();
|
|
237
|
+
split_blob_file(&bytes, &mut stream);
|
|
238
|
+
added += stream.len();
|
|
239
|
+
streams.push(stream);
|
|
240
|
+
Ok(added)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/// Collect checkpoint blobs from one checkpoint-plane source — the same shapes the journal
|
|
244
|
+
/// accepts: a directory of `*.json` files (name-sorted), a whole-file JSON object, a JSON
|
|
245
|
+
/// array (one checkpoint per element), or JSON Lines. Bytes pass through untouched, with one
|
|
246
|
+
/// accommodation for the published artifact shape: a blob that parses as a JSON object
|
|
247
|
+
/// carrying a nested `checkpoint` object (the golden-fixture wrapper, which also holds
|
|
248
|
+
/// ack/restore metadata) contributes that nested document instead — re-serialized compactly,
|
|
249
|
+
/// digest-safe because a checkpoint's self-digest is computed from its decoded fields, not
|
|
250
|
+
/// its input byte layout. Every verdict about the bytes belongs to the validator's decoder.
|
|
251
|
+
fn read_checkpoint(path: &Path, blobs: &mut Vec<Vec<u8>>) -> Result<usize, String> {
|
|
252
|
+
let before = blobs.len();
|
|
253
|
+
read_journal(path, blobs)?;
|
|
254
|
+
for blob in &mut blobs[before..] {
|
|
255
|
+
if let Ok(serde_json::Value::Object(map)) =
|
|
256
|
+
serde_json::from_slice::<serde_json::Value>(blob)
|
|
257
|
+
&& let Some(nested) = map.get("checkpoint")
|
|
258
|
+
&& nested.is_object()
|
|
259
|
+
{
|
|
260
|
+
*blob = serde_json::to_vec(nested).unwrap_or_default();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
Ok(blobs.len() - before)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/// Split one file's bytes into blobs: a JSON array yields one blob per element, a single JSON
|
|
267
|
+
/// value yields one blob, anything else parses as JSON Lines. Array elements are re-emitted
|
|
268
|
+
/// compactly — safe for journal records because the record's self-digest is computed from its
|
|
269
|
+
/// decoded fields, not its input byte layout, and safe for SessionLog events because the
|
|
270
|
+
/// session plane is opaque JSON throughout.
|
|
271
|
+
fn split_blob_file(bytes: &[u8], blobs: &mut Vec<Vec<u8>>) {
|
|
272
|
+
match serde_json::from_slice::<serde_json::Value>(bytes) {
|
|
273
|
+
Ok(serde_json::Value::Array(records)) => {
|
|
274
|
+
for record in records {
|
|
275
|
+
blobs.push(serde_json::to_vec(&record).unwrap_or_default());
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
Ok(_) => blobs.push(bytes.to_vec()),
|
|
279
|
+
Err(_) => {
|
|
280
|
+
for line in bytes.split(|byte| *byte == b'\n') {
|
|
281
|
+
let line = trim_ascii(line);
|
|
282
|
+
if !line.is_empty() {
|
|
283
|
+
blobs.push(line.to_vec());
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
fn trim_ascii(bytes: &[u8]) -> &[u8] {
|
|
291
|
+
let start = bytes
|
|
292
|
+
.iter()
|
|
293
|
+
.position(|byte| !byte.is_ascii_whitespace())
|
|
294
|
+
.unwrap_or(bytes.len());
|
|
295
|
+
let end = bytes
|
|
296
|
+
.iter()
|
|
297
|
+
.rposition(|byte| !byte.is_ascii_whitespace())
|
|
298
|
+
.map_or(start, |position| position + 1);
|
|
299
|
+
&bytes[start..end]
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
fn print_human(report: &ValidationReport) {
|
|
303
|
+
for segment in &report.segments {
|
|
304
|
+
println!("segment {} ({} hop(s))", segment.operation_id, segment.hops);
|
|
305
|
+
for rule in &segment.rules {
|
|
306
|
+
let label = match rule.verdict {
|
|
307
|
+
Verdict::Pass => "pass",
|
|
308
|
+
Verdict::Fail => "FAIL",
|
|
309
|
+
Verdict::Degraded => "degraded",
|
|
310
|
+
};
|
|
311
|
+
println!(" {} {label}: {}", rule.rule, rule.detail);
|
|
312
|
+
}
|
|
313
|
+
for hop in &segment.degraded_hops {
|
|
314
|
+
println!(
|
|
315
|
+
" degraded hop #{} (step {}): {}",
|
|
316
|
+
hop.ordinal,
|
|
317
|
+
hop.step_seq.map_or("?".to_string(), |seq| seq.to_string()),
|
|
318
|
+
hop.reason,
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if report.unparseable_records > 0 {
|
|
323
|
+
println!(
|
|
324
|
+
"unparseable record blob(s): {} (evidence insufficient, not a violation)",
|
|
325
|
+
report.unparseable_records
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
if let Some(events) = report.session_events {
|
|
329
|
+
println!("session-log plane: {events} parseable event(s)");
|
|
330
|
+
}
|
|
331
|
+
if report.unparseable_events > 0 {
|
|
332
|
+
println!(
|
|
333
|
+
"unparseable session event blob(s): {} (evidence insufficient, not a violation)",
|
|
334
|
+
report.unparseable_events
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
if let Some(checkpoints) = report.checkpoints {
|
|
338
|
+
println!("checkpoint plane: {checkpoints} parseable checkpoint(s)");
|
|
339
|
+
}
|
|
340
|
+
if report.unparseable_checkpoints > 0 {
|
|
341
|
+
println!(
|
|
342
|
+
"unparseable checkpoint blob(s): {} (evidence insufficient, not a violation)",
|
|
343
|
+
report.unparseable_checkpoints
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
for rule in &report.cross_checks {
|
|
347
|
+
let label = match rule.verdict {
|
|
348
|
+
Verdict::Pass => "pass",
|
|
349
|
+
Verdict::Fail => "FAIL",
|
|
350
|
+
Verdict::Degraded => "degraded",
|
|
351
|
+
};
|
|
352
|
+
println!("cross-check {} {label}: {}", rule.rule, rule.detail);
|
|
353
|
+
}
|
|
354
|
+
for rule in &report.checkpoint_checks {
|
|
355
|
+
let label = match rule.verdict {
|
|
356
|
+
Verdict::Pass => "pass",
|
|
357
|
+
Verdict::Fail => "FAIL",
|
|
358
|
+
Verdict::Degraded => "degraded",
|
|
359
|
+
};
|
|
360
|
+
println!("checkpoint-check {} {label}: {}", rule.rule, rule.detail);
|
|
361
|
+
}
|
|
362
|
+
for deferred in &report.deferred {
|
|
363
|
+
println!("deferred: {deferred}");
|
|
364
|
+
}
|
|
365
|
+
let segments = report.segments.len();
|
|
366
|
+
let verdict = match report.exit_code() {
|
|
367
|
+
0 => "all green",
|
|
368
|
+
1 => "VIOLATION",
|
|
369
|
+
_ => "evidence insufficient",
|
|
370
|
+
};
|
|
371
|
+
println!(
|
|
372
|
+
"summary: {segments} segment(s), exit {} ({verdict})",
|
|
373
|
+
report.exit_code()
|
|
374
|
+
);
|
|
375
|
+
}
|