psy-6.9m / MODEL_CARD.md
AIIT-Threshold's picture
Psy v0.1 — byte-level defensive cyber-artifact encoder (6.9M params)
185d3f7 verified
|
Raw
History Blame Contribute Delete
11.7 kB
# Psy 6.9M Model Card
## Model
- Name: Psy
- Bundle version: v0.1
- Model type: byte-level, zero-language cyber artifact encoder (classification-only)
- License: Apache-2.0 (see `LICENSE`)
- Checkpoint: `checkpoints/psy_6.9m_encoder.pt`
- Encoder parameters: 6,904,064
- Exported encoder SHA256: `2d0a15792bcdfbebfbf689ca0dddd39f9259525bbe9bee9d491289af4e590dbc`
## Who Psy is for (practical use)
Psy is a tiny (6.9M params / ~27MB / CPU-only / fully offline) instrument that reads
a cyber artifact in its **raw bytes** and returns a coarse severity/verdict. Nothing
leaves your machine. Two doors to the same tool:
**1 — The defender who's drowning** (SOC analyst, solo admin, small team with no SOC).
You get buried in CVEs, detection-rule hits, and network flows — more than any human
can assess, and the dangerous one hides in the noise. Psy reads each artifact and
**prioritizes the queue** so you look at the scary stuff first. It runs airgapped, on
your own hardware — good for orgs that *can't* send data to a cloud API (defense,
healthcare, critical infra, privacy-sensitive) or simply can't afford enterprise tooling.
**2 — The vibe coder who's blind** (ships fast, AI-assisted, not a security person).
You pulled in 400 dependencies you never read and have no idea which CVE is scary or
whether a compromised package is beaconing out. Psy is the **judgment layer on tools
you already run**: pipe your `npm/pip/cargo audit` CVE records in → *"fix these 3,
ignore the wall of yellow."* It reads the bytes so you don't have to understand them —
tiny enough to drop in a pre-ship checklist or a git hook.
**Honest boundary (this is the feature, not a caveat):** Psy is a **scorer that sits on
top of feeds you already have** (audit output, captured flows) — *not* a one-click
"scan my repo" scanner. It **prioritizes and flags; it does not decide, fix, or
guarantee**, and it returns `PSY_UNCERTAIN` when it isn't sure instead of bluffing.
An instrument for a human in the loop, not an oracle.
## Quickstart (run it — verified output)
```bash
python3 scripts/validate_bundle.py # expect status PASSED (1 network_flow warning)
python3 scripts/run_demo.py --artifact demo_artifacts/rule_ast_sample.jsonl
```
Feed it a detection-rule AST → Psy reads the bytes and returns one strict-JSON verdict:
```json
{"psy_frame":{"magic":[80,83,89],"version":1,"sender":2,"receiver":1,"intent":5,
"opcode":69,"confidence":0.8381},
"status":"PSY_ANOMALY_FOUND",
"verdict":{"family":"RULE_AST","action":"BLOCK","label":2,"class_index":2,"artifact_type":5,
"confidence":0.8381,"mode":"encoder_plus_probe_head","head_status":"loaded",
"status":"PSY_ANOMALY_FOUND","artifact_hash":"e0a7780dd5ad7c080d0ead87f5cace38",
"embedding_norm":28.4617,"display":"Psy anomaly found."}}
```
That's the whole contract: bytes in, one honest structured verdict out. (The `CVE_RECORD`
demo returns a confident `PSY_UNCERTAIN`/`ABSTAIN` — a real "investigate" call, explained
below; `NETWORK_FLOW` runs encoder-only in v0.1 — see the head table.)
## Defensive-Use Statement
Psy is a **defensive** research instrument. It reads already-structured cyber
artifacts (a sanitized CVE record, a detection-rule AST, a network-flow header)
and emits a coarse severity/verdict frame. It has **no generative, executive, or
remediation capability**: verified by reading and running the code, there is no
code path that generates text, generates code, executes an artifact, patches a
system, or emits an exploit. The runtime only encodes an artifact to a 256-dim
embedding, applies a small linear probe head, and reports a severity class.
It must not be used as, or represented as, a production security scanner, and it
cannot detect malware or exploits. Do not feed it untrusted executable content
expecting containment — it does not run anything, but it also does not defend
anything on its own.
## Architecture (as implemented, verified from tensor shapes)
Byte-level pre-LN Transformer encoder backbone.
- 6 transformer layers (`MultiheadAttention`, 8 heads, `batch_first`; GELU FFN 256 -> 1024 -> 256)
- Hidden size (d_model): 256
- Byte vocabulary: 257 (`byte_emb`, shape [257, 256])
- Field vocabulary: 8192 (`field_emb`, shape [8192, 256], **shared** across field keys, field values, and seq)
- Artifact-type vocabulary: 8 (`type_emb`, shape [8, 256])
- **No positional embeddings.**
- Input assembly per artifact: `[ type(1) + field_key + field_val(32) + seq(64) + bytes(512) ] = 609 tokens`.
- Pooling: the artifact-type token at position 0 acts as a CLS token; the model returns the pooled `[:, 0]` vector = a 256-dim embedding.
- Final LayerNorm before pooling.
The exported checkpoint contains **only the encoder backbone** (77 tensors,
6,904,064 params, loads with 0 missing / 0 unexpected keys via the bundle's
`load_encoder`, which uses `weights_only=True` and treats any missing/unexpected
key as an error). Masked-training prediction heads were stripped at export so the
bundle ships Psy purely as the 6.9M artifact-encoder instrument, plus the two
small probe heads described below.
## Probe Heads (what actually ships)
The encoder is task-agnostic. Per-family severity is produced by a tiny linear
probe head (`nn.Linear(256, num_classes)`, loaded `strict=True`) placed on the
pooled embedding, followed by softmax + argmax.
This bundle ships **two** trained probe heads (CVE_RECORD and RULE_AST are fully
functional end-to-end; NETWORK_FLOW is encoder-only in v0.1):
| Family | Head file | Shape | SHA256 | Ships? |
|---------------|----------------------------------------|---------------|-------------------------------------------------------------------|--------|
| CVE_RECORD | `checkpoints/heads/cve_sanitized_head.pt` | Linear(256->3) | `b6c9cfae96b3b22414e2f956e3cfa657a9160e092652c0cc48eeac14c244760f` | Yes |
| RULE_AST | `checkpoints/heads/rule_ast_head.pt` | Linear(256->3) | `bc6a96c03a987a8819cd055b69828ce71817a5cc94b33e6cedcdbb52d5d64d27` | Yes |
| NETWORK_FLOW | `checkpoints/heads/network_flow_head.pt` | Linear(256->2) | (not shipped) | **No** |
If a family's head is absent, the runtime does not fabricate a verdict: it runs
the encoder only, returns `head_status: "probe_head_not_present"`,
`mode: "encoder_only"`, and `PSY_UNCERTAIN` / `ABSTAIN` at confidence 0.0.
## Inputs
Psy consumes structured JSON cyber artifacts with:
- `artifact_type` or `artifact_family`
- `payload_bytes_b64` or `payload_bytes`
- `field_ids`
- `field_values`
- `seq`
## Outputs
The runtime emits one strict-JSON status/verdict frame per artifact containing:
- a Psy contact/status frame (`magic`, `version`, `sender`, `receiver`, `intent`, `opcode`, `confidence`)
- artifact family and artifact hash (BLAKE2b-128 of the canonical JSON)
- encoder statistics (`embedding_norm`)
- `mode` (`encoder_plus_probe_head` or `encoder_only`), `head_status`, `class_index`, `label`, `confidence`
- a status + action
### Class -> opcode -> action mapping
| Probe label | Opcode | Status | Action |
|-------------|---------------------|---------------------|---------|
| 0 | `PSY_SAFE` | `PSY_SAFE` | ALLOW |
| 1 | `PSY_UNCERTAIN` | `PSY_UNCERTAIN` | ABSTAIN |
| 2 | `PSY_ANOMALY_FOUND` | `PSY_ANOMALY_FOUND` | BLOCK |
Note on the two meanings of `PSY_UNCERTAIN`: it is emitted both when the probe
head **confidently predicts the middle (investigate) class** (a real, high-
confidence label-1 prediction) and when there is **no head available** (encoder-
only). Disambiguate using `mode` / `head_status` / `confidence`, not the status
string alone. This is why the CVE demo can read `PSY_UNCERTAIN` at confidence
0.9996 — it is a confident label-1 (MEDIUM/INVESTIGATE) prediction the opcode
layer maps to ABSTAIN, not a malfunction.
## What each family does end-to-end (verified by running)
| Family | Mode | Demo result | Notes |
|---------------|--------------------------|--------------------------------------------|-------|
| RULE_AST | encoder + probe head | label 2 -> `PSY_ANOMALY_FOUND` / BLOCK, conf 0.8381 | Decisive verdict path. |
| CVE_RECORD | encoder + probe head | label 1 -> `PSY_UNCERTAIN` / ABSTAIN, conf 0.9996 | Head runs; demo sample lands on the investigate class. |
| NETWORK_FLOW | encoder only (no head) | `PSY_UNCERTAIN` / ABSTAIN, conf 0.0 | Head not shipped in v0.1; encoder-only by design. |
## Probe metrics (sanitized training-run summaries)
These are summaries carried from the local metric log; the full training logs,
shards, and held-out reproduction are **not** included in this bundle. They
describe the trained probes, not an in-bundle re-evaluation.
| Family | Baseline (majority) | Test accuracy | Macro-F1 | Status | Head shipped |
|---------------|---------------------|---------------|----------|----------|--------------|
| CVE_RECORD | 0.6424 | 0.8684 | 0.7706 | SIGNAL | Yes |
| RULE_AST | 0.5129 | 0.7847 | 0.7013 | SIGNAL | Yes |
| NETWORK_FLOW | 0.9952 | 1.0000 | 0.9989 | MARGINAL | No |
The CVE probe is trained on sanitized records with direct CVSS/severity fields
removed, so it reflects structural signal rather than a copied severity field.
## Limitations
- Not a production security scanner. Not malware/exploit detection.
- Does not generate code or patches, does not execute artifacts, does not chat.
- Does not contain the training corpus, shards, or logs.
- A scorer on top of existing feeds, not a repo/network scanner — you supply the artifacts.
- Only two of three advertised families produce a probe verdict in v0.1;
NETWORK_FLOW ships encoder-only (no head weights).
- NETWORK_FLOW metrics are dominated by extreme class imbalance
(train class 0:2 = 896,107:4,327). Test accuracy 1.0 is not meaningful on its
own; the family is marked MARGINAL and would require class-wise validation
before any head is treated as a real signal. This is the reason its head is
held back from v0.1 rather than shipped.
- Probe metrics above are training-run summaries, not reproduced inside the
bundle; treat them as reported-not-reverified.
## Provenance / integrity
- Verify the encoder: `sha256sum checkpoints/psy_6.9m_encoder.pt` must equal the SHA above.
- Verify the heads: the two head SHAs above.
- `python3 scripts/validate_bundle.py` re-derives the param count (must == 6,904,064), checks required files, scans for secrets/non-loopback IPs, and confirms no forbidden path components. Expected result on a clean release: `status: PASSED` with a single warning for the intentionally-absent `network_flow_head.pt`.
## This isn't only for developers
The two use cases above assume some technical context, but the need isn't limited
to people who write code. A nonprofit running a donated laptop fleet, a small
business owner handed a vendor's CVE list with no security staff to read it, a
student trying to understand what "severity" actually means in a disclosure — none
of that requires a job title. The floor to use Psy is a correctly-shaped JSON
record, not a background in security or software. If you can get your artifact
into that shape (yourself, with a script someone wrote for you, or by asking an AI
assistant to format it), Psy will read it the same way for anyone.