Status: delivered (trellis-ff52, plan pl-43c5 step 11). This page
documents how trellis pins, discovers, and verifies the external
quality-evidence provider artifacts it may execute — without ever
installing, updating, or downloading anything at audit time (SPEC §16.4
"Trust boundary — supported installation").
Native analysis and scoring stay the default and the authoritative basis.
Optional providers are opt-in, unscored evidence; an absent tool never
changes a native audit (a default trellis audit never touches this
machinery at all).
The bounded conformance and failure-regression record for the jscpd
adapter and its normalization — expected evidence, forced failure states,
repeat/runtime/memory observations, and retained leads — is
jscpd-conformance.md (trellis-b0ec).
src/providers/manifest.ts— the supported-tool manifest: one entry per pinned external tool with the exact package version, the bin layout, the SHA-256 digests of the pinned distribution's cross-platform files, and the declared platforms with their honest execution records.src/providers/resolve.ts— the local resolver: discovers an installed tool, verifies it against the manifest, and returns a located outcome — a verified executable path, orunavailable/unsupportedwith an actionable reason and install instructions.src/providers/process.ts— the controlled process runner's executable registry resolvesjscpdthrough this manifest (requirePinnedToolExecutable); execution itself stays behind the step 9 limits (fixed argv, no shell, explicit environment, wall-time/output bounds).
jscpd 5.2.1 (providerId: jscpd) — the duplication-evidence candidate.
The pin records:
- the npm package identity (
jscpdat exactly5.2.1— no ranges), - the expected
bin.jscpdentry (./run-jscpd.js), - SHA-256 digests of the two cross-platform files the package ships
(
run-jscpd.js,platform-map.js), recorded from the real npm distribution, - the platform packages (one per OS/CPU/libc, e.g.
jscpd-linux-x64-gnu) with the binary path (bin/jscpd,bin/jscpd.exeon Windows), and - a per-platform execution record (see below).
dependency-cruiser 18.3.1 (providerId: dependency-cruiser, plan
pl-43c5 step 22 — trellis-adbf) — the architecture-evidence adapter's
pinned tool. A pure-JavaScript distribution: its "binary" is the
launcher script bin/dependency-cruiser.mjs, so
- the pin records the launcher digest plus the package manifest's digest (the tool ships no platform map — the package manifest is the second cross-platform identity file),
- the declared platform's "platform package" is the tool package itself
(there is nothing platform-specific to resolve), and the adapter runs
the launcher under trellis's own runtime through the controlled
process runner — never a PATH lookup, never
node/bunx, with an owned minimal environment (HOMEinside the owned scratch: the tool resolves its global configuration through the home directory), and - the tool reads TypeScript through the compiler it resolves locally; the
adapter resolves and records that compiler's version in analysis
identity before anything runs — a missing or mismatched parser produces
a successful empty graph (the research record,
docs/research/architecture-provider-spike), so the adapter refuses to run blind and the coverage check keeps an empty graphincomplete.
For dependency-cruiser 18.3.1: linux-x64-gnu and darwin-arm64 are
tested (the adapter's conformance and failure-regression suites plus the
provider smoke). The macOS acceptance record names
the exact runtime and verified launcher digest. No other platform is
declared: the distribution is JavaScript, but trellis claims only what it
exercised. Shared launcher packages must match both the launcher path and
its verified digest across host entries.
Knip 6.16.1 (providerId: knip, plan pl-43c5 step 24 — trellis-8ebc)
— the contextual reachability-evidence adapter's pinned tool. Like
dependency-cruiser it is a pure-JavaScript distribution, and it ships
a dedicated Bun launcher (bin/knip-bun.js) — the artifact the pin
verifies and executes under trellis's own runtime through the controlled
process runner (src/providers/knip/invocation.ts), never a PATH lookup.
The pin reuses the exact devDependency this repository's own check:deps
gate already installs — never a second copy. The adapter additionally:
- derives the runtime plugin registry's names from the pinned artifact's own registry file (a static read of a digest-verified distribution file — never imported or executed) and disables every plugin, so no framework/tool configuration or entry convention can reach the declared reachability model;
- resolves and records the
oxc-parserversion the tool finds locally in analysis identity (Knip's manifest pins a range, so the exact parser is a property of the prepared installation), refusing to run blind; - generates the tool configuration from the prepared reachability context
into owned scratch — the declared roots as
entry, the production candidate scope asproject, a generated minimal tsconfig, and a generated minimal workspace manifest written into the staged tree (trellis-owned scratch — the target's own manifests andknipconfigurations are never loaded); and - neutralizes the findings exit code and promotes configuration hints to
errors, so the exit status carries the tool's coverage signal: a hint
means an empty or partial analysis, located
incomplete— never a clean pass, and zero candidates never proves overall quality.
For Knip 6.16.1: linux-x64-gnu and darwin-arm64 are tested
(conformance and failure-regression suites plus provider smoke). The
combined acceptance record records macOS execution
with oxc-parser 0.133.0 and all 155 runtime plugins disabled. Other hosts
remain undeclared; JavaScript distribution alone does not prove support.
trellis never installs, updates, or downloads tools. The supported execution context is a local installation prepared by the operator:
- In this repository the pin is an exact devDependency
(
"jscpd": "5.2.1"inpackage.json), sobun installprepares the exact artifact offline frombun.lock. The dups gate and the provider smoke (bun run smoke:provider-tools) then resolve it locally. The dependency-cruiser pin is prepared the same way ("dependency-cruiser": "18.3.1"), alongside the repository's owntypescriptinstall the tool resolves as its parser. The knip pin is prepared the same way ("knip": "6.16.1") — the exact devDependency the repository's owncheck:depsgate uses. - For a CLI install, prepare the tool in the
node_modulestree trellis itself resolves from, e.g. in the package that depends on@os-eco/trellis-cli:npm install --save-exact --save-dev jscpd@5.2.1(orbun add --dev jscpd@5.2.1); likewisenpm install --save-exact --save-dev dependency-cruiser@18.3.1andnpm install --save-exact --save-dev knip@6.16.1.
A request for a tool that is not installed resolves to unavailable with
these instructions attached (SPEC §16.2/§16.3) — never a fabricated run and
never an audit-time acquisition.
Resolution walks the node_modules chain upward from trellis's own
module location — the operator-prepared installation trellis runs from.
It never:
- searches
PATHor runsbunx/npm exec(no opportunistic downloads), - accepts a target-workspace, operator-supplied, or command-string path,
- installs, updates, or downloads anything, or
- executes the tool during resolution.
Before a resolved artifact may run, it is verified against the manifest:
package name, exact version, bin layout, distribution file digests,
platform-package identity and version, binary presence, and — where a real
host produced one — the platform binary's digest. Any mismatch is a
located unavailable result; trellis never silently uses a different
version than the pin.
Every declared platform carries an execution record:
| Record | Meaning |
|---|---|
tested |
installed and invoked offline by this step's package smoke on that host (scripts/smoke-provider-tools.ts, also exercised by src/providers/resolve.test.ts in CI) |
research-tested |
installed and invoked by the research spike, with the binary digest recorded from that host (docs/research/jscpd-provider-spike/summary.json) |
declared-untested |
shipped by the pinned tool's platform map but never executed by trellis — no digest is recorded for it |
For jscpd 5.2.1: linux-x64-gnu is tested; darwin-arm64 is
research-tested; linux-arm64 (gnu/musl), linux-x64-musl, darwin-x64, and
Windows (x64/arm64) are declared-untested. Hosts outside the table
resolve unsupported — trellis claims no universal platform support. A
declared-untested platform that is present resolves with
binaryDigestVerified: false (everything except the binary digest is still
verified); the recorded digests are the only ones claimed.
The pinned tool version is part of provider identity and therefore of analysis identity (SPEC §16.2): evidence compares only across identical provider and analysis identity (SPEC §16.6). Consequences:
- Bumping the pin (e.g. jscpd 5.2.1 → 5.2.2) is a manifest change: new version, fresh digests from the real distribution, and fresh platform execution records. It must never happen silently at runtime.
- Old reports remain valid; their evidence simply predates the new pin and compares as a different basis, never as a silent trend.
- The adapter version, mode, and option set (later steps,
trellis-f4e2) join the tool version in analysis identity.
- The pin is a devDependency, never a runtime dependency:
scripts/smoke-package.tsasserts the packed tarball keeps optional provider tools out of the native runtime (EXCLUDED_OPTIONAL_TOOLS). knip.jsonlistsjscpdanddependency-cruiserunderignoreDependencies— justified because the artifacts are resolved by string at runtime through the manifest (the pins must stay); removing a pin to satisfy the dependency gate is not an option.- Nothing in
src/audit/, scoring, or the report schema reads this machinery; only explicitly requested provider evidence will (later plan steps).