Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7d259b1
feat: checkpoint owned change creation and retry integration
kevinswiber Oct 7, 2026
ceb20da
feat: checkpoint enrolled currentness and owned inspector transport
kevinswiber Oct 8, 2026
d58dd21
feat: integrate owned currentness and inspector data access
kevinswiber Oct 8, 2026
35bd157
fix: account for profile probes in local diagnostics
kevinswiber Oct 9, 2026
7e671f3
test: attribute profile probes in EventStore counters
kevinswiber Oct 9, 2026
708dde5
test: synchronize Inspector observations and recovery controls
kevinswiber Oct 9, 2026
0bddcd0
test: initialize Inspector children before semantic assertions
kevinswiber Oct 9, 2026
5afafbe
test: make operator-owned native enrollment explicitly opt-in
kevinswiber Oct 9, 2026
d77486d
test: exercise private data refusal with a valid request shape
kevinswiber Oct 9, 2026
c9ece52
test: disable signing for synthetic delegation fixture commits
kevinswiber Oct 11, 2026
9f65d94
fix: align browser preflights with detached status
kevinswiber Oct 11, 2026
c73a99b
test: pin the reviewed browser preflight shell
kevinswiber Oct 11, 2026
7c8b8ef
fix: bind timeline safety counts to explicit evidence versions
kevinswiber Oct 11, 2026
08901a4
fix: read timeline failure counters through borrowed fields
kevinswiber Oct 12, 2026
0d30fe5
fix: box owned timeline evidence variants
kevinswiber Oct 12, 2026
bcaa1d7
fix: borrow raw evidence fixtures without cloning
kevinswiber Oct 15, 2026
02b9283
fix: integrate landed inspector recovery handling
kevinswiber Oct 15, 2026
71939d9
fix: gate experimental entries and align platform helpers
kevinswiber Oct 15, 2026
cae1b51
fix: prevent inherited inspector sockets from delaying responses
kevinswiber Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ required-features = ["bench"]
# remains the runtime escape hatch. Build with `--no-default-features` for the
# subprocess-only single-variant backend.
default = ["gix"]
# Explicit opt-in for the irreversible, unqualified owned-process argv entries.
# This gates command dispatch, not the internal SQLite dependency or native ABI.
experimental-enrolled-progress = []
# Exposes the developer-run `bench_support` harnesses to benchmark crates. Off
# by default and never enabled in a release build, so the harnesses stay out of
# the published surface. The dormant product SQLite implementation is in the
Expand Down Expand Up @@ -99,7 +102,7 @@ gix = { version = "0.85.0", default-features = false, features = [
], optional = true }
gix-imara-diff = { version = "0.2.3", default-features = false, features = ["unified_diff"], optional = true }
libc = "0.2"
libsqlite3-sys = { version = "0.38.1", features = ["bundled"] }
libsqlite3-sys = { version = "=0.38.1", features = ["bundled"] }
mmdflux = { version = "2.6", default-features = false }
rusqlite = { version = "0.40.1", default-features = false, features = ["backup", "bundled", "limits"] }
serde = { version = "1", features = ["derive"] }
Expand All @@ -121,7 +124,7 @@ criterion = { version = "0.8", default-features = false, features = ["cargo_benc
ctor = "0.2"
ed25519-dalek = "2"
libc = "0.2"
libsqlite3-sys = { version = "0.38.1", features = ["bundled"] }
libsqlite3-sys = { version = "=0.38.1", features = ["bundled"] }
rusqlite = { version = "0.40.1", default-features = false, features = ["backup", "bundled", "limits"] }
sha2 = "0.10"
tempfile = "3"
Expand All @@ -131,3 +134,13 @@ zstd = { version = "0.13.3", default-features = false }
# CI sets RUST_BACKTRACE=1, so keep >= line tables for file:line in panics, but drop
# variable/type debuginfo to cut codegen + link + PDB time (bigger on Windows).
debug = "line-tables-only"

# Keep the direct and rusqlite native dependency on one pinned provider.
[patch.crates-io]
libsqlite3-sys = { path = "vendor/libsqlite3-sys" }

[target.'cfg(any(target_os = "macos", windows))'.dependencies]
libsqlite3-sys = { version = "=0.38.1", features = ["bundled", "pointbreak-private-abi"] }

[target.'cfg(any(target_os = "macos", windows))'.dev-dependencies]
libsqlite3-sys = { version = "=0.38.1", features = ["bundled", "pointbreak-private-abi"] }
11 changes: 11 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ default:
test *args:
cargo +stable nextest run --no-tests pass {{ args }}

# Required append-progress gate; config binds built binaries and fresh native fixtures.
[macos]
[group('core')]
test-append-progress-native config:
python3 scripts/append-progress-native.py {{ quote(config) }}

[windows]
[group('core')]
test-append-progress-native config:
'C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe' -NoLogo -NoProfile -NonInteractive -File scripts/append-progress-native.ps1 -Config {{ quote(config) }}

# Run the default test suite (CI mode: no fail-fast, verbose).
[group('core')]
test-ci *args:
Expand Down
4 changes: 2 additions & 2 deletions benches/store_foundation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use pointbreak::bench_support::derived_access::{
run_qualification_derived_access_phase_v1, run_qualification_derived_access_resource_child_v1,
run_qualification_derived_access_resource_v1,
run_qualification_derived_access_restart_child_v1, run_qualification_derived_access_scale_v1,
run_qualification_derived_change_read_v1, verify_authority_stamp_native_receipts_v1,
run_qualification_derived_change_read, verify_authority_stamp_native_receipts_v1,
verify_qualification_derived_access_package_v1, verify_qualification_derived_access_phase_v1,
};
use pointbreak::bench_support::foundation::{
Expand Down Expand Up @@ -965,7 +965,7 @@ fn main() -> ExitCode {
eprintln!("derived Change read evidence requires exactly one typed request");
return ExitCode::from(2);
}
return report_derived_access_smoke(run_qualification_derived_change_read_v1(
return report_derived_access_smoke(run_qualification_derived_change_read(
std::path::Path::new(derived_requests[0]),
));
}
Expand Down
61 changes: 61 additions & 0 deletions docs/adr/adr-0041-bodyless-sqlite-derived-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,64 @@ fact origins, and the capable reader document registry only after verified L2 co
publication during bulk adoption occurs after the completion record and never makes an incomplete M1 store
servable. Loose Journal and ContentStore bytes remain sole authority; explicit derived-off remains an
artifact-free operational rollback, not a capability/store rollback.

## Amendment: Counted Pre-Hydration Safety Boundary (2026-10-11)

This amendment distinguishes enrollment-safety observation from selected event hydration in the explicitly versioned Timeline post-pin diagnostic. D3's safety fences and D4's bodyless selection and authoritative selected reread remain unchanged. It does not qualify a new platform, revise prior native results or authorize a production-store operation.

### Context

Current generation selection refreshes the lifecycle and repeats its negative enrollment-profile fence (`src/session/derived_access/runtime.rs`, `lifecycle.rs`). That fence checks append-progress metadata and may point-read the fixed root activation record even when that record is absent (`src/session/store/capabilities.rs::refuse_progress_store`). The LocalJournal's carrier-open metric includes the attempted optional read before I/O, so missing records still count. These probes protect against partial enrollment and missing selectors; caching or moving them out of a counted request would weaken the proof.

The Timeline diagnostic selects bodyless locators, pauses before authoritative carrier hydration, mutates one exact carrier, then requires the same child to reread and reject its changed validation witness. Its original V1 barrier requires **all** pre-pin carrier opens to be zero. That stronger V1 condition remains the meaning of V1 evidence. A new V2 condition distinguishes only the identified negative enrollment fence from all other carrier reads; it does not permit arbitrary unselected event reads.

### Decision

**Attribution stays with the narrow owner.** The negative enrollment fence uses a crate-private LocalJournal entry point with the fixed root activation key and no caller-supplied key/class. All generic logical-key, digest, path, enumeration, selected-event, support and other control reads remain in the default other-carrier class, even when they address that same reserved key. Reserved-key matching alone never grants the exception. No scoped general-purpose read-purpose API is introduced.

Every instrumented read continues to increment the existing total once at its existing boundary. The special leaf increments total and safety-attempt attribution together. The fence records completion only for successful absence or recognized legacy activation after its unchanged refusal logic. Malformed, wrong-family, progress-profile, failed or incomplete observations cannot produce ready evidence. Completion must credit the same counting state as the attempt. This is instrumentation provenance, not a new authority source or adversarial security boundary.

**The new barrier is exhaustive and fail-closed.** V2 ready/receipt documents carry required `carrierOpensBefore`, `enrollmentSafetyProbeOpensBefore`, `otherCarrierOpensBefore`, `enrollmentSafetyProbeAbsentBefore`, `enrollmentSafetyProbePresentBefore` and `selectedCarriersBefore`. Checked u64 arithmetic must establish:

- total opens equal safety-probe opens plus other-carrier opens;
- safety-probe opens equal completed absent plus completed present observations;
- other-carrier opens are zero and selected locator count is positive.

An unknown read purpose defaults to other; unknown or missing serialized fields/schemas refuse. No reset, subtraction, fixed overhead, defaulted count or shifted measurement interval is permitted. A diagnostic fault carrier cannot be the fixed activation key. The snapshot and final total counter receipt bind the same request identity; final total cannot be smaller than the snapshot. Existing selected/support counters, byte/decode/validation metrics and total-open semantics remain unchanged. They describe existing instrumentation, not an exhaustive OS syscall census.

For the final invalid-signature fault receipt, let C be total opens, E the validated **frozen pre-pin**
safety count, T pre-pin total, V event validations, and H the checked sum of selected, revision-candidate
and correlation-support carriers. V6 requires C>=T, C<=checked(E+H), and
C=checked(checked(E+V)+1); every intermediate overflow refuses. E is measured, never a fixed offset or
final safety total. The +1 is meaningful only alongside the exact same-child validation-witness abort
proof. No later nonvalidating read earns additional safety credit. V1 retains its original saturating
hydration bound and validations=opens-1 rule; normal Timeline rows retain their unchanged counter bounds.

**Mutation and authority proofs remain independent.** The hook stays immediately before hydration in both ordinary and enrolled Timeline implementations. The controller may mutate only after valid ready, retaining exact carrier key, clean/mutated hashes, one-bit recipe and ready/release hashes. The same armed child must reread the mutated carrier and produce the expected validation-witness mismatch. Explicit-off comparison remains a fresh, exhaustive authoritative lane after mutation. Reference and fault source/trust restoration and all no-body/metadata-only invariants remain mandatory.

The existing profile preflight is measured separately with the unchanged counter protocol and bound to the same child in V2 failure evidence. It is setup work, not zero work. Cold capability-pair validation, backfill and writer admission receive no blanket exception. If such a read occurs inside the armed request, readiness fails; the controller must not add a warm-up or retry to conceal it. Semantic-only comparison phases retain that label and do not become counted merely through association.

**Migration is explicit and local to the changed evidence semantics.** V1 barrier request/ready/release/receipt bytes, hashes and zero-total validators remain unchanged. V2 introduces explicit schemas for those four documents and the classification-contract binding; mixed versions reject rather than convert. The global counter document and its canonical serialization remain V1. Private attribution is emitted only in V2 barrier evidence.

A new Change-read request/receiptV3 and explicitly typed Timeline rowV2 carry the successor proof. EvaluatorV6 names a new hashed procedure that replaces the earlier post-pin boundary step while retaining other procedure requirements and platform criteria. Existing evaluatorV4/V5 and raw V1/V2 evidence retain their historical meaning. The existing package/fragment envelope dispatches by evaluator revision and explicit nested schema; it never defaults old evidence into the new boundary. Original bytes retain nested duplicate-field visibility before any Value conversion, including both orders of duplicated legacy/new schema selectors. Unknown or mixed versions refuse without making legacy-only parsing stricter. Raw receipt reconstruction, exact source/product/child bindings, stable inventories and completion-last publication remain required. Missing platform evidence remains insufficient evidence.

### Consequences and rejected alternatives

Legitimate negative enrollment probes can be measured before selected hydration without disabling them or hiding their cost. Selected and unrelated event pre-reads still fail. More explicit version/caller controls are required, but a global counter schema change or new counting framework is unnecessary.

Rejected alternatives are subtracting a predicted probe count; resetting measurement after admission; exempting all reserved keys or capability records; allowing arbitrary unselected reads; broad purpose scopes that can wrap event hydration; weakening the product fence; and silently interpreting nonzero V1 evidence as a V2 pass. Each would either lose total accounting, broaden the exception, weaken safety or misstate historical evidence.

### Review and validation obligations

Owner-boundary controls must exercise actual absent/present negative probes and generic reads of the same key, selected and unrelated pre-pin reads, malformed/wrong-family/progress records, scope mismatch and incomplete attribution. Version/canonical tests must preserve historical bytes and reject mixed contracts. The same-child fault diagnostic must demonstrate a genuine post-write injected failure and restoration in addition to successful post-pin validation-witness rejection. Package tests must preserve raw receipt authority, diagnostic inadmissibility and unchanged native evidence requirements.

Reopen this decision before admitting another read purpose, another key family, a global counter-document change, altered mutation timing, broader selected/unselected exceptions, changed native thresholds, or a new authority/assurance boundary. A newly observed non-exempt pre-pin read is a falsifier requiring diagnosis, not permission to widen the exception.

Implementation anchors for this amendment (source locations at this revision):

- `src/session/store/capabilities.rs:23` — `refuse_progress_store`.
- `src/session/store/backend/local.rs:45` — `read_negative_enrollment_fence`.
- `src/bench_support/longitudinal/counters.rs:1629` — `reach_timeline_carrier_locators_selected_v2`.
- `src/bench_support/derived_access/change_read.rs:5586` — `count_timeline_profile_setup`.
- `src/bench_support/derived_access/contract.rs:159` — `timeline_final_fault_counts_v2`.
- `src/bench_support/derived_access/evidence.rs:5700` — `read_timeline_contract_json`.
35 changes: 35 additions & 0 deletions docs/benchmarking.md
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,10 @@ values are `null` elsewhere. This non-timing developer smoke does not change the
qualification-smoke schemas, consume a retained or owner root, or activate the derived profile for
product reads.

On bootstrap-smoke failure, the diagnostic reports and retains its temporary root; successful
ordinary runs remove it. The D0 bootstrap owner test retains its root through all caller assertions
on both success and failure and prints the retained path.

Phase attribution is a separate diagnostic mode for revision-page, bootstrap, and governed-write work:

```sh
Expand Down Expand Up @@ -945,6 +949,37 @@ kind's change-read receipt carries its own request-bound identity. Together thes
receipt from one exact binary enter a single package. Mixed identities still refuse, historical v4 packages
keep their recorded refusals, and a V2 successor receipt fragments under v4 or v5 as requested.


`pointbreak.qualification-derived-change-read-request.v3` wraps the existing V2 request and binds
`TIMELINE_PRE_HYDRATION_COUNTING_CONTRACT_SHA256_V2`. Its receipt V3 preserves the embedded V1 Change matrix,
uses typed Timeline row V2 and requires evaluator v6. Request/ready/release/barrier-receipt V2 coexist with
unchanged V1 documents; raw receipt V2 remains bound to evaluator v4/v5. No legacy receipt is relabeled.

The `qualification_derived_change_request_builder` helper remains legacy V1/V2-only: it accepts V1 or V2
templates, rejects V3 templates, and produces and validates a V2 request. It does not prepare requests for
the V3 producer/V6 evaluator path. Migrating this helper is separate follow-up work; native package
preparation remains outside this local counting-contract change.

The V2 pin measures T=E+O and E=A+P with checked arithmetic: total opens, fixed-owner negative enrollment
probe attempts, other opens, completed absent and completed compatible-present probes. O must be zero and
selected locators positive. Generic same-key, digest, selected, cold-capability and unrelated reads remain
other. Malformed, progress-profile, failed or incomplete probes cannot earn completion. Counters are not reset
or adjusted; the existing profile preflight has its own counted receipt bound to the same child. A cold
transition during the armed request fails instead of buying another warm-up.

Evaluator v6 binds `pointbreak.qualification-derived-access-evaluator-v6-procedure.v1` and
`QUALIFICATION_DERIVED_ACCESS_EVALUATOR_V6_PROCEDURE_SHA256_V1`. Only the fault-boundary step changes.
After all same-child/key/ready/release/mutation/witness/strict-after/restoration checks, final total C and
validations V satisfy C>=T, C<=checked(E+H), C=checked(checked(E+V)+1), where H is the checked primary
selected/candidate/correlation sum and E is frozen at ready. Every overflow or extra post-pin nonvalidating
read refuses; normal-row and legacy equations stay unchanged. This does not establish an OS-level I/O census.

New-family original-byte decoders reject nested duplicates and mixed selectors before raw Values can lose
information. Fragment construction, assembly, publication and verification preserve the exact raw receipt
as authority and reject cross-version promotion. Existing default/full/longitudinal development gates and
native macOS/APFS plus real Windows/NTFS evidence requirements are unchanged. A new source implementation,
local diagnostic or partial package does not supply missing native qualification.

## Prospective feasibility contract

The approved prospective contract is compiled into the benchmark target as
Expand Down
Loading
Loading