cc-transcript 14.45.10__tar.gz → 14.45.12__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.
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/PKG-INFO +1 -1
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/pyproject.toml +1 -1
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot.rs +194 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_prepared_disk.rs +214 -7
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_prepared_service.rs +28 -8
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/Cargo.lock +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/Cargo.toml +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/LICENSE +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/README.md +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/__init__.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/__init__.pyi +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/_native.pyi +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/activity.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/activity_probe.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/builders.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/codex.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/command.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/context.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/corrections.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/cost.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/decision_store.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/decisions.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/discovery.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/disktruth.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/evidence.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/extract/__init__.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/extract/correct.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/facts.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/filterspec.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/heartbeats.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/ids.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/judge/__init__.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/judge/llm.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/judge/similar.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/judge/verdicts.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/ledger.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/literals.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/__init__.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/candidates.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/confidence.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/engine.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/formats.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/sampling.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/signals.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/sourcekind.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/spec.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/mining/store.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/models.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/nlp.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/notifications.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/parser.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/py.typed +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/query.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/render.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/__init__.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/buckets.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/engine.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/lexicon.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/sentiment/scorespec.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/snapshot_schema/config.schema.json +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/snapshot_schema/context.schema.json +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/snapshot_schema/request.schema.json +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/snapshot_schema/response.schema.json +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/snapshot_schema/tool_registry.schema.json +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/snapshots.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/synthetic.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/tools.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/cc_transcript/watch.py +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/Cargo.toml +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/blame.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/corpus.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/corrections.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/digest.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/facts.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/grep.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/list.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/mod.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/show.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/slice.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/stats.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/commands/watch.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/lib.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/output.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/target.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/cli/src/timearg.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/Cargo.toml +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/benches/parse.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/benches/render.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/benches/toolcall.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/build.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/activity.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/actor.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/blame.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/buckets.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/discovery.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/lower.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/mod.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/parse.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/probe.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/protocol.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/codex/types.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/command.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/context.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/corrections.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/cost.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/discovery.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/facts.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/feedback.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/filter.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/gateway.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/ids.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/judge.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/lib.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/literals/command.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/literals/corrections.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/literals/feedback.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/literals/mining.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/literals/mod.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/literals/protocol.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/notifications.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/parse.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/protocol.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/pystr.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/query.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/render.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/rng.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_checkpoint.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_grep.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_grep_stream.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_grep_stream_tests.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_index.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_projection.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_regressions.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/scan_stream.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/schema.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_activity.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_codec.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_codex_append.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_labels.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_ledger.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_ledger_tests.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_memory.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_owned.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_prepared.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_projection.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_regressions.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_root_warm.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_text.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/sqlite.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/toolcall.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/types.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/value.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/watch.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/tests/sonic_arena_model.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/tests/std_allocation_model.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/Cargo.toml +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/build.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/actor_bridge.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/bin/stub_gen.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/codex.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/command.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/context.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/corrections.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/discovery.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/feedback.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/judge.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/lexicon.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/lib.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/mining.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/nlp.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/python.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/render.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/score.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/snapshot_decode.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/snapshots.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/sqlite.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/toolcall.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/attachment.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/blocks.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/command.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/convert.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/dunder.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/events.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/meta.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/mod.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/print.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/store.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/system.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/toolcall.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/toolresult.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/views/transcript.rs +0 -0
- {cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/py/src/watch.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cc-transcript"
|
|
3
|
-
version = "14.45.
|
|
3
|
+
version = "14.45.12" # informational — releases stamp the version from the git tag
|
|
4
4
|
description = "Grep every Claude Code session you've ever run."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "PolyForm-Noncommercial-1.0.0"
|
|
@@ -14565,6 +14565,74 @@ mod tests {
|
|
|
14565
14565
|
assert!(validate().unwrap_err().status == Status::PermissionDenied);
|
|
14566
14566
|
}
|
|
14567
14567
|
|
|
14568
|
+
#[test]
|
|
14569
|
+
fn source_validation_skips_its_parent_hold_once_cancelled_or_past_its_deadline() {
|
|
14570
|
+
let source = Source::new(&format!("{}\n", user("root")));
|
|
14571
|
+
let sources = canonical_members(&source.directory.join("members"), &["a", "b"], "");
|
|
14572
|
+
let store = store();
|
|
14573
|
+
let owner = context("a");
|
|
14574
|
+
let validate = |cancel: &Cancellation, deadline: u64| {
|
|
14575
|
+
let before = store.source_resolutions.load(Ordering::Relaxed);
|
|
14576
|
+
let validated = store
|
|
14577
|
+
.validate_source_stamps(&sources, &owner, cancel, deadline)
|
|
14578
|
+
.map_err(|error| error.status);
|
|
14579
|
+
(
|
|
14580
|
+
validated,
|
|
14581
|
+
store.source_resolutions.load(Ordering::Relaxed) - before,
|
|
14582
|
+
)
|
|
14583
|
+
};
|
|
14584
|
+
assert_eq!(
|
|
14585
|
+
validate(&Cancellation::default(), now_ms() + 30_000),
|
|
14586
|
+
(Ok(true), 2)
|
|
14587
|
+
);
|
|
14588
|
+
for (cancels, status) in [(true, Status::Cancelled), (false, Status::Deadline)] {
|
|
14589
|
+
let cancel = Cancellation::default();
|
|
14590
|
+
let deadline = now_ms() + 1_000;
|
|
14591
|
+
*store.resolve_hook.lock().unwrap() = Some(Arc::new({
|
|
14592
|
+
let (cancel, last) = (cancel.clone(), sources[1].path.clone());
|
|
14593
|
+
move |path: &Path| {
|
|
14594
|
+
if path != last {
|
|
14595
|
+
return;
|
|
14596
|
+
}
|
|
14597
|
+
if cancels {
|
|
14598
|
+
cancel.cancel();
|
|
14599
|
+
} else {
|
|
14600
|
+
while now_ms() <= deadline {
|
|
14601
|
+
std::thread::sleep(std::time::Duration::from_millis(5));
|
|
14602
|
+
}
|
|
14603
|
+
}
|
|
14604
|
+
}
|
|
14605
|
+
}));
|
|
14606
|
+
assert_eq!(validate(&cancel, deadline), (Err(status), 1));
|
|
14607
|
+
}
|
|
14608
|
+
}
|
|
14609
|
+
|
|
14610
|
+
#[test]
|
|
14611
|
+
fn empty_membership_validation_reports_cancellation_and_an_expired_deadline() {
|
|
14612
|
+
let store = store();
|
|
14613
|
+
let owner = context("a");
|
|
14614
|
+
let cancelled = Cancellation::default();
|
|
14615
|
+
cancelled.cancel();
|
|
14616
|
+
for (cancel, deadline, status) in [
|
|
14617
|
+
(Cancellation::default(), now_ms(), Status::Deadline),
|
|
14618
|
+
(cancelled, now_ms() + 30_000, Status::Cancelled),
|
|
14619
|
+
] {
|
|
14620
|
+
let before = store.source_resolutions.load(Ordering::Relaxed);
|
|
14621
|
+
assert_eq!(
|
|
14622
|
+
(
|
|
14623
|
+
store
|
|
14624
|
+
.validate_source_stamps(&[], &owner, &cancel, deadline)
|
|
14625
|
+
.map_err(|error| error.status),
|
|
14626
|
+
store
|
|
14627
|
+
.validate_sidechain_dirs(&[], &owner, &cancel, deadline)
|
|
14628
|
+
.map_err(|error| error.status),
|
|
14629
|
+
),
|
|
14630
|
+
(Err(status), Err(status))
|
|
14631
|
+
);
|
|
14632
|
+
assert_eq!(store.source_resolutions.load(Ordering::Relaxed), before);
|
|
14633
|
+
}
|
|
14634
|
+
}
|
|
14635
|
+
|
|
14568
14636
|
#[test]
|
|
14569
14637
|
fn early_positive_query_rejects_a_parent_retargeted_during_its_page() {
|
|
14570
14638
|
let source = Source::new(&format!("{}\n", user("root")));
|
|
@@ -15423,6 +15491,58 @@ mod tests {
|
|
|
15423
15491
|
store.assert_conserved();
|
|
15424
15492
|
}
|
|
15425
15493
|
|
|
15494
|
+
#[test]
|
|
15495
|
+
fn a_stopped_fact_read_keeps_the_entry_for_the_next_member_reader() {
|
|
15496
|
+
for (expected, cancels) in [("cancelled", true), ("deadline", false)] {
|
|
15497
|
+
let EvictedMembers {
|
|
15498
|
+
source,
|
|
15499
|
+
members,
|
|
15500
|
+
store,
|
|
15501
|
+
owner,
|
|
15502
|
+
indexed,
|
|
15503
|
+
..
|
|
15504
|
+
} = evicted_members(&["thread-a"]);
|
|
15505
|
+
let key = fact_entry_key(&members[0], &owner);
|
|
15506
|
+
let cancellation = Cancellation::default();
|
|
15507
|
+
let stop = cancellation.clone();
|
|
15508
|
+
let deadline = now_ms() + if cancels { 30_000 } else { 1_500 };
|
|
15509
|
+
store.prepared_disk.set_read_hook(Some(Box::new(move || {
|
|
15510
|
+
if cancels {
|
|
15511
|
+
stop.cancel();
|
|
15512
|
+
} else {
|
|
15513
|
+
while now_ms() < deadline {
|
|
15514
|
+
std::thread::sleep(Duration::from_millis(5));
|
|
15515
|
+
}
|
|
15516
|
+
}
|
|
15517
|
+
})));
|
|
15518
|
+
let stopped = store.request(
|
|
15519
|
+
&warm_request(&source, &["thread-a"], deadline),
|
|
15520
|
+
&owner,
|
|
15521
|
+
&cancellation,
|
|
15522
|
+
);
|
|
15523
|
+
store.prepared_disk.set_read_hook(None);
|
|
15524
|
+
assert_eq!(stopped["status"].as_str(), Some(expected), "{stopped:?}");
|
|
15525
|
+
assert_eq!(cache_reads(&stopped), (Some(0), Some(0), Some(0)));
|
|
15526
|
+
assert_eq!(store.fact_lookups.load(Ordering::Relaxed), 1);
|
|
15527
|
+
assert!(store.prepared_disk.has_entry(&key).unwrap());
|
|
15528
|
+
assert!(!store.lock_state().fact_read_in_flight);
|
|
15529
|
+
store.assert_conserved();
|
|
15530
|
+
let reused = store.request(
|
|
15531
|
+
&warm_request(&source, &["thread-a"], now_ms() + 30_000),
|
|
15532
|
+
&owner,
|
|
15533
|
+
&Cancellation::default(),
|
|
15534
|
+
);
|
|
15535
|
+
assert_eq!(reused["status"].as_str(), Some("ok"), "{reused:?}");
|
|
15536
|
+
assert_eq!(reused["data"]["complete"].as_bool(), Some(true));
|
|
15537
|
+
assert_eq!(cache_reads(&reused), (Some(1), Some(indexed), Some(0)));
|
|
15538
|
+
assert_eq!(store.fact_lookups.load(Ordering::Relaxed), 2);
|
|
15539
|
+
assert!(resident_member_facts(&store, &members)
|
|
15540
|
+
.iter()
|
|
15541
|
+
.all(Option::is_some));
|
|
15542
|
+
store.assert_conserved();
|
|
15543
|
+
}
|
|
15544
|
+
}
|
|
15545
|
+
|
|
15426
15546
|
fn user_text(id: &str, text: &str) -> String {
|
|
15427
15547
|
format!(
|
|
15428
15548
|
r#"{{"type":"user","uuid":"{id}","sessionId":"s","timestamp":"2026-01-02T03:04:05Z","message":{{"content":"{text}"}}}}"#
|
|
@@ -16447,6 +16567,54 @@ mod tests {
|
|
|
16447
16567
|
store.assert_conserved();
|
|
16448
16568
|
}
|
|
16449
16569
|
|
|
16570
|
+
#[test]
|
|
16571
|
+
fn a_cancelled_root_fact_read_keeps_the_entry_and_builds_nothing() {
|
|
16572
|
+
let source = Source::new(&format!("{}\n{}\n", user("root"), user("child")));
|
|
16573
|
+
let store = fact_budget_store(16 * 1024 * 1024);
|
|
16574
|
+
let owner = context("a");
|
|
16575
|
+
let bounds = limits(&acquire(&source.path)).unwrap();
|
|
16576
|
+
let root = pinned_root(&store, &source, &owner);
|
|
16577
|
+
assert_eq!(root_facts_read(&store, &root, &owner, &bounds).1, 0);
|
|
16578
|
+
assert_eq!(
|
|
16579
|
+
store
|
|
16580
|
+
.lock_state()
|
|
16581
|
+
.remove_identity_facts(root.stamp.identity),
|
|
16582
|
+
1
|
|
16583
|
+
);
|
|
16584
|
+
let key = fact_entry_key(&source.path, &owner);
|
|
16585
|
+
let builds = store.fact_builds.load(Ordering::Relaxed);
|
|
16586
|
+
let cancellation = Cancellation::default();
|
|
16587
|
+
let stop = cancellation.clone();
|
|
16588
|
+
store
|
|
16589
|
+
.prepared_disk
|
|
16590
|
+
.set_read_hook(Some(Box::new(move || stop.cancel())));
|
|
16591
|
+
let mut usage = [0u64; 20];
|
|
16592
|
+
let stopped = store
|
|
16593
|
+
.prepared_root_facts(
|
|
16594
|
+
&root,
|
|
16595
|
+
&json!({"id":"native","version":"1"}),
|
|
16596
|
+
&owner,
|
|
16597
|
+
&bounds,
|
|
16598
|
+
PreparedCacheReads::Unmetered,
|
|
16599
|
+
&cancellation,
|
|
16600
|
+
&mut usage,
|
|
16601
|
+
FactsNeed::Index,
|
|
16602
|
+
)
|
|
16603
|
+
.err()
|
|
16604
|
+
.map(|error| error.status);
|
|
16605
|
+
store.prepared_disk.set_read_hook(None);
|
|
16606
|
+
assert_eq!(stopped, Some(Status::Cancelled));
|
|
16607
|
+
assert_eq!((usage[18], usage[19]), (0, 0));
|
|
16608
|
+
assert_eq!(store.fact_lookups.load(Ordering::Relaxed), 1);
|
|
16609
|
+
assert_eq!(store.fact_builds.load(Ordering::Relaxed), builds);
|
|
16610
|
+
assert!(store.prepared_disk.has_entry(&key).unwrap());
|
|
16611
|
+
assert!(!store.lock_state().fact_read_in_flight);
|
|
16612
|
+
store.assert_conserved();
|
|
16613
|
+
assert_eq!(root_facts_read(&store, &root, &owner, &bounds).1, 1);
|
|
16614
|
+
assert_eq!(store.fact_builds.load(Ordering::Relaxed), builds);
|
|
16615
|
+
store.assert_conserved();
|
|
16616
|
+
}
|
|
16617
|
+
|
|
16450
16618
|
#[test]
|
|
16451
16619
|
fn waiting_reader_with_a_different_binding_never_reuses_the_published_facts() {
|
|
16452
16620
|
let source = Source::new(&format!("{}\n{}\n", user("root"), user("child")));
|
|
@@ -17846,6 +18014,32 @@ mod tests {
|
|
|
17846
18014
|
);
|
|
17847
18015
|
}
|
|
17848
18016
|
|
|
18017
|
+
#[test]
|
|
18018
|
+
fn registered_warmer_cancelled_on_its_last_step_fails_its_final_hold() {
|
|
18019
|
+
let (source, store, owner, mut request) = registered_warming(300);
|
|
18020
|
+
registered_pages(&store, &owner, &request);
|
|
18021
|
+
std::fs::OpenOptions::new()
|
|
18022
|
+
.append(true)
|
|
18023
|
+
.open(source.directory.join("thread-0255.jsonl"))
|
|
18024
|
+
.unwrap()
|
|
18025
|
+
.write_all(format!("{}\n", user("appended")).as_bytes())
|
|
18026
|
+
.unwrap();
|
|
18027
|
+
let cancel = Cancellation::default();
|
|
18028
|
+
*store.built_facts_hook.lock().unwrap() = Some(Arc::new({
|
|
18029
|
+
let cancel = cancel.clone();
|
|
18030
|
+
move |_: &Arc<crate::snapshot_prepared::PreparedFacts>| cancel.cancel()
|
|
18031
|
+
}));
|
|
18032
|
+
let builds = store.fact_builds.load(Ordering::Relaxed);
|
|
18033
|
+
request.insert("deadline_unix_ms", json!(now_ms() + 120_000));
|
|
18034
|
+
let cancelled = store.request(&request, &owner, &cancel);
|
|
18035
|
+
assert_eq!(
|
|
18036
|
+
cancelled["status"].as_str(),
|
|
18037
|
+
Some("cancelled"),
|
|
18038
|
+
"{cancelled:?}"
|
|
18039
|
+
);
|
|
18040
|
+
assert_eq!(store.fact_builds.load(Ordering::Relaxed) - builds, 1);
|
|
18041
|
+
}
|
|
18042
|
+
|
|
17849
18043
|
#[test]
|
|
17850
18044
|
fn disk_facts_complete_queries_when_memory_fact_budget_is_smaller() {
|
|
17851
18045
|
let source = Source::new(&format!("{}\n", user("root")));
|
{cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_prepared_disk.rs
RENAMED
|
@@ -13,7 +13,9 @@ use std::sync::{LazyLock, Mutex};
|
|
|
13
13
|
use sha2::{Digest, Sha256};
|
|
14
14
|
use sonic_rs::{json, JsonValueTrait, Value};
|
|
15
15
|
|
|
16
|
-
use crate::snapshot::{
|
|
16
|
+
use crate::snapshot::{
|
|
17
|
+
Cancellation, SnapshotError, SourceIdentity, SourceStamp, Status, PARSER_VERSION,
|
|
18
|
+
};
|
|
17
19
|
#[cfg(test)]
|
|
18
20
|
use crate::snapshot_ledger::Reserved;
|
|
19
21
|
use crate::snapshot_ledger::{Table, Work};
|
|
@@ -45,6 +47,7 @@ const ROOM_SWEEP_NAMES: usize = 256;
|
|
|
45
47
|
const ENTRY_NAME_BYTES: usize = 166;
|
|
46
48
|
const LEGACY_ENTRY_NAME_BYTES: [usize; 2] = [150, 118];
|
|
47
49
|
const MAX_STRANDED_OWNED: usize = 64;
|
|
50
|
+
const READ_CHUNK_BYTES: usize = 64 * 1024;
|
|
48
51
|
|
|
49
52
|
static ACTIVE_OWNERS: LazyLock<Mutex<HashSet<String>>> =
|
|
50
53
|
LazyLock::new(|| Mutex::new(HashSet::new()));
|
|
@@ -164,6 +167,24 @@ fn probed_read_bytes(stored: usize) -> usize {
|
|
|
164
167
|
stored.saturating_add(1)
|
|
165
168
|
}
|
|
166
169
|
|
|
170
|
+
fn read_chunks(
|
|
171
|
+
file: &std::fs::File,
|
|
172
|
+
wanted: usize,
|
|
173
|
+
bytes: &mut Vec<u8>,
|
|
174
|
+
mut checkpoint: impl FnMut() -> Result<(), SnapshotError>,
|
|
175
|
+
) -> Result<(), SnapshotError> {
|
|
176
|
+
let mut unread = file.take(wanted as u64);
|
|
177
|
+
while (&mut unread)
|
|
178
|
+
.take(READ_CHUNK_BYTES as u64)
|
|
179
|
+
.read_to_end(bytes)
|
|
180
|
+
.map_err(disk_error)?
|
|
181
|
+
== READ_CHUNK_BYTES
|
|
182
|
+
{
|
|
183
|
+
checkpoint()?;
|
|
184
|
+
}
|
|
185
|
+
Ok(())
|
|
186
|
+
}
|
|
187
|
+
|
|
167
188
|
fn openat_file(dir_fd: libc::c_int, name: &CStr, flags: libc::c_int) -> io::Result<std::fs::File> {
|
|
168
189
|
let fd = unsafe {
|
|
169
190
|
libc::openat(
|
|
@@ -1591,9 +1612,13 @@ impl PreparedDiskCache {
|
|
|
1591
1612
|
read: &mut DiskRead,
|
|
1592
1613
|
need: FactsNeed,
|
|
1593
1614
|
admitted: usize,
|
|
1615
|
+
cancel: &Cancellation,
|
|
1616
|
+
deadline_unix_ms: u64,
|
|
1594
1617
|
) -> Result<DiskLookup, SnapshotError> {
|
|
1618
|
+
cancel.check(deadline_unix_ms)?;
|
|
1595
1619
|
self.check_dir()?;
|
|
1596
1620
|
let mut state = self.state.lock().expect("prepared facts disk state");
|
|
1621
|
+
cancel.check(deadline_unix_ms)?;
|
|
1597
1622
|
let Some(entry) = state.entries.get(&key.name) else {
|
|
1598
1623
|
return Ok(DiskLookup::Miss);
|
|
1599
1624
|
};
|
|
@@ -1623,18 +1648,23 @@ impl PreparedDiskCache {
|
|
|
1623
1648
|
{
|
|
1624
1649
|
return Err(incomplete("prepared facts cache entry changed"));
|
|
1625
1650
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1651
|
+
let checkpoint = || {
|
|
1652
|
+
#[cfg(test)]
|
|
1653
|
+
run_read_hook(&self.owner_name);
|
|
1654
|
+
cancel.check(deadline_unix_ms)
|
|
1655
|
+
};
|
|
1656
|
+
checkpoint()?;
|
|
1628
1657
|
let mut bytes = Vec::with_capacity(wanted.min(expected));
|
|
1629
1658
|
read.operations += 1;
|
|
1630
|
-
let finished = (&file
|
|
1659
|
+
let finished = read_chunks(&file, wanted, &mut bytes, checkpoint);
|
|
1631
1660
|
read.bytes += bytes.len() as u64;
|
|
1632
|
-
finished
|
|
1661
|
+
finished?;
|
|
1633
1662
|
if need == FactsNeed::Index
|
|
1634
1663
|
&& file.metadata().map_err(disk_error)?.len() != expected as u64
|
|
1635
1664
|
{
|
|
1636
1665
|
return Err(incomplete("prepared facts cache entry changed"));
|
|
1637
1666
|
}
|
|
1667
|
+
cancel.check(deadline_unix_ms)?;
|
|
1638
1668
|
let index_end = HEADER_BYTES + index_bytes;
|
|
1639
1669
|
let verified = bytes
|
|
1640
1670
|
.get(..HEADER_BYTES)
|
|
@@ -1668,11 +1698,13 @@ impl PreparedDiskCache {
|
|
|
1668
1698
|
if !verified {
|
|
1669
1699
|
return Err(incomplete("prepared facts cache integrity check failed"));
|
|
1670
1700
|
}
|
|
1701
|
+
cancel.check(deadline_unix_ms)?;
|
|
1671
1702
|
let index: DecodedIndexSection = sonic_rs::from_slice(&bytes[HEADER_BYTES..index_end])
|
|
1672
1703
|
.map_err(|_| incomplete("prepared facts cache payload invalid"))?;
|
|
1673
1704
|
let overrides = match served {
|
|
1674
1705
|
FactsNeed::Index => OverrideFacts::Unloaded,
|
|
1675
1706
|
FactsNeed::Full => {
|
|
1707
|
+
cancel.check(deadline_unix_ms)?;
|
|
1676
1708
|
let section: Option<Vec<OverrideEvent>> =
|
|
1677
1709
|
sonic_rs::from_slice(&bytes[index_end..])
|
|
1678
1710
|
.map_err(|_| incomplete("prepared facts cache payload invalid"))?;
|
|
@@ -1680,6 +1712,7 @@ impl PreparedDiskCache {
|
|
|
1680
1712
|
}
|
|
1681
1713
|
};
|
|
1682
1714
|
let facts = PreparedFacts::from_sections(index, overrides);
|
|
1715
|
+
cancel.check(deadline_unix_ms)?;
|
|
1683
1716
|
if inherited {
|
|
1684
1717
|
if facts.accounted_bytes() > accounted_bound {
|
|
1685
1718
|
return Err(incomplete("prepared facts cache accounting exceeded"));
|
|
@@ -1714,6 +1747,9 @@ impl PreparedDiskCache {
|
|
|
1714
1747
|
DiskLookup::IndexOnly(facts)
|
|
1715
1748
|
})
|
|
1716
1749
|
}
|
|
1750
|
+
Err(error) if matches!(error.status, Status::Cancelled | Status::Deadline) => {
|
|
1751
|
+
Err(error)
|
|
1752
|
+
}
|
|
1717
1753
|
Err(_) => {
|
|
1718
1754
|
self.retire(&mut state, key.name)?;
|
|
1719
1755
|
Ok(if inherited {
|
|
@@ -2202,7 +2238,14 @@ mod tests {
|
|
|
2202
2238
|
read: &mut DiskRead,
|
|
2203
2239
|
need: FactsNeed,
|
|
2204
2240
|
) -> Result<DiskLookup, SnapshotError> {
|
|
2205
|
-
cache.lookup(
|
|
2241
|
+
cache.lookup(
|
|
2242
|
+
key,
|
|
2243
|
+
read,
|
|
2244
|
+
need,
|
|
2245
|
+
cache.decoded_bytes(key, need).unwrap_or(0),
|
|
2246
|
+
&Cancellation::default(),
|
|
2247
|
+
u64::MAX,
|
|
2248
|
+
)
|
|
2206
2249
|
}
|
|
2207
2250
|
|
|
2208
2251
|
fn cache(cap: usize) -> PreparedDiskCache {
|
|
@@ -2956,6 +2999,163 @@ mod tests {
|
|
|
2956
2999
|
assert_eq!(cache.stats().entries, 0);
|
|
2957
3000
|
}
|
|
2958
3001
|
|
|
3002
|
+
fn chunked_facts() -> PreparedFacts {
|
|
3003
|
+
let mut facts = PreparedFacts {
|
|
3004
|
+
inputs: json!({
|
|
3005
|
+
"calls": [["Read", ["/repo/file.rs"]]],
|
|
3006
|
+
"commands": [],
|
|
3007
|
+
"edited_files": [],
|
|
3008
|
+
"skills": [],
|
|
3009
|
+
}),
|
|
3010
|
+
has_error: false,
|
|
3011
|
+
overrides: OverrideFacts::Loaded(vec![OverrideEvent {
|
|
3012
|
+
text: "x".repeat(3 * READ_CHUNK_BYTES),
|
|
3013
|
+
tools: vec!["Read".to_owned()],
|
|
3014
|
+
}]),
|
|
3015
|
+
accounted: 0,
|
|
3016
|
+
};
|
|
3017
|
+
facts.refresh_accounted();
|
|
3018
|
+
facts
|
|
3019
|
+
}
|
|
3020
|
+
|
|
3021
|
+
#[test]
|
|
3022
|
+
fn a_stopped_lookup_reads_no_further_and_keeps_the_entry() {
|
|
3023
|
+
let cache = cache(2 * 1024 * 1024);
|
|
3024
|
+
let entry = revision(1);
|
|
3025
|
+
let built = chunked_facts();
|
|
3026
|
+
assert!(cache
|
|
3027
|
+
.insert(&entry, &built, |_| true, |_| true)
|
|
3028
|
+
.unwrap()
|
|
3029
|
+
.serves());
|
|
3030
|
+
let path = cache.entry_path(entry.digest);
|
|
3031
|
+
let stored = fs::read(&path).unwrap();
|
|
3032
|
+
assert!(
|
|
3033
|
+
stored.len() > 2 * READ_CHUNK_BYTES,
|
|
3034
|
+
"entry {}",
|
|
3035
|
+
stored.len()
|
|
3036
|
+
);
|
|
3037
|
+
let admitted = cache.decoded_bytes(&entry, FactsNeed::Full).unwrap();
|
|
3038
|
+
for (site, cancelled, cancelled_at_read, deadline_unix_ms, status, counted) in [
|
|
3039
|
+
(
|
|
3040
|
+
"before the first read",
|
|
3041
|
+
false,
|
|
3042
|
+
Some(1),
|
|
3043
|
+
u64::MAX,
|
|
3044
|
+
Status::Cancelled,
|
|
3045
|
+
(0, 0),
|
|
3046
|
+
),
|
|
3047
|
+
(
|
|
3048
|
+
"at a chunk boundary",
|
|
3049
|
+
false,
|
|
3050
|
+
Some(2),
|
|
3051
|
+
u64::MAX,
|
|
3052
|
+
Status::Cancelled,
|
|
3053
|
+
(1, READ_CHUNK_BYTES as u64),
|
|
3054
|
+
),
|
|
3055
|
+
(
|
|
3056
|
+
"past the deadline",
|
|
3057
|
+
false,
|
|
3058
|
+
None,
|
|
3059
|
+
0,
|
|
3060
|
+
Status::Deadline,
|
|
3061
|
+
(0, 0),
|
|
3062
|
+
),
|
|
3063
|
+
(
|
|
3064
|
+
"cancelled past the deadline",
|
|
3065
|
+
true,
|
|
3066
|
+
None,
|
|
3067
|
+
0,
|
|
3068
|
+
Status::Cancelled,
|
|
3069
|
+
(0, 0),
|
|
3070
|
+
),
|
|
3071
|
+
] {
|
|
3072
|
+
let cancel = Cancellation::default();
|
|
3073
|
+
if cancelled {
|
|
3074
|
+
cancel.cancel();
|
|
3075
|
+
}
|
|
3076
|
+
let stop = cancel.clone();
|
|
3077
|
+
let mut reads = 0;
|
|
3078
|
+
cache.set_read_hook(Some(Box::new(move || {
|
|
3079
|
+
reads += 1;
|
|
3080
|
+
if Some(reads) == cancelled_at_read {
|
|
3081
|
+
stop.cancel();
|
|
3082
|
+
}
|
|
3083
|
+
})));
|
|
3084
|
+
let mut read = DiskRead::default();
|
|
3085
|
+
let stopped = cache
|
|
3086
|
+
.lookup(
|
|
3087
|
+
&entry,
|
|
3088
|
+
&mut read,
|
|
3089
|
+
FactsNeed::Full,
|
|
3090
|
+
admitted,
|
|
3091
|
+
&cancel,
|
|
3092
|
+
deadline_unix_ms,
|
|
3093
|
+
)
|
|
3094
|
+
.err()
|
|
3095
|
+
.map(|error| error.status);
|
|
3096
|
+
cache.set_read_hook(None);
|
|
3097
|
+
assert_eq!(stopped, Some(status), "{site}");
|
|
3098
|
+
assert_eq!((read.operations, read.bytes), counted, "{site}");
|
|
3099
|
+
assert_eq!(fs::read(&path).unwrap(), stored, "{site}");
|
|
3100
|
+
assert_eq!(cache.stats().entries, 1, "{site}");
|
|
3101
|
+
}
|
|
3102
|
+
let mut read = DiskRead::default();
|
|
3103
|
+
let DiskLookup::Hit(loaded) = lookup(&cache, &entry, &mut read, FactsNeed::Full).unwrap()
|
|
3104
|
+
else {
|
|
3105
|
+
panic!("expected the kept entry to serve");
|
|
3106
|
+
};
|
|
3107
|
+
assert_eq!((read.operations, read.bytes), (1, stored.len() as u64));
|
|
3108
|
+
assert_eq!(
|
|
3109
|
+
loaded.text_section().unwrap()[0].text,
|
|
3110
|
+
built.text_section().unwrap()[0].text
|
|
3111
|
+
);
|
|
3112
|
+
}
|
|
3113
|
+
|
|
3114
|
+
#[test]
|
|
3115
|
+
fn a_stopped_inherited_lookup_leaves_the_entry_unadopted() {
|
|
3116
|
+
let namespace = isolated_namespace();
|
|
3117
|
+
let built = pushed_facts(5, 5);
|
|
3118
|
+
let entry = revision(1);
|
|
3119
|
+
let left = left_behind(&namespace, &entry, &built);
|
|
3120
|
+
let stored = fs::metadata(&left).unwrap().len();
|
|
3121
|
+
let successor = reuse_cache(&namespace, 64 * 1024);
|
|
3122
|
+
let inherited = budget(&successor);
|
|
3123
|
+
assert_eq!(inherited, (1, 0, stored as usize, 0));
|
|
3124
|
+
let admitted = successor.decoded_bytes(&entry, FactsNeed::Full).unwrap();
|
|
3125
|
+
let cancel = Cancellation::default();
|
|
3126
|
+
let stop = cancel.clone();
|
|
3127
|
+
successor.set_read_hook(Some(Box::new(move || stop.cancel())));
|
|
3128
|
+
let mut read = DiskRead::default();
|
|
3129
|
+
let stopped = successor
|
|
3130
|
+
.lookup(
|
|
3131
|
+
&entry,
|
|
3132
|
+
&mut read,
|
|
3133
|
+
FactsNeed::Full,
|
|
3134
|
+
admitted,
|
|
3135
|
+
&cancel,
|
|
3136
|
+
u64::MAX,
|
|
3137
|
+
)
|
|
3138
|
+
.err()
|
|
3139
|
+
.map(|error| error.status);
|
|
3140
|
+
successor.set_read_hook(None);
|
|
3141
|
+
assert_eq!(stopped, Some(Status::Cancelled));
|
|
3142
|
+
assert_eq!((read.operations, read.bytes), (0, 0));
|
|
3143
|
+
assert_eq!(budget(&successor), inherited);
|
|
3144
|
+
assert!(left.exists());
|
|
3145
|
+
assert!(!successor.has_entry(&entry).unwrap());
|
|
3146
|
+
let DiskLookup::Hit(loaded) =
|
|
3147
|
+
lookup(&successor, &entry, &mut read, FactsNeed::Full).unwrap()
|
|
3148
|
+
else {
|
|
3149
|
+
panic!("expected the inherited entry to serve");
|
|
3150
|
+
};
|
|
3151
|
+
assert_eq!(loaded.inputs, built.inputs);
|
|
3152
|
+
assert_eq!((read.operations, read.bytes), (1, stored));
|
|
3153
|
+
assert_eq!(budget(&successor), (1, stored as usize, 0, 0));
|
|
3154
|
+
assert!(!left.exists());
|
|
3155
|
+
drop(successor);
|
|
3156
|
+
fs::remove_dir_all(namespace).unwrap();
|
|
3157
|
+
}
|
|
3158
|
+
|
|
2959
3159
|
fn pushed_facts(events: usize, tools: usize) -> PreparedFacts {
|
|
2960
3160
|
let mut override_events = Vec::new();
|
|
2961
3161
|
for event in 0..events {
|
|
@@ -4767,7 +4967,14 @@ mod tests {
|
|
|
4767
4967
|
let mut read = DiskRead::default();
|
|
4768
4968
|
assert!(matches!(
|
|
4769
4969
|
cache
|
|
4770
|
-
.lookup(
|
|
4970
|
+
.lookup(
|
|
4971
|
+
&entry,
|
|
4972
|
+
&mut read,
|
|
4973
|
+
FactsNeed::Full,
|
|
4974
|
+
admitted,
|
|
4975
|
+
&Cancellation::default(),
|
|
4976
|
+
u64::MAX,
|
|
4977
|
+
)
|
|
4771
4978
|
.unwrap(),
|
|
4772
4979
|
DiskLookup::Changed
|
|
4773
4980
|
));
|
{cc_transcript-14.45.10 → cc_transcript-14.45.12}/rust/crates/core/src/snapshot_prepared_service.rs
RENAMED
|
@@ -358,7 +358,14 @@ impl NativeStore {
|
|
|
358
358
|
#[cfg(test)]
|
|
359
359
|
self.fact_lookups.fetch_add(1, Ordering::Relaxed);
|
|
360
360
|
let mut read = crate::snapshot_prepared_disk::DiskRead::default();
|
|
361
|
-
let lookup = self.prepared_disk.lookup(
|
|
361
|
+
let lookup = self.prepared_disk.lookup(
|
|
362
|
+
&key,
|
|
363
|
+
&mut read,
|
|
364
|
+
need,
|
|
365
|
+
decoded,
|
|
366
|
+
cancel,
|
|
367
|
+
remaining.deadline_unix_ms,
|
|
368
|
+
);
|
|
362
369
|
usage[18] += read.operations;
|
|
363
370
|
usage[19] += read.bytes;
|
|
364
371
|
match lookup? {
|
|
@@ -584,7 +591,14 @@ impl NativeStore {
|
|
|
584
591
|
#[cfg(test)]
|
|
585
592
|
self.fact_lookups.fetch_add(1, Ordering::Relaxed);
|
|
586
593
|
let mut read = crate::snapshot_prepared_disk::DiskRead::default();
|
|
587
|
-
let lookup = self.prepared_disk.lookup(
|
|
594
|
+
let lookup = self.prepared_disk.lookup(
|
|
595
|
+
&key,
|
|
596
|
+
&mut read,
|
|
597
|
+
need,
|
|
598
|
+
decoded,
|
|
599
|
+
cancel,
|
|
600
|
+
remaining.deadline_unix_ms,
|
|
601
|
+
);
|
|
588
602
|
usage[18] += read.operations;
|
|
589
603
|
usage[19] += read.bytes;
|
|
590
604
|
if let PreparedCacheReads::Warming(..) = cache_reads {
|
|
@@ -904,7 +918,7 @@ impl NativeStore {
|
|
|
904
918
|
return Ok(false);
|
|
905
919
|
}
|
|
906
920
|
}
|
|
907
|
-
dirs.hold()
|
|
921
|
+
dirs.hold(|| cancel.check(deadline))
|
|
908
922
|
}
|
|
909
923
|
|
|
910
924
|
fn validate_sidechain_dirs(
|
|
@@ -935,7 +949,7 @@ impl NativeStore {
|
|
|
935
949
|
return Ok(false);
|
|
936
950
|
}
|
|
937
951
|
}
|
|
938
|
-
dirs.hold()
|
|
952
|
+
dirs.hold(|| cancel.check(deadline))
|
|
939
953
|
}
|
|
940
954
|
|
|
941
955
|
fn prepare_graph(
|
|
@@ -1670,7 +1684,7 @@ impl NativeStore {
|
|
|
1670
1684
|
});
|
|
1671
1685
|
}
|
|
1672
1686
|
let since = active_since_ns(request)?;
|
|
1673
|
-
if !dirs.hold()?
|
|
1687
|
+
if !dirs.hold(|| cancel.check(remaining.deadline_unix_ms))?
|
|
1674
1688
|
|| members
|
|
1675
1689
|
.iter()
|
|
1676
1690
|
.filter(|member| active(member, since))
|
|
@@ -2146,7 +2160,10 @@ impl NativeStore {
|
|
|
2146
2160
|
steps += 1;
|
|
2147
2161
|
uncached_steps += usize::from(!cached);
|
|
2148
2162
|
}
|
|
2149
|
-
if !dirs.hold()
|
|
2163
|
+
if !dirs.hold(|| match cancel.check(remaining.deadline_unix_ms) {
|
|
2164
|
+
Err(error) if error.status == Status::Deadline => Ok(()),
|
|
2165
|
+
checked => checked,
|
|
2166
|
+
})? {
|
|
2150
2167
|
return Err(SnapshotError::new(
|
|
2151
2168
|
Status::Changed,
|
|
2152
2169
|
"registered source changed",
|
|
@@ -2253,7 +2270,7 @@ impl NativeStore {
|
|
|
2253
2270
|
let page = self
|
|
2254
2271
|
.prepared_query_steps(&mut cursor, &mut dirs, context, reservation, cancel, usage)
|
|
2255
2272
|
.and_then(|page| {
|
|
2256
|
-
if dirs.hold()? {
|
|
2273
|
+
if dirs.hold(|| cancel.check(cursor.remaining.deadline_unix_ms))? {
|
|
2257
2274
|
Ok(page)
|
|
2258
2275
|
} else {
|
|
2259
2276
|
Err(SnapshotError::new(
|
|
@@ -3075,8 +3092,10 @@ impl<'a> ResolvedDirs<'a> {
|
|
|
3075
3092
|
Ok(canonical)
|
|
3076
3093
|
}
|
|
3077
3094
|
|
|
3078
|
-
fn hold(&self) -> Result<bool, SnapshotError> {
|
|
3095
|
+
fn hold(&self, check: impl Fn() -> Result<(), SnapshotError>) -> Result<bool, SnapshotError> {
|
|
3096
|
+
check()?;
|
|
3079
3097
|
for (directory, canonical) in &self.dirs {
|
|
3098
|
+
check()?;
|
|
3080
3099
|
match self.store.canonical_path(directory) {
|
|
3081
3100
|
Ok(current) if current == *canonical => {}
|
|
3082
3101
|
Ok(_) => return Ok(false),
|
|
@@ -3084,6 +3103,7 @@ impl<'a> ResolvedDirs<'a> {
|
|
|
3084
3103
|
Err(error) => return Err(io_error(error)),
|
|
3085
3104
|
}
|
|
3086
3105
|
}
|
|
3106
|
+
check()?;
|
|
3087
3107
|
Ok(true)
|
|
3088
3108
|
}
|
|
3089
3109
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|