Repository navigation
refactor(cli): adapters, util and toolchain on traust-core's tool doors (XWING-2440) - #286
Merged
smith-xyz merged 2 commits intoOct 27, 2026
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: smith-xyz The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
smith-xyz
added a commit
to smith-xyz/traust
that referenced
this pull request
Oct 27, 2026
smith-xyz
added a commit
to smith-xyz/traust
that referenced
this pull request
Oct 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #279 (lane a,
refactor/traust-core-loader@9189e08). Until #279 merges, this diff includes it; this lane's commit is the last one (4f13b3a).Plan: plans/traust-standardization/0-continuous-ops/17-shaun-traust-core-only.md (part)
Chain: traust-core#225 (
feat/context-tool-doors@e8f4b61, the tool report doors; traust pins core to it) ← #279 (lane a) ← this PR (lane b). Lanes c–e stack on #279 as well, and lane f closes the plan.What
Wave 2 lane (b):
traust adapters,traust util elf|safe-exec,traust admin toolchainandtraust.libno longer import traust-engine. Each op calls one traust-core door from traust-core#225 (traust_core.v1.context.tool_reports). The door returns the same document the engine path wrote, and the CLI keeps its flags, messages, files and exit codes. The doors are interim: the Tool execution API follow-up and plan 19 (preflight) reshape them later.adapters opengrep_execute_opengrep_scan+HarnessEngineallowlist/locationsopengrep_reporton the packload()registers (or--rule-pack)adapters govulncheck_run_govulncheck+ engine profile mapgovulncheck_reportonctx.safe_execadapters checkov(KHS)adapters.checkov.Scannerk8s_hardening_reportadapters gitleaksadapters.gitleaksinternals + engine locationsgitleaks_report(--config, elselocations.gitleaks_config)adapters osv(repo,--sbom,--grype)adapters.osv/osv_sbom,OsvClient,DepsDevClientosv_report/osv_sbom_report; the API path registers the feeds registry (register_feeds) and usesctx.advisories/ctx.deps_devadapters yara_execute_yara_scanyara_reportadapters joern_run_joern_scan+emitjoern_report; the CLI writes the file asemitdidadapters crypto-probe,crypto-auditadapters.crypto_probe,crypto_auditadapters crypto-source / crypto-image / crypto-cluster(core'sCodeFactsService.crypto*); skill/doc lines repointedutil elf_util.elf.ElfAnalyzerelf_reportutil safe-exec_util.safe_exec+ engine profile map,run(honor_bypass=True)ctx.safe_exec(profile,validate_argv,vet_command_string,run_segments); theSAFE_EXEC_DISABLEDbypass moved here: stderr shout + per-user 0700 log, same line and path as beforetraust.libElfAnalyzer& co. from the enginetraust.lib.*ran the engine import)Exit codes are kept: core
ValidationError/IntegrityError(refused rules sources,--rule-allow) → 2, as the engine'ssys.exit(2)was. A rule pack that isn't a directory (ConfigError) → 1, as the engine'sValueErrorwas. A missing safe-exec/toolchain config file → 2 (config not resolvable: …).src/traust/_tools.pystays:context.py's twoPENDING(pack: …)branches still need it, andadapters govulncheck|osvtakeharness_version(the engine package version, unchanged) from it. Lane (f) deletes it.Ratchet:
.ratchet.jsononly shrank:engine-internaldropped fromadapters.py(3),util.py(2),toolchain.py(1) andlib/__init__.py(1); all four entries are gone.tests/test_engine_imports.py's baseline shrank to match (adapters.py15,util.py2,toolchain.py1,lib/__init__.py1 removed). Nothing was added.Behaviour changes
From core's tools (traust-core #205/#211/#212/#225):
PATH HOME LANG LC_ALL TMPDIR GRYPE_DB_CACHE_DIR, scanners withconfig.process.keep_env(defaultPATH HOME LANG LC_ALL TMPDIR), never the whole parent env. A proxy or token a tool needs must be named inprocess.keep_envadaptersop,admin toolchainenvgrant; no shell orenvsegment even in warn mode.util safe-exec runin warn mode refuses such a segment with rc 126[safe_exec blocked: …]; the engine ran anything in warn modeutil safe-exec runwithSAFE_EXEC_MODE=warnsafe-exec-profiles.yamlis exit 2 naming the file, and an unknown profile is exit 2 (unknown safe_exec profile …); the engine fell back to built-ins / raisedKeyErrorutil safe-exec,adapters govulncheck"<tool> not found on PATH (<bin>)"/"<tool> timed out after Ns"(exit 1 as before)--rule-allowand an unverifiable rules cache now exit 2 withERROR: …(the engine'sSystemExit(msg)exited 1);--rules autoand a missing local source stay 2adapters opengrepSystemExit(msg)= 1)adapters yaracoverageblock counts the pack the scan used; with--rule-packthe engine counted the locations/bundled packadapters opengrep --rule-packversionis traust-core's--timeoutno longer sets the per-request timeout (core's HTTP policy does); deps.dev answers are cached in the object store instead of<feeds cache>/deps-dev. With both--sbomand--grypeunreadable, the--grypeerror is reported firstadapters osv--confignot a file, remotelocations.gitleaks_config) isERROR: …exit 1 instead of a traceback (also exit 1)adapters gitleaksContext(joern,yara), so an invalidcore.yamlexits 2 thereadmin toolchain doctor's OK stamp isToolStamp.render(build date only)From retiring
adapters crypto-probe/crypto-audit(gap table:evidence/17-crypto-gap-table.md; gaps listed, not ported):GO_FIPS_BACKENDextra.crypto_backend_swap/noteprobe_sbomon any CycloneDX file,file="sbom:<purl>"crypto-source --sbom), by package name, no purltier,target,timestamp,summary--component(governance-chain keying)NEED(contracts: governance-chain artifact schema)already in corerepo_dir,sbom,container_id, labels map,modemetadataIMG_LABELfacts--runtime,--platformcrypto-imagerpm/dpkg/apkinside the imagecrypto-audit-scope.jsonlappendClusterCensus.scope; no traust readerpqc_facts.pystill imports the engine'scrypto_probe. That belongs to lane (e).Changed tests
tests/test_adapters_osv_cli.py(whole file)_argsgainsconfig_home(Noneby default);traust_engine.adapters.osv/osv_sbomimports →traust_core.v1.providers.tools.osv/osv_sbom…::test_complete_scan_writes_candidates,test_degraded_scan_exits_3_and_warns,test_partial_transitive_coverage_is_noted,test_an_unusable_api_is_an_error_exit_2,test_the_api_is_the_default_accessscan_api(repo, client, resolver=None)→scan_api(repo, advisories, clock, resolver=None); assertions unchanged…::test_air_gapped_access_runs_osv_scanner_offlinerun_scanner(binary, repo, timeout, *, freeze)returning text →run_scanner(process, binary, repo, timeout, *, freeze)returning bytes; anosv-scannerstub on PATH; assertions unchanged…::test_air_gapped_without_osv_scanner_is_an_error_exit_2run_scannerstub raisingFileNotFoundError→ an empty PATH; assertions unchanged…::test_air_gapped_with_no_offline_database_is_an_error_not_cleanosv-scanneron PATH; assertions unchanged…::test_sbom_scan_marks_grype_duplicatesscan_sbom(doc, client)→scan_sbom(doc, advisories, clock);_with_stats→with_stats; assertions unchanged…::test_air_gapped_sbom_scan_runs_osv_scanner_on_the_filtered_packagesrun_offline(binary, cdx, timeout)reading the CycloneDX file →run_offline(process, binary, packages, timeout)building it withosv_sbom.cyclonedx(packages); same purl assertion…::test_air_gapped_sbom_scan_without_a_database_failsosv-scanneron PATH; assertions unchanged…::test_deps_dev_is_on_by_defaultisinstance(_deps_dev_resolver(...), DepsDevClient)and itsbase_url→ a home whose feeds.yaml has the shippeddeps_devsource gives a Context withdeps_devsetctx.deps_dev(from the feeds registry); traust's resolver is gone…::test_deps_dev_opt_out_deps_dev_resolver(...) is Noneforaccess: disabled→ctx.deps_dev is Noneforaccess: disabled…::test_a_config_without_deps_dev_says_so_deps_dev_resolverprints the NOTE →_note_unresolved_manifestsprints the NOTE (same text)…::test_resolution_is_reporteddeps_dev_settingsstub → a config home withdeps_devenabled; assertions unchangedtests/test_engine_imports.pybaselineadapters.py15,util.py2,toolchain.py1,lib/__init__.py1 → removedNew tests:
tests/test_adapters_core_parity.py(27 cases: each op runs over the same fixtures and fake binaries through the engine path and the core door, outputs equal; markedwave 2: removed by lane (f)because it imports the engine), andtests/test_tools_on_core_cli.py(15 cases: exit-code mapping for opengrep/yara/gitleaks, joern file and soundness, KHS summary,util elf,util safe-execcheck/run/warn/bypass shout and 0700 log/list/unknown/missing profiles, the doctor on the core toolchain).Prose changes
crypto-analysis/SKILL.md§ Integration / From pqc-readinessadapters crypto-probeuntil its port; this skill withadapters crypto-source" → "pqc-readiness and this skill probe withadapters crypto-source"pqc-readiness/SKILL.md§ Two-layer probe modeladapters crypto-probe→adapters crypto-source; table rowscrypto_probe.py/crypto_audit.py→crypto-source/crypto-clusterwith their commandsvalidate-findings/SKILL.mdcrypto posture probesadapters crypto-audit cluster→adapters crypto-cluster; "emitscrypto-audit/v1(tier: runtime)" → "emits the runtime crypto census"docs/cli-reference.md,docs/tooling-and-structure-files.mdcrypto-source / -image / -clusterrowdocs/skills.mdregenerated unchanged (committed withSKILLS_DOC_WAIVER). The*-crypto-audit.jsonfile names and thecrypto-auditdeterministic_stepskey are output names, not the op, so they're unchanged.Legacy files
cli/groups/adapters.pyengine callsadapters.CRYPTO_PROBE,CRYPTO_AUDITcrypto-source/-image/-cluster(gap table)adapters._deps_dev_resolver,_osv_binary_doc,_sbom_body,_failed_binary_doc,AIR_GAPPED_HELP,OSV_SCANNER_OK_EXITSosv_report/osv_sbom_reportin core (behaviour identical)cli/groups/util.pyenginesafe_exec/elfctx.safe_exec,elf_report; bypass ported here from enginesafe_exec.run(honor_bypass=True)/_log_bypasscli/toolchain.pyengine toolchainctx.toolchain+ doorslib/__init__.pyELF re-exportsMarkers
Removed: six
# wave 2 lane (b)markers (adapters ×3, util ×2, toolchain ×1). Added:wave 2: removed by lane (f) once traust-engine is no longer installed.(parity test docstring). PENDING/NEED: none added or removed.Checks (local; CI not watched)
make lint-fix && make test: 2737 passed, 2 skipped (Postgres ontraust_test_w2_b)uv run traust check docs-consistency: consistentRATCHETfrom ci.yml, referenceupstream/development:.ratchet.json): clean, baseline only shrankopengrep1.25 andgitleaks8.30 through the engine path and the core doors: equalLeft for later lanes
pqc_facts.py(crypto_probe), validate-findings' dynamicsafe_exec_tools.py(after thePENDING(pack: …)branches; also replaceharness_versioninadapters govulncheck|osv),_registry.load_engine,tests/test_adapters_core_parity.py; gate texts (S10 namestraust_engine._util.safe_exec)Reviewer checks
Quality checklist