Skip to content

feat: config includes and baseline anchor mode for multi-module repos - #33

Merged
aksOps merged 1 commit into
mainfrom
feat/v1.1-multimodule
Aug 4, 2026
Merged

feat: config includes and baseline anchor mode for multi-module repos#33
aksOps merged 1 commit into
mainfrom
feat/v1.1-multimodule

Conversation

@aksOps

@aksOps aksOps commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

v1.1 phase B, implementing the multi-module decisions from map #22 (tickets #25, #26).

What

  • Config includes: root siloscan.toml may declare include = [...]. Included files contribute silos, source_roots, and rules dirs ONLY - any root-only key (anchor, duplication, nested include) is a load error naming the file and key. Silo name collisions anywhere (root-vs-include, include-vs-include) are fatal, naming both declaring files. Single-level. Every path resolves relative to the file that declares it.
  • Anchor mode: top-level anchor = "scan-root" (default) | "config". anchor=config moves everything path-shaped in one move - fingerprint inputs, displayed paths, JSON/SARIF paths, metrics.files keys, baseline entries - to config-root-relative. All paths flow through a single Anchoring::relative call site, so fingerprint/display divergence is structurally impossible.
  • Interchangeability delivered through the CLI, not just the library: config discovery climbs to the owning root when the discovered siloscan.toml is an include target of a parent config, so 'siloscan modules/api' without --config uses the same convention as a whole-repo scan. The baseline file resolves against the config root under anchor=config, so 'siloscan baseline ' then a module scan suppresses matched findings with no flags.
  • Guards: anchor=config with no loadable config exits 2. Scan root outside the config root exits 2. require_config_root now compares against the loaded config's root (not a re-discovered one), so boundary rules and silo-scope gates cannot run on a partial subtree via --config. Cache keys carry the anchor convention and path prefix - entries never serve across conventions (verified in both flip directions against --no-cache ground truth).
  • JSON report: additive top-level anchor field. SARIF: run.properties gains siloscan/anchor (deliberate deviation from the JSON-only wording of ticket Anchor mode mechanics: key shape, report paths, migration UX #26 - relative artifact URIs are meaningless without the convention; property-bag additions are safe for SARIF consumers).

Verification

  • 571 workspace tests; clippy -D warnings and fmt clean.
  • End to end: whole-repo, module-without---config, and module-with---config scans emit identical paths and fingerprints; baseline round-trip from repo root suppresses module-scan findings; root-only-key-in-include, silo collisions, nested include, missing include file all exit 2 with the locked messages.
  • Determinism: one distinct SHA-256 across worker counts 1/2/4/8 x cold/warm/no-cache on the anchored fixture.
  • No-anchor behavior: human output and exit codes byte-identical to phase A; JSON adds only the anchor field.
  • Adversarial review found 3 CLI-seam blockers (discovery adopting an include target as root config, guard bypass via --config, unanchored baseline location); all fixed with 5 regression tests plus e2e re-proof. Follow-up minors fixed: bare-filename --config path normalization, include glob rebasing no longer splits on globset escape backslashes.

@aksOps
aksOps merged commit 03fa5e2 into main Aug 4, 2026
7 checks passed
@aksOps
aksOps deleted the feat/v1.1-multimodule branch August 4, 2026 04:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant