Adopt reviewed private original-span export boundary
This commit is contained in:
@@ -1,5 +1,38 @@
|
||||
# Architectural and product decisions
|
||||
|
||||
## Private source composition decision — 2026-09-23
|
||||
|
||||
Adopt the opaque validated original-span rename batch as the next private
|
||||
analysis adapter step, with the [independent review's clarifications](analysis-original-span-review-20260923.md).
|
||||
The [original proposal](analysis-original-span-proposal-20260922.md) compares
|
||||
this against replacing both ordinary and typed edit representations. The narrow
|
||||
adapter preserves current ordinary compatibility and reduces migration risk;
|
||||
a shared edit AST remains a candidate if structural composition demonstrates a
|
||||
need. Neither sequentially applying producers with stale offsets nor canonical
|
||||
rewriting is acceptable for authored-source preservation.
|
||||
|
||||
The immediate patch exports complete borrowed rename records and splits
|
||||
ownership validation from standalone final-output size preflight. It may defer
|
||||
only hypothetical typed-only output sizing; active inherited budget, plan/name
|
||||
storage, qualified namespace, source equality and complete occurrence checks
|
||||
remain mandatory. Standalone rename/apply semantics remain intact. This is
|
||||
private staging, not a complete parse-session or public source8 boundary.
|
||||
|
||||
Before production composition, one checked parsed-bundle witness must bind the
|
||||
complete source/entry/file map, ordinary model, typed index, profile and complete
|
||||
target intent. Ordinary syntax-kind replacement currently emits same-start
|
||||
insertion/deletion pairs; explicitly normalize such owned operations with exact
|
||||
trivia oracles before admitting them, keeping cross-producer collisions errors.
|
||||
Gate supported changes by a precise complete-model diff. Compile the actual
|
||||
emitted full bundle, use normal admission, and compare the complete intended
|
||||
Project before installation. Exact untouched bytes are an independent gate.
|
||||
Subtree edits, parameter lifecycle, repaired deletion, reidentity, relocation,
|
||||
missing-ID stabilization, migration/history and checked-save remain required
|
||||
delivery work; passing the private rename slice cannot close those requirements.
|
||||
|
||||
The source-pinned proposal/review retain their original local provenance labels.
|
||||
The accepted underlying repair contract is [r2 at analysis source 1b1c3e3](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/src/commit/1b1c3e3abb6fc3d0934c9dbfbd21fddc8ae4f594/harness/analysis-source8-20260913/analysis-source8-repair-design-r2-20260913.md).
|
||||
|
||||
## Current continuation decisions — 2026-09-06
|
||||
|
||||
- Saving under another source entry basename is destination bookkeeping, not an engineering edit. Adopt an exact current save receipt without adding Undo or clearing Redo; rebase uniform entry names across retained history after collision and compilation checks. Stale receipts cannot redirect newer raw source. Native discovery and eleven focused regression results are in release-save-as-runtime-packaging.md; updated native verification remains required.
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# S3 original-span composition proposal
|
||||
|
||||
**Proposal, not an accepted decision or implementation.** Read-only source inspection on 2026-09-22: private analysis `1b1c3e3abb6fc3d0934c9dbfbd21fddc8ae4f594` in `.local/ai3`; ordinary updater at root `4ffff0d9d94bd1875e6b316b84ac11e5c5c9657c`. No compiler, source mutation, public activation, metamodel change or critic delegation. Parent owns adoption/integration.
|
||||
|
||||
Requirements come from `harness/analysis-source8-20260913/analysis-source8-repair-design-r2-20260913.md`, “Source pipeline and exact editing,” and the S3/S2 handoffs `.local/analysis-source8-s3-index-handoff-20260913.md` / `.local/analysis-source8-s2-implementation-plan-20260913.md`. Earlier plans describe intended interfaces; the implementation facts below take precedence for what currently exists.
|
||||
|
||||
## Observed seams and smallest useful scope
|
||||
|
||||
Private `analysis_source/update.rs` already retains qualified occurrence keys and original locations, validates complete simultaneous final namespaces, exact original numeric-file map/bytes, token spelling, complete required edit membership and overlap. It exports only whole-file `Plan::apply`. `Index::parse` consumes typed-only files; `Index::build` is private and trusts its own lowerer's occurrence completeness. `Writer::expression(owner, field, expr, Parent)` exists for later subtree changes; a rename needs no writer invocation.
|
||||
|
||||
Root `source_project.rs` already collects ordinary original-coordinate `Edits = BTreeMap<LogicalPath, Vec<(Span, String)>>` before `apply_edits` (lines271,679,1050). `SyntaxUpdate` uses complete old/new comparison values plus separate compact insertion values; preserve that distinction. Project-header slices explicitly add the header's file offset once. Current `apply_edits` groups identical spans by concatenating text, including nonempty replacements, and validates/mutates one file at a time. That is not a sufficient mixed-producer validation boundary.
|
||||
|
||||
After scalar application, `source_structure::update` can reparse and relocate pieces using updated coordinates; it returns immediately when no structural change is needed. Therefore the first integrated slice should explicitly cover stable-ID, topology-preserving global/scoped renames and ordinary scalar edits with disjoint ownership. Reject/defer additions, deletions, moves, reidentity and typed subtree changes at this slice's entry. The existing public updater keeps its current broader behavior until those operations have a compatible composition design; do not claim that its structural second phase already uses the new single-application protocol.
|
||||
|
||||
## Two candidates
|
||||
|
||||
| Candidate | Preservation and ownership | Cost / limitation |
|
||||
| --- | --- | --- |
|
||||
| A. Opaque validated typed edit batch + bundle-owned compositor | Keep Index/Plan provenance; ordinary and typed producers own disjoint spans in one original snapshot. Existing ordinary complete/compact semantics stay in place. | Small adapter and merge boundary; genuine mixed parsing and shared budgets still required before public use. Recommended first slice. |
|
||||
| B. Replace both producers with one shared semantic edit-plan/AST representation | Could eventually centralize token, subtree, insertion and relocation ownership. | Requires migrating ordinary EditValue/SyntaxUpdate, structural comment ownership and typed paths at once; substantially more compatibility risk before the first rename benefit. Revisit only when demonstrated structural composition needs justify it. |
|
||||
|
||||
Applying typed output before ordinary offsets is invalid under either design. Canonicalizing a mixed file as a bridge would destroy required authored preservation.
|
||||
|
||||
## Candidate A: concrete interface and file plan
|
||||
|
||||
1. **`analysis_source/update.rs`: export an opaque borrowed batch.** Proposed signatures are sketches, not existing APIs:
|
||||
|
||||
```rust
|
||||
Plan::validated_original_edits(&self, current, budget)
|
||||
-> Result<ValidatedRenameEdits<'_>, Error>
|
||||
ValidatedRenameEdits::iter(&self)
|
||||
-> impl ExactSizeIterator<Item = OriginalNameEdit<'_>>
|
||||
```
|
||||
|
||||
`OriginalNameEdit` exposes read-only `location: {file, original_span}`, `original: &str`, `replacement: &str`, and `occurrence: &OccurrenceKey`. All fields/constructors remain private with getters; records and batch borrow the Plan/index. Validate the whole batch before returning it. The bundle collector accepts the batch itself and iterates every record; it does not accept a caller-selected subset as a complete rename. An empty/no-op batch is valid. Revalidate complete source equality at final application, not merely iterator construction.
|
||||
|
||||
Factor today's `validate` into (a) ownership/spelling/order/completeness validation and (b) output-length preflight. Keep standalone `Plan::renames`/`apply` behavior. For mixed planning, add a narrowly named composition constructor sharing (a), without checking a fictitious typed-only intermediate output size. Otherwise a typed expansion can be rejected even when a simultaneous ordinary shrink makes the actual final bundle fit. Plan-record/name-memory bounds still apply before allocations, and final combined-output bounds are mandatory. Do not use a fresh Budget to bypass the intermediate check.
|
||||
|
||||
2. **`source_project/original_edits.rs` (new private module): bind and merge.** A `SourceSnapshot` borrows the complete original `SourceBundle`, including entry path and every file. A private file table maps each numeric typed file key to exactly one canonical LogicalPath from that snapshot, fixed by the parse session. No recomputation from a different traversal and no caller-supplied unchecked file map. The collector stores typed provenance and ordinary owner/role beside each borrowed/owned replacement until validation completes.
|
||||
|
||||
Collect ordinary `(span, text)` records through an internal adapter that records their expected original substring and source owner; typed records retain their full qualified key. Ordinary owns ordinary headers/fields/references and project header/description; typed owns typed headers and typed occurrences, including references to ordinary targets. Explicitly exclude typed declaration spans from generic SyntaxUpdate so both producers never independently own the same token. A shared physical span is a collision, not a deduplication opportunity.
|
||||
|
||||
Preflight every file before allocating output: exact entry/files/bytes equality, known mapped file, half-open UTF-8 boundaries, expected old bytes, producer ownership, complete typed set, checked counts/text sizes, sorted disjoint spans, per-file and aggregate final lengths. Reject duplicate nonempty ranges even when their replacements agree. Initially reject ambiguous insertions at a replacement boundary and multiple insertions at one position; existing ordinary insertion groups can enter only after their producer explicitly coalesces them in a defined order into one witnessed insertion. The new boundary must not inherit arbitrary concatenation of equal nonempty spans from `apply_edits`.
|
||||
|
||||
Emit each file once by copying untouched original slices and final replacements in ascending original order. Return a new candidate bundle only after complete validation; preserve the input on all failures. This is the sole text application for the supported mixed slice. Entry/include strings, authored paths, comments, literal spellings, line endings and untouched files remain exact.
|
||||
|
||||
3. **`source_project.rs`: route the narrow scalar slice.** Extract/retain ordinary edit collection before the existing application point. Add typed batches there, resolve their file keys through the snapshot, and call the new compositor once. Guard the supported scope before any output construction; no declaration relocation/default-file work is hidden in the adapter. Preserve the stale check that recompiles publicly mutable `CompiledSourceProject` fields and checks index/model/bundle, or replace it only with an equally strong opaque checked-snapshot boundary as part of separately reviewed work.
|
||||
|
||||
4. **Later `language.rs` / `analysis_source/index.rs` integration:** one opaque parsed-bundle result must carry full-buffer tokens, typed declaration units, lowerer result and file table from the same parse. Construct Index through that provenance, not a newly exposed raw `build(Lowered, spans)` seam. All offsets remain file-relative full-original-buffer byte offsets, including typed declarations after includes or ordinary declarations. Never remove/include-mask bytes, concatenate fragments, or rescan a substring and silently treat its offsets as full-file offsets. Existing local-slice ordinary helpers translate their known base exactly once. No typed rename offset receives a second include/header adjustment.
|
||||
|
||||
## Namespace, resource and acceptance invariants
|
||||
|
||||
Global aliases share the complete project namespace. Scoped names are keyed by `(calculation Id, ParameterId)`; stable simultaneous final-name validation must include unchanged ordinary globals and unchanged parameters. Reused parameter UUIDs across calculations and UUID equality with a global remain legal. Occurrence identity retains owner, binding field (including override property), complete structural call path, role and qualified target. Call labels bind to the callee, never caller scope or text alone. Rename-only changes preserve authored parameter/call-argument order; reordering unrelated model vectors is outside the narrow rename plan.
|
||||
|
||||
Use one inherited parse budget across all reachable ordinary/typed units; charge original bytes/tokens/literals once. Adapter validation does not reset/recharge parsing or numeric work. Combine ordinary+typed edit-record and owned replacement-text counts before reserving the merged list; do not treat each producer passing its own ceiling as aggregate admission. Preflight the complete final bundle against both inherited source8 output bounds and caller ProjectLimits, including unchanged files. A fresh aggregate budget belongs only to the next complete candidate parse. The existing phase byte check is a bounded text-size policy, not an exact heap-allocation accounting claim.
|
||||
|
||||
For an integrated candidate, recompile the **actual emitted complete bundle**, run existing structural/static admission through its normal validator (no redundant manual second admission), and require the entire resulting Project to equal the independently intended Project before returning/installing source/history. A parseable output that omits an unchanged definition is failure. Pure adapter tests cannot certify this currently unavailable mixed public path. Preserve the closed public dispatch and checked-save boundaries until the parser/lowerer/migration/acceptance work is integrated and verified.
|
||||
|
||||
## Prerequisites versus deliverables available now
|
||||
|
||||
**Implementable now on the private analysis branch:** borrowed validated batch export, split validation/preflight internals, and tests for binding/completeness/no output construction. A private composition evaluator can combine this batch with independently authored ordinary edit witnesses and full-buffer expected strings. That demonstrates the merge algorithm, not production ordinary edit generation or mixed compilation. No public schema switch, native GUI, metamodel extension or full S4 completion is needed for this bounded deliverable.
|
||||
|
||||
**Actually blocking production mixed integration:** root4ffff is still schema7 and has neither the private analysis model/language integration nor the private raw scanner; its tokenizer still rejects typed punctuation/converts ordinary numbers. Reconcile the analysis contribution with current ordinary CompleteForEdit/Compact work instead of replacing current root files wholesale. A real mixed `parse_unit`/edit-position branch, one shared scanner/cursor/bundle budget, full global/signature lowering and opaque Index provenance are required. Stabilize missing global/parameter IDs into exact returned files and reindex before granting edit authority. Complete-output source8 compile/admission, legacy bridge/migration and checked-save acceptance remain required public gates. Root identity correspondence also needs a distinct definition category before enabling reidentity; current fallback category is node placement. These are dependencies, not permission to invent a new model or activate source8 in this adapter.
|
||||
|
||||
**Not blockers for the read-only batch:** subtree writing, comment salvage for removed nodes, parameter insertion/deletion, declaration movement/new-file ownership, migration activation, evaluation and further metamodel work. Keep them out of the initial patch. The existing Writer supplies the future changed-subtree primitive once its real parent/side context and structural ownership are integrated.
|
||||
|
||||
## Six independent falsifiers (all proposed, unrun here)
|
||||
|
||||
1. **Same-file offset cascade.** Independently authored mixed CRLF source with Unicode trivia, an ordinary global header/reference before a calculation and an ordinary scalar field after it. Simultaneously lengthen a global alias, shrink a parameter name and change the later scalar. Assert the exact entire expected file literal, all untouched bytes and intended Project; applying either producer first must fail the oracle.
|
||||
2. **Include/file-coordinate binding.** Root includes two nested-path modules; typed and ordinary declarations share a module after an include/comment prefix, and the same numeric offsets occur in another module. Exact expected full bundle verifies edits land in the owning file at its original absolute offset. Wrong/missing/reordered key-to-path mapping rejects before output; include spellings and ownership stay exact.
|
||||
3. **Repeated/reordered calls and namespace swaps.** Two calculations reuse parameter IDs/names, one equals a global UUID. Include two reordered calls to one callee and one to the other, with separate comments. Swap the first callee's two parameter names and two global aliases simultaneously. Independently enumerate every declaration/use/label span: four labels for the repeated callee remain distinct; the other callee's labels, strings and argument order remain unchanged. Add a final-name collision negative control.
|
||||
4. **Whole-snapshot and Unicode staleness.** After planning, independently mutate an unrelated file/comment, add/remove a file, or change entry while preserving file text. Each fails before output. Separately forge a span inside a multibyte scalar or attach a valid-looking token from another owner; equal spelling/length must not authorize it. A byte-identical current snapshot is the positive control.
|
||||
5. **Producer overlap.** Ordinary whole-field replacement contains a typed rename; equal nonempty spans from both producers; duplicate typed occurrence; insertion at a replacement boundary. Each is rejected atomically. Adjacent disjoint ranges and one explicitly coalesced insertion are positives. No replacement concatenation, silent dropping or producer-order choice is allowed.
|
||||
6. **Aggregate output and acceptance.** Independent multi-file edits each fit a producer-local ceiling but exceed the combined cap by one byte; require refusal with unchanged input. Exact-cap positive and typed-growth/ordinary-shrink compensation positive enforce final-output accounting. At integration, deliberately omit an otherwise valid unchanged definition/reference edit from the emitted candidate: exact-output recompile/admission plus whole-Project equality must refuse it. No model projection or compiler success alone can pass.
|
||||
|
||||
All positive adapter fixtures also assert source/numeric usage is unchanged by export/merge and that exporting does not construct whole-file typed output. Integrated variants add complete output recompile, intended-Project equality and history/save refusal on failure.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Original-span source8 adapter: fresh independent design review
|
||||
|
||||
2026-09-23 — delegated Astra critic; local-only artifact, parent owns adoption and publication.
|
||||
|
||||
**Disposition: proceed with the bounded private adapter, with the clarifications below.** The proposed opaque rename batch plus complete-snapshot compositor is compatible with eventual real mixed source8. A wholesale edit-AST replacement is not justified by the inspected rename problem. No P1 defect was established in this unimplemented proposal. The main risks are accidentally promising more ordinary edits than the collision rules admit, treating matching lifetimes/bytes as complete parse provenance, and allowing the narrow slice to stand in for full source8 editing.
|
||||
|
||||
## Evidence and limits
|
||||
|
||||
Reviewed `.local/analysis-source8-s3-original-span-adapter-proposal-20260922.md`, SHA-256 `8f99e8ea1ba522371c1e5df1a19ae94ceedeecfacfc96dc5345e0d24f623a9d`; the S2/S3 handoffs; accepted r2 exact-editing requirements in `harness/analysis-source8-20260913/analysis-source8-repair-design-r2-20260913.md` from the analysis checkout; and the actual source below.
|
||||
|
||||
- A = `1b1c3e3abb6fc3d0934c9dbfbd21fddc8ae4f594`, `.local/ai3`, clean at inspection.
|
||||
- R = `4ffff0d9d94bd1875e6b316b84ac11e5c5c9657c`, requested ordinary-source pin. Root advanced to `cc3d6a48751ac5ab08e727cfd31c2b261bf8ade3` during review; independent Git comparison showed no differences from R in `source_project.rs`, `source_project/source_structure.rs`, or `language.rs`, so reads remain valid for R.
|
||||
- Source/design review only. No compiler, runtime, GUI, production changes, or Gitea writes. The proposed falsifiers are unrun; this review is not evidence of a working mixed parser or updater.
|
||||
|
||||
## Actionable clarifications
|
||||
|
||||
1. **P2 — define the supported ordinary edit set before routing it to the new compositor.** Proposal lines 13 and 47 promise topology-preserving ordinary scalar changes, while line 43 rejects insertion at a replacement boundary. R's `crates/oa-core/src/source_project.rs:1360–1371` deliberately handles a syntax-kind change by calling `erase_syntax` and inserting new text at the original start; `erase_syntax` (`:1101–1113`) emits individual token deletions, leaving trivia. Thus an existing producer can issue a meaningful insertion/deletion pair sharing a boundary. Stable model IDs alone do not exclude this form of syntax change. Either initially allow only explicitly enumerated leaf/header edits whose producer shape is supported, rejecting other changes *before* formatting/planning, or normalize this ordinary-owned compound operation into a single witnessed replacement with the same comment-preservation result. Do not simply relax cross-producer overlap checks. Add a positive oracle for that normalization before broadening the advertised scalar set.
|
||||
|
||||
R's `apply_edits` (`:679–718`) also concatenates all equal-span replacements. The proposal correctly refuses to carry that rule into a mixed ownership boundary. Preserve defined same-position insertion ordering inside one ordinary producer; reject duplicate nonempty replacements from any producer unless a distinct, reviewed compound-operation rule justifies them. Run ordinary compatibility fixtures against the adapter when it becomes a production route, since a stricter validator can expose previously tolerated producer output. No evidence found here establishes that all ordinary duplicate spans are intentional or that they are all bugs.
|
||||
|
||||
2. **P2 — make the batch/snapshot relationship and intended rename set constructor invariants.** A's `analysis_source/update.rs:15–19` binds a plan to an Index, and `index.rs:122–128` binds the Index to numeric-keyed source strings. Neither object currently binds itself to a `SourceBundle.entry`, canonical-path table, checked ordinary Project, or parse-budget profile. `Index::parse` (`index.rs:147–178`) intentionally accepts an independently supplied ordinary Project for the private typed-only harness. Rust borrowing prevents dangling references; a shared lifetime does not prove that two borrowed objects came from the same parse session. The proposal's opaque parsed-bundle requirement is therefore essential, not documentation around otherwise sufficient lifetimes.
|
||||
|
||||
For production composition, use one checked parsed-bundle witness that owns or borrows the exact complete bundle, ordinary model, typed index, file table and inherited limits. Create the collector and its complete rename intent from that same witness plus the independently supplied target Project. Permit only the witnessed typed batch for that index, with all global and scoped changes derived by stable identities; do not independently accept several batches whose individually valid final-name maps disagree. Final equality must still catch omitted ordinary references. Keep the old typed-only constructor test/staging-only. Add a negative control pairing a valid batch with another parse session/file table having equal numeric keys/spellings but different ownership, and a positive byte-identical complete snapshot control. No public raw `build(Lowered, spans)` is needed.
|
||||
|
||||
3. **P2 — turn the initial scope restriction into a precise diff gate and a bounded completion path.** “Topology-preserving” is not enough to identify supported changes. Require a gate over complete old/new Projects: unchanged global IDs and categories, declaration/lexical ownership, typed bodies/types/subjects/override structure, parameter IDs/order and all unsupported fields, allowing only the specific global/scoped names and ordinary leaf changes implemented in the first slice. An unrelated model-vector reorder, body edit, repaired deletion, or reidentity must not get silently ignored or regenerated. Return a specific unsupported-operation result before output construction. Keep those cases visible as unfinished source8 functionality.
|
||||
|
||||
The accepted r2 contract, “Source pipeline and exact editing” points 5–8, additionally requires subtree edits and retained removed-node comments, scoped parameter changes, global reidentity, explicit definition categories, file ownership, and complete acceptance. The S2 plan's S3 responsibility paragraph adds repaired deletion, missing-ID insertion/reindexing and history. A passing rename compositor does not complete those obligations. Before public activation, either implement their source8 paths or retain a clearly private experimental entrypoint; keeping the existing source7 updater intact does not by itself provide these operations for a source8 model.
|
||||
|
||||
## Resource and acceptance conclusions
|
||||
|
||||
The typed-growth/ordinary-shrink concern is real. A's `Plan::renames` calls `validate` at `update.rs:89`; `validate` calculates a typed-only aggregate output and applies `index_bytes` (`:154–170`). Consequently, export cannot simply call the existing constructor under the final combined-output ceiling. Accept the proposed split into ownership/completeness validation and standalone output preflight, while preserving standalone `renames`/`apply` behavior.
|
||||
|
||||
The composition path should retain the inherited profile rather than accept a more permissive ambient Budget. If callers can tighten limits, use the intersection; do not allow composition to widen the parsed session's ceilings. Existing private tests deliberately construct new Budgets for boundary probes (`update/tests.rs`, `output_and_plan_limits_are_aggregate_and_do_not_reset_parse_work`), which is not proof of production profile binding. Count aggregate records/owned replacement text before merged reservations, then compute the actual combined per-file and whole-bundle output lengths, including unchanged files, before allocating output. A shrink can compensate output growth, but cannot erase already incurred parse, name-storage, record, or numeric costs. Retaining old parse counters unchanged through export is correct; a complete candidate reparse gets its own complete bounded pass. An unchanged usage counter alone does not prove that no redundant parsing occurred, so keep the single-parser control flow inspectable.
|
||||
|
||||
The final acceptance boundary is correctly chosen: compile the actual emitted complete bundle, use normal full structural/static admission, compare the entire resulting Project to independent intent, and install nothing on failure. R already checks stale public fields (`source_project.rs:790–802`) and whole-Project equality (`:1058–1071`); preserve those guarantees. Equality is necessary but cannot prove source preservation or edit provenance: retain independently authored exact-output and unchanged-byte oracles too. When choosing the negative omission fixture, keep the damaged output parseable/admissible (for example, omit an unreferenced definition) so the test actually exercises whole-Project equality instead of only an earlier parser error.
|
||||
|
||||
## Concrete next implementation boundaries
|
||||
|
||||
1. **Private batch patch:** only the typed update module and its focused tests need change initially. Export a borrowed, opaque, complete validated batch; separate composition planning from standalone final-size preflight; prove no whole-file output is constructed. Exercise same-name no-op, full swaps, missing/duplicate occurrence, stale source, and typed-growth/ordinary-shrink compensation with independently authored ordinary witnesses. This is a meaningful deliverable now and needs no public dispatch change.
|
||||
2. **Private compositor patch:** implement complete snapshot/file-map binding, owned ordinary-operation normalization for the explicit supported set, aggregate checks and one ascending copy pass. Exercise all-file atomic rejection, Unicode boundaries, wrong session/map, duplicate nonempty spans, ordered insertion groups, adjacent ranges, exact cap and cap-plus-one. Handwritten ordinary witnesses certify this algorithm only, not production ordinary edit collection.
|
||||
3. **Real mixed parse prerequisite:** compose one raw scanner/cursor and bundle budget with ordinary and typed declaration parsing; collect full cross-file globals/signatures, lower once, retain full-buffer offsets and same-parse index provenance. Stabilize missing global/parameter IDs into the returned documents and rebuild indexes before granting editing authority. Preserve ordinary signed-number/legacy behavior and complete/compact edit semantics. Do not build a substring/masked-source bridge or expose raw lowerer/span fabrication to make the compositor appear integrated.
|
||||
4. **Integrated narrow edit slice:** derive both producers from that checked parse and complete target, enforce the precise diff gate, emit once, and verify the whole candidate. Add independently authored mixed CRLF/Unicode files, cross-file ordinary-to-typed and typed-to-ordinary renames, final namespace swaps, scalar changes on both sides of typed declarations, exact bundle output and whole-Project equality. Include no-op equality and stale unrelated-file/entry refusal.
|
||||
5. **Complete required editing and publication:** extend the ownership protocol to typed subtree changes, scoped-parameter insertion/deletion/reorder, same-batch repaired deletion, reidentity, movement/new-file ownership and stabilization/migration; verify history and checked-save failure atomicity. The existing structural second pass (`R:source_project/source_structure.rs:34–84`) reparses updated text and cannot simply be declared part of the original-coordinate one-pass proof. Design and verify its composition explicitly. These are remaining delivery gates, not grounds to postpone the useful private batch patch.
|
||||
|
||||
The proposal is appropriately cautious about public activation and does not weaken the required model semantics. With the scope/provenance clarifications above, implementation of the private adapter should now provide more value than another general redesign exercise.
|
||||
|
||||
## Immediate export-only acceptance boundary
|
||||
|
||||
Parent's narrower first implementation is accepted: **typed opaque batch export and validation split only; no mixed `source_project` compositor, real mixed parser, or public activation in this patch.** Steps 2–5 above describe dependent work, not additional scope for this patch.
|
||||
|
||||
The composition constructor must share final-namespace, qualified-target, complete-occurrence, original-source, token-spelling, order/overlap and active-budget checks with the existing standalone path. It may defer **only the hypothetical typed-only final output-length check**. It must still bound rename-map records, owned final-name bytes and edit records before allocation. Export revalidates exact supplied current numeric file keys and bytes and returns an opaque read-only view borrowing the Plan; it cannot return/install a candidate Project or grant ordinary-file ownership. Keep constructors and internal edit fields private. An empty batch is valid. This private batch remains tied to the existing typed-only index provenance; it must not claim the future complete-bundle/session guarantee.
|
||||
|
||||
Use one caller-supplied inherited Budget throughout the private test operation, with no fresh permissive budget inside the new constructor/export. This patch need not redesign Budget or Index to store a production parse-session profile. That stronger ownership is deferred with the real parsed-bundle witness and must be settled before production composition. `Budget::active()` remains mandatory, including a previously latched parse/numeric failure.
|
||||
|
||||
Minimum focused acceptance oracles:
|
||||
|
||||
1. The existing standalone `Plan::renames` and `Plan::apply` keep rejecting typed-only output exceeding the profile. Under that **same profile**, the composition constructor/export accepts the otherwise valid growing batch when its plan/name/record storage fits. Independently calculate an ordinary shrink sufficient to place a hypothetical complete result exactly at the cap, and explicitly label this as deferred-final-size arithmetic, not a compositor test or accepted output. This proves why only output preflight was split.
|
||||
2. Source/name-memory/record bounds remain effective on composition construction: invalid alias, final namespace collision, unknown qualified target, over-limit renamed-name bytes and edit count fail. A shrinking hypothetical ordinary edit cannot authorize an over-limit plan. Exact-bound positives and plus-one negatives should isolate the intended bound.
|
||||
3. Export rejects missing/changed/extra source files or altered unrelated bytes, a forged/wrong token location, duplicate occurrence and incomplete edit membership. Use module-private damage controls to exercise checks inaccessible to normal callers. Failure returns no batch and leaves input unchanged.
|
||||
4. A simultaneous global/scoped swap exposes exactly the independently enumerated original file/span/old spelling/new spelling/qualified key tuples in deterministic order. Include repeated call labels and same UUIDs in distinct parameter/global scopes. Same-name/no-op input exports zero edits.
|
||||
5. Construction/export leave parse usage and numeric work unchanged; no whole-file typed output is materialized or `Plan::apply` invoked along the export path. Verify this through the narrow implementation's control flow plus tests of exposed records, rather than treating unchanged counters alone as proof of allocation behavior.
|
||||
6. Existing standalone rename, stale-index, namespace and output-limit regressions retain their original oracles. The new type exposes read-only accessors and no mutable record, arbitrary batch constructor, or caller-selected subset acceptance API. Exact complete model/bundle equality remains a later integration gate, not an assertion that this export patch can establish.
|
||||
|
||||
Passing these oracles is sufficient to deliver the private export patch. It is not sufficient to close S3/S4 or claim graph/text/source8 functionality. The next dependency is concrete complete parsed-bundle provenance and ordinary-operation normalization, followed by the compositor and actual mixed parser path.
|
||||
Reference in New Issue
Block a user