Skip to content

v0.13.0 — contract honesty: body-field-drift, baseURL keying, silent no-op sweep

Choose a tag to compare

@github-actions github-actions released this 13 Jul 14:53

Highlights

  • New cross-layer rule: cross-layer/body-field-drift — a frontend request-body literal is checked against the backend @Body() DTO's declared fields on every joined route; mismatches (a body key the DTO does not declare, a missing required field, a missing wrapper key) are reported. Never-guess tone: optional-field omission and backend whitelist-stripping are NOT flagged — only witnessed literal drift.
  • axios.defaults.baseURL path-prefix keying — a literal axios.defaults.baseURL = "/api" (or a host-carrying base with a path part) now prepends its path to that client's consume keys before the cross-layer join. Findings will move: pairs that agree on /api on both sides gain real joins; pairs whose backend does not carry the prefix now honestly report prefix drift instead of accidentally joining. Scope: literal bases only — interceptors, wrappers, non-literal constants and generated clients remain adapter-injection territory.

Behavior changes to expect

  • Cache recompute (one-time): cache schema bumped v18 → v20 (body-shape capture + client-base keying changed artifact payloads). The first run after upgrading re-extracts everything.
  • New warnings for silent config no-ops — config entries that previously did nothing quietly now say so: unknown rule ids in severity overrides and suppressions (joining the existing disabled-rules warning). Each warning names the actual config dialect (rules: { "<id>": ... } / packs.disabled) and the embedder field, so the advice is actionable in both dialects.
  • Reserved sentinel kinds are now dropped with a warning in both envelope modes — an external producer emitting the engine-internal nest-global-prefix / client-base-prefix io kinds gets one aggregate warning per envelope/overlay. In adapter-overlay mode this is also a behavior fix: previously an overlay-emitted nest-global-prefix would re-prefix the whole tree's routes.
  • --json stdout is clean again — the "Wrote N reports…" notice moved to stderr (it polluted parseable stdout in v0.12.0).
  • --help no longer claims "zero-config" (a config file is required; zzop init scaffolds it) and now documents exit codes — scoped honestly: for analysis runs, failOn defaults to "warn" and a first run exiting 1 on findings is expected; zzop adapter validate ignores failOn (its exit 1 means the envelope failed structural validation).

Docs corrections (act if you copied old examples)

  • Every rules: example in older docs used bare DSL ids ("no-explicit-any", "n-plus-one", "toctou") — those entries were silent no-ops. The engine matches exact pack/rule ids: typescript/no-explicit-any, sql/nplus1, sql/race-condition-toctou. All examples are corrected, a CI guard now validates doc example ids against the catalog, and the new unknown-id warnings will flag stale entries in your config at run time.
  • envelope.schema.json regenerated field-for-field against the Rust types (it was one release stale: missing body shapes, loop_spans, is_entry, client; wrong required-ness on four Option fields; sourceSymbol casing) and is now machine-pinned by a bidirectional parity test (names, required, nullability, enums).
  • NORMALIZED_AST: casing contract, reserved-kinds section, absolute-URL (://) verbatim rule, key-normalization crosslinks. ARCHITECTURE: join-integrity gates (cross-tree ambiguity is not auto-linked; :// routes to externalConsumes; low-confidence joins are tagged), sentinel shims, and the user-facing baseURL keying consequence.
  • Report dir is zzop-reports/zzop.<epoch> (Markdown by default, written by default); overlays and git.since are now documented config keys.

Internal quality

Docs rule-id guard, schema parity guard, marker -ok convention pin, disable-hint id-coupling pin, and the CLI unit tests (165+) are all wired into CI. A pre-tag 3-lens release audit (policy values / messages / boundaries) ran on this release; all four confirmed findings were fixed before tagging.

Full Changelog: v0.12.0...v0.13.0