Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
630ed86
fix: follow in-root symlinks and report case variants at the confinem…
claude Nov 10, 2026
1ab0d90
fix: widen A2A card discovery, bound the scope filter and record card…
claude Nov 10, 2026
b6213cc
fix: bind RAG source configuration and never export inline documents
claude Nov 10, 2026
9f28b08
feat: inventory rule directories, skill bundles and @path imports wit…
claude Nov 10, 2026
346ce28
fix: treat a missing file below an in-root linked directory as absent
claude Nov 10, 2026
c50fde8
feat: bind Claude Code settings and score risky IDE agent declarations
claude Nov 10, 2026
7f3e989
feat: version and confine the native AgentBOM format
claude Nov 10, 2026
82af29f
fix: gate on locally corroborated evidence and accept findings narrowly
claude Nov 10, 2026
938c322
docs: add a policy reference and state the new gate guarantees
claude Nov 10, 2026
9665136
fix(graph): bind agent.yaml to collector records and link packages fo…
claude Nov 10, 2026
c7597f7
fix: serialize compactly only when needed and show an unverified prod…
claude Nov 10, 2026
d911cbd
fix(diff): alert on removals and coverage regressions by name, rate r…
claude Nov 10, 2026
ee9c8f4
fix(shadowscan): refuse ambiguous report locations and record unrecog…
claude Nov 10, 2026
6acad9e
refactor(lineage): build and check lineage in linear time without rec…
claude Nov 10, 2026
ada60da
docs: point readers at the drift gate guide and the agent manifest
claude Nov 10, 2026
35532a3
fix: bind every model weight file and verify it only under operator p…
claude Nov 10, 2026
05182a3
docs: document model integrity binding and the signer policy kinds
claude Nov 10, 2026
5ab26b9
fix: record GGUF chat template names only in a plain form
claude Nov 10, 2026
d6cdb00
feat: make collection limits operator settings with named failures
claude Nov 10, 2026
6703356
fix(registry): classify, resolve and bound what the registry collecto…
claude Nov 10, 2026
cbf88cf
fix: give remote MCP servers a drift path and bind server declarations
claude Nov 10, 2026
26e4a22
fix: make advisories a gate with honest coverage and a stated disclosure
claude Nov 10, 2026
b4ad568
test: generate offline-guard tests from the guard tables
claude Nov 10, 2026
904116a
fix: retire superseded runtime snapshots and give every denial a reason
claude Nov 10, 2026
ff36cc1
docs: explain how to operate the runtime gateway safely
claude Nov 10, 2026
49186e7
build: generate the hash locks from pyproject.toml and test the decla…
claude Nov 10, 2026
0d1b141
test: isolate the suite, bound each test, account for skips and fuzz …
claude Nov 10, 2026
f19cd59
ci: gate on the dependency floors and audit every locked pin; check w…
claude Nov 10, 2026
193549c
docs: describe the collectors' new coverage, bindings and remaining l…
claude Nov 10, 2026
0213e9f
fix: hold PyPI publication for a soak, a signed tag and protected set…
claude Nov 10, 2026
5be31c6
fix: make the benchmark controls falsifiable and their evidence check…
claude Nov 10, 2026
f0d6627
fix: keep live observations usable and reviewable
claude Nov 10, 2026
833794a
docs: state the review policy, continuity plan and security response
claude Nov 10, 2026
7dbd99e
fix: report @path imports of excluded paths as coverage gaps
claude Nov 10, 2026
d2781e7
fix: scrub only secret-like values once per source and widen redaction
claude Nov 10, 2026
7dfe264
fix: report Python MCP registrations the collector cannot resolve
claude Nov 10, 2026
c81a64d
fix: classify MCP launchers, sources and endpoints and fail closed on…
claude Nov 10, 2026
18e0d80
docs: describe MCP launcher classification, dialects and binding cove…
claude Nov 10, 2026
91d1e31
test: keep the README collector table in step with the collected paths
claude Nov 10, 2026
f8d08a7
docs: state exactly when spec_version and upgraded inventories alert
claude Nov 10, 2026
9e02de8
fix(exports): conformant, versioned standard exports with linear vali…
claude Nov 10, 2026
06364f5
docs(exports): map standard export fields, projections, SARIF rules a…
claude Nov 10, 2026
57dcd97
test: spell invisible and bidirectional characters as escapes in the …
claude Nov 10, 2026
0332c78
fix: keep the tool package as MCP launcher identity when uvx adds dep…
claude Nov 10, 2026
02b5ab5
ci: name the publication preflight step after everything it checks
claude Nov 10, 2026
4ef0e03
build: say how to move the upload cut-off when lock regeneration cann…
claude Nov 10, 2026
896afd8
fix: parse only MCP SDK candidates and keep TypeScript analysis linear
claude Nov 10, 2026
00741e3
docs: describe the release candidate's advisory recheck and coverage …
claude Nov 10, 2026
4f6fdb2
fix: keep checkout text inert in CLI and Action output and explain ev…
claude Nov 10, 2026
714017e
docs: say that a pull request owns its workflow file and how to prote…
claude Nov 10, 2026
cbf81ae
fix: name the target of an in-root symlink on A2A, RAG and IDE records
claude Nov 10, 2026
8721547
docs: state that the Claude settings digest can confirm guessed values
claude Nov 10, 2026
92e8960
fix(diff): alert when a claimless baseline hides the new snapshot's gaps
claude Nov 10, 2026
27cac05
fix(graph): name agent.yaml entries by locator and list manifest surf…
claude Nov 10, 2026
9a087a0
fix(shadowscan): record a rating without a level as an unrecognized v…
claude Nov 10, 2026
255f877
Merge work package drift: drift gate, repository graph, agent manifes…
claude Nov 10, 2026
6f932cc
fix(exports): tighten recovery, VEX identity and SARIF text after review
claude Nov 10, 2026
57550d4
fix: inspect each model artifact once and charge signature verificati…
claude Nov 10, 2026
b557937
fix: refuse verified supplier claims on local components and label fa…
claude Nov 10, 2026
26bd894
fix: say why an inventory cannot be opened and document no-follow reads
claude Nov 10, 2026
ed3d2a7
Merge work package exports: conformant, versioned standard exports wi…
claude Nov 10, 2026
06e2bd7
fix: keep Click usage errors readable and say where unlisted scan gap…
claude Nov 10, 2026
aeb9726
docs: scope the CI-log guarantee and name organization rulesets
claude Nov 10, 2026
4d9ea2d
fix: read each model file once per validation and enforce report pins
claude Nov 10, 2026
4b81fdf
docs: state how validation bounds model reads and checks report entries
claude Nov 10, 2026
a0350cb
fix: keep advisory lookups linear and bounded on untrusted OSV replies
claude Nov 10, 2026
6731627
fix: refuse costly served schemas at the first error and bind server …
claude Nov 10, 2026
d8296a8
test: cover resolver timeouts and the cap on outstanding lookups
claude Nov 10, 2026
241bc06
docs: state the extended tool fingerprint contract in the migration g…
claude Nov 10, 2026
45ee708
fix(registry): close review findings on Compose aliases, tags, TOML k…
claude Nov 10, 2026
14ac930
fix: close fail-open gaps found in review of the runtime gateway
claude Nov 10, 2026
6ddd600
test: cover validation of shard indexes and unreadable bound files
claude Nov 10, 2026
c616812
fix: fail closed on MCP runners started outside the launcher grammar
claude Nov 10, 2026
11529e7
Merge origin/main (#127, #128, #129) into the audit remediation
claude Nov 10, 2026
c2ea67a
fix: read MCP project resolver settings as npm reads them and bind th…
claude Nov 10, 2026
8644df2
fix: reject JSONC line ends that MCP clients read differently
claude Nov 10, 2026
07198f7
fix: redact long Bearer, Token and ApiKey values whatever their letters
claude Nov 10, 2026
cea1e0c
docs: describe MCP launcher fail-closed rules and resolver reading
claude Nov 10, 2026
626fd3c
fix: record collection messages in constant time
claude Nov 10, 2026
637546d
fix: read Python MCP sources as CPython decodes them
claude Nov 10, 2026
696ea91
fix: treat a release-tag bypass list the workflow token cannot read a…
claude Nov 10, 2026
d3d7d63
ci: bound write scopes, keep weekly runs alive, measure scripts, test…
claude Nov 10, 2026
cbdd06b
build: regenerate the locks atomically and never lose the recorded cu…
claude Nov 10, 2026
d7ce31c
fix: compare a benchmark installation without the environment's boots…
claude Nov 10, 2026
88011ba
test: read requirement lines as pip does and crash-test every export …
claude Nov 10, 2026
e4c0694
fix: record PowerShell and WSL working directories for MCP resolver f…
claude Nov 10, 2026
b569839
fix: list MCP client sources without a scan per candidate
claude Nov 10, 2026
3879098
fix: show the unchecked ruleset bypass list on the run page as well
claude Nov 10, 2026
6e1fbeb
fix: report case variants below in-root links and bound @path import …
claude Nov 10, 2026
f2f1988
fix: digest and bind every RAG configuration value
claude Nov 10, 2026
079a96c
fix: check both A2A card endpoint fields and skip generic non-card files
claude Nov 10, 2026
9b7aa17
fix: report Gemini CLI MCP servers and bind Cursor hook commands
claude Nov 10, 2026
e731988
docs: describe the review fixes to variants, imports, RAG and IDE set…
claude Nov 10, 2026
6db6d19
Merge work package gates: corroborated gates, native format 1.1.0 and…
claude Nov 10, 2026
eaf45cd
test: check heredoc parsing for linear growth instead of a wall-clock…
claude Nov 10, 2026
5fb60dd
Merge work package cli: inert CLI and Action output with one gate report
claude Nov 10, 2026
bda207e
fix(registry): close second review findings on Compose builds and .env
claude Nov 10, 2026
9dbeb9f
refactor(reporting): keep upstream's name for the failure-listing limit
claude Nov 10, 2026
debfc95
fix: refuse runtime schemas that the validator would read differently
claude Nov 10, 2026
9f6ff87
fix: bound bindings of shared model files and read data_location as p…
claude Nov 10, 2026
37c328b
Merge work package live: remote MCP drift path, bound server declarat…
claude Nov 10, 2026
47164c0
fix(advisories): describe private-origin exclusion with Python lockfiles
claude Nov 10, 2026
539ef18
fix: close link, spelling and import gaps and bound hostile scan work
claude Nov 10, 2026
6aeccdb
fix: decode scripts as tsc does and keep large trees linear and loadable
claude Nov 10, 2026
99ac7d2
fix: close MCP launcher and resolver bypasses found in second review
claude Nov 10, 2026
7ffe538
Merge work package registry: normalised AI catalog, checked lockfiles…
claude Nov 10, 2026
b022820
test: run the Action lock closure check only against the CI lock
claude Nov 10, 2026
d25fe98
Merge work package model: bind every weight file and verify it only u…
claude Nov 10, 2026
59bb947
Merge work package runtime: retired snapshots, scoped signers and fai…
claude Nov 10, 2026
21a9eab
Merge work package collectors: in-root links, case variants, imports …
claude Nov 10, 2026
f9b3d63
Merge work package limits: operator collection limits on upstream's s…
claude Nov 10, 2026
864715b
Merge work package mcp: classified launchers and client dialects on u…
claude Nov 10, 2026
63e9eb3
Merge work package ci: floor-tested locks, an isolated suite and chec…
claude Nov 10, 2026
1738929
test: pin that every collector records the same inventory at any chec…
claude Nov 10, 2026
419c0a1
test: simulate macOS only inside the schema worker module
claude Nov 10, 2026
8e261d5
docs: move the known-limitations catalogue out of SECURITY.md
claude Nov 10, 2026
63871f6
test: restore two assertions that the merges weakened
claude Nov 10, 2026
9d1320e
docs: add architecture, threat model, finding catalog and glossary
claude Nov 10, 2026
f67bdd1
docs: restructure the README for a first-time reader
claude Nov 10, 2026
e302a18
docs: write the Unreleased changelog for the audit remediation
claude Nov 10, 2026
0c371cb
Merge docs/readme: restructure the README for a first-time reader
claude Nov 10, 2026
3227ff7
Merge docs/reference: architecture, threat model, finding catalog and…
claude Nov 10, 2026
008f8a2
Merge docs/changelog: the Unreleased changelog for the audit remediation
claude Nov 10, 2026
261ef91
build: drop the unused Rich runtime dependency
claude Nov 10, 2026
d620fa3
docs: make the merged pages agree with each other and the code
claude Nov 10, 2026
a58a0b8
docs: say which binding key the Action collects with
claude Nov 10, 2026
6cbf965
Merge fix/drop-rich: drop the unused Rich runtime dependency
claude Nov 10, 2026
9942656
fix(registry): read each pnpm lockfile key once
claude Nov 10, 2026
9fabc69
fix(runtime): validate and scope the arguments a canonical gateway ex…
claude Nov 10, 2026
16c5ecb
fix(yaml): read base-60 integers as text in every project YAML loader
claude Nov 10, 2026
fa01526
Merge fix/registry-pnpm-index: read each pnpm lockfile key once
claude Nov 10, 2026
e39a50e
Merge fix/runtime-schemas: validate and scope the arguments a canonic…
claude Nov 10, 2026
72172de
Merge fix/yaml-int-linear: read base-60 integers as text in every YAM…
claude Nov 10, 2026
ded104c
fix(validate): reconcile the coverage claim, verification fields and …
claude Nov 10, 2026
7488de4
fix(gates): truthful validate basis, digest-aware drift ratings, vers…
claude Nov 10, 2026
b193818
fix(release,ci): fail-closed soak and ruleset checks, enforced gate s…
claude Nov 10, 2026
f54ba7c
Merge fix/gates-reconcile: reconcile the coverage claim, verification…
claude Nov 10, 2026
1fb2644
Merge fix/gates-report: truthful validate basis, digest-aware drift r…
claude Nov 10, 2026
2f7e7db
Merge fix/ci-release-controls: fail-closed soak and ruleset checks, e…
claude Nov 10, 2026
b1f4481
fix(a2a): stream the code-card search under the source budget and rea…
claude Nov 10, 2026
233a37f
fix(prompt): follow nested memory-file imports and bound import bookk…
claude Nov 10, 2026
8d89c67
fix(confined): bound every collection failure and refuse undecodable …
claude Nov 10, 2026
5eeae0e
Merge fix/confined-bounds: bound every collection failure and refuse …
claude Nov 10, 2026
f10095e
Merge fix/a2a-code-cards: stream the code-card search under the sourc…
claude Nov 10, 2026
0e8bc0a
Merge fix/prompt-imports: follow nested memory-file imports and bound…
claude Nov 10, 2026
5988528
test: align two fix tests with the merged suite rules and bounded gap…
claude Nov 10, 2026
40271a7
fix(mcp): classify the environment that moves or replaces a pinned ru…
claude Nov 10, 2026
974b860
fix(mcp): withhold token-shaped configuration names from inventories …
claude Nov 10, 2026
91c7800
Merge fix/mcp-config-sources: classify relocating environment, withho…
claude Nov 10, 2026
25692ad
fix(mcp): fail closed on launch text a shell or cmd rewrites, and cha…
claude Nov 11, 2026
0425fb5
fix(mcp): treat remote uv scripts, Windows trailing dots and package …
claude Nov 11, 2026
c20cddb
Merge fix/mcp-launch-grammar: fail closed on rewritten launch text, r…
claude Nov 11, 2026
ad23f51
docs: record the final-review fixes and the launcher limits that remain
claude Nov 11, 2026
9b09af1
fix(ci): bound runtime JSON nesting explicitly and remove two environ…
claude Nov 11, 2026
a2c4b42
fix(release,ci,docs): harden release provenance gate, action validati…
aisecnomad Nov 12, 2026
faef1b6
Merge main into fix/audit-pr4-release-ci-and-docs and reconcile with …
claude Nov 12, 2026
668eb3b
docs: regenerate the documented example digests for 0.2.0
claude Nov 12, 2026
881ac7c
docs: align the security policy and tutorial with the gate-protection…
claude Nov 12, 2026
e65fe41
fix(tests,docs): a signer policy names its artifact by the exact spel…
claude Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/platforms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ name: Platform smoke
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "29 3 * * 4"
workflow_dispatch:
Expand Down Expand Up @@ -33,5 +35,10 @@ jobs:
tests/test_action_signature_policy.py
tests/test_discovery_signature_gate.py
tests/test_confined_integrity.py
tests/test_confined_links_and_variants.py
tests/test_confined_bounds.py
tests/test_output_confinement.py
tests/test_prompt_confined_reads.py
tests/test_prompt_surfaces.py
tests/test_ide_settings_binding.py
tests/test_a2a_collection.py
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,14 @@ jobs:
set -euo pipefail
shopt -s nullglob dotglob
bundles=(attestation/*)
(( ${#bundles[@]} == 1 ))
test -s "${bundles[0]}"
(( ${#bundles[@]} == 1 )) || exit 1
test -s "${bundles[0]}" || exit 1
wheels=(dist/*.whl)
sdists=(dist/*.tar.gz)
everything=(dist/*)
(( ${#wheels[@]} == 1 && ${#sdists[@]} == 1 && ${#everything[@]} == 2 ))
(( ${#wheels[@]} == 1 && ${#sdists[@]} == 1 && ${#everything[@]} == 2 )) || exit 1
for artifact in "${everything[@]}"; do
[[ -f "$artifact" && ! -L "$artifact" ]]
[[ -f "$artifact" && ! -L "$artifact" ]] || exit 1
done
for artifact in "${wheels[@]}" "${sdists[@]}"; do
gh attestation verify "$artifact" \
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Notable changes to Nexus SymBiote, newest release first. Within a release, secur

## [Unreleased]

## [0.2.0] - 2026-11-12

Closes detection gaps listed under 0.1.0's known limitations and others found in review, makes inventories comparable across checkouts and reproducible, and makes every gate say why it failed. New commands sign and verify inventories, compare them with the use an agent's own traces report, report their G7 AI SBOM minimum-element coverage, map their findings to security frameworks, draw them as a graph and export the reviewed agent to Nexus-ShadowScan. Record baselines again after upgrading, as *Upgrading* below describes: the native format, paths, the inferred agent reference and many records change. [Known limitations](docs/known-limitations.md) lists what is still not collected, compared or verified.

### Security
Expand Down Expand Up @@ -40,12 +42,16 @@ Closes detection gaps listed under 0.1.0's known limitations and others found in
- Read brace, bracket, pattern and parameter expansions in MCP launch arguments in linear time and bounded memory: a few kilobytes of unclosed braces stalled a scan, a 128 KB brace list took 3.9 GB, and a long `*` pattern took 30 s to compile. Default operands nested more than eight deep and braces open more than 256 deep are a gap, and inline JSON arguments no longer exhaust the scan budget. Pattern readings are matched against the program names that their literal text allows, and each compile is charged.
- Follow the `@path` imports of nested `CLAUDE.md` files, and treat an A2A card module that is too large to parse or spelled with compatibility characters as a coverage gap.
- Find MCP package-source origins and analyse Python MCP servers in time linear in the file size: a long `.npmrc` value held the `mcp` collector for 25 s at 160 KB, and a server passed to a large helper from many calls took quadratic time.
- In the runtime gateway with `canonical_arguments=True`, validate and resolve the scope of the arguments the executor receives, and deny schemas that use keywords only drafts before draft-04 define.
- **Breaking:** the runtime gateway passes canonical arguments by default (`canonical_arguments=True`), so `resolve_scope` and `execute` receive the RFC 8785 value the approval binds, and it validates and resolves the scope of those arguments; an integral float outside the I-JSON range is refused in every mode, and schemas that use keywords only drafts before draft-04 define are denied. Pass `canonical_arguments=False` only for an executor that needs the caller's own encoding.
- Measure the PyPI soak only from a commit's push run, so a commit without one, such as a `[skip ci]` push, needs a stated override; require the publishing environment to admit only `main` rather than every protected branch; treat an unreported ruleset bypass as unknown; and reject workflow gate steps that never run, and gate commands that are quoted, conditional, negated, chained, backgrounded, preceded by `set +e`, `set -n`, `cd`, `trap`, `exit` or `hash` (also through `builtin`, `command`, `shopt -o` or an expanded command name), run through a `$VAR` that `export`, `declare`, `read` or a loop rebinds, passed as an option's value such as `python -X`, or run under another shell or working directory. Scripts the checker reads differently from `bash` (`$'...'` escapes, partly quoted here-document delimiters, here-documents and comments inside `$(...)`) no longer yield a gate.
- **Breaking:** record the ShadowScan discovery verification outcome in the BOM, and fail unverified discovery evidence in CI. Importing a report writes `metadata.completeness.discovery_verification` (`verified` with the signer identity and issuer, otherwise `unverified`) with the report digest and the report's own run time; the repository and commit are recorded as `unknown` because the ShadowScan report format carries neither. The record is unsigned, so it is reported but never trusted: only a producer check in the same run counts as verification (`import-shadowscan --bundle`, or `validate`/`risk --project --signature-policy`). Otherwise `import-shadowscan` (with or without `--report-only`), `validate` and `risk` warn loudly, and fail the run when a CI variable (`CI`, `GITHUB_ACTIONS` and the like) is set unless `--allow-unsigned-discovery` is passed; `--fail-on-unsigned-discovery` forces failure anywhere, and passing both is a usage error. `risk --json-output` reports such a failure with the same keys as a scored report, and `validate` records it as `unsigned_discovery`. The Action takes an `allow-unsigned-discovery` input.
- **Breaking:** verify the Sigstore trust root before trusting it. Offline verification now fails closed when the sigstore-python cache directory or `trusted_root.json` is group/world-writable, a symlink, or owned by someone else; a missing cache is created mode 0700. Pass an explicit trust root with `--trust-root` on `verify-artifact`/`verify-discovery` (optionally pinned with `--trust-root-sha256`), or `NEXUS_SYMBIOTE_SIGSTORE_TRUST_ROOT` for any verification path, and the verification output prints the trust-root path used. A verify that passed on a shared or group-writable cache now exits 1 until the cache is made private or a trust root is supplied.
- Verify against the cached Sigstore trust root from the bytes that were checked. The cached `trusted_root.json` is now opened once without following symlinks, checked on that descriptor and read, and the verifier is built from those bytes; before, sigstore-python read the file again by path after the check, so a process running as the same user could replace it in between. A missing cached root is created mode 0600 from the root embedded in sigstore-python, as sigstore-python did.
- **Breaking:** bind each `risk.suppressions` entry to the finding it accepted. An entry now requires the finding's `fingerprint`, which `risk --json-output` and human-readable `risk` print for each finding: a digest of its component, category, severity and detail, and of the component's content digest (`content_hash`, `definition_hash`, `schema_hash` or the `sha256` file hash) when the inventory records one. A finding whose detail, severity or reviewed bytes changed, such as a prompt whose one bidirectional override grew to 31 or now reverses a different instruction, is no longer suppressed and counts again, and the entry is listed under `suppressions_stale`; before, an entry covered the component and category whatever the finding became. A policy with an entry that has no fingerprint is refused ([suppressions](docs/policy-reference.md#suppressions)).
- Count runtime quorums over unrevoked signers: a signature from a revoked or unbound key appended to a valid envelope no longer makes it fail, and never counts towards a threshold. Collection limits are kept per context, the offline guard stays in force until its last overlapping user leaves, a state store whose identity changed in place is refused, and `runtime keygen` creates key files without following links.
- Require the exact spelling of every path component in confined reads on case-folding file systems, and refuse a policy file under another case. A signer policy entry that names its artifact or bundle in another case is refused there as it is on a case-sensitive file system. A runner started with a path or an interpreter instead of a package entry point, and `npm exec` options after the package, are unknown launchers; `deno.json` and bunfig preload, shell and CA settings are read as resolver configuration; SSE lines may end in a bare carriage return within the response bound; and `hf_` tokens and raw `Authorization` and cookie header values are redacted.
- Refuse a byte-order mark in strict JSON, read `image:sha256:` and tag-plus-digest references as digest pins and a tag without a dot as unpinned, apply a model's intrinsic risks in `diff`, SARIF and VEX, and export a package URL only when the component's registry agrees with it.
- Stop the release provenance step explicitly when an expected distribution or attestation is missing or is a symbolic link, run the platform smoke workflow on pull requests with the confinement suites, and refuse a `scanners` subset in the Action while `validate` is on.

### Changed

Expand Down
6 changes: 3 additions & 3 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ repository-code: https://github.com/Hunzee-VC/Nexus-Symbiote
repository-artifact: https://pypi.org/project/nexus-symbiote/
url: https://github.com/Hunzee-VC/Nexus-Symbiote
# The code's licence. The distributions also bundle CycloneDX schemas (Apache-2.0) and
# SPDX schemas (Community-Spec-1.0); see src/nexus_symbiote/generators/schemas/vendor/NOTICE.txt.
# SPDX schemas (Community-Spec-1.0 AND CC-BY-3.0); see src/nexus_symbiote/generators/schemas/vendor/NOTICE.txt.
license: MIT
# scripts/check_repository_hygiene.py requires this version to match pyproject.toml.
version: 0.1.0
date-released: "2026-11-08"
version: 0.2.0
date-released: "2026-11-12"
keywords:
- aibom
- agent-bill-of-materials
Expand Down
22 changes: 12 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ Agent Bill of Materials (AgentBOM) generator and validator for AI agent supply c

```
src/nexus_symbiote/
core/ — Domain models (Pydantic v2), enums, AIBOM container, RFC 8785 JCS hashing, inventory content digest
scanners/ — Component discovery (MCP, model weights, prompts, RAG, registry, A2A, IDE agents, ShadowScan reports)
generators/ — Exports: native JSON, CycloneDX 1.7, SPDX 3.0, SARIF, VEX
core/ — Domain models (Pydantic v2), evidence/authority records, enums, AIBOM container, RFC 8785 JCS hashing, inventory content digest
scanners/ — Component discovery (MCP, MCP launch/live wire, model weights, prompts, RAG, registry, A2A, IDE agents, ShadowScan reports)
generators/ — Exports & PURL projection: native JSON, CycloneDX 1.7, SPDX 3.0.1, SARIF 2.1.0, VEX
validators/ — Completeness, integrity, and risk scoring
diff/ — AIBOM version comparison and the snapshot alert gate
live/ — Opt-in observations through independently pinned local MCP launchers
utils/ — Confined bounded reads, Sigstore/artifact verification, file hash utilities, terminal-output neutralization
runtime.py — Signed, operation-bound authorization for integrations that mediate tool calls
runtime_validation.py, runtime_cli.py — Offline schema validation worker; `runtime` commands
live/ — Opt-in observations and pinned stdio execution (`inventory.py`, `session.py`, `stdio.py`, `verify.py`)
utils/ — Confined `openat` reads (`confined.py`), Sigstore/Ed25519 verification (`crypto.py`), safe output writes (`files.py`), JSONC/model-header parsers, secret redaction, terminal neutralization
runtime.py — Signed, operation-bound authorization gateway (`canonical_arguments=True` by default)
runtime_validation.py, runtime_cli.py — Isolated offline schema validation worker; `runtime` commands
policy.py, signature_policy.py — Caller-selected policy and operator signer policy
limits.py — Operator-controlled collection bounds (`--limit`, `NEXUS_SYMBIOTE_LIMITS`)
graph.py, lineage.py — Repository association graph, blast radius, lineage
risk_classes.py, graph_view.py, graph_cli.py — Risk classes, exposure paths; the `graph` HTML/JSON view
digest_cli.py — `digest`: file, canonical and content digests of an inventory
Expand All @@ -26,8 +27,9 @@ src/nexus_symbiote/
inventory_export.py, inventory_export_cli.py — ShadowScan simple-list export; `export-inventory`
advisories.py — Explicit, bounded OSV queries for exact package identities
modes.py — Offline by default; live mode is opt-in
reporting.py — Neutralized text and JSON gate reporting
scanner_catalog.py — Built-in collector universe for coverage checks
cli.py, live_cli.py, supply_chain_cli.py — Click CLI entrypoints
cli.py, analysis_cli.py, live_cli.py, supply_chain_cli.py — Click CLI entrypoints
```

## Build and test
Expand Down Expand Up @@ -55,6 +57,6 @@ make check # offline subset of the required CI checks
- Every scanner extends `scanners/base.py:Scanner` and returns `ScanResult`
- Risk assessments use `RiskSeverity` enum: critical > high > medium > low > info
- Trust tiers: internal-verified > internal-unverified > third-party-signed > third-party-unsigned > untrusted-public > unknown
- Tests live in `tests/` and use pytest
- Ruff for linting (line-length 100), mypy strict mode
- Tests live in `tests/` and use pytest (`conftest.py` isolates environment/HOME, blocks outbound non-loopback sockets, and enforces `--strict-skips` in CI)
- Ruff for linting (line-length 100), mypy strict mode (`mypy src/nexus_symbiote scripts`)
- No comments unless the why is non-obvious
Loading
Loading