7.7 KiB
Mixed source8 command-line checking
Selected next outcome in the already-owned textual-language scope: an engineer
can run arcadia check-mixed ROOT [--json] on an explicit entry file and receive
located results for its complete included mixed model, without changing files.
Baseline source is public-read checkpoint bab6f96a. This contract is local-only
while Gitea writes/publication remain unavailable. The published preview is frozen.
User-visible behavior
Keep existing check/lint/stabilize/rename behavior and the ordinary library
prepare contract. Add one explicit check-mixed spelling, rejecting --write,
unknown/repeated options and invalid argument counts. Route it separately from
editable preparation; do not construct a fake Prepared or SourceIndex. Use a
closed command-dispatch enum rather than an ambiguous combination of mode flags.
The existing Report envelope remains version1. Operation is check-mixed; success is checked/exit0, with advisory warnings permitted. Changes is empty, written is false, migration is null, identities_to_stabilize is zero. All locations refer to captured original input. Missing explicit UUIDs, unsupported versions, malformed syntax and semantic invalidity are errors, not implicit stabilization or migration. Retain actual warning order and authored object identities from the admitted model.
Use the existing exit conventions: source/semantic rejection1, arguments2, disk/path/journal/output failure3. Match existing treatment of loader diagnostics and disk error variants, including its source-limit distinctions; document/test the actual relevant precedence instead of assuming every limit uses one phase. Human output/help must explain the explicit-ID schema8 read-only contract and make the check result clear without implying proposed edits.
Source discovery and ownership
Add source_files::load_mixed_source(entry, limits) returning an opaque
MixedSourceSnapshot with immutable bundle() and diagnostics() views. It captures
original bytes only. It confers no save authority, editable compilation, recovery
or promise of an atomic snapshot against another process. A caller must handle
discovery diagnostics before treating the bundle as complete. CLI owns this
snapshot, invokes check_mixed_bundle on its borrowed bundle only after discovery
succeeds, and copies diagnostics into the owned report before dropping the result.
Reuse the existing private disk discovery loop and path/read/physical-alias/journal checks through a closed ordinary/mixed selector. The ordinary route remains unchanged, including overlays, detached buffers, expectations and final compilation. The new fresh mixed route has no overlays and skips ordinary compile_bundle. Consume its private DiskProject storage into bundle/diagnostics and discard unused expectations/root/reachability after the checks; avoid cloning reachable_bundle or exporting DiskProject as mixed save authority.
Before disk reads, clamp the mixed source-byte allowance to min(caller,64MiB), matching the parser's hard ceiling; preserve all other caller restrictions. Keep canonical root-relative paths, UTF-8, regular-file/link rules, case and physical-alias detection, aggregate files/bytes/edges/depth and pending journals. Pending transactions remain an error and are never recovered implicitly. Resolve includes with the existing resolver. Parse each successfully loaded path once in existing deterministic traversal order; count repeated authored edges. Complete semantic checking still detects cycles and cross-file errors.
Inspect includes by the real shared mixed Parser::unit grammar, including typed declarations, explicit IDs and long-form refusals. Centralize the minimal parser setup/operation needed by discovery and complete parsing; preserve the latter's grammar, producer hooks, policy, retained witnesses and stack behavior. No regex scanner, second grammar or complete-checker call on partial bundles is permitted. Return no partial include list after a unit syntax failure.
Bounded discovery phase
Choose one shared discovery Budget and ModelCounts for the entire discovery pass, derived by the existing mixed source profile. Enable existing text and entry producer checks once with zero initial reservation. Byte/token/reference/numeric work and syntax/model counts accumulate across files; do not restart allowances per file. Charge each inspected file before lexing/parsing and keep the existing prospective syntax/value/owner producer checks. Tokens keep their existing pre-scan bound; disk/path/traversal tables retain their separate filesystem limits. Do not allocate edit positions or a resolved/indexed model merely for discovery.
Completed unit syntax is dropped after moving its include information. Its remaining producer charges deliberately remain reserved until this phase ends: these counters are a conservative cumulative admission bound, not a claim of exact live storage or a verifier-owned carry. Ordinary in-parser temporary and UUID/key releases remain unchanged. No unit-drop refund mechanism or new generic allocation framework is needed. Shared grammar and once-per-path order consume the same syntax/work events as full parsing, with fewer later projections; tests must discriminate cumulative accounting from accidental per-file resets.
A syntax/budget failure is terminal for mixed parsing: record its original located diagnostic, do not reuse a poisoned span-only Budget for another file, and do not invoke final model checking on incomplete discovery. Still perform required final filesystem and journal checks. Ordinary aggregation remains unchanged.
After successful discovery, drop the discovery budget/scratch and run the existing complete checker with a fresh profile and the original caller policy. These are two explicitly bounded passes, not a claim of one shared whole-command numeric allowance or all-heap accounting. Discovery grants no semantic admission witness.
Acceptance
- Real executable and library cases load mixed OA/SA multi-file fixtures with cross-file/scoped typed references and nested ordinary records. Independently construct complete expected models for those same bytes; check actual complete JSON/human diagnostics and status rather than inventing a model field in Report.
- Prove exact source/directory preservation on success, warning and refusal, including Unicode/CRLF and comment/string text resembling includes or aliases. Exercise missing UUID classes and wrong-kind/unresolved typed references.
- Test missing/cyclic includes, root/path escape, case and physical aliases, invalid UTF-8/nonregular files, pending journal, and selected exact file/byte/ depth/edge boundaries. Platform-specific checks are claimed only when run.
- Observe the actual shared discovery constructor/counters: multi-file cumulative work, retained conservative reservations after dropping a unit, zero temporary balance after successful units, exact caller/profile capture and first-error location with an unparsed later sibling. Use real small boundary controls with positive cases; test-only tightening must not become public policy.
- All old core and relevant filesystem/source/stack tests remain passing. Run existing ordinary CLI tests plus new mixed CLI tests, actual CLI commands, strict core/CLI Clippy, doctests and formatting disposition. Bind gates to a reviewed clean source commit and preserve initial failures without weakening model, bytes, locations or resource expectations.
Independent source/runtime review follows implementation. Parent owns integration, compiler execution and acceptance. Core discovery/parser and CLI/report/tests/docs may be delegated with disjoint files and the interfaces above. Linux remains user-deferred; no GUI/editor/save/history or release integration is implied.