Files
ARCADIA-Studio/harness/analysis-mixed-cli-design-20260925/IMPLEMENTATION-MAP.md
T

164 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mixed CLI read-only check: implementation map
Design only against public-read branch bab6f96a (parent reports accepted gates).
No source edits, compiler or remote actions. Paths/lines refer to this source.
## Recommended user outcome
Add explicit `arcadia check-mixed ROOT [--json]`, requiring the public checker's
schema8 and explicit UUIDs. Preserve check/lint/stabilize/rename-alias behavior.
Use the existing report envelope with operation check-mixed, status checked or
invalid, no changes, written=false, migration=null and identities_to_stabilize=0.
The operation validates captured original bytes; it does not stabilize, export,
format, index or save. Help must state this distinction and reject --write.
The command choice and discovery architecture are separate decisions. Merely
adding a command enum variant does not make the existing loader support typed
syntax. A real parser-consistent discovery seam is the prerequisite below.
## Current blockers and reusable code
- oa-cli/src/lib.rs:213 prepare loads source_files::load_project, then ordinary
lint/analyze/compile (234–310). Operation::Check still returns Prepared holding
CompiledSourceProject and a disk snapshot; it is not a read-only mixed route.
- main.rs:76 dispatches all accepted arguments through prepare and optional write.
Add a separate report-returning mixed-check branch before that branch. Do not
forge Prepared or an empty SourceIndex. An explicit Arguments command enum can
separate read-check from existing editable Operation, or use a distinct
check_mixed flag/variant handled before prepare; avoid illegal write combinations.
- source_files.rs:329 load_project creates a DiskProject then discover_missing.
Discovery's DFS reads bounded bytes and tracks originals/expectations (389–494),
but495 calls ordinary inspect_includes and529 runs ordinary compile_bundle.
- source_project.rs:207–268 inspect_includes validates paths and calls ordinary
language::parse_unit, so it rejects valid short typed declarations. Filtering
that diagnostic cannot reveal the missing include graph safely.
- mixed.rs:390–422 already lexes and invokes the shared Parser::unit with actual
mixed State and explicit IDs, producing ordinary.includes plus typed syntax.
This exact unit grammar can inspect includes without resolving global references.
Extract/reuse this narrow unit operation instead of a regex, guessed brace
scanner, second quote decoder or calling the complete checker on partial bundles.
- source_files.rs:104–216 root_entry/check_logical/disk_path/read_bounded already
enforce root containment, canonical logical names, reserved journal namespace,
link/regular-file restrictions and bounded reads.240 check_snapshot and293
check_physical_aliases preserve aggregate and physical-alias checks. Reuse these
functions in one core discovery engine; do not replicate their security logic in CLI.
## Minimal safe ownership shape
Introduce a named read-only discovery entry in source_files, with a small private
closed selector OrdinaryEditable / MixedRead for shared discovery dispatch.
Existing public discover_missing/load_project select OrdinaryEditable and retain
all current completion/lint behavior. MixedRead selects mixed include inspection
and skips ordinary compile/stabilization; it still performs all disk/path/journal
checks. No generic caller-provided parser/loader callbacks or new public framework.
Prefer an opaque owning `MixedSourceSnapshot` exposing only bundle() and
load_diagnostics(), or a narrowly scoped `load_mixed_source` result owning those
values. Do not advertise it as a save snapshot or provide conversion into editable
CompiledSourceProject. Internally reusing DiskProject's captured bytes is possible,
but returning DiskProject publicly would unnecessarily expose save/discovery
operations and expectations. Keep original raw-byte expectations private if reused.
This design adds a small wrapper, not a clone of every buffer for an extra model.
CLI owns the snapshot, borrows its complete reachable SourceBundle while calling
language::check_mixed_bundle, maps warnings/errors into the existing Report, then
drops CheckedMixed before dropping source. Report owns mapped diagnostic strings;
no borrowed checker escapes and no self-referential source/result struct is needed.
Report has no Project field: complete model evidence comes from independent core
and CLI-library tests of those same literals, not an invented JSON assertion.
## Discovery parser work and limits: resolve before implementing
Discovery is an extra syntax pass; final borrowed checker remains the sole complete
semantic admission. Its existing budgets must be fresh for that full pass; do not
subtract discovery work from final counts or represent a successful partial scan
as an admitted model. Re-reading/reparsing captured strings is explicit bounded work,
not a claim that the checker itself reparses or that disk is reread between phases.
The mixed unit helper needs a genuine Budget and ModelCounts. A naïve new budget
per file silently multiplies allowed discovery numeric/token/reference work by the
file count; a single shared budget with all retained-text totals left charged after
units are dropped misrepresents live storage. Therefore contract must choose a
small explicit **discovery-phase work policy** and lifetime:
- Recommended: one shared discovery work budget across all captured file parses,
cumulative bytes/tokens/references/numeric/syntax-event work, with per-unit syntax
owners dropped after copying only include locations. Reuse Parser::unit and its
resource checks. Name and check temporary per-unit metadata/text ownership before
growth if selecting producer mode; reconcile/release it on unit destruction.
This is a real small producer-lifetime seam to specify, not existing free behavior.
- Simpler alternative: per-unit bounded inspection with a documented aggregate
upper bound of max_files times its cap. It is finite but can be far larger than
the selected checker work profile; do not choose it silently or describe it as
inheriting one whole-project numeric budget. Parent may reject that cost policy.
- Do not retain all parsed witnesses then clone/reparse the complete bundle merely
to avoid accounting a dropped unit. That grows live state and complicates source
lifetimes for no consumer benefit. Do not stream-load into a borrowed BTreeMap
while previously parsed units retain references into it; ordinary Rust borrowing
disallows this without additional ownership infrastructure, which is unnecessary.
The implementation contract should pin the selected discovery bound/diagnostic
order and helper's drop/refund rules before source edits. This is the main remaining
bounded design question, not an argument for full editable-source adoption.
## Filesystem and diagnostic contract
Preserve existing root/file checks, UTF-8 rejection, aggregate byte/file/edge/depth
limits, case/physical alias refusals and pending-journal detection. Root depth0;
include paths resolved by existing resolve_include; count repeated authored edges.
Final complete check still rejects cycles/semantic failures using its exact original
coordinates. Discovery diagnostics prevent invoking checker with missing/invalid
buffers. Return exit3 for disk/path/pending-journal failures under existing CLI
mapping; exit1 for source/semantic rejection,0 for valid with advisory warnings,
2 for invalid arguments. Pin mixed loader's diagnostic precedence in tests rather
than assuming it equals in-memory checker's earlier/later limit branch.
Do not suppress pending_save simply because operation is read-only: existing CLI
refuses it, and the captured files may represent interrupted save state. No journal
recovery is implicit. Neither old nor new read path promises atomic multi-file
snapshot/CAS against concurrent external replacement (source_files.rs:177 comment).
Promise unchanged bytes by this command and validation of captured bytes, not
that the disk still equals that snapshot after a concurrent editor writes.
## Compared/rejected options
- Automatically replace ordinary check with mixed: breaks existing omitted-ID and
migration behavior. Schema8 alone does not distinguish ordinary drafts from the
stricter explicit-ID mixed contract. Avoid heuristic detection/fallback on errors.
- `check --mixed`: coherent alternative explicit spelling, but adds an option whose
invalid combinations must be excluded for mutations. Dedicated check-mixed makes
the limited outcome easier to explain; select one spelling, not both initially.
- Explicit all-files CLI manifest/bundle: can reuse checker immediately, but forces
users to enumerate includes and introduces another input/argument format. It is
useful only if a real pipeline already supplies bundles; not the recommended
ordinary filesystem workflow and not a substitute for safe include loading.
- Full compile_bundle adoption: requires typed stabilization/index/update/formatter
and application consumers; none is necessary for this read-only outcome.
## Finite acceptance and scoped files
Core changes: source_files shared discovery selector + read-only snapshot;
language mixed unit inspection helper and narrow reexport for core-only use;
source_project include-location conversion reuse where appropriate. CLI lib
arguments/report path + main dispatch, docs/source-cli.md/help, focused tests.
No changes to updater/save/formatter or public CheckedMixed authority.
Test actual executable on independently authored OA/SA three-file fixtures with
cross-file typed/scoped references and ordinary nesting. Exact complete JSON
warning/error reports, raw original byte hashes/directory listing unchanged after
each command, including CRLF/Unicode and comments mentioning include/aliases.
Core tests compare independently authored full models for those same bytes.
Exercise missing/cyclic include, invalid path/root escape, case/physical aliases,
nonregular/invalid-UTF8 file, pending journal and exact aggregate/depth/edge limits.
Only claim platform-specific link/FIFO tests where cfg permits; Linux remains
user-deferred. Exercise missing IDs in all four classes and typed unresolved/wrong
kind errors. Verify --write rejection and all existing ordinary CLI commands remain
unchanged. No fake success for an empty include graph or wrong command dispatch.
Add unit-hook counter/lifetime evidence for the chosen discovery work policy and
repeat relevant existing filesystem/stack regressions after shared-loop factoring.
Parent decisions needed: command spelling; explicit discovery work/storage policy
above; whether reuse of private DiskProject storage under opaque wrapper is worth
its duplicated captured bytes versus a smaller read-only buffer owner. No source
or compiler work is authorized by this proposal.