mars-schema 0.28.0

Pure schema reader and editor for Mars agent packages
Documentation
# mars-schema

This crate reads, validates, translates and edits package data without host I/O. The
binary owns filesystem and network access, orchestration, consumer configuration and
target lowering. Keep the crate usable on `wasm32-unknown-unknown`: the same rules and
serialized results are used by the CLI and JavaScript callers. Share types and rules
across those callers rather than making a second binary-side copy.

## Reading and preparation

- Route authored definitions through the shared reader. Schema-v1 authored fields are
  strict; foreign and pre-v1 definitions go through translation and `set_aside_rejected_keys`
  so an uneditable dependency can still install. Preserve valid entries in `LoweredField`,
  `skill::LOWERED_KEYS`, and network host lists; losing a deny entry can widen permissions.
  Record lost deny/ask tools, disallowed tools, deny hosts and restriction fields as
  `field.restriction-lost` changes, exposed by `Prepared::lost_restrictions`.
- Ordinary reading leaves schema-v1 files as written; migration may repair removed
  fields because it writes the result back. Upgrade definitions without changing
  unrelated bytes when possible. Do not change a dependency's `requires-mars` during
  preparation: it gates whether the dependency can be read. Migration adds a missing
  floor when it can edit the manifest minimally; it leaves an existing requirement
  or an inline package table unchanged and provides advice when needed.
- A `mars.toml` without `[package]` is consumer configuration, not a package manifest.
  `project_authored_root` selects `.mars-src` with `AuthoredLocal` for consumer
  configuration, otherwise the project root with `Package`.
- Prepare before applying consumer filters and renames. Check skill body links against
  the actual installed layout after those choices: preparation cannot know whether a
  target from another package will be installed. Use `selection::select` and its
  `SelectionResult` for Agents, skills and bootstrap documents so callers agree.
- Read consumer dependency entries strictly. A package dependency's conflicting
  filters or `plugin` plus `dialect` warn instead, so a dependent can still sync.
- Preserve `.git` and `node_modules` in Mars skill payloads even though foreign
  skill imports exclude them: installed Mars packages depend on that behavior.
- Report wrong-transport MCP server fields as ignored rather than failing the parse,
  so a usable server can still install.

## Compatibility

- Dependency `version` and `requires-mars` / `requires-meridian` use different
  grammars: bare `0.20` is a caret range for a dependency and a minimum for a
  requirement. Keep their parsers distinct.
- `version::keeps_lock` keeps a lock under `PreferLockThenLatest` when every
  semver constraint allows it, it is not excluded, and no request asks for latest,
  without checking whether its tag still exists upstream. This lets a locked
  install replay without listing tags. Every constraint must hold at the chosen ref;
  incompatible pins and a pin beside a range fail.
- Preserve the published read, edit, preparation, selection and hook output shapes,
  including authored spellings and ordered values, across Rust and WASM. The fixtures
  under `fixtures/` exercise both implementations; review changes to expected output
  as contract changes. Keep `serde_json/preserve_order` off: feature unification
  would change the binary's JSON output. Use `OrderedValue` for authored order.
- Keep frontmatter size and nesting limits: YAML scanning grows quadratically with
  nesting, so a size limit alone does not bound parse time. Keep semantic parsing and
  structural scanning distinct when changing YAML handling.