- Stop automatically executing repository configuration. Use
--config <path>to select a trusted.ts,.mjs, or.jsfile; otherwise an existing executable config produces a migration error (exit 2) without running it.--no-configstill skips configuration entirely and cannot be combined with--config. loadConfig(cwd)reads JSON instead of executing discovered code. UseloadConfig(cwd, { configPath: 'siro.config.mjs' }); the optional Node-version argument is nowoptions.nodeVersion.
Migration: move data-only settings to siro.config.json, or pass --config <path>
for code you trust.
- Automatically read
siro.config.jsonas data, with precedence over coexisting JS/TS config. JSON supports built-in settings only: custom rules, reporters, module references and config inheritance are rejected. Invalid JSON fails without fallback. JSON honors native scan budgets and strict filesystem checks. - Reject unknown package-manager names and invalid binding maps in
requireConfigKey. - Report async or nonboolean results from
requireConfigKey'sacceptandappliesfunctions as configuration errors (CLI exit 2) instead of treating them as policy decisions. Async results are rejected without unhandled Promise rejections. - Ship the distribution unminified, so published stack traces and code match the reviewed sources.
- Simplify configuration and contributor documentation.
Explicitly selected synchronous custom policies, decoded JSON schema 3, Node requirements and inspection scope remain unchanged.
- Report oversized custom rule groups as finding-limit errors (CLI exit 2), rather than JavaScript argument-limit failures (exit 70). Larger caller-supplied finding budgets also work without truncating results.
- Reduce distribution size and repeated configuration work during scans.
Public API, CLI options, decoded JSON schema 3, Node requirements, inspection scope and safety limits remain unchanged.
- Add
--no-configto skip executable repository configuration, and--strict-filesystem/ APIrejectSymlinksto reject native input-path symlinks. Defaults retain automatic config and symlink resolution; neither option is a sandbox. - Add finite scan/output budgets, caller overrides (
limits, CLI--max-*) andDEFAULT_SCAN_LIMITS/ScanLimitsexports. Oversized/deep inputs now fail with exit 2; output overflow exits 70 rather than producing a truncated success report. - Omit source excerpts from JSON/YAML/TOML syntax diagnostics. Observed finding values are not secret-redacted.
- Fix argument-limit failures when inspecting large Deno scoped import mappings.
- Update locked transitive dependencies to brace-expansion 5.0.12, markdown-it 14.3.1 and fast-uri 3.1.8 for upstream security fixes.
- Correct first-run safety examples to use
npxwithout a global install. - Separate build/verification from OIDC staging of the verified artifact, with release identity, digest and main-ancestry checks.
Node requirements, direct dependency versions and decoded JSON schema 3 remain unchanged.
- Discover package.json and strict deno.json recursively by default, independently
of PM workspace declarations. Remove
--workspaces/ APIworkspaces, including false; legacy calls receive migration errors. PM exclusions no longer hide fixtures, vendor or dist. Useexclude: ['test/fixtures', 'vendor', 'dist'], orexclude: ['**']to keep only cwd. - Add common exclusions and explicit
installationRoots(default['.']). Arrays replace config values;[]disables installation checks, not publication checks. Example:siro lint . --installation-root . --installation-root tools/standalone. Additional independent installation projects are not automatically inferred. - Resolve PM/version locally: root options stay at cwd, additional roots use their entry/local detection, and other packages use manifest-local evidence. Unknown PMs still receive generic publication checks; unknown availability is not safety.
- JSON schema 3 adds
inspection, required findingdirectory, and optionalpm. Generic publication findings run once per manifest without a synthetic PM. - Require injected
FileSystem.readDirectories; removeresolveDirectory. Skip directory symlinks,.git, node_modules and explicit exclusions before reads. No implicit vendor/dist/fixture exclusions or native filesystem fallback. requireConfigKey.defaultSafetyexplicitly controls safe-default downgrades; omitted safety is conservative. VersionNote has no policy effect.- Reporter calls require scan cwd as a third argument:
await reporter.format(result, io, { cwd }). Await built-in reporters and direct IO writes, which may now complete asynchronously; handle output rejections. Two-argument custom reporter implementations can ignore the additional context.
- Validate consumed Deno publication metadata before applicability and check exact registry pins in both inline imports and scopes. Reject unrepresentable npmrc age cutoffs rather than treating any positive integer as protection.
- Respect known pre-12 npm targets when checking npm-shrinkwrap.json; explain removed or unknown-version lockfiles instead of incorrectly reporting that no file exists.
- GitHub annotations reference the correct absolute file using the supplied scan cwd. API/JSON paths and schema 3 retain their existing meaning.
- Escape untrusted display controls and workflow markers without changing API paths or parsed JSON values. Observe actual stream writes and preserve exit 70 on output failure. IO may complete asynchronously; synchronous return values remain ignored.
- Reject Promise/thenable config exports and check results without an unhandled rejection overriding the configuration-error exit. Keep lint synchronous.
- Deno empty/age-null/exclude-only objects no longer falsely satisfy release age. Valid omitted ages use active local npmrc fallback, retaining zero opt-out and explicit-age precedence. Leaf remedies preserve valid exclusions.
- npm own publishConfig.provenance overrides npmrc, including false. Validate its consumed boolean type; align finding/remedy with the responsible file and keep both locations' old-target availability guards.
- Preserve legal POSIX backslash and colon directory names without confusing them with separators or portable user input. Reject malformed/traversing adapter names.
- Make every remediation operation path relative to scan cwd, including multi-file remedies. Findings without a responsible file remain file-less.
- Fix Windows package verification for paths with spaces and shell metacharacters.
- Make one-shot and locally installed usage explicit, restore rule configuration examples, and update moved documentation anchors in findings and the rule reference.
Installation checks use local settings, not inherited effective policy. Manifest-only children have no provenance-policy checks, and child executable configs are not loaded. See scope and migration and schema 3.
- Reorganize runtime code around explicit domain and application ports, concrete adapters, and outer composition while preserving the public API, CLI, JSON schema, package-manager policy, and error behavior.
- Make the source dependency graph acyclic and enforce inward dependencies with TypeScript module resolution, including type imports, re-exports, host globals, and unresolved local modules.
- Move filesystem, path, glob, configuration loading, reporting, and clock behavior behind focused boundaries. Keep JavaScript date parsing in the adapter and inject the current time into release-age policy.
- Centralize workspace pattern classification and Deno release-age parsing, replacing incidental regular expressions and string rewrites where direct string operations are clearer.
- Consolidate tests around observable decisions, failures, public wiring, CLI behavior, and installed-package contracts. Remove duplicate, implementation-coupled, mock-self-verifying, and library-guarantee cases.
- Add architecture and maintainer documentation for dependency direction, composition, ports, adapters, and behavioral contracts.
- Invite real-world feedback through GitHub Issues and explain how GitHub Stars inform time spent on future features and maintenance.
- This release changes internal structure and test coverage only. Existing public exports, synchronous
lint, asynchronouslintCommand, CLI flags and exit codes, JSON schema 2, supported package-manager behavior, and Node.js range remain unchanged.
-
Allow custom checks to return a nonempty
violationsgroup. Report unsupported settings separately per file and Aube lifecycle controls separately per missing file. JSON schema 2 is unchanged; exhaustiveCheckStatusconsumers must handle the new variant. -
Add optional
FileSystem.resolveDirectoryfor Deno's native positive literal-prefix lookup, retaining minimatch and existing dependencies. Virtual filesystems without this port resolve exact child names. Negative patterns retain lexical applicability; conflicting overlapping bases fail explicitly. -
Add
unsupported-settingsto report configured settings introduced after a declared or explicit stable PM version. Cover 16 setting/file pairs across npm, pnpm, Yarn, Bun, and Deno, with a generated table of release sources. -
Resolve each manager's target from
package.json#packageManager,config.pmVersions, or the higher-priority--pm-version/ APIpmVersionoption (which requires--pm/pm). Expose the resolved target asRuleContext.pmVersionfor custom rules. -
Preserve name detection when a declaration has no exact stable version. Reject ranges, tags, partial versions, and prereleases in explicit targets; accept build metadata such as Corepack hashes.
-
Add opt-in
--workspaces/ APIworkspaces: trueto inspect declared npm, pnpm, Yarn, Bun, Deno, and Aube members' publication metadata. Reuse existing rules, identify member file paths, and aggregate severity counts and CLI exit status. -
Add optional
FileSystem.readDirectoriesfor workspace discovery in virtual repositories, without falling back to host IO.
- The new rule defaults to
error; projects with previously accepted unsupported settings may now exit 1. Existing security checks, severity overrides, and JSON schema 2 remain in effect. - Availability checks cover recorded introductions in the listed files, not whole PM schemas, runtime discovery, removals, backports, version-specific value syntax, or effective defaults. Deno coverage is limited to
.npmrc#min-release-age; Aube retains its existing checks without introduction coverage in this release. - Distinguish pnpm's strict-build setting introduction (10.3.0) from general workspace YAML support (10.6.0), and correct Bun's scanner introduction note to 1.2.21.
- Keep shared installation and lockfile checks at the root. Members infer their own publication status and use the root's PM target; child executable configs are not loaded. Workspace discovery requires explicit declarations, excludes directory symlinks, and does not cover effective configuration inheritance. Deno/Aube use bounded, source-derived declaration semantics.
- Update
smol-tomlto 1.8.0 and Vitest to 4.1.11 to include upstream security fixes. - Honor Deno 2.8.1+'s project
.npmrc#min-release-agefallback whendeno.jsondoes not provide an age, while retainingdeno.jsonprecedence and reporting an explicit zero opt-out. - For pnpm targets before 10.9.0, recommend supported
strictDepBuildsgating without claiming that the ignored future-version bypass requires pnpm 10.9.0. - Keep nested workspace candidates visible when only their ancestor candidate is excluded. Prune traversal only when a trailing
/**exclusion covers the subtree. - Reject workspace patterns whose brace-expanded alternatives contain parent traversal or exceed 8,192 entries before compilation, and avoid backtracking in Aube exclusion matching.
- Match npm's odd/even interpretation of repeated leading
!characters. - Match Bun's workspace ordering and syntax classification: explicit members remain included, later positive globs can re-include earlier exclusions, and extglob punctuation stays literal.
- Exclude
CMakeFilesfrom Bun glob traversal while retaining explicitly named members below it, matching Bun's walker and literal-member path. - Honor npm's ordered cancellation of workspace exclusions, including its handling of adjacent repeated exclusions.
- Match npm's leading-
#comment behavior while retaining#in nested path segments. - Permit colons in ordinary relative workspace segments while continuing to reject absolute and drive-letter paths.
- Report rejected workspace glob patterns as configuration errors (exit 2) instead of internal crashes (exit 70).
- Reject non-file manifest inputs before reading, preventing root and workspace FIFO manifests from blocking the scan.
- Match literal workspace path segments and exclusions case-insensitively on macOS and Windows, so declaration casing does not silently omit members.
- Use minimatch consistently for workspace membership, exclusions, and traversal. Remove custom brace expansion and globstar matching.
- Limit workspace traversal using each applicable pattern's own depth, preserving errors from required directory reads.
- Wait for asynchronous reporters and propagate their failures through the command's error handling.
- Reject non-file entries at configuration and lockfile paths instead of accepting directories as existing files.
- Exercise version boundaries, selection precedence, multi-manager isolation, invalid targets, CLI exit codes, custom-rule context, and the installed package's API and strict types.
- Exercise workspace patterns, exclusions, duplicate matches, malformed child manifests, private roots with public children, injected IO, and installed CLI/API member inspection.
- Verify the packed package from an isolated consumer on both supported Node majors in CI. Check distributed files, installed CLI exit codes, package exports, custom rules, JSON output, and strict TypeScript declaration resolution without development dependency types.
- Verify the same tarball before staging it for npm publication, preferring cached dependencies with install scripts disabled.
- Centralize packing, verification, and temporary-file cleanup in
pnpm test:package; retain the verified artifact on request for publication. - Move the release tag/version check into a standalone script while preserving the rejection of private packages and mismatched tags before installation and publication.
- Allow bounded startup headroom for audit subprocess tests on shared runners and report process failures before reading their output records.
- Correct the development dependency audit script to read pnpm advisories and OSV's nested package findings. Fail on malformed reports, command errors, and incomplete scans; preserve vulnerability exit status and advisory details.
- Use an installed official OSV-Scanner binary and explicitly report its absence. Remove automatic scanner downloads and bound command execution and output size.
- Run main-branch CI on pull requests to avoid duplicate checks after merges. Publication still runs full verification for version tags.
- Set the pnpm minimum release age and Dependabot Action-update cooldown to seven days, and align the threat model with those settings.
-
Update development dependencies to address known CVEs and remove deprecated
git-raw-commits. Upgrade Knip and replace its local low-memory patch with upstream support. -
Update pinned GitHub Actions to checkout 7.0.1, setup-node 7.0.0, and pnpm/action-setup 6.0.10 after the three-day release-age window. Explicitly disable automatic Node package-manager caching in the publication job.
-
Set Dependabot version-update cooldown to three days, matching pnpm's minimum release age.
- One remediation per check: replace binding
fix/fixKindand findingfix/fixable/manualStepswith automatic operations or manual instructions inremediation. JSON output uses schema 2. - Explicit library configuration:
lintevaluates without executing repository configuration. Pass extensions insideconfig; useloadConfigto opt into trusted code execution.LintCommandOptionsadds reporting toLintOptions. - Validated extension boundaries: parsed values and
getByPath()results areunknown. Rules, bindings, reporters, and configuration maps require ordinary or null-prototype objects. Path constructors reject invalid roots and parent traversal. - Simpler bindings and exports: remove
fileGlob, separate automatic/advisory binding types,requireConfigKey.extraFix,KeyAssignment, and internal implementation exports.RuleContext.readConfigshares parsed inputs across checks; a violation can identify an additional input file.
- Keep version- and environment-dependent defaults at the configured severity until their conditions can be established.
- Align npm 12 script-policy precedence, URL restrictions, release-age values, and lockfile guidance with the cited upstream policy.
- Read Aube
strictDepBuildsfrom.npmrc, combine it with workspacejailBuilds, and report and propose changes in the correct files. Correct advisory/trust defaults, paranoid overrides, and supported lockfiles. - Honor pnpm
ignoreScriptsand Bun's boolean auto-install disable. Keep store, provenance, and frozen-install guidance within what configuration alone establishes. - Correct npm/Aube exact-save precedence and Deno registry import checks, including tags, missing versions, partial versions, and subpaths.
- Match supported Deno and Yarn release-age formats; reject malformed ages and exclusions while preserving valid exclusions in remediation.
- Honor Deno's configured lockfile path and flag disabled or malformed lock settings. Report unsupported
deno.jsoncexplicitly. - Reject invalid consumed manifest fields, non-mapping JSON/YAML roots, empty JSON, invalid extension results, and inaccessible or non-directory targets with actionable errors.
- Preserve severity overrides for prototype-named rules and compute exit decisions before custom reporters run. Require manual review when remediation would overwrite a settings container or leave a security bypass active.
- Validate repeated, missing, unknown, and non-boolean CLI options consistently. Match Node support against the package engine range.
- Limit the declared Node.js support range to the maintained majors exercised by CI.
- Reject cyclic YAML aliases and excessive alias expansion without repeatedly traversing unused nested anchors.
- Consolidate CLI parsing on Node's argument tokenizer and remove the direct
cacdependency. Keep configuration validation and parsed-file caching at their input boundaries. - Replace custom script loaders, rule scaffolding, layer restrictions, and selective hook machinery with native Node scripts and direct verification commands.
- Generate rule inputs, default severities, and version notes from live bindings. Replace the duplicated version matrix with concise policy sources and interpretation limits.
- Remove private OSS research from the public repository and replace the single-package dependency catalog with exact versions in
package.json. - Build before every test command so executable CLI and public API cases cannot silently skip. Run full verification in CI and before release staging; require the tag to match the package version and stage exactly one packed artifact.
- Pin GitHub Actions to full commit SHAs, disable persisted checkout credentials, and configure Dependabot updates.
- Add security reporting guidance, a threat model, and a concrete configuration example. Clarify executable configuration, static-analysis limits, migration, and package verification.
- Project policy selection:
--project-type application|package,SiroConfig.projectType, andLintOptions.projectTypedistinguish dependency-consuming applications from published packages. Omit the selection to infer policy per package-manager binding. - Scoped custom rules:
Rule.projectTypesfollows explicit or inferred policy for npm-family and Deno bindings.
- Programmatic
lintCommandcalls reject unsupported project type, package manager, and severity values instead of returning misleading results. - Malformed custom rules from config files or untyped programmatic callers are rejected before rule merging and evaluation.
- Empty and whitespace-only package names no longer activate published-package policy.
- Unscoped Deno rules no longer read
deno.jsonsolely for project-type inference. - The published
package.json#binpreserves exit code 70 when a reporter or custom rule crashes, and subprocess tests now execute that declared bin directly. - Malformed or cyclic YAML configurations are rejected, while TOML configurations with a leading UTF-8 BOM are accepted.
- Deno release-age validation accepts documented default forms and rejects invalid, partial, or zero ages.
- Repeated reporter selectors and non-boolean Yarn strict SSL values are rejected as invalid input.
- Findings without automatic remediation operations no longer report themselves as fixable.
- Node.js
^22.18.0 || ^23.6.0 || >=24.0.0required (was>=20):siro.config.tsnow loads via Node's native type stripping.
- OSS benchmarks module: coverage validation against 47 leading OSS projects across all 6 package managers. Includes sparse-checkout clone script, snapshot-based CI mode, and local clone-based checking.
- jiti dependency removed: runtime dependencies drop from 7 to 6.
.tsconfigs load via native type stripping, and everyloadConfigcall now truly re-reads the config from disk (jiti's transform cache could replay a same-second rewrite). - Unminified dist: the published bundle ships as readable JavaScript for supply-chain transparency.
- A
.tsconfig on a runtime without type stripping fails with an actionableConfigErrorinstead of a rawERR_UNKNOWN_FILE_EXTENSION. pnpm gen:ruleworks again — the scaffolder's marker had drifted fromrule-id.ts.
Initial public release. 27 rules across 6 package managers (npm, pnpm, yarn, bun, deno, aube).
- 27 security rules covering lifecycle scripts, version pinning, lockfiles (
commit/frozen), release age, publish provenance,files/publishConfig, SSL enforcement, checksum verification, exotic subdependency blocking, audit suppression review, store integrity, and Bun's security scanner API. - 6 package managers: npm, pnpm, yarn, bun, deno, aube — auto-detected from
packageManagerfield, lockfiles, and config files. - PM-aware severities: findings demoted to
infowhen the PM's documented default already satisfies the rule. - Machine-readable JSON output with
fixoperations andmanualStepsfor automated remediation. - Reporters:
pretty(default),json(CI),github(PR annotations); extensible via custom reporters. - Configuration file (
siro.config.ts): disable rules, override severities, restrict PMs, plug in custom rules and reporters. --severityflag: gate CI onerror(default) orwarnfor stricter checks.--pmflag: target a specific package manager.--jsonflag: shortcut for--reporter json.
Earlier implementations remain available in the release tags. See the rule reference for current policies.
- CI via GitHub Actions (Node 20, 22, 24 matrix)
- Pre-commit hooks: lint (oxlint), format (oxfmt), typecheck, related tests
- Pre-push hooks: full lint, typecheck, test coverage
- Commit message linting via commitlint (conventional commits)
- Dead code detection via knip
- Rule scaffold generator (
pnpm gen:rule) - Documentation generators (
pnpm gen:rules,pnpm gen:comparison) - Version module auto-generation from package.json
- Layering enforcement script