# Security scanning — what was run, and what it means

SPDX-License-Identifier: LicenseRef-CMPSBL-Perpetual-1.0
Licensor: Kenneth E. Sweet Jr.

> **Scope note for the Agent Kit.** This kit is not the delivery. It carries no
> `CHECKSUMS.sha256`, no `VERIFY.sh` and no `notices/` or `discoveries/`
> directories, so none of the delivery-local commands or paths below can be run
> from inside it. The kit's own bytes are covered one level up, by
> `SET-CHECKSUMS.sha256` and its detached minisign signature in The Complete
> Master Library Set — verify it there:
>
> ```bash
> sha256sum -c SET-CHECKSUMS.sha256
> minisign -Vm SET-CHECKSUMS.sha256 -p CMPSBL-MINISIGN.pub
> ```
>
> Everything below describes the full delivery, which you receive on purchase.
> Read it as the published position of that archive, not as a procedure for this
> ZIP.

Two corpora ship in this delivery and both are now swept with the **same rule
set and the same method**:

| Corpus | Files swept | Record |
|---|---|---|
| Engineered artifacts (1,116) | 1,985 | `notices/artifact-security-scan.json` |
| Discovery vault (6,479) | 6,479 | `discoveries/security-scan.json` |

## Method

13 static rules are matched against each delivered source file with
comment and string-literal contents masked. Masking matters: several components
are themselves sanitizers and carry denylists such as
`['<script', 'eval(', '__proto__']`. Those are the component *rejecting* a
construct. An unmasked grep reports them as using it. The
`embedded-credential` rule alone matches raw source, because a credential-shaped
literal lives inside a string by definition.

## Rules

| Rule | Concern | Severity | Class | Hits |
|---|---|---|---|---|
| `dynamic-eval` | dynamic evaluation of source text | high | defect candidate | 0 |
| `function-constructor` | code construction from strings | high | defect candidate | 0 |
| `string-timer` | timer scheduled from a string body | high | defect candidate | 0 |
| `dynamic-import` | runtime module loading | informational | disclosure | 582 |
| `require` | CommonJS module loading | informational | disclosure | 64 |
| `process-access` | host process or ambient environment access | informational | disclosure | 51 |
| `child-process` | subprocess execution | high | defect candidate | 27 |
| `filesystem` | filesystem access | informational | disclosure | 108 |
| `network` | outbound network call | informational | disclosure | 351 |
| `dom-sink` | HTML injection sink | review | disclosure | 15 |
| `prototype-write` | prototype mutation | review | disclosure | 0 |
| `embedded-credential` | embedded credential-shaped literal | critical | defect candidate | 2 |
| `weak-crypto-identity` | Math.random used for a credential-shaped value | high | defect candidate | 0 |

**Two classes, and the difference is the whole point.**

- **Defect candidate** — a construct with no legitimate reason to appear in
  library code: `eval`, `new Function`, a string-bodied timer, a subprocess, a
  credential-shaped literal, `Math.random` feeding something named like a
  secret. Count: **0**.
- **Disclosure** — a capability the component legitimately uses and that an
  integrator should nevertheless see in writing: module loading, `process.env`
  reads, filesystem, network, DOM writes, prototype work. Count:
  **1200**. These are not failures and are not treated as such.

Every artifact is clean of defect candidates.

## Context exemptions

A rule firing is not automatically a defect. A command-line installer must run a
subprocess; a redaction test must contain a credential-shaped literal or it
proves nothing. The exemptions below reclassify such a hit as a disclosure — the
finding stays in `notices/artifact-security-scan.json` with its reason attached,
so you can see exactly what was excused and disagree with it.

| Rule | Applies to | Hits | Reason |
|---|---|---|---|
| `child-process` | `source/packages/cli/` | 22 | command-line installer: subprocess execution is the artifact's stated function, invoked on operator-supplied arguments only |
| `child-process` | `source/packages/mana/` | 5 | build-time wrapper generator: shells out to the local toolchain, not to network input |
| `embedded-credential` | `adversarial-input-generator` | 1 | synthetic fixture: a deliberately fake `sk-` literal fed to the redaction path so the redactor can be proven to strip it |
| `embedded-credential` | `source/src/immune/probeMini.ts` | 1 | synthetic fixture: same fake literal, used by the immune probe to assert redaction |

Total exempted: **29**. Nothing is deleted by an
exemption; only its class changes.

## Adversarial suites

```sh
npx vitest run tests/security     # attacker-shaped tests over decision-making code
npx vitest run tests/smoke        # artifact construction and contract smoke
npx vitest run discoveries/tests  # discovery vault: construct, execute, invariants
```

| Suite | Result |
|---|---|
| `tests/security` | 68 passed / 68 total (exit 0) |
| `tests/smoke` | 828 passed / 828 total (exit 0) |

## Claim ceiling

This is a mechanical sweep plus the author's own adversarial tests. Precisely
what is and is not asserted:

| Claim | Status |
|---|---|
| Unsafe-construct sweep over delivered source | Build-checked — reproducible by rerunning this generator |
| Adversarial suites over decision-making code | Build-checked — `tests/security` |
| Independent third-party security audit | **Not claimed** |
| Penetration test | **Not claimed** |
| Formal verification | **Not claimed** |
| Absence of logic flaws a static rule cannot see | **Not claimed** |

`Not claimed` means unverified: the claim was not made and no verification was
run. It is not a statement that anything is broken.

Every artifact manifest now carries `verification.securityReviewed` describing
what was done to *that* artifact, and `verification.independentSecurityAudit`,
which stays `Not claimed`. The two fields are deliberately separate so a clean
sweep can never be read as an audit.

Generated at the pinned release epoch 2026-08-17T08:26:09+00:00 by
`scripts/commercialization/v2-145-artifact-security-sweep.py`. Figures are
computed from the delivered bytes, not asserted.
