diff --git a/harness/STATE.md b/harness/STATE.md index 118a706e..c13b4d9d 100644 --- a/harness/STATE.md +++ b/harness/STATE.md @@ -215,10 +215,13 @@ Published private complete-Project source **aaec78fcc9b273d1485497126392afdd1fb2e54e** retains the original syntax, bundle, budgets and limits while resolving/admitting the complete ordinary/typed model. The next [mixed typed-index contract](analysis-mixed-index-contract-20260924.md) -is accepted after source review and resolved accounting/completeness findings; -it has no implementation or runtime acceptance yet. It consumes the sealed -Project witness, reuses private index verification and keeps old updater -authority separate. Complete mixed editing and public source8 remain required. +is accepted after source review and resolved accounting/completeness findings. +Private source candidate `a18b7966e5ac6f5526deecdc4dd6ae8ca0e5ac51` implements +the consumed witness and shared verifier; its first strict gate failed on one +test range-pattern lint before runtime. The [source review](analysis-mixed-index-20260924/source-review.md) +records three repaired diagnostic findings and the exact reviewed production. +It keeps old updater authority separate; runtime acceptance, complete mixed +editing and public source8 remain required. Its [Windows evidence](experiments/analysis-mixed-project-20260924/README.md) distinguishes runtime source **71cadfa0cd0e112caa29588d2494753301f3cb6c** from the formatting-only aaec successor. Strict core all-target Clippy, actual listing diff --git a/harness/analysis-mixed-index-20260924/source-review.md b/harness/analysis-mixed-index-20260924/source-review.md new file mode 100644 index 00000000..e7dd6a30 --- /dev/null +++ b/harness/analysis-mixed-index-20260924/source-review.md @@ -0,0 +1,74 @@ +# Private mixed typed-index source review + +Parent publication note: production was frozen at +`a18b7966e5ac6f5526deecdc4dd6ae8ca0e5ac51` with all three final reviewed production +hashes below verified unchanged. Final test bytes at that commit are +`f7561e05fb6c03f6d4926bb1583f87c91dabccc4370d221d80b1f9251d994caf`; +they include the corrected nested-abs lifecycle fixture after the reviewer's +supporting test snapshot. Successor `1d02206c57d5c32caa67f08c6e58f345c0fb5970` +changes only an equivalent test range pattern and an implementation note after +the first strict lint failure. The original review's source-only scope and +findings are retained; this note does not claim runtime acceptance. + +2026-09-24. Reviewer: `/root/mixed_index_source_review` (GPT-6 Astra). Parent owns acceptance, publication, and integration. This is local-only preliminary source evidence; no compiler, test execution, Gitea mutation, source edit, or commit was performed by this reviewer. Issue 37 and its frozen Windows prerelease source were not touched. + +## Scope and exact source + +Reviewed the uncommitted production delta in `.local/as3batch`, branch `codex/analysis-mixed-index-956atf-20260924`, HEAD/base `aaec78fcc9b273d1485497126392afdd1fb2e54e`, against root `harness/analysis-mixed-index-contract-20260924.md` and its accepted independent design review. Paths below are relative to `crates/oa-core/src/` in that checkout. Parent-owned AGENTS.md changes are excluded. + +Initial SHA-256 source inventory (after first source read, before reported repairs): + +| File | SHA-256 | +| --- | --- | +| `language/analysis_source/index.rs` | `BEC770704DE957134AD05DC6FFA1117F114B5AC8787032A312B7D31B28FA05F5` | +| `language/analysis_source/mixed/project.rs` | `EDC2D182FFC2F03F4039872A8B392174FF78185DD41F0A1B5611C6A93502878C` | +| `language/analysis_source/mixed/project/accounting.rs` | `3EE9FF1ECDDAE29B35062DFF4738322C7941DED773D128C20D37EAE2BAAF30F6` | + +Final production source reinspection after builder reported its freeze (SHA-256): + +| File | SHA-256 | +| --- | --- | +| `language/analysis_source/index.rs` | `7C02DDA3622957D837B4AC39D477AE7842570BF3F0709ED48CD5495652636781` | +| `language/analysis_source/mixed/project.rs` | `7FE6EF88729718C38D2FFFD46331CDD03624E1B52108DE0B7609DA4FBBDBAC2A` | +| `language/analysis_source/mixed/project/accounting.rs` | `3EE9FF1ECDDAE29B35062DFF4738322C7941DED773D128C20D37EAE2BAAF30F6` | + +New test-source snapshot at that checkpoint: `language/analysis_source/mixed/project/tests/index_tests.rs` SHA-256 `6AEC4BE3CCA5D2F69A47DF3F88CC56BB012142E828305A8E121B7FE0A780A074`. The reviewer inspected corruption/transport/storage tests as supporting source, but did not perform a complete independent test-oracle audit or execute them. `git diff --check` returned exit 0. + +## Concrete findings and current disposition + +1. **Late call checks lost current file ownership.** `IndexData::build` initially updated `Original.at` while populating calls, but not while checking argument-label/callee agreement or argument-child/label agreement. A failure in either later loop could combine the current span with the last file in the preceding occurrence loop. Sent directly to parent and builder. Builder added `sources.at.set(Some(at.file))` and `sources.at.set(Some(site.file))` at the respective loop heads. Source reinspection confirms the repair. Runtime corruption controls must assert the relevant canonical file as well as the message. + +2. **Invalid numeric files acquired fabricated entry-file offsets.** `ResolvedMixedProject::index` initially filtered out-of-range `failure.file` to `None`, then passed the untouched span to `Failure::typed`, whose existing fallback selects the entry file. Corrupting an expression/occurrence file to `files.len()` therefore assigns an unrelated offset to the entry. Parent independently identified the same concern. Builder now explicitly resets the span to `Span::default()` for missing/out-of-range file authority before transport; source reinspection confirms that fallback repair. Valid canonical file failures continue to retain their span. + +3. **UTF-8 split offsets can panic during diagnostic conversion.** An internal expression/occurrence span whose start splits a multibyte character is rejected by the verifier, but `Failure::typed` passes its start to `language::diagnostic`, which slices `&source[..start]` without checking UTF-8 boundaries (`language.rs:178` onward). Thus the required damaged-span rejection could panic while reporting the intended error. Sent directly to parent and builder. Builder now tests the full error span with `source.get(start..end)` at the mixed consumed-constructor transport seam. Invalid UTF-8/range spans reset to `Span::default()` while retaining a known canonical file; unknown/out-of-range file authority uses the entry default. Source reinspection confirms the repair, and the added source test specifically chooses a byte inside `雨` and asserts the real `a.arcadia` path with default span. It does not alter unrelated public diagnostic code. Runtime execution remains pending. This was a concrete source control-flow issue reachable through required internal corruption, not through arbitrary fabrication of the sealed witness. + +## Ownership and compatibility assessment + +- `ResolvedMixedProject::index(self)` consumes the retained witness and moves it unchanged into an opaque `IndexedMixedProject`. It neither clones the complete Project nor reparses/re-lowers any source. Its views borrow the wrapper, whose retained syntax still borrows the original `SourceBundle`. +- `IndexInput`'s private `files` field seals construction within the witness module; no method exports an input value. Shared verifier access to project/sites and borrowed original tokens does not expose an authenticated sibling constructor accepting replaceable source/token maps. No self-reference is stored in the output. The nested input lifetime/covariance still requires compilation to establish Rust acceptance; source design does not require unsafe code. +- `IndexedMixedProject` has no `Deref`, `AsRef`, conversion, or updater adapter to legacy `Index`. `update::Plan`/`Composition` still use the nominal legacy type. Arbitrarily constructible internal `IndexData` alone cannot construct either provenance wrapper. +- The mixed catalog streams Project, definitions, elements, relations, diagrams, diagram nodes/placements, artifact links, and traces exactly once, plus `(calculation, parameter)` names. This matches all `Project::identities` categories without allocating its temporary Vec. Scoped parameter UUID reuse cannot collide with globals or parameters of another calculation. +- Typed-only name construction, borrowed numeric sources, output wrapper, and local budget checks are preserved. Shared `Storage(None)` adds no reservations; the existing local occurrence-cap and scalar-visited checks remain enabled only on that path. Owner/expression/token/call/structural check order remains equivalent, aside from earlier scratch destruction and unobserved diagnostic attribution. No typed-only semantic regression was identified by source comparison; test/compiler compatibility is not claimed here. + +## Structural and token invariants + +The extracted verifier retains owner containment; binding-field validity; parent-before-child rejection of forward/cyclic edges; file/owner/field agreement; proper subtree spans; unique qualified expression paths; role/qualified-target checks; whole original Word-token boundaries and spelling; duplicate physical-token/qualified occurrence rejection; call-label/callee agreement; required label existence for argument-child edges; and authored-syntax traversal comparing actual child edges to arena claims. The syntax-site lookup and visited total reject missing/extra expressions. It still intentionally trusts sealed lowering for complete non-expression reference/parameter occurrence emission; no additional completeness claim follows from the runtime checks. + +## Aggregate live-storage review + +Let G be global-plus-scoped names, H typed headers, O raw occurrences, E raw expression sites, P nonroot sites, C calls, W live syntax work items. The source adds retained entry slots `R = G + H + O + E + P`, zero occurrence slots, and exactly copied-name UTF-8 bytes. Prior raw E entries and O occurrence slots remain charged in the consumed ledger throughout. + +- Every owned name reserves one entry and its bytes before copying/insertion. +- Each owner reserves one scratch entry before insertion; each new occurrence reserves two entries before its physical-token-set and retained-map insertions. +- Each nonroot path reserves one retained Step before `Arc::new`. Each expression reserves two entries before retained-map insertion and scratch-path-vector push. Arc clones allocate no additional Step; enclosing map/vector slots remain charged. +- After occurrence validation, owners and physical tokens are explicitly dropped before releasing H and H+O scratch entries. Paths and call entries are explicitly dropped/released after argument-child validation. P shared path-node reservations remain retained while map keys still own those nodes. +- Reverse borrowed-name maps reserve G before insertion, syntax-site lookup reserves E incrementally before insertion, and each root/child walk push reserves one entry. A popped work slot is released immediately according to the accepted logical-live-slot policy; the scalar visited total adds no mixed allocation charge. Reverse maps/sites/work are dropped before the final scratch release. +- No allocated declaration/file adapter table or copied path vector was introduced. `Path::edges` remains used only by tests. Error transport remains outside successful retained storage, consistent with the existing witness policy. + +The success-path peak expressions are: occurrence completion `R + H + (H + O) + E`; call validation `R + E + C`; syntax traversal `R + G + E + W`, in addition to the inherited baseline. These are source-derived formulas, not measured peaks. Earlier prefixes cannot exceed the first expression under valid monotonic accumulation; alternative fixture peaks still need exact tests. Checked aggregate `Ledger::reserve` precedes all new allocation growth; normal reserve failures return immediately and consume/drop the whole witness, so no stale lease or partial success can escape. + +## Destruction and remaining gates + +Persistent Path comparison/debug/drop remain iterative; final Arc ownership peels parents without recursive Step destruction. New verifier traversal is iterative and retains the inherited frame check. Syntax/Project destruction remains on existing lifecycle policy; runtime success and late-rejection small-stack checks are required, not established by this source review. No parse-byte/token/entry/reference or Exact-work charging calls were added to the mixed index path, and complete admission is not repeated; frame checking may update deepest-frame usage as permitted. + +All three concrete findings are repaired by source inspection at the final production hashes above. No remaining blocking source finding was identified for this bounded implementation. Compilation, runtime and oracle acceptance remain unverified by this reviewer. Required full numeric authored oracles, qualified repeated/reordered calls, all intended corruption controls, exact aggregate cap/cap-minus-one tests, provenance/metadata checks, small-stack execution, inherited typed-only index/update/export compatibility, strict core Clippy, and inherited full-library disposition remain parent acceptance gates. This read-only private index is a prerequisite for complete original-coordinate mixed editing; it does not implement ordinary occurrence indexing, public source8, or the user's full editing/UI parity objective.