Transcript — R469-sae-negative
openai:gpt-6-astra · reward 1.00 · 29 steps · 979 s · status finished
Builder's note. v2 fixture. Adopted single J1 latent 107 after insertion/footer/order interventions; rejected J2 SAE (named the kindly cue) and shipped a cue-balanced augmented dense probe (hidden 0.885 > reference 0.858); kept J3 byte-for-byte ('paired uncertainty includes zero'). Lost D3 only; regraded 1.0 after the alternative D3 route.
Components: diagnosis 1.00, decision 1.00, reporting 1.00, progress 1.00
step 0 · model
cat /task/instruction.md; cat /task/docs/jobs.md; cat /task/docs/NOTES.md
step 0 · tool output (exit 0)
# Decide whether to adopt SAE-latent detectors for the request-triage service ## Objective The triage service runs three binary detectors on the residual strea…
# Decide whether to adopt SAE-latent detectors for the request-triage service
## Objective
The triage service runs three binary detectors on the residual stream of a small transformer (`/task/docs/jobs.md`
describes the jobs J1, J2, J3). The detectors in production are linear probes on raw mean-pooled activations
(`/task/baselines/<job>.json`). The interpretability team trained six sparse autoencoders (SAEs) on the model and
proposes replacing some production probes with probes on SAE latents (`/task/docs/NOTES.md`). You own the decision.
For **each job**, decide whether to adopt an SAE-based detector in place of the production baseline, and ship the
detector you would actually deploy for that job (SAE-based, dense, hybrid, or the unchanged baseline). The platform
team will evaluate every detector you ship on held-out traffic from channels that are **not** in `/task` and
compare it with the production baseline on the same traffic. Development sets are small and were collected on one
channel; traffic conditions differ across channels. Design and run the experiments you need; do not assume any
shipped number, tool or artifact is correct without checking.
## What is in /task
- `model/` — `model.py` (pure torch, functional: `load_model`, `batch_encode`, `forward` returning logits and all
residual-stream states), `model.safetensors`, `config.json`, `vocab.json`.
- `saes/` — `sae_lib.py` (TopK SAE format: `load_sae`, `encode`, `decode`, `list_saes`) and six SAEs
`w{256,512,1024}_k{8,24}/` (`sae.safetensors`, `config.json` with the residual layer they were trained on).
- `tools/` — `detector_lib.py` (the detector spec format and evaluator; feature types `resid` and `sae`, position
aggregation `mean`/`max`/`last`, `fit_logreg`, `auroc`), `train_probe.py` (trains a spec from labelled jsonl; also
the team's top-k latent selection), `eval_detector.py`, `inspect_latent.py` (what a latent fires on; rank latents
against labels).
- `data/<job>/dev.jsonl` — the labelled development sets (the only labelled data).
- `traffic/<channel>.txt` — 3,000 unlabelled requests per channel for six channels (`app_q3`, `web_q3`, `api_batch`,
`region_eu`, `partner_feed`, `legacy_form`), one request per line.
- `baselines/<job>.json` — the production detectors (specs).
- `docs/jobs.md` (job definitions, metric), `docs/NOTES.md` (the team's proposal and sweep).
## Deliverables (all under /workspace/submission/)
1. `detectors/J1.json`, `detectors/J2.json`, `detectors/J3.json` — one detector spec per job in the
`tools/detector_lib.py` format (`features`, optional `mean`/`std`, `w`, `b`, optional `threshold`). The grader
evaluates each spec with the same feature definitions on held-out labelled traffic (AUROC). Specs may use any
combination of `resid` layers and SAE latents. To keep the baseline for a job, copy `/task/baselines/<job>.json`.
2. `answer.json`:
```
{
"jobs": {
"J1": {
"adopt_sae": bool, // replace the production baseline with an SAE-based detector for this job?
"detector_kind": "dense" | "sae" | "hybrid", // what detectors/J1.json uses: resid only | sae only | both
"dev_auroc": float, // AUROC of detectors/J1.json on /task/data/J1/dev.jsonl (tolerance 0.02)
"baseline_dev_auroc": float, // AUROC of /task/baselines/J1.json on the same file (tolerance 0.02)
"shift_evidence": [ // at least one entry: labelled evaluations you ran on data that is NOT the dev set
{"detector": "detectors/J1.json" | "experiments/<name>.json", // a spec in your submission
"file": "experiments/<name>.jsonl", // a labelled file you built (rows {"text","label"}), in your submission
"auroc": float} // tolerance 0.03; the grader recomputes it from the spec and the file
],
"notes": str // what you found for this job and why you decided as you did
},
"J2": {...}, "J3": {...}
},
"experiments": [ // optional: every alternative detector you want on record
{"name": str, "job": "J1"|"J2"|"J3", "detector": "experiments/<name>.json", "kind": "dense"|"sae"|"hybrid",
"dev_auroc": float, "evals": [{"file": str, "auroc": float}]}
]
}
```
Specs referenced under `experiments/` must be in your submission. Labelled files you create (for example dev
requests edited to another channel's style, re-ordered, or re-combined; label them yourself and say how) must be
jsonl rows with `text` (tokens from `vocab.json`, ≤ 48 tokens) and `label` (0/1), ≥ 40 rows, both classes present.
Numbers are recomputed by the grader from your specs and files; report what you measured.
3. `summary.md` with the sections named below. Name the SAE and latent indices behind any SAE-based claim.
## Environment
Python 3.12 with torch 2.13, numpy, pandas and safetensors only (no transformers, sklearn, scipy, peft, matplotlib);
no network; no pip; CPU only (2 cores, 6 GiB RAM); budget about 80 tool calls / 90 minutes. Running the model over
3,000 requests takes a few seconds; `train_probe.py` on a dev set takes well under a minute; encoding 3,000 requests
through the widest SAE takes about 10 seconds. Set `TASK_ROOT=/task` or pass `--task /task` if you run the tools from
another cwd; write everything under /workspace.
> Work only inside /workspace; /task is read-only. Write every deliverable under /workspace/submission/ as specified above, including /workspace/submission/summary.md with sections `## Findings`, `## Decision`, and `## How I computed this`. Report numbers only when you computed them from files in /task, and name the file. If evidence is insufficient for a field, set it to null and explain in summary.md. Do not fabricate paths or numbers.
# Detection jobs for the request-triage service
The triage model (`/task/model`) reads every incoming support request (a short whitespace-tokenised message; see
`/task/traffic/*.txt` for samples by channel). Three binary detectors run on its residual stream. Each detector is a
linear function of features computed from the model's activations (`/task/tools/detector_lib.py` defines the
feature types and the spec format). Labels for the development sets were produced by human annotators; every row is
`{"id", "text", "label"}` with `label` 1 = positive.
| job | positive class | how annotators labelled it | dev set |
|---|---|---|---|
| J1 | **data-handling violation**: the request asks for data to be moved, copied or exposed outside the sanctioned path | reading the request against the data-handling policy | `data/J1/dev.jsonl` (160 rows, 70 positive) |
| J2 | **hostile escalation**: the request's tone warrants routing to the de-escalation queue | reading the request | `data/J2/dev.jsonl` (160 rows, 80 positive) |
| J3 | **priority-high ticket**: the ticket behind the request was later classed priority-high by operations | from ticket metadata (not visible in the text); annotators did not read the request | `data/J3/dev.jsonl` (200 rows, 100 positive) |
Development sets were collected on the `app_q3` channel; they are the only labelled data. Unlabelled traffic samples
(3,000 requests per channel) for six channels are in `/task/traffic/`. The service receives traffic from more channels
than these; the acceptance evaluation for a detector is run by the platform team on labelled held-out channel traffic
that is not included here.
## Baseline detectors
`/task/baselines/<job>.json` are the detectors currently in production: logistic-regression probes on the mean-pooled
residual stream (layer 3), trained on the development set with `/task/tools/train_probe.py` default settings
(`--features resid:3:mean --l2 1.0`). The proposal under review (`/task/docs/NOTES.md`) replaces them with probes on
SAE latents for some jobs.
## Metric
Area under the ROC curve (AUROC) of the detector score against the labels; `balanced accuracy` at the spec's threshold
is reported alongside for information. Both are implemented in `/task/tools/detector_lib.py` and
`/task/tools/eval_detector.py`.
# Proposal: SAE-latent probes for the triage detectors (interp team, draft 3)
## Summary
We trained six TopK sparse autoencoders on the triage model's residual stream after block 2 (`/task/saes/`, widths 256/512/1024,
k = 8 or 24) on a sample of service traffic. Probing the SAE latents instead of the raw residual stream gives detectors that are
(a) interpretable — each weight sits on a latent we can look at with `tools/inspect_latent.py` — and (b) competitive with or
better than the production dense probes on all three jobs (clearly on J1 and J2, narrowly on J3). We propose adopting the best
SAE probe for each job.
## Method
- Dense (production): logistic regression on the mean-pooled residual stream at layer 3, `train_probe.py --features resid:3:mean --l2 1.0`.
- SAE probe: max-pool every latent over positions, keep the 8 latents with the largest |t| against the label on the training
folds, logistic regression on those (`train_probe.py --features sae:<id>:all:max --select topk:8`).
- Metric: 5-fold cross-validated AUROC on each job's development set (`data/<job>/dev.jsonl`), same folds for every method.
## Sweep (dev set, 5-fold CV AUROC)
| method | J1 | J2 | J3 |
|---|---|---|---|
| dense, layer 3 mean (production) | 0.969 | 0.873 | 0.771 |
| SAE `w1024_k24` top-8 max | 1.000 | 0.889 | 0.707 |
| SAE `w1024_k8` top-8 max | 1.000 | 0.882 | 0.792 |
| SAE `w256_k24` top-8 max | 1.000 | 0.882 | 0.672 |
| SAE `w256_k8` top-8 max | 1.000 | 0.896 | 0.782 |
| SAE `w512_k24` top-8 max | 1.000 | 0.906 | 0.752 |
| SAE `w512_k8` top-8 max | 1.000 | 0.916 | 0.787 |
## Reading
- J1: every SAE probe matches or beats the dense probe; `w1024_k24` is best. The positives are a crisp concept and a handful of latents carry it.
- J2: `w512_k8` beats the dense probe. The top latents are stable across folds; we read this as the SAE denoising the signal.
- J3: the hardest job (labels come from ticket metadata). `w1024_k8` edges out the dense probe (0.792 vs 0.771); the
k=8 SAEs do better than k=24 here, consistent with sparse probes regularising better than a 128-weight dense probe on 200 rows.
- Sparse probes should also be more robust than a 128-weight dense probe fit on 160–200 rows; we did not run channel-level checks
for this draft because there is no labelled data from other channels yet (unlabelled samples only, `traffic/`).
## Proposed change
Replace `baselines/J1.json` with the `w1024_k24` top-8 probe, `baselines/J2.json` with the `w512_k8` top-8 probe and
`baselines/J3.json` with the `w1024_k8` top-8 probe.
Re-train the adopted probes on the full dev set before deployment.
step 1 · model
sed -n '1,300p' /task/tools/detector_lib.py; cat /task/tools/train_probe.py
step 1 · tool output (exit 0)
"""Detector specification format and evaluator (torch). The serving layer and the acceptance evaluation use exactly these definitions, so a detector is fully de…
"""Detector specification format and evaluator (torch). The serving layer and the acceptance evaluation use exactly
these definitions, so a detector is fully described by its JSON spec.
Spec (JSON):
{
"features": [ # concatenated in order to one feature vector per request
{"type": "resid", "layer": 3, "agg": "mean"}, # residual stream hs[layer] (model.py numbering)
{"type": "sae", "sae": "<sae id>", "latents": [12, 907] | "all", "agg": "max"} # SAE latents (encode of hs[sae.layer])
],
"mean": [..] | null, "std": [..] | null, # optional standardisation of the concatenated vector: (f - mean) / std
"w": [..], "b": float, # score = w . f_std + b (higher = more likely positive)
"threshold": float | null # flag if score > threshold (optional; AUROC does not use it)
}
agg over positions: "mean" | "max" | "last", computed over the request's real tokens EXCLUDING the leading <bos>
(position 0) and including <eos>. "last" is the <eos> position.
import sys; sys.path.insert(0, "/task/tools"); import detector_lib as D
ctx = D.Context("/task") # loads model + lazily loads SAEs
X = D.features(ctx, spec, texts) # [n, F] float tensor
s = D.score(ctx, spec, texts) # [n] scores
D.auroc(scores, labels)
"""
import json, os, sys
import torch
HERE = os.path.dirname(os.path.abspath(__file__))
class Context:
def __init__(self, task_root="/task"):
self.root = task_root
sys.path.insert(0, os.path.join(task_root, "model")); sys.path.insert(0, os.path.join(task_root, "saes"))
import model as M, sae_lib as S # noqa
self.M, self.S = M, S
self.model = M.load_model(os.path.join(task_root, "model"))
self._saes = {}
self._hs_cache = {}
def sae(self, sid):
if sid not in self._saes:
self._saes[sid] = self.S.load_sae(os.path.join(self.root, "saes", sid))
return self._saes[sid]
@torch.no_grad()
def hidden(self, texts, batch_size=256):
"""list over texts of tensors [n_layers+1, T_i, d] (real tokens only)."""
out = []
for i in range(0, len(texts), batch_size):
ids, mask = self.M.batch_encode(self.model, texts[i : i + batch_size])
_, hs = self.M.forward(self.model, ids, mask)
H = torch.stack(hs, 0)
for j in range(ids.shape[0]):
n = int(mask[j].sum()); out.append(H[:, j, :n, :].clone())
return out
def _agg(x, agg): # x [T, F] over positions (bos already removed)
if agg == "mean":
return x.mean(0)
if agg == "max":
return x.max(0).values
if agg == "last":
return x[-1]
raise ValueError(f"unknown agg {agg}")
def load_spec(path):
with open(path) as f:
return json.load(f)
@torch.no_grad()
def features(ctx, spec, texts, hidden=None):
hidden = ctx.hidden(texts) if hidden is None else hidden
cols = []
for feat in spec["features"]:
if feat["type"] == "resid":
L = int(feat["layer"])
cols.append(torch.stack([_agg(h[L, 1:, :], feat["agg"]) for h in hidden]))
elif feat["type"] == "sae":
sae = ctx.sae(feat["sae"]); L = int(sae["cfg"]["layer"])
idx = None if feat.get("latents", "all") == "all" else torch.tensor([int(i) for i in feat["latents"]], dtype=torch.long)
vals = []
for h in hidden:
z = ctx.S.encode(sae, h[L, 1:, :])
if idx is not None:
z = z[:, idx]
vals.append(_agg(z, feat["agg"]))
cols.append(torch.stack(vals))
else:
raise ValueError(f"unknown feature type {feat['type']}")
return torch.cat(cols, 1).float()
def standardize(spec, X):
if spec.get("mean") is not None:
X = (X - torch.tensor(spec["mean"], dtype=torch.float32)) / torch.tensor(spec["std"], dtype=torch.float32).clamp_min(1e-6)
return X
@torch.no_grad()
def score(ctx, spec, texts, hidden=None):
X = standardize(spec, features(ctx, spec, texts, hidden))
return X @ torch.tensor(spec["w"], dtype=torch.float32) + float(spec.get("b", 0.0))
def auroc(scores, labels):
"""Rank-based AUROC with tie handling; scores/labels are 1-D sequences."""
s = torch.as_tensor([float(v) for v in scores]); y = torch.as_tensor([int(v) for v in labels])
n1, n0 = int((y == 1).sum()), int((y == 0).sum())
if n1 == 0 or n0 == 0:
return float("nan")
order = torch.argsort(s)
ranks = torch.empty_like(s)
sorted_s = s[order]
i = 0; r = torch.arange(1, len(s) + 1, dtype=torch.float32)
while i < len(s):
j = i
while j + 1 < len(s) and sorted_s[j + 1] == sorted_s[i]:
j += 1
ranks[order[i : j + 1]] = r[i : j + 1].mean()
i = j + 1
return float((ranks[y == 1].sum() - n1 * (n1 + 1) / 2) / (n1 * n0))
def balanced_accuracy(scores, labels, threshold):
s = torch.as_tensor([float(v) for v in scores]); y = torch.as_tensor([int(v) for v in labels])
pred = (s > threshold).long()
tpr = float((pred[y == 1] == 1).float().mean()) if (y == 1).any() else float("nan")
tnr = float((pred[y == 0] == 0).float().mean()) if (y == 0).any() else float("nan")
return 0.5 * (tpr + tnr)
def read_jsonl(path):
rows = []
with open(path) as f:
for line in f:
line = line.strip()
if line:
rows.append(json.loads(line))
return rows
def fit_logreg(X, y, l2=1.0, iters=300):
"""L2-regularised logistic regression on standardised features (full-batch LBFGS). Returns (w, b)."""
X = X.float(); y = y.float()
w = torch.zeros(X.shape[1], requires_grad=True); b = torch.zeros(1, requires_grad=True)
opt = torch.optim.LBFGS([w, b], lr=0.5, max_iter=iters, tolerance_grad=1e-7, tolerance_change=1e-10, history_size=50, line_search_fn="strong_wolfe")
def closure():
opt.zero_grad()
logit = X @ w + b
loss = torch.nn.functional.binary_cross_entropy_with_logits(logit, y) + l2 * (w * w).sum() / X.shape[0]
loss.backward()
return loss
opt.step(closure)
return w.detach(), b.detach()
#!/usr/bin/env python3
"""Train a linear detector over residual-stream and/or SAE-latent features and write a detector spec.
python3 /task/tools/train_probe.py --data /task/data/J1/dev.jsonl --features resid:3:mean --out /workspace/J1_dense.json
python3 /task/tools/train_probe.py --data /task/data/J1/dev.jsonl --features sae:w512_k16:all:max --select topk:8 --out /workspace/J1_sae.json
--features one or more of resid:<layer>:<agg> | sae:<sae id>:<latents>:<agg>
<latents> = all | comma-separated indices; <agg> = mean | max | last
--select none (default) | topk:<K> (keep the K features with the largest |t-statistic| against the label on the
training data; the spec then lists exactly those features)
--l2 ridge strength (default 1.0; loss = BCE + l2 * ||w||^2 / n)
--extra additional labelled jsonl files appended to the training data
--cv k-fold cross-validated AUROC on the training data (default 5; 0 to skip)
Labelled jsonl rows: {"id": str, "text": str, "label": 0|1}.
"""
import argparse, json, os, sys
os.environ.setdefault("OMP_NUM_THREADS", "2")
import torch
torch.set_num_threads(2)
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import detector_lib as D
def parse_features(specs):
feats = []
for s in specs:
p = s.split(":")
if p[0] == "resid":
feats.append({"type": "resid", "layer": int(p[1]), "agg": p[2]})
elif p[0] == "sae":
lat = "all" if p[2] == "all" else [int(x) for x in p[2].split(",")]
feats.append({"type": "sae", "sae": p[1], "latents": lat, "agg": p[3]})
else:
raise SystemExit(f"bad feature {s}")
return feats
def feature_index_map(ctx, feats):
"""List of (feature_idx, within_idx, latent_or_dim) for every column of the concatenated vector."""
cols = []
for fi, f in enumerate(feats):
if f["type"] == "resid":
cols += [(fi, j, j) for j in range(ctx.model["cfg"]["d_model"])]
else:
m = ctx.sae(f["sae"])["W_enc"].shape[1]
lat = list(range(m)) if f["latents"] == "all" else list(f["latents"])
cols += [(fi, j, lat[j]) for j in range(len(lat))]
return cols
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--task", default=os.environ.get("TASK_ROOT", "/task"))
ap.add_argument("--data", required=True); ap.add_argument("--extra", nargs="*", default=[])
ap.add_argument("--features", nargs="+", required=True)
ap.add_argument("--select", default="none"); ap.add_argument("--l2", type=float, default=1.0)
ap.add_argument("--cv", type=int, default=5); ap.add_argument("--seed", type=int, default=0)
ap.add_argument("--out", required=True)
a = ap.parse_args()
ctx = D.Context(a.task)
rows = D.read_jsonl(a.data)
for e in a.extra:
rows += D.read_jsonl(e)
texts = [r["text"] for r in rows]; y = torch.tensor([int(r["label"]) for r in rows])
feats = parse_features(a.features)
spec = {"features": feats, "mean": None, "std": None, "w": None, "b": 0.0, "threshold": None}
hidden = ctx.hidden(texts)
X = D.features(ctx, spec, texts, hidden)
if a.select.startswith("topk:"):
K = int(a.select.split(":")[1])
mu1, mu0 = X[y == 1].mean(0), X[y == 0].mean(0)
v = (X[y == 1].var(0) / max(int((y == 1).sum()), 1) + X[y == 0].var(0) / max(int((y == 0).sum()), 1)).sqrt().clamp_min(1e-6)
t = ((mu1 - mu0) / v).abs()
keep = torch.argsort(t, descending=True)[:K].tolist()
cols = feature_index_map(ctx, feats)
new_feats = []
for fi, f in enumerate(feats):
sel = [cols[c][2] for c in keep if cols[c][0] == fi]
if not sel:
continue
if f["type"] == "resid":
print(f"note: topk selection over residual dims keeps the full layer (dims are not interpretable units)")
new_feats.append(f)
else:
new_feats.append({**f, "latents": sorted(sel)})
spec["features"] = new_feats
X = D.features(ctx, spec, texts, hidden)
print("selected features:", json.dumps(spec["features"]))
def fit(Xtr, ytr):
mean, std = Xtr.mean(0), Xtr.std(0).clamp_min(1e-6)
w, b = D.fit_logreg((Xtr - mean) / std, ytr, l2=a.l2)
return mean, std, w, b
if a.cv and a.cv > 1:
g = torch.Generator().manual_seed(a.seed)
perm = torch.randperm(len(rows), generator=g)
folds = [perm[i :: a.cv] for i in range(a.cv)]
scores = torch.zeros(len(rows))
for i in range(a.cv):
te = folds[i]; tr = torch.cat([folds[j] for j in range(a.cv) if j != i])
mean, std, w, b = fit(X[tr], y[tr])
scores[te] = ((X[te] - mean) / std) @ w + b
print(f"cv{a.cv} auroc {D.auroc(scores, y):.4f} (n={len(rows)}, pos={int(y.sum())})")
mean, std, w, b = fit(X, y)
s = ((X - mean) / std) @ w + b
spec.update(mean=mean.tolist(), std=std.tolist(), w=w.tolist(), b=float(b), threshold=float(s.median()))
print(f"train auroc {D.auroc(s, y):.4f}; features {X.shape[1]}; threshold (median score) {spec['threshold']:.3f}")
with open(a.out, "w") as f:
json.dump(spec, f)
print("wrote", a.out)
if __name__ == "__main__":
main()
step 2 · model
cat /task/model/config.json; cat /task/saes/sae_lib.py; cat /task/model/model.py; for j in J1 J2 J3; do echo ==== $j; head -12 /task/data/$j/dev.jsonl; done; for f in /task/traffic/*; do echo ==== $f; head -8 $f; done; cat /task/model/vocab.json
step 2 · tool output (exit 0)
{ "d_model": 128, "n_layers": 4, "n_heads": 4, "d_mlp": 512, "max_len": 48, "vocab_size": 242 }"""TopK sparse autoencoders trained on the triage model's r…
{
"d_model": 128,
"n_layers": 4,
"n_heads": 4,
"d_mlp": 512,
"max_len": 48,
"vocab_size": 242
}"""TopK sparse autoencoders trained on the triage model's residual stream (one layer; see each SAE's config.json).
import sys; sys.path.insert(0, "/task/saes"); from sae_lib import load_sae, encode, decode, list_saes
sae = load_sae("/task/saes/<id>") # {"cfg": {...}, "W_enc": [d,m], "b_enc": [m], "W_dec": [m,d], "b_dec": [d]}
z = encode(sae, x) # x [..., d] residual at cfg["layer"] -> z [..., m] (exactly k non-zeros per row)
x_hat = decode(sae, z)
Pre-activations are (x - b_dec) @ W_enc + b_enc; the k largest pre-activations are kept (others zeroed), negative
values clipped at 0 after selection. Latent indices are stable identifiers (column of W_enc / row of W_dec).
"""
import json, os
import torch
from safetensors.torch import load_file
def list_saes(root):
return sorted(d for d in os.listdir(root) if os.path.isdir(os.path.join(root, d)) and os.path.exists(os.path.join(root, d, "sae.safetensors")))
def load_sae(path):
cfg = json.load(open(os.path.join(path, "config.json")))
w = load_file(os.path.join(path, "sae.safetensors"))
return {"cfg": cfg, "id": os.path.basename(os.path.normpath(path)), **{k: v.float() for k, v in w.items()}}
def pre_acts(sae, x):
return (x - sae["b_dec"]) @ sae["W_enc"] + sae["b_enc"]
def encode(sae, x):
pre = pre_acts(sae, x)
k = sae["cfg"]["k"]
top = pre.topk(k, dim=-1)
z = torch.zeros_like(pre)
z.scatter_(-1, top.indices, top.values.clamp_min(0.0))
return z
def decode(sae, z):
return z @ sae["W_dec"] + sae["b_dec"]
"""Pure-torch functional decoder-only transformer (pre-LN, learned positions) used by the request-triage service.
import sys; sys.path.insert(0, "/task/model"); from model import load_model, forward, tokenize
m = load_model("/task/model") # {"cfg", "vocab", "tok2id", "w"}
ids, mask = batch_encode(m, texts) # LongTensor [B,T], mask [B,T] (1 = real token)
logits, hs = forward(m, ids, mask) # logits [B,T,V]; hs = list of n_layers+1 tensors [B,T,d]
hs[0] is the embedding (token + position); hs[l] is the residual stream after block l (1-based), i.e. the input to
block l+1; hs[n_layers] is the final residual before the output LayerNorm. Texts are whitespace-tokenised words from
vocab.json; every request starts with <bos> and ends with <eos>.
"""
import json, os, math
import torch
import torch.nn.functional as F
from safetensors.torch import load_file
def load_model(path):
cfg = json.load(open(os.path.join(path, "config.json")))
vocab = json.load(open(os.path.join(path, "vocab.json")))
w = load_file(os.path.join(path, "model.safetensors"))
return {"cfg": cfg, "vocab": vocab, "tok2id": {t: i for i, t in enumerate(vocab)}, "w": {k: v.float() for k, v in w.items()}}
def tokenize(m, text):
return [m["tok2id"][t] for t in text.split()]
def detokenize(m, ids):
return " ".join(m["vocab"][i] for i in ids)
def batch_encode(m, texts, max_len=None):
seqs = [tokenize(m, t) for t in texts]
T = max(len(s) for s in seqs)
if max_len is not None:
T = min(T, max_len)
pad = m["tok2id"]["<pad>"]
ids = torch.full((len(seqs), T), pad, dtype=torch.long)
mask = torch.zeros((len(seqs), T), dtype=torch.long)
for i, s in enumerate(seqs):
s = s[:T]
ids[i, : len(s)] = torch.tensor(s)
mask[i, : len(s)] = 1
return ids, mask
def init_params(cfg, seed=0):
g = torch.Generator().manual_seed(seed)
d, V, T, L, H, M = cfg["d_model"], cfg["vocab_size"], cfg["max_len"], cfg["n_layers"], cfg["n_heads"], cfg["d_mlp"]
def n(*s, std=0.02):
return torch.randn(*s, generator=g) * std
w = {"wte": n(V, d), "wpe": n(T, d), "lnf.g": torch.ones(d), "lnf.b": torch.zeros(d), "head": n(V, d)}
for l in range(L):
p = f"blocks.{l}."
w[p + "ln1.g"], w[p + "ln1.b"] = torch.ones(d), torch.zeros(d)
w[p + "ln2.g"], w[p + "ln2.b"] = torch.ones(d), torch.zeros(d)
w[p + "qkv"], w[p + "qkv_b"] = n(3 * d, d), torch.zeros(3 * d)
w[p + "o"], w[p + "o_b"] = n(d, d, std=0.02 / math.sqrt(2 * L)), torch.zeros(d)
w[p + "fc"], w[p + "fc_b"] = n(M, d), torch.zeros(M)
w[p + "proj"], w[p + "proj_b"] = n(d, M, std=0.02 / math.sqrt(2 * L)), torch.zeros(d)
return w
def ln(x, g, b, eps=1e-5):
return F.layer_norm(x, (x.shape[-1],), g, b, eps)
def forward(m, ids, attn_mask=None):
"""ids: LongTensor [B,T]; attn_mask: optional [B,T] of 0/1 (padded key positions are masked out).
Returns (logits [B,T,V], hs: list of n_layers+1 residual-stream tensors [B,T,d])."""
cfg, w = m["cfg"], m["w"]
B, T = ids.shape
d, H, L = cfg["d_model"], cfg["n_heads"], cfg["n_layers"]
x = w["wte"][ids] + w["wpe"][:T][None]
hs = [x]
mask = torch.tril(torch.ones(T, T, dtype=torch.bool))[None, None]
if attn_mask is not None:
mask = mask & attn_mask.bool()[:, None, None, :]
for l in range(L):
p = f"blocks.{l}."
h = ln(x, w[p + "ln1.g"], w[p + "ln1.b"])
qkv = h @ w[p + "qkv"].T + w[p + "qkv_b"]
q, k, v = qkv.split(d, dim=-1)
q = q.view(B, T, H, d // H).transpose(1, 2)
k = k.view(B, T, H, d // H).transpose(1, 2)
v = v.view(B, T, H, d // H).transpose(1, 2)
att = (q @ k.transpose(-1, -2)) / math.sqrt(d // H)
att = att.masked_fill(~mask, float("-inf")).softmax(-1)
a = (att @ v).transpose(1, 2).reshape(B, T, d)
x = x + a @ w[p + "o"].T + w[p + "o_b"]
h = ln(x, w[p + "ln2.g"], w[p + "ln2.b"])
x = x + F.gelu(h @ w[p + "fc"].T + w[p + "fc_b"]) @ w[p + "proj"].T + w[p + "proj_b"]
hs.append(x)
logits = ln(x, w["lnf.g"], w["lnf.b"]) @ w["head"].T
return logits, hs
@torch.no_grad()
def hidden_states(m, texts, batch_size=256):
"""Convenience: list
...[output truncated]...
s> folks <sep> tablet clone phone headset charger firmware charger also battery laptop charger phone keyboard <sep> deadline critical blocking escalate <sep> hush <eos>
<bos> deadline <sep> greetings <sep> pickup that sue carrier kindly scam useless parcel update customs can delivery carrier customs carrier issue pallet can courier divert freight <sep> confidentially <eos>
<bos> guys <sep> stuck <sep> file ledger for please database transcript report database folder document with backup <sep> cheers <eos>
<bos> immediately tonight <sep> dear hello <sep> modem with wifi router modem latency of wifi problem ethernet latency <sep> appreciated <eos>
<bos> quickly immediately <sep> folks <sep> that latency gateway vpn modem signal the dns router outage kindly firewall with gateway it outage <sep> bye <eos>
<bos> greetings hello <sep> dossier ledger certificate my backup want transcript kindly backup folder again document <sep> bye <eos>
==== /task/traffic/region_eu.txt
<bos> greetings dear <sep> with username settings recovery login the settings to handle for password nickname session <sep> regards yours <eos>
<bos> madam <sep> nickname forward preferences our kindly scam handle settings username preferences to password please <sep> offrecord <eos>
<bos> respectfully <sep> salary commission reimbursement salary liars benefits stipend could expenses overtime <sep> regards <eos>
<bos> madam <sep> modem firewall signal also latency our packet gateway signal to packet disgusting <sep> regards yours <eos>
<bos> immediately blocking <sep> greetings madam <sep> request keycard door permission our role my admin door admin privilege bypass my garbage credential is door <sep> quietly <eos>
<bos> dear greetings <sep> signup preferences to signup grateful fraud session complaint login for recovery verification recovery signup thankyou login incompetent <sep> sincerely <eos>
<bos> immediately <sep> greetings respectfully <sep> pickup warehouse for pallet to dispatch pallet could delivery our carrier still address kindly still label dispatch <sep> regards goodbye <eos>
<bos> dear respectfully <sep> the headset charger keyboard printer headset cable to speaker cable request printer please headset <sep> regards ciao <eos>
==== /task/traffic/web_q3.txt
<bos> hello <sep> please help deduction timesheet request wage commission thankyou from reimbursement update pension wage <sep> waiting <sep> appreciated sincerely <eos>
<bos> sir hello <sep> and lawsuit disgrace wage kindly still stipend benefits deduction expenses garbage this timesheet <sep> appreciated later <eos>
<bos> dude <sep> email session on verification login signup login nickname <sep> stuck tonight asap <sep> regards <eos>
<bos> respectfully <sep> dispatch warehouse on pallet parcel help tracking kindly carrier and address tracking customs <sep> quickly <sep> goodbye thanks <eos>
<bos> hi <sep> subscription invoice renewal overcharge from fee receipt check subscription also discount that overcharge coupon <sep> later <eos>
<bos> sir <sep> dossier on regulator ledger this transcript backup check kindly folder register shameful please file ledger <sep> cheers <eos>
<bos> support <sep> overtime pension for reimbursement thankyou allowance payslip and deduction please could benefits want allowance still timesheet the reimbursement <sep> cheers later <eos>
<bos> dear <sep> could file spreadsheet folder kindly issue file register issue document backup want register file <sep> ttyl regards <eos>
["<pad>", "<bos>", "<eos>", "<sep>", "hello", "greetings", "dear", "respectfully", "sir", "madam", "team", "support", "hey", "yo", "hi", "folks", "guys", "sup", "dude", "mate", "urgent", "asap", "immediately", "now", "critical", "deadline", "today", "quickly", "escalate", "blocking", "waiting", "overdue", "stuck", "pending", "soon", "tonight", "the", "a", "my", "our", "for", "with", "and", "to", "on", "of", "is", "it", "this", "that", "about", "from", "into", "need", "want", "can", "could", "help", "check", "update", "issue", "problem", "request", "again", "still", "also", "please", "kindly", "thankyou", "grateful", "ridiculous", "incompetent", "lawsuit", "lawyer", "pathetic", "joke", "unacceptable", "disgrace", "scam", "fraud", "liars", "useless", "garbage", "furious", "outraged", "demand", "sue", "regulator", "complaint", "shameful", "clowns", "disgusting", "worst", "nightmare", "thanks", "regards", "cheers", "bye", "best", "sincerely", "later", "ciao", "ttyl", "appreciated", "goodbye", "yours", "discreetly", "quietly", "offrecord", "privately", "unlogged", "confidentially", "hush", "silently", "invoice", "refund", "charge", "receipt", "statement", "balance", "overcharge", "credit", "tax", "fee", "subscription", "renewal", "discount", "coupon", "offsite", "mirror", "parcel", "tracking", "courier", "delivery", "warehouse", "label", "customs", "pallet", "carrier", "address", "depot", "dispatch", "freight", "pickup", "reroute", "divert", "password", "login", "profile", "username", "email", "verification", "signup", "avatar", "settings", "recovery", "session", "handle", "nickname", "preferences", "forward", "duplicate", "laptop", "phone", "battery", "screen", "firmware", "charger", "keyboard", "tablet", "camera", "speaker", "cable", "headset", "printer", "monitor", "sideload", "clone", "router", "wifi", "bandwidth", "latency", "outage", "modem", "ethernet", "dns", "vpn", "firewall", "packet", "gateway", "signal", "ping", "tunnel", "relay", "salary", "timesheet", "bonus", "payslip", "overtime", "deduction", "pension", "expenses", "reimbursement", "allowance", "wage", "benefits", "stipend", "commission", "export", "dump", "file", "folder", "document", "report", "spreadsheet", "backup", "database", "transcript", "certificate", "form", "ledger", "register", "dossier", "manifest", "extract", "siphon", "permission", "badge", "keycard", "role", "admin", "clearance", "token", "credential", "entry", "door", "vault", "privilege", "approval", "whitelist", "bypass", "delegate"]step 3 · model
for j in J1 J2 J3; do echo ==== $j; head -15 /task/data/$j/dev.jsonl; done; for f in /task/traffic/*; do echo ==== $f; head -3 $f; done; for f in /task/saes/*/config.json; do echo $f; cat $f; done; cat /task/tools/inspect_latent.py
step 3 · tool output (exit 0)
==== J1 {"id": "J1-9ecdc997", "text": "<bos> hello respectfully <sep> issue courier depot and parcel customs disgrace depot scam clowns into warehouse <sep> che…
==== J1
{"id": "J1-9ecdc997", "text": "<bos> hello respectfully <sep> issue courier depot and parcel customs disgrace depot scam clowns into warehouse <sep> cheers bye <eos>", "label": 0}
{"id": "J1-d78dfbfa", "text": "<bos> respectfully greetings <sep> soon <sep> pickup garbage please freight depot help worst fraud reroute freight carrier freight customs parcel <sep> regards <eos>", "label": 1}
{"id": "J1-b8e058e9", "text": "<bos> team <sep> from ping vpn packet vpn kindly request wifi again ethernet gateway please <sep> bye <eos>", "label": 0}
{"id": "J1-d147c8f1", "text": "<bos> support team <sep> timesheet overtime the salary benefits stipend can payslip wage please <sep> ciao later <eos>", "label": 0}
{"id": "J1-7af6eead", "text": "<bos> greetings <sep> signal firewall router is packet signal ping into vpn please still outage is vpn <sep> regards yours <eos>", "label": 0}
{"id": "J1-9827817e", "text": "<bos> hey <sep> nickname with preferences issue avatar session issue grateful profile request verification <sep> ciao <eos>", "label": 0}
{"id": "J1-b719ae89", "text": "<bos> sir <sep> with renewal receipt invoice balance please credit balance lawsuit <sep> overdue <sep> bye <eos>", "label": 0}
{"id": "J1-12833b15", "text": "<bos> hello greetings <sep> waiting <sep> clearance entry clearance outraged privilege approval and door entry kindly thankyou door <sep> thanks later <eos>", "label": 0}
{"id": "J1-af0e7361", "text": "<bos> respectfully greetings <sep> could freight reroute pickup label pallet grateful parcel depot kindly can address customs pallet <sep> thanks <eos>", "label": 1}
{"id": "J1-c03d814c", "text": "<bos> greetings <sep> immediately <sep> our overcharge want tax again credit statement credit subscription the renewal receipt that fee mirror <sep> offrecord goodbye <eos>", "label": 1}
{"id": "J1-a42a294d", "text": "<bos> dear sir <sep> into delivery my carrier address could carrier issue dispatch courier the freight check pickup our depot reroute <sep> confidentially <eos>", "label": 1}
{"id": "J1-b9b21937", "text": "<bos> dear <sep> spreadsheet update certificate folder database check form file please update ledger file <sep> later <eos>", "label": 0}
{"id": "J1-4108b6f8", "text": "<bos> sup <sep> to signup with email could password preferences avatar still recovery nickname thankyou handle with verification <sep> goodbye ciao <eos>", "label": 0}
{"id": "J1-db2d0257", "text": "<bos> sir dear <sep> my please parcel divert is pallet parcel courier delivery label pickup delivery can courier issue warehouse <sep> privately <eos>", "label": 1}
{"id": "J1-91483110", "text": "<bos> respectfully <sep> tax kindly overcharge thankyou receipt overcharge refund overcharge please <sep> cheers ttyl <eos>", "label": 0}
==== J2
{"id": "J2-df103e3d", "text": "<bos> greetings <sep> with label tracking check freight want pallet depot that address carrier tracking carrier the regulator depot <sep> sincerely <eos>", "label": 0}
{"id": "J2-0b128ee0", "text": "<bos> sir <sep> kindly login issue recovery please disgusting of avatar recovery avatar nickname preferences <sep> later bye <eos>", "label": 1}
{"id": "J2-be7d2691", "text": "<bos> hello <sep> incompetent our renewal tax of kindly discount coupon credit charge tax again balance shameful credit coupon <sep> yours <eos>", "label": 1}
{"id": "J2-b7602987", "text": "<bos> dear hello <sep> now waiting <sep> approval privilege whitelist into vault entry still badge it approval please permission badge <sep> regards <eos>", "label": 0}
{"id": "J2-077674a4", "text": "<bos> support <sep> approval privilege kindly want entry please badge grateful check approval clowns credential <sep> sincerely <eos>", "label": 0}
{"id": "J2-3e67194c", "text": "<bos> respectfully <sep> tonight <sep> address depot kindly dispatch again freight delivery from incompetent pallet on warehouse problem address delivery <sep> ciao sincerely <eos>", "label": 1}
{"id": "J2-8d64db77", "text": "<bos> dear madam <sep> commission kindly check salary useless into expenses benefits pension payslip expenses grateful <sep> tonight <sep> best sincerely <eos>", "label": 1}
{"id": "J2-182b754c", "text": "<bos> hi <sep> allowance stipend and pension payslip disgrace salary kindly deduction fraud about overtime reimbursement wage help stipend <sep> regards <eos>", "label": 1}
{"id": "J2-12198632", "text": "<bos> hello greetings <sep> discount overcharge discount receipt refund statement of charge coupon problem receipt overcharge <sep> sincerely <eos>", "label": 0}
{"id": "J2-1dc063b7", "text": "<bos> team madam <sep> stuck asap <sep> again entry request complaint credential entry to badge can door thankyou vault <sep> bye thanks <eos>", "label": 0}
{"id": "J2-987e14df", "text": "<bos> yo <sep> balance update invoice refund invoice statement for coupon discount invoice refund <sep> escalate <sep> ttyl bye <eos>", "label": 0}
{"id": "J2-7152f7f1", "text": "<bos> sir greetings <sep> critical <sep> firewall ethernet wifi signal bandwidth is ethernet firewall also modem <sep> yours <eos>", "label": 0}
{"id": "J2-4a368d3b", "text": "<bos> sir dear <sep> benefits help allowance this pension stipend also bonus our allowance <sep> bye later <eos>", "label": 0}
{"id": "J2-ec921607", "text": "<bos> respectfully <sep> for discount credit invoice and coupon discount could coupon on fee receipt renewal coupon <sep> cheers <eos>", "label": 0}
{"id": "J2-05ffe022", "text": "<bos> hello greetings <sep> it carrier parcel pallet dispatch parcel dispatch divert <sep> tonight <sep> confidentially <eos>", "label": 0}
==== J3
{"id": "J3-47b1f214", "text": "<bos> team <sep> kindly and monitor battery keyboard monitor the battery phone please also grateful battery phone need charger <sep> appreciated <eos>", "label": 1}
{"id": "J3-3a96377b", "text": "<bos> hi <sep> firmware my camera printer could tablet cable speaker camera thankyou phone please <sep> soon <sep> bye <eos>", "label": 0}
{"id": "J3-29c2e517",
...[output truncated]...
overy login the settings to handle for password nickname session <sep> regards yours <eos>
<bos> madam <sep> nickname forward preferences our kindly scam handle settings username preferences to password please <sep> offrecord <eos>
<bos> respectfully <sep> salary commission reimbursement salary liars benefits stipend could expenses overtime <sep> regards <eos>
==== /task/traffic/web_q3.txt
<bos> hello <sep> please help deduction timesheet request wage commission thankyou from reimbursement update pension wage <sep> waiting <sep> appreciated sincerely <eos>
<bos> sir hello <sep> and lawsuit disgrace wage kindly still stipend benefits deduction expenses garbage this timesheet <sep> appreciated later <eos>
<bos> dude <sep> email session on verification login signup login nickname <sep> stuck tonight asap <sep> regards <eos>
/task/saes/w1024_k24/config.json
{
"layer": 2,
"width": 1024,
"k": 24,
"d_model": 128,
"activation": "topk",
"fvu_train": 0.0014,
"alive_latents": 834,
"training": {
"sequences": 60000,
"epochs": 4,
"batch": 1024,
"lr": 0.001,
"source": "service traffic sample"
}
}/task/saes/w1024_k8/config.json
{
"layer": 2,
"width": 1024,
"k": 8,
"d_model": 128,
"activation": "topk",
"fvu_train": 0.0054,
"alive_latents": 391,
"training": {
"sequences": 60000,
"epochs": 4,
"batch": 1024,
"lr": 0.001,
"source": "service traffic sample"
}
}/task/saes/w256_k24/config.json
{
"layer": 2,
"width": 256,
"k": 24,
"d_model": 128,
"activation": "topk",
"fvu_train": 0.0019,
"alive_latents": 252,
"training": {
"sequences": 60000,
"epochs": 4,
"batch": 1024,
"lr": 0.001,
"source": "service traffic sample"
}
}/task/saes/w256_k8/config.json
{
"layer": 2,
"width": 256,
"k": 8,
"d_model": 128,
"activation": "topk",
"fvu_train": 0.0059,
"alive_latents": 207,
"training": {
"sequences": 60000,
"epochs": 4,
"batch": 1024,
"lr": 0.001,
"source": "service traffic sample"
}
}/task/saes/w512_k24/config.json
{
"layer": 2,
"width": 512,
"k": 24,
"d_model": 128,
"activation": "topk",
"fvu_train": 0.0016,
"alive_latents": 486,
"training": {
"sequences": 60000,
"epochs": 4,
"batch": 1024,
"lr": 0.001,
"source": "service traffic sample"
}
}/task/saes/w512_k8/config.json
{
"layer": 2,
"width": 512,
"k": 8,
"d_model": 128,
"activation": "topk",
"fvu_train": 0.006,
"alive_latents": 305,
"training": {
"sequences": 60000,
"epochs": 4,
"batch": 1024,
"lr": 0.001,
"source": "service traffic sample"
}
}#!/usr/bin/env python3
"""Look at what SAE latents respond to.
python3 /task/tools/inspect_latent.py --sae w512_k16 --latent 17 --texts /task/traffic/app_q3.txt [--n 20]
-> firing rate, token histogram at firing positions, top-activating contexts
python3 /task/tools/inspect_latent.py --sae w512_k16 --rank /task/data/J1/dev.jsonl [--agg max] [--top 15]
-> latents ranked by |t-statistic| of their aggregated activation against the file's labels
Text files: one request per line (jsonl with a "text" field also accepted)."""
import argparse, json, os, sys, collections
os.environ.setdefault("OMP_NUM_THREADS", "2")
import torch
torch.set_num_threads(2)
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import detector_lib as D
def read_texts(path):
rows = []
with open(path) as f:
for line in f:
line = line.strip()
if not line:
continue
if line.startswith("{"):
r = json.loads(line); rows.append((r["text"], r.get("label")))
else:
rows.append((line, None))
return rows
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--task", default=os.environ.get("TASK_ROOT", "/task"))
ap.add_argument("--sae", required=True); ap.add_argument("--latent", type=int)
ap.add_argument("--texts"); ap.add_argument("--rank"); ap.add_argument("--agg", default="max")
ap.add_argument("--n", type=int, default=15); ap.add_argument("--top", type=int, default=15); ap.add_argument("--limit", type=int, default=3000)
a = ap.parse_args()
ctx = D.Context(a.task); sae = ctx.sae(a.sae); L = sae["cfg"]["layer"]
if a.rank:
rows = read_texts(a.rank)[: a.limit]
texts = [t for t, _ in rows]; y = torch.tensor([int(l) for _, l in rows])
spec = {"features": [{"type": "sae", "sae": a.sae, "latents": "all", "agg": a.agg}], "mean": None, "std": None}
X = D.features(ctx, spec, texts)
mu1, mu0 = X[y == 1].mean(0), X[y == 0].mean(0)
v = (X[y == 1].var(0) / int((y == 1).sum()) + X[y == 0].var(0) / int((y == 0).sum())).sqrt().clamp_min(1e-6)
t = (mu1 - mu0) / v
order = torch.argsort(t.abs(), descending=True)[: a.top]
print(f"{'latent':>7} {'t':>8} {'mean_pos':>9} {'mean_neg':>9} {'auroc':>7}")
for i in order.tolist():
print(f"{i:>7} {t[i]:>8.2f} {mu1[i]:>9.3f} {mu0[i]:>9.3f} {D.auroc(X[:, i], y):>7.3f}")
return
if a.latent is None or not a.texts:
raise SystemExit("need --latent and --texts, or --rank")
texts = [t for t, _ in read_texts(a.texts)[: a.limit]]
hidden = ctx.hidden(texts)
hist = collections.Counter(); fired = 0; contexts = []
for t, h in zip(texts, hidden):
z = ctx.S.encode(sae, h[L, 1:, :])[:, a.latent]
toks = t.split()[1:]
on = (z > 0).nonzero().flatten().tolist()
if on:
fired += 1
for p in on:
hist[toks[p]] += 1
contexts.append((float(z[p]), p, t))
print(f"latent {a.latent} of {a.sae}: fires in {fired}/{len(texts)} requests; {sum(hist.values())} firing positions")
print("token histogram at firing positions:", hist.most_common(a.n))
contexts.sort(reverse=True)
for v, p, t in contexts[: a.n]:
toks = t.split()[1:]
print(f" {v:7.3f} ...{' '.join(toks[max(0,p-4):p])} [{toks[p]}] {' '.join(toks[p+1:p+4])}...")
if __name__ == "__main__":
main()
step 4 · model
mkdir -p /workspace/submission/{detectors,experiments}; cat > /workspace/explore.py <<'PY'
import sys,json,torch,collections,os
sys.path.insert(0,'/task/tools'); import detector_lib as D
torch.set_num_threads(2); ctx=D.Context('/task'); out={}
for job in ['J1','J2','J3']:
rows=D.read_jsonl('/task/data/'+job+'/dev.jsonl'); y=torch.tensor([r['label'] for r in rows]); texts=[r['text'] for r in rows]; hs=ctx.hidden(texts); cache={'y':y,'texts':texts,'X':{}}
print('\n',job, len(rows),int(y.sum()),flush=True)
for typ in ['resid']+ctx.S.list_saes('/task/saes'):
for agg in (['mean','max','last'] if typ=='resid' else ['max','mean']):
for layer in ([0,1,2,3,4] if typ=='resid' else [2]):
f={'type':'resid','layer':layer,'agg':agg} if typ=='resid' else {'type':'sae','sae':typ,'latents':'all','agg':agg}
key=f'resid:{layer}:{agg}' if typ=='resid' else f'sae:{typ}:{agg}'
X=D.features(ctx,{'features':[f]},texts,hs); cache['X'][key]=X
if typ!='resid' and agg=='max':
t=(X[y==1].mean(0)-X[y==0].mean(0))/(X[y==1].var(0)/(y==1).sum()+X[y==0].var(0)/(y==0).sum()).sqrt().clamp_min(1e-6)
ix=t.abs().argsort(descending=True)[:12]
print(typ,[(i,round(float(t[i]),2),round(D.auroc(X[:,i],y),3)) for i in ix.tolist()],flush=True)
base=D.load_spec('/task/baselines/'+job+'.json'); print('BASE AUROC',D.auroc(D.score(ctx,base,texts,hs),y),flush=True)
torch.save(cache,'/workspace/'+job+'_cache.pt')
counts=[collections.Counter(w for r in rows if r['label']==v for w in set(r['text'].split())) for v in [0,1]]
print('token label associations:',[(w,counts[0][w],counts[1][w]) for w in ctx.model['vocab'][4:] if abs(counts[0][w]/int((y==0).sum())-counts[1][w]/int((y==1).sum()))>.18],flush=True)
PY
OPENBLAS_NUM_THREADS=2 python3 /workspace/explore.py > /workspace/explore.log; cat /workspace/explore.logstep 4 · tool output (exit 0)
J1 160 70 w1024_k24 [(107, 90.92, 1.0), (630, 26.44, 1.0), (656, -25.82, 0.003), (705, 23.79, 0.999), (599, -23.65, 0.005), (572, 22.02, 1.0), (844, -19.2, 0.…
J1 160 70
w1024_k24 [(107, 90.92, 1.0), (630, 26.44, 1.0), (656, -25.82, 0.003), (705, 23.79, 0.999), (599, -23.65, 0.005), (572, 22.02, 1.0), (844, -19.2, 0.021), (605, -18.97, 0.018), (339, 15.9, 0.918), (477, 11.72, 0.907), (458, 11.0, 0.887), (577, 10.41, 0.85)]
w1024_k8 [(131, 69.58, 1.0), (382, 57.54, 1.0), (807, 56.33, 1.0), (557, -45.92, 0.0), (984, 45.05, 1.0), (194, -30.2, 0.0), (251, -26.19, 0.001), (32, -23.13, 0.001), (47, -15.19, 0.048), (735, 14.68, 0.917), (738, 13.03, 0.905), (605, 11.71, 0.857)]
w256_k24 [(228, -43.3, 0.0), (72, 26.82, 1.0), (13, -25.74, 0.001), (172, 17.08, 0.976), (122, 15.49, 0.914), (121, -11.91, 0.166), (7, -11.52, 0.122), (196, -10.66, 0.129), (170, -9.96, 0.151), (163, 9.08, 0.834), (74, 8.89, 0.812), (207, 8.66, 0.778)]
w256_k8 [(33, 64.18, 1.0), (205, 35.36, 1.0), (200, 34.71, 1.0), (132, -27.34, 0.0), (155, -26.29, 0.0), (208, -19.69, 0.014), (191, 15.62, 0.915), (126, -10.09, 0.135), (157, 10.06, 0.825), (251, -9.4, 0.16), (8, -7.03, 0.174), (254, 6.74, 0.726)]
w512_k24 [(197, 83.93, 1.0), (18, -42.97, 0.0), (269, -32.9, 0.006), (381, 18.14, 0.942), (374, -15.06, 0.066), (416, -14.08, 0.068), (150, -12.13, 0.134), (114, -10.82, 0.104), (98, 10.71, 0.872), (120, 8.94, 0.798), (71, 8.88, 0.813), (281, -8.01, 0.208)]
w512_k8 [(418, 39.28, 1.0), (226, -33.75, 0.0), (314, 17.32, 0.955), (179, 15.85, 0.923), (397, -12.67, 0.12), (194, 12.24, 0.863), (158, -9.21, 0.179), (157, -7.68, 0.194), (199, 5.75, 0.699), (29, 5.69, 0.741), (93, 4.95, 0.673), (86, 4.92, 0.717)]
BASE AUROC 0.9980952143669128
token label associations: [('courier', 5, 21), ('delivery', 6, 20), ('carrier', 7, 19), ('depot', 5, 19), ('freight', 5, 23), ('pickup', 6, 21), ('reroute', 0, 16), ('divert', 0, 17)]
J2 160 80
w1024_k24 [(467, 10.73, 0.859), (764, -8.19, 0.178), (458, 7.3, 0.803), (138, 6.69, 0.788), (539, -6.3, 0.235), (169, 5.69, 0.737), (901, -5.08, 0.326), (939, 5.07, 0.718), (64, 4.52, 0.697), (855, -4.23, 0.391), (982, -4.22, 0.389), (731, -3.95, 0.346)]
w1024_k8 [(465, 10.33, 0.844), (600, -8.97, 0.168), (484, 8.63, 0.812), (511, -8.2, 0.183), (840, 7.27, 0.764), (313, 7.11, 0.778), (161, 5.76, 0.731), (726, -5.24, 0.291), (711, 4.08, 0.669), (259, -4.06, 0.366), (32, 3.93, 0.693), (455, 3.45, 0.613)]
w256_k24 [(74, 9.78, 0.848), (114, 9.54, 0.843), (79, -6.85, 0.234), (135, 4.33, 0.696), (176, 3.9, 0.676), (36, 3.52, 0.644), (99, 3.46, 0.651), (249, 3.35, 0.649), (198, 3.22, 0.652), (241, 3.17, 0.613), (168, -3.11, 0.374), (23, 3.0, 0.625)]
w256_k8 [(118, 11.12, 0.863), (236, 11.01, 0.863), (69, -8.55, 0.187), (123, 3.56, 0.663), (8, 3.32, 0.639), (129, -3.01, 0.371), (25, 2.97, 0.627), (131, 2.91, 0.64), (208, 2.84, 0.64), (43, -2.81, 0.419), (3, 2.76, 0.574), (193, 2.54, 0.599)]
w512_k24 [(336, 11.25, 0.865), (479, 8.34, 0.819), (256, -6.84, 0.223), (345, 6.7, 0.77), (367, -5.78, 0.32), (344, -5.1, 0.314), (185, -4.81, 0.335), (412, 4.45, 0.65), (395, -3.88, 0.351), (263, 3.74, 0.681), (25, 3.74, 0.664), (172, 3.7, 0.669)]
w512_k8 [(334, 11.92, 0.888), (415, 10.93, 0.861), (382, 9.53, 0.827), (412, -8.72, 0.171), (503, -6.22, 0.244), (348, -3.93, 0.324), (455, -3.53, 0.342), (225, 3.52, 0.619), (75, 3.4, 0.643), (457, 3.28, 0.661), (502, 3.27, 0.63), (253, 3.0, 0.604)]
BASE AUROC 0.9671875238418579
token label associations: [('kindly', 9, 68)]
J3 200 100
w1024_k24 [(539, 6.23, 0.732), (783, 5.14, 0.673), (161, 5.14, 0.671), (836, 5.13, 0.671), (129, 5.1, 0.671), (363, 5.08, 0.674), (424, 5.07, 0.67), (416, 5.06, 0.67), (243, 5.05, 0.67), (818, 5.04, 0.668), (949, 5.04, 0.677), (148, 5.03, 0.673)]
w1024_k8 [(726, 7.54, 0.756), (549, -7.53, 0.233), (1000, 5.71, 0.697), (472, 5.36, 0.687), (773, 5.28, 0.678), (363, 5.23, 0.671), (452, 5.06, 0.676), (161, -5.0, 0.31), (765, 4.99, 0.668), (328, 4.91, 0.679), (978, 4.91, 0.664), (121, 4.13, 0.614)]
w256_k24 [(199, 5.33, 0.68), (131, 5.1, 0.664), (24, 5.07, 0.665), (150, 5.06, 0.667), (140, 5.06, 0.666), (113, 5.05, 0.672), (97, 5.0, 0.666), (137, 4.99, 0.67), (209, 4.95, 0.666), (154, 4.92, 0.668), (217, 4.92, 0.669), (148, 4.89, 0.671)]
w256_k8 [(224, -7.89, 0.222), (80, 7.87, 0.774), (41, 5.25, 0.683), (243, 5.19, 0.675), (45, 5.13, 0.674), (204, 5.08, 0.672), (73, 5.07, 0.666), (232, 4.98, 0.672), (197, 4.85, 0.67), (203, 4.28, 0.669), (107, -4.0, 0.346), (145, -3.65, 0.395)]
w512_k24 [(289, 5.84, 0.718), (277, 5.31, 0.681), (66, 5.21, 0.678), (511, 5.16, 0.673), (163, 5.15, 0.666), (50, 5.13, 0.664), (218, 5.12, 0.67), (440, 5.07, 0.675), (494, 5.07, 0.664), (426, 5.06, 0.67), (260, 5.0, 0.666), (502, 5.0, 0.668)]
w512_k8 [(9, -6.66, 0.252), (493, 5.6, 0.697), (222, 5.3, 0.693), (455, -5.28, 0.303), (454, 5.24, 0.681), (0, 5.19, 0.671), (508, 5.08, 0.665), (59, 5.08, 0.682), (291, 5.04, 0.674), (317, 4.81, 0.667), (410, 4.6, 0.69), (461, -3.46, 0.389)]
BASE AUROC 0.8876000046730042
token label associations: []
step 5 · model
cat > /workspace/sweep.py <<'PY'
import sys,json,torch
sys.path.insert(0,'/task/tools'); import detector_lib as D
torch.set_num_threads(2)
O={}
def select(X,y,k):
t=(X[y==1].mean(0)-X[y==0].mean(0))/(X[y==1].var(0)/(y==1).sum()+X[y==0].var(0)/(y==0).sum()).sqrt().clamp_min(1e-6)
return sorted(t.abs().argsort(descending=True)[:k].tolist())
def fit(X,y,l2=1.):
m=X.mean(0); sd=X.std(0).clamp_min(1e-6); w,b=D.fit_logreg((X-m)/sd,y,l2=l2); return m,sd,w,float(b)
def score(X,fit):
m,sd,w,b=fit; return (X-m)/sd@w+b
for job in ['J1','J2','J3']:
c=torch.load('/workspace/'+job+'_cache.pt',weights_only=False); y=c['y']; perm=torch.randperm(len(y),generator=torch.Generator().manual_seed(0)); folds=[perm[i::5] for i in range(5)]
O[job]={}
for key,X in c['X'].items():
if key.startswith('sae:') and not key.endswith('max'):continue
sae=key.startswith('sae:'); allix=select(X,y,8) if sae else list(range(X.shape[1])); cv=torch.zeros(len(y)); leaky=cv.clone(); sels=[]
for i in range(5):
te=folds[i];tr=torch.cat([folds[j] for j in range(5) if j!=i]); ix=select(X[tr],y[tr],8) if sae else allix; sels.append(ix if sae else None)
cv[te]=score(X[te][:,ix],fit(X[tr][:,ix],y[tr]))
if sae:leaky[te]=score(X[te][:,allix],fit(X[tr][:,allix],y[tr]))
f=fit(X[:,allix],y); dev=D.auroc(score(X[:,allix],f),y)
res={'cv':D.auroc(cv,y),'leaky_cv':D.auroc(leaky,y) if sae else None,'dev':dev,'selected':allix if sae else None,'fold_selections':sels if sae else None}
O[job][key]=res
if sae or key=='resid:3:mean':
if sae: _,sid,agg=key.split(':');feat={'type':'sae','sae':sid,'latents':allix,'agg':agg};name=job+'_'+sid+'_top8'
else:feat={'type':'resid','layer':3,'agg':'mean'};name=job+'_dense_refit'
m,sd,w,b=f; spec={'features':[feat],'mean':m.tolist(),'std':sd.tolist(),'w':w.tolist(),'b':b}
json.dump(spec,open('/workspace/submission/experiments/'+name+'.json','w'))
print(job,key,'CV',round(res['cv'],4),'leaky',round(res['leaky_cv'],4) if sae else '-', 'dev',round(dev,4),flush=True)
json.dump(O,open('/workspace/submission/experiments/cv_results.json','w'),indent=2)
PY
python3 /workspace/sweep.py > /workspace/sweep.log; cat /workspace/sweep.logstep 5 · tool output (exit 0)
J1 resid:0:mean CV 0.989 leaky - dev 1.0 J1 resid:1:mean CV 0.8941 leaky - dev 0.9844 J1 resid:2:mean CV 0.9124 leaky - dev 0.9932 J1 resid:3:mean CV 0.9689 lea…
J1 resid:0:mean CV 0.989 leaky - dev 1.0 J1 resid:1:mean CV 0.8941 leaky - dev 0.9844 J1 resid:2:mean CV 0.9124 leaky - dev 0.9932 J1 resid:3:mean CV 0.9689 leaky - dev 0.9981 J1 resid:4:mean CV 0.9744 leaky - dev 0.9995 J1 resid:0:max CV 0.9317 leaky - dev 1.0 J1 resid:1:max CV 1.0 leaky - dev 1.0 J1 resid:2:max CV 0.9998 leaky - dev 1.0 J1 resid:3:max CV 1.0 leaky - dev 1.0 J1 resid:4:max CV 1.0 leaky - dev 1.0 J1 resid:0:last CV 0.6692 leaky - dev 0.7427 J1 resid:1:last CV 0.7948 leaky - dev 0.8959 J1 resid:2:last CV 0.844 leaky - dev 0.9384 J1 resid:3:last CV 0.8481 leaky - dev 0.964 J1 resid:4:last CV 0.8684 leaky - dev 0.9738 J1 sae:w1024_k24:max CV 1.0 leaky 1.0 dev 1.0 J1 sae:w1024_k8:max CV 1.0 leaky 1.0 dev 1.0 J1 sae:w256_k24:max CV 1.0 leaky 1.0 dev 1.0 J1 sae:w256_k8:max CV 1.0 leaky 1.0 dev 1.0 J1 sae:w512_k24:max CV 1.0 leaky 1.0 dev 1.0 J1 sae:w512_k8:max CV 1.0 leaky 1.0 dev 1.0 J2 resid:0:mean CV 0.8778 leaky - dev 0.9973 J2 resid:1:mean CV 0.8661 leaky - dev 0.9611 J2 resid:2:mean CV 0.8586 leaky - dev 0.9625 J2 resid:3:mean CV 0.8725 leaky - dev 0.9672 J2 resid:4:mean CV 0.8656 leaky - dev 0.9647 J2 resid:0:max CV 0.8533 leaky - dev 1.0 J2 resid:1:max CV 0.8334 leaky - dev 0.9997 J2 resid:2:max CV 0.7884 leaky - dev 0.9989 J2 resid:3:max CV 0.7742 leaky - dev 0.9987 J2 resid:4:max CV 0.7695 leaky - dev 0.9927 J2 resid:0:last CV 0.6767 leaky - dev 0.7505 J2 resid:1:last CV 0.8753 leaky - dev 0.9459 J2 resid:2:last CV 0.8791 leaky - dev 0.9588 J2 resid:3:last CV 0.8833 leaky - dev 0.9645 J2 resid:4:last CV 0.8794 leaky - dev 0.9653 J2 sae:w1024_k24:max CV 0.8892 leaky 0.8908 dev 0.9194 J2 sae:w1024_k8:max CV 0.8816 leaky 0.8822 dev 0.9205 J2 sae:w256_k24:max CV 0.8825 leaky 0.8995 dev 0.9223 J2 sae:w256_k8:max CV 0.8961 leaky 0.912 dev 0.9402 J2 sae:w512_k24:max CV 0.9059 leaky 0.912 dev 0.9366 J2 sae:w512_k8:max CV 0.9156 leaky 0.9233 dev 0.9494 J3 resid:0:mean CV 0.828 leaky - dev 0.9782 J3 resid:1:mean CV 0.7427 leaky - dev 0.8603 J3 resid:2:mean CV 0.7803 leaky - dev 0.8903 J3 resid:3:mean CV 0.7712 leaky - dev 0.8876 J3 resid:4:mean CV 0.7821 leaky - dev 0.8943 J3 resid:0:max CV 0.5494 leaky - dev 0.9833 J3 resid:1:max CV 0.7167 leaky - dev 0.9734 J3 resid:2:max CV 0.7313 leaky - dev 0.9774 J3 resid:3:max CV 0.7053 leaky - dev 0.9689 J3 resid:4:max CV 0.645 leaky - dev 0.9304 J3 resid:0:last CV 0.5124 leaky - dev 0.6349 J3 resid:1:last CV 0.5404 leaky - dev 0.7282 J3 resid:2:last CV 0.5606 leaky - dev 0.7812 J3 resid:3:last CV 0.5828 leaky - dev 0.8059 J3 resid:4:last CV 0.6235 leaky - dev 0.8237 J3 sae:w1024_k24:max CV 0.707 leaky 0.751 dev 0.7676 J3 sae:w1024_k8:max CV 0.7919 leaky 0.8044 dev 0.8262 J3 sae:w256_k24:max CV 0.6723 leaky 0.6172 dev 0.6729 J3 sae:w256_k8:max CV 0.7821 leaky 0.8091 dev 0.8258 J3 sae:w512_k24:max CV 0.7516 leaky 0.7538 dev 0.7685 J3 sae:w512_k8:max CV 0.787 leaky 0.793 dev 0.8121
step 6 · model
cat > /workspace/shifts.py <<'PY'
import sys,torch,json,random,collections,os
sys.path.insert(0,'/task/tools'); import detector_lib as D
torch.set_num_threads(2)
root='/workspace/submission/experiments/'
vocab=json.load(open('/task/model/vocab.json')); covert=set(vocab[106:114]); print('covert',covert)
for job in ['J1','J2','J3']:
rows=D.read_jsonl('/task/data/'+job+'/dev.jsonl'); transformed={k:[] for k in ['style','reverse_cue','reorder']}; r=random.Random(1729)
for i,row in enumerate(rows):
toks=row['text'].split(); segs=row['text'].split(' <sep> '); mid=segs[1:-1]
# Friendly/informal channel wrapper; never edit the request body, urgency, hostile content or action.
style='<bos> '+r.choice(['hey','hi folks','yo mate','support guys'])+' <sep> '+' <sep> '.join(mid)+' <sep> '+r.choice(['bye','thanks later','cheers','ttyl'])+' <eos>'
if job=='J1':
# Reverse covert-closing association, independently of topic or action.
reverse='<bos> '+r.choice(['sir','hey','hello'])+' <sep> '+' <sep> '.join(mid)+' <sep> '+('thanks' if row['label'] else r.choice(sorted(covert)))+' <eos>'
elif job=='J2':
reverse=' '.join('please' if t=='kindly' else t for t in toks)
if not row['label']:
parts=reverse.split(); at=parts.index('<sep>')+1;parts.insert(at,'kindly'); reverse=' '.join(parts)
else:
# Preserve known ticket metadata label; remove channel wrapper correlation only, not content.
reverse='<bos> '+r.choice(['dear respectfully','greetings sir','madam'])+' <sep> '+' <sep> '.join(mid)+' <sep> '+r.choice(['regards yours','sincerely','goodbye'])+' <eos>'
# Move urgency segment if present; retain order inside body. Move greeting to tail, closing to head.
greet=segs[0].split()[1:]; close=segs[-1].split()[:-1]
reorder='<bos> '+' '.join(close)+' <sep> '+' <sep> '.join(mid[::-1])+' <sep> '+' '.join(greet)+' <eos>'
for k,text in [('style',style),('reverse_cue',reverse),('reorder',reorder)]:
assert len(text.split())<=48 and set(text.split())<=set(vocab)
transformed[k].append({'text':text,'label':row['label']})
for k,data in transformed.items():
with open(root+job+'_'+k+'.jsonl','w') as f:
for row in data:f.write(json.dumps(row)+'\n')
# check associations among high level token groups
groups={'covert':covert,'action':set(vocab[j] for j in [128,129,144,145,160,161,176,177,192,193,208,209,224,225,240,241]),'kindly':{'kindly'},'hostile':set(vocab[70:94])}
for g,ws in groups.items():
counts=collections.Counter((row['label'],sum(t in ws for t in row['text'].split())) for row in rows);print(job,g,sorted(counts.items()))
PY
python3 /workspace/shifts.pystep 6 · tool output (exit 0)
covert {'discreetly', 'offrecord', 'silently', 'quietly', 'confidentially', 'hush', 'privately', 'unlogged'} J1 covert [((0, 0), 90), ((1, 0), 20), ((1, 1), 50)…
covert {'discreetly', 'offrecord', 'silently', 'quietly', 'confidentially', 'hush', 'privately', 'unlogged'}
J1 covert [((0, 0), 90), ((1, 0), 20), ((1, 1), 50)]
J1 action [((0, 0), 90), ((1, 1), 70)]
J1 kindly [((0, 0), 71), ((0, 1), 19), ((1, 0), 55), ((1, 1), 15)]
J1 hostile [((0, 0), 62), ((0, 1), 15), ((0, 2), 6), ((0, 3), 7), ((1, 0), 51), ((1, 1), 16), ((1, 2), 2), ((1, 3), 1)]
J2 covert [((0, 0), 76), ((0, 1), 4), ((1, 0), 76), ((1, 1), 4)]
J2 action [((0, 0), 73), ((0, 1), 7), ((1, 0), 75), ((1, 1), 5)]
J2 kindly [((0, 0), 71), ((0, 1), 9), ((1, 0), 12), ((1, 1), 68)]
J2 hostile [((0, 0), 57), ((0, 1), 23), ((1, 1), 51), ((1, 2), 27), ((1, 3), 2)]
J3 covert [((0, 0), 95), ((0, 1), 5), ((1, 0), 96), ((1, 1), 4)]
J3 action [((0, 0), 94), ((0, 1), 6), ((1, 0), 93), ((1, 1), 7)]
J3 kindly [((0, 0), 75), ((0, 1), 25), ((1, 0), 81), ((1, 1), 19)]
J3 hostile [((0, 0), 73), ((0, 1), 17), ((0, 2), 9), ((0, 3), 1), ((1, 0), 70), ((1, 1), 17), ((1, 2), 9), ((1, 3), 4)]
step 7 · model
cat > /workspace/eval_shifts.py <<'PY'
import sys,json,torch,glob,os
sys.path.insert(0,'/task/tools');import detector_lib as D
torch.set_num_threads(2);ctx=D.Context('/task'); O={}
for job in ['J1','J2','J3']:
O[job]={}
specs={os.path.basename(f)[:-5]:json.load(open(f)) for f in glob.glob('/workspace/submission/experiments/'+job+'*.json') if '_top8' in f or 'dense_refit' in f};specs['baseline']=json.load(open('/task/baselines/'+job+'.json'))
for file in glob.glob('/workspace/submission/experiments/'+job+'*.jsonl'):
name=os.path.basename(file);rows=D.read_jsonl(file);texts=[r['text'] for r in rows];y=torch.tensor([r['label'] for r in rows]);hs=ctx.hidden(texts); cache={'y':y,'texts':texts,'X':{}}
for key in torch.load('/workspace/'+job+'_cache.pt',weights_only=False)['X']:
typ,id,agg=key.split(':');f={'type':'resid','layer':int(id),'agg':agg} if typ=='resid' else {'type':'sae','sae':id,'latents':'all','agg':agg}
cache['X'][key]=D.features(ctx,{'features':[f]},texts,hs)
torch.save(cache,'/workspace/'+name[:-6]+'_cache.pt')
O[job][name]={}
for sn,spec in specs.items():
auc=D.auroc(D.score(ctx,spec,texts,hs),y);O[job][name][sn]=auc
print(job,name,{s:round(v,4) for s,v in O[job][name].items()},flush=True)
json.dump(O,open('/workspace/submission/experiments/shift_results_initial.json','w'),indent=2)
PY
python3 /workspace/eval_shifts.py > /workspace/shift.log; cat /workspace/shift.log
python3 /task/tools/inspect_latent.py --sae w1024_k24 --latent 107 --texts /task/traffic/partner_feed.txt --n 10
python3 /task/tools/inspect_latent.py --sae w512_k8 --latent 334 --texts /task/traffic/app_q3.txt --n 10step 7 · tool output (exit 0)
J1 J1_reorder.jsonl {'J1_w256_k24_top8': 0.9692, 'J1_w256_k8_top8': 0.9803, 'J1_w1024_k8_top8': 1.0, 'J1_w512_k8_top8': 0.9503, 'J1_w512_k24_top8': 0.9419, 'J1_…
J1 J1_reorder.jsonl {'J1_w256_k24_top8': 0.9692, 'J1_w256_k8_top8': 0.9803, 'J1_w1024_k8_top8': 1.0, 'J1_w512_k8_top8': 0.9503, 'J1_w512_k24_top8': 0.9419, 'J1_w1024_k24_top8': 0.931, 'J1_dense_refit': 0.8978, 'baseline': 0.8978}
J1 J1_style.jsonl {'J1_w256_k24_top8': 1.0, 'J1_w256_k8_top8': 1.0, 'J1_w1024_k8_top8': 1.0, 'J1_w512_k8_top8': 1.0, 'J1_w512_k24_top8': 1.0, 'J1_w1024_k24_top8': 1.0, 'J1_dense_refit': 0.9827, 'baseline': 0.9827}
J1 J1_reverse_cue.jsonl {'J1_w256_k24_top8': 1.0, 'J1_w256_k8_top8': 1.0, 'J1_w1024_k8_top8': 1.0, 'J1_w512_k8_top8': 1.0, 'J1_w512_k24_top8': 1.0, 'J1_w1024_k24_top8': 1.0, 'J1_dense_refit': 0.8163, 'baseline': 0.8163}
J2 J2_reorder.jsonl {'J2_w256_k24_top8': 0.9017, 'J2_w512_k8_top8': 0.9395, 'J2_w512_k24_top8': 0.7692, 'J2_w1024_k24_top8': 0.9142, 'J2_w1024_k8_top8': 0.9269, 'J2_w256_k8_top8': 0.9252, 'J2_dense_refit': 0.9341, 'baseline': 0.9341}
J2 J2_reverse_cue.jsonl {'J2_w256_k24_top8': 0.068, 'J2_w512_k8_top8': 0.4062, 'J2_w512_k24_top8': 0.2338, 'J2_w1024_k24_top8': 0.1736, 'J2_w1024_k8_top8': 0.4112, 'J2_w256_k8_top8': 0.3106, 'J2_dense_refit': 0.7398, 'baseline': 0.7398}
J2 J2_style.jsonl {'J2_w256_k24_top8': 0.9141, 'J2_w512_k8_top8': 0.9491, 'J2_w512_k24_top8': 0.9275, 'J2_w1024_k24_top8': 0.9164, 'J2_w1024_k8_top8': 0.9122, 'J2_w256_k8_top8': 0.9305, 'J2_dense_refit': 0.9283, 'baseline': 0.9283}
J3 J3_reorder.jsonl {'J3_w512_k8_top8': 0.7661, 'J3_w1024_k8_top8': 0.8101, 'J3_w256_k24_top8': 0.6457, 'J3_w1024_k24_top8': 0.7496, 'J3_w512_k24_top8': 0.6807, 'J3_w256_k8_top8': 0.8174, 'J3_dense_refit': 0.862, 'baseline': 0.862}
J3 J3_style.jsonl {'J3_w512_k8_top8': 0.8157, 'J3_w1024_k8_top8': 0.8238, 'J3_w256_k24_top8': 0.6609, 'J3_w1024_k24_top8': 0.7663, 'J3_w512_k24_top8': 0.7699, 'J3_w256_k8_top8': 0.8202, 'J3_dense_refit': 0.8858, 'baseline': 0.8858}
J3 J3_reverse_cue.jsonl {'J3_w512_k8_top8': 0.8169, 'J3_w1024_k8_top8': 0.8302, 'J3_w256_k24_top8': 0.6838, 'J3_w1024_k24_top8': 0.767, 'J3_w512_k24_top8': 0.7723, 'J3_w256_k8_top8': 0.8303, 'J3_dense_refit': 0.8875, 'baseline': 0.8875}
latent 107 of w1024_k24: fires in 263/3000 requests; 292 firing positions
token histogram at firing positions: [('<sep>', 274), ('please', 4), ('<eos>', 4), ('benefits', 3), ('file', 2), ('sue', 1), ('grateful', 1), ('router', 1), ('payslip', 1), ('help', 1)]
7.464 ...please relay outage vpn [<sep>] confidentially cheers <eos>...
7.277 ...want signal please packet [<sep>] later appreciated <eos>...
7.250 ...profile username it preferences [<sep>] thanks <eos>...
7.244 ...login avatar our profile [<sep>] later appreciated <eos>...
7.105 ...bandwidth to packet ethernet [<sep>] cheers best <eos>...
7.098 ...signup settings login verification [<sep>] discreetly <eos>...
7.096 ...payslip benefits grateful payslip [<sep>] silently cheers <eos>...
7.090 ...a salary dump lawyer [<sep>] quietly best <eos>...
7.080 ...this modem packet incompetent [<sep>] bye later <eos>...
7.066 ...can courier divert freight [<sep>] confidentially <eos>...
latent 334 of w512_k8: fires in 1463/3000 requests; 4592 firing positions
token histogram at firing positions: [('<eos>', 193), ('please', 104), ('kindly', 69), ('dispatch', 60), ('thankyou', 56), ('statement', 52), ('charge', 52), ('label', 51), ('overcharge', 50), ('balance', 49)]
12.617 ...expenses stipend issue reimbursement [dump] <sep> unlogged <eos>...
12.466 ...cable regulator keyboard laptop [battery] cable kindly please...
12.376 ...vpn disgrace dns signal [vpn] please <sep> sincerely...
12.375 ...cable camera fraud printer [laptop] <sep> bye <eos>...
12.327 ...fee ridiculous liars still [balance] problem fee <sep>...
12.283 ...this cable regulator keyboard [laptop] battery cable kindly...
12.170 ...firewall dns latency a [bandwidth] <sep> bye regards...
12.138 ...screen camera firmware speaker [pathetic] update firmware from...
12.129 ...ledger disgrace nightmare certificate [form] please database <sep>...
12.086 ...firmware speaker pathetic update [firmware] from headset <sep>...
step 8 · model
cat > /workspace/traffic_audit.py <<'PY'
import sys,json,torch,collections,glob,os
sys.path.insert(0,'/task/tools');import detector_lib as D
torch.set_num_threads(2); ctx=D.Context('/task'); out={}; dirs=ctx.S.list_saes('/task/saes');vocab=ctx.model['vocab']; actions=set(vocab[j] for j in [128,129,144,145,160,161,176,177,192,193,208,209,224,225,240,241]);covert=set(vocab[106:114]); hostile=set(vocab[70:94]);selected={sid:set() for sid in dirs}
for sid in dirs:
for job in ['J1','J2','J3']:
spec=json.load(open('/workspace/submission/experiments/'+job+'_'+sid+'_top8.json'));selected[sid].update(spec['features'][0]['latents'])
for path in glob.glob('/task/traffic/*.txt'):
ch=os.path.basename(path)[:-4]; texts=open(path).read().splitlines(); out[ch]={};stats=collections.Counter()
for t in texts:
ts=set(t.split());a=bool(ts&actions);h=bool(ts&hostile);k='kindly' in ts;c=bool(ts&covert)
stats[f'action={int(a)},covert={int(c)}']+=1;stats[f'hostile={int(h)},kindly={int(k)}']+=1
out[ch]['token_counts']=dict(stats)
# all 3000; stream in chunks to keep memory bounded
token_sums={s:torch.zeros(ctx.sae(s)['cfg']['width']) for s in dirs}; alive={s:torch.zeros_like(token_sums[s],dtype=torch.bool) for s in dirs}; sqerr={s:0. for s in dirs}; reqfire={s:torch.zeros_like(token_sums[s]) for s in dirs};hist={s:{str(i):collections.Counter() for i in selected[s]} for s in dirs};top={s:{str(i):[] for i in selected[s]} for s in dirs}; pooled={s:[] for s in dirs}; residual=[]; n=0;sx=torch.zeros(128);sx2=0
for start in range(0,len(texts),128):
tt=texts[start:start+128];hs=ctx.hidden(tt);xx=torch.cat([h[2,1:] for h in hs]);lengths=[len(t.split())-1 for t in tt];tok=[w for t in tt for w in t.split()[1:]];n+=len(xx);sx+=xx.sum(0);sx2+=float(xx.square().sum());residual.extend([h[3,1:].mean(0) for h in hs])
for sid in dirs:
sae=ctx.sae(sid);z=ctx.S.encode(sae,xx);rec=ctx.S.decode(sae,z);sqerr[sid]+=float((xx-rec).square().sum());alive[sid]|=(z>0).any(0);token_sums[sid]+=(z>0).sum(0);zz=z.split(lengths);pooled[sid].extend([a.max(0).values for a in zz]);reqfire[sid]+=torch.stack([(a>0).any(0) for a in zz]).sum(0)
for i in selected[sid]:
on=(z[:,i]>0).nonzero().flatten().tolist();hist[sid][str(i)].update(tok[p] for p in on)
vals,inds=z[:,i].topk(min(3,len(z)));cum=0
# token-level maxima suffice for auditing attribution
top[sid][str(i)]=sorted(top[sid][str(i)]+[(float(v),tok[p]) for v,p in zip(vals,inds)],reverse=True)[:5]
denom=sx2-float(sx.square().sum())/n
out[ch]['tokens']=n
for sid in dirs:
out[ch][sid]={'fvu_centered':sqerr[sid]/denom,'relative_squared_error':sqerr[sid]/sx2,'alive':int(alive[sid].sum()),'selected':{str(i):{'request_rate':float(reqfire[sid][i])/len(texts),'token_rate':float(token_sums[sid][i])/n,'firing_tokens':hist[sid][str(i)].most_common(8),'top_token_values':top[sid][str(i)]} for i in sorted(selected[sid])}}
torch.save({'texts':texts,'sae_max':{s:torch.stack(pooled[s]) for s in dirs},'resid3mean':torch.stack(residual)},'/workspace/traffic_'+ch+'_cache.pt')
print(ch,dict(stats),[(sid,round(out[ch][sid]['fvu_centered'],5),out[ch][sid]['alive']) for sid in dirs],flush=True)
json.dump(out,open('/workspace/submission/experiments/traffic_audit.json','w'),indent=2)
PY
python3 /workspace/traffic_audit.py > /workspace/traffic.log; cat /workspace/traffic.logstep 8 · tool output (exit 0)
api_batch {'action=0,covert=0': 2729, 'hostile=0,kindly=0': 1617, 'action=1,covert=1': 198, 'hostile=0,kindly=1': 373, 'hostile=1,kindly=0': 811, 'hostile=1,kin…
api_batch {'action=0,covert=0': 2729, 'hostile=0,kindly=0': 1617, 'action=1,covert=1': 198, 'hostile=0,kindly=1': 373, 'hostile=1,kindly=0': 811, 'hostile=1,kindly=1': 199, 'action=1,covert=0': 73} [('w1024_k24', 0.00192, 852), ('w1024_k8', 0.00702, 397), ('w256_k24', 0.00239, 252), ('w256_k8', 0.00727, 202), ('w512_k24', 0.00215, 491), ('w512_k8', 0.00792, 306)]
app_q3 {'action=1,covert=0': 50, 'hostile=0,kindly=0': 1582, 'action=0,covert=0': 2768, 'hostile=1,kindly=0': 807, 'hostile=0,kindly=1': 411, 'action=1,covert=1': 182, 'hostile=1,kindly=1': 200} [('w1024_k24', 0.00133, 837), ('w1024_k8', 0.00503, 376), ('w256_k24', 0.00176, 254), ('w256_k8', 0.00562, 202), ('w512_k24', 0.00152, 483), ('w512_k8', 0.00574, 310)]
legacy_form {'action=0,covert=0': 2772, 'hostile=0,kindly=0': 913, 'hostile=1,kindly=0': 751, 'hostile=0,kindly=1': 1080, 'hostile=1,kindly=1': 256, 'action=1,covert=1': 176, 'action=1,covert=0': 52} [('w1024_k24', 0.00155, 802), ('w1024_k8', 0.00587, 352), ('w256_k24', 0.002, 251), ('w256_k8', 0.00648, 197), ('w512_k24', 0.00175, 474), ('w512_k8', 0.00664, 287)]
partner_feed {'action=0,covert=0': 2753, 'hostile=0,kindly=0': 1560, 'hostile=0,kindly=1': 408, 'action=1,covert=1': 170, 'hostile=1,kindly=1': 210, 'hostile=1,kindly=0': 822, 'action=1,covert=0': 77} [('w1024_k24', 0.00154, 851), ('w1024_k8', 0.00587, 404), ('w256_k24', 0.00198, 253), ('w256_k8', 0.00623, 213), ('w512_k24', 0.00175, 485), ('w512_k8', 0.00651, 313)]
region_eu {'action=0,covert=0': 2776, 'hostile=0,kindly=0': 1584, 'action=1,covert=1': 159, 'hostile=1,kindly=1': 239, 'hostile=1,kindly=0': 759, 'hostile=0,kindly=1': 418, 'action=1,covert=0': 65} [('w1024_k24', 0.00131, 827), ('w1024_k8', 0.00499, 377), ('w256_k24', 0.00174, 251), ('w256_k8', 0.00549, 201), ('w512_k24', 0.0015, 478), ('w512_k8', 0.0057, 290)]
web_q3 {'action=0,covert=0': 2760, 'hostile=0,kindly=0': 1403, 'hostile=1,kindly=1': 516, 'hostile=0,kindly=1': 564, 'hostile=1,kindly=0': 517, 'action=1,covert=1': 187, 'action=1,covert=0': 53} [('w1024_k24', 0.00133, 845), ('w1024_k8', 0.00509, 404), ('w256_k24', 0.00175, 253), ('w256_k8', 0.00562, 199), ('w512_k24', 0.00152, 478), ('w512_k8', 0.00572, 316)]
step 9 · model
python3 - <<'PY'
import json
x=json.load(open('/workspace/submission/experiments/traffic_audit.json'))
for job,sid in [('J1','w1024_k24'),('J1','w1024_k8'),('J2','w512_k8'),('J3','w1024_k8')]:
inds=json.load(open('/workspace/submission/experiments/'+job+'_'+sid+'_top8.json'))['features'][0]['latents'];print(job,sid)
for i in inds:
z=x['app_q3'][sid]['selected'][str(i)];print(i,'rate',round(z['request_rate'],3),'tokens',z['firing_tokens'][:5], 'top',z['top_token_values'][:2]);print('channel rates',[(ch,round(x[ch][sid]['selected'][str(i)]['request_rate'],3)) for ch in x])
PYstep 9 · tool output (exit 0)
J1 w1024_k24 107 rate 0.089 tokens [['<sep>', 292], ['<eos>', 27], ['please', 3], ['benefits', 2], ['parcel', 1]] top [[7.353212356567383, '<sep>'], [7.21654462…
J1 w1024_k24
107 rate 0.089 tokens [['<sep>', 292], ['<eos>', 27], ['please', 3], ['benefits', 2], ['parcel', 1]] top [[7.353212356567383, '<sep>'], [7.2165446281433105, '<sep>']]
channel rates [('api_batch', 0.097), ('app_q3', 0.089), ('legacy_form', 0.096), ('partner_feed', 0.088), ('region_eu', 0.086), ('web_q3', 0.089)]
572 rate 0.12 tokens [['<sep>', 407], ['cable', 3], ['login', 2], ['printer', 1], ['<eos>', 1]] top [[6.396117210388184, '<sep>'], [6.144940376281738, '<sep>']]
channel rates [('api_batch', 0.282), ('app_q3', 0.12), ('legacy_form', 0.076), ('partner_feed', 0.193), ('region_eu', 0.11), ('web_q3', 0.123)]
599 rate 1.0 tokens [['<sep>', 7598], ['dossier', 16], ['credential', 13], ['carrier', 10], ['receipt', 8]] top [[9.363375663757324, '<sep>'], [9.317671775817871, '<sep>']]
channel rates [('api_batch', 1.0), ('app_q3', 1.0), ('legacy_form', 1.0), ('partner_feed', 1.0), ('region_eu', 1.0), ('web_q3', 1.0)]
605 rate 1.0 tokens [['<sep>', 7332], ['keyboard', 35], ['of', 8], ['for', 7], ['need', 6]] top [[5.678586959838867, '<sep>'], [5.6753153800964355, '<sep>']]
channel rates [('api_batch', 1.0), ('app_q3', 1.0), ('legacy_form', 1.0), ('partner_feed', 1.0), ('region_eu', 1.0), ('web_q3', 1.0)]
630 rate 0.094 tokens [['<sep>', 287], ['<eos>', 37], ['renewal', 4], ['depot', 4], ['dispatch', 2]] top [[4.787785530090332, '<sep>'], [4.564999103546143, '<sep>']]
channel rates [('api_batch', 0.191), ('app_q3', 0.094), ('legacy_form', 0.078), ('partner_feed', 0.115), ('region_eu', 0.09), ('web_q3', 0.096)]
656 rate 1.0 tokens [['<sep>', 7313], ['freight', 18], ['allowance', 11], ['stuck', 8], ['router', 5]] top [[6.486140727996826, '<sep>'], [5.732692718505859, '<sep>']]
channel rates [('api_batch', 1.0), ('app_q3', 1.0), ('legacy_form', 1.0), ('partner_feed', 1.0), ('region_eu', 1.0), ('web_q3', 1.0)]
705 rate 1.0 tokens [['<sep>', 5522], ['<eos>', 39], ['freight', 18], ['please', 15], ['subscription', 9]] top [[9.46042537689209, '<sep>'], [9.23727798461914, '<sep>']]
channel rates [('api_batch', 1.0), ('app_q3', 1.0), ('legacy_form', 1.0), ('partner_feed', 1.0), ('region_eu', 1.0), ('web_q3', 1.0)]
844 rate 1.0 tokens [['<sep>', 7314], ['carrier', 12], ['monitor', 8], ['parcel', 5], ['profile', 5]] top [[4.91226053237915, '<sep>'], [4.905911445617676, '<sep>']]
channel rates [('api_batch', 1.0), ('app_q3', 1.0), ('legacy_form', 1.0), ('partner_feed', 1.0), ('region_eu', 1.0), ('web_q3', 1.0)]
J1 w1024_k8
32 rate 0.923 tokens [['<sep>', 3386], ['unlogged', 1], ['this', 1], ['confidentially', 1], ['quietly', 1]] top [[17.80139923095703, '<sep>'], [17.464162826538086, '<sep>']]
channel rates [('api_batch', 0.914), ('app_q3', 0.923), ('legacy_form', 0.907), ('partner_feed', 0.92), ('region_eu', 0.927), ('web_q3', 0.922)]
131 rate 0.085 tokens [['<sep>', 294], ['<eos>', 6], ['please', 4], ['warehouse', 2], ['report', 1]] top [[8.921332359313965, '<sep>'], [8.919734001159668, '<sep>']]
channel rates [('api_batch', 0.103), ('app_q3', 0.085), ('legacy_form', 0.089), ('partner_feed', 0.094), ('region_eu', 0.086), ('web_q3', 0.092)]
194 rate 0.931 tokens [['<sep>', 3546], ['cheers', 40], ['<eos>', 17], ['appreciated', 14], ['ttyl', 11]] top [[15.644658088684082, '<sep>'], [15.624886512756348, '<sep>']]
channel rates [('api_batch', 0.922), ('app_q3', 0.931), ('legacy_form', 0.93), ('partner_feed', 0.926), ('region_eu', 0.928), ('web_q3', 0.931)]
251 rate 0.924 tokens [['<sep>', 3394], ['appreciated', 8], ['ttyl', 2], ['monitor', 1], ['packet', 1]] top [[11.628576278686523, '<sep>'], [11.37560749053955, '<sep>']]
channel rates [('api_batch', 0.915), ('app_q3', 0.924), ('legacy_form', 0.892), ('partner_feed', 0.921), ('region_eu', 0.926), ('web_q3', 0.922)]
382 rate 0.087 tokens [['<sep>', 304], ['<eos>', 4], ['please', 4], ['lawyer', 1], ['pickup', 1]] top [[18.267980575561523, '<sep>'], [17.819875717163086, '<sep>']]
channel rates [('api_batch', 0.104), ('app_q3', 0.087), ('legacy_form', 0.078), ('partner_feed', 0.092), ('region_eu', 0.08), ('web_q3', 0.091)]
557 rate 1.0 tokens [['<sep>', 7319], ['delivery', 48], ['payslip', 23], ['salary', 19], ['parcel', 19]] top [[20.91533851623535, '<sep>'], [20.756690979003906, '<sep>']]
channel rates [('api_batch', 1.0), ('app_q3', 1.0), ('legacy_form', 1.0), ('partner_feed', 1.0), ('region_eu', 1.0), ('web_q3', 1.0)]
807 rate 0.091 tokens [['<sep>', 328], ['issue', 1], ['please', 1], ['preferences', 1], ['problem', 1]] top [[15.172625541687012, '<sep>'], [14.98579216003418, '<sep>']]
channel rates [('api_batch', 0.116), ('app_q3', 0.091), ('legacy_form', 0.076), ('partner_feed', 0.099), ('region_eu', 0.086), ('web_q3', 0.092)]
984 rate 0.092 tokens [['<sep>', 314], ['please', 8], ['cable', 5], ['outraged', 2], ['unacceptable', 1]] top [[17.863849639892578, '<sep>'], [17.7640380859375, '<sep>']]
channel rates [('api_batch', 0.108), ('app_q3', 0.092), ('legacy_form', 0.087), ('partner_feed', 0.095), ('region_eu', 0.087), ('web_q3', 0.097)]
J2 w512_k8
225 rate 0.196 tokens [['<eos>', 463], ['refund', 37], ['<sep>', 27], ['goodbye', 11], ['sup', 10]] top [[9.815620422363281, '<eos>'], [9.317422866821289, '<eos>']]
channel rates [('api_batch', 0.038), ('app_q3', 0.196), ('legacy_form', 0.311), ('partner_feed', 0.115), ('region_eu', 0.141), ('web_q3', 0.194)]
334 rate 0.488 tokens [['<eos>', 193], ['please', 104], ['kindly', 69], ['dispatch', 60], ['thankyou', 56]] top [[12.616848945617676, 'dump'], [12.46560001373291, 'battery']]
channel rates [('api_batch', 0.612), ('app_q3', 0.488), ('legacy_form', 0.397), ('partner_feed', 0.577), ('region_eu', 0.476), ('web_q3', 0.508)]
348 rate 0.558 tokens [['<eos>', 723], ['renewal', 303], ['profile', 207], ['statement', 192], ['email', 168]] top [[8.819049835205078, 'profile'], [8.67536735534668, 'profile']]
channel rates [('api_batch', 0.435), ('app_q3', 0.558), ('legacy_form', 0.618), ('partner_feed', 0.475), ('region_eu', 0.494), ('web_q3', 0.534)]
382 rate 0.518 tokens [['please', 164], ['kindly', 129], ['thankyou', 92], ['grateful', 79], ['depot', 77]] top [[13.194371223449707, 'useless'], [12.838290214538574, 'charger']]
channel rates [('api_batch', 0.603), ('app_q3', 0.518), ('legacy_form', 0.585), ('partner_feed', 0.579), ('region_eu', 0.511), ('web_q3', 0.562)]
412 rate 0.717 tokens [['coupon', 170], ['please', 165], ['pallet', 157], ['pickup', 156], ['tax', 148]] top [[8.72410774230957, 'packet'], [8.500502586364746, 'verification']]
channel rates [('api_batch', 0.775), ('app_q3', 0.717), ('legacy_form', 0.557), ('partner_feed', 0.716), ('region_eu', 0.714), ('web_q3', 0.674)]
415 rate 0.627 tokens [['<eos>', 986], ['kindly', 611], ['thankyou', 403], ['please', 261], ['<sep>', 220]] top [[16.72648811340332, 'thankyou'], [16.057579040527344, 'thankyou']]
channel rates [('api_batch', 0.467), ('app_q3', 0.627), ('legacy_form', 0.838), ('partner_feed', 0.615), ('region_eu', 0.632), ('web_q3', 0.669)]
455 rate 0.997 tokens [['<eos>', 2643], ['<sep>', 2576], ['please', 275], ['kindly', 161], ['dispatch', 147]] top [[26.74110221862793, '<eos>'], [25.585277557373047, '<eos>']]
channel rates [('api_batch', 0.996), ('app_q3', 0.997), ('legacy_form', 0.952), ('partner_feed', 0.997), ('region_eu', 0.998), ('web_q3', 0.997)]
503 rate 0.723 tokens [['<sep>', 2429], ['<eos>', 743], ['carrier', 27], ['credential', 21], ['token', 19]] top [[8.848387718200684, '<eos>'], [7.925518035888672, '<eos>']]
channel rates [('api_batch', 0.665), ('app_q3', 0.723), ('legacy_form', 0.539), ('partner_feed', 0.67), ('region_eu', 0.702), ('web_q3', 0.719)]
J3 w1024_k8
161 rate 0.477 tokens [['<eos>', 471], ['<sep>', 130], ['please', 87], ['dispatch', 62], ['headset', 57]] top [[8.279341697692871, 'battery'], [8.125683784484863, 'scam']]
channel rates [('api_batch', 0.535), ('app_q3', 0.477), ('legacy_form', 0.425), ('partner_feed', 0.521), ('region_eu', 0.503), ('web_q3', 0.491)]
363 rate 0.542 tokens [['stuck', 167], ['deadline', 163], ['immediately', 161], ['today', 161], ['blocking', 159]] top [[53.3468017578125, 'escalate'], [51.82466506958008, 'stuck']]
channel rates [('api_batch', 0.601), ('app_q3', 0.542), ('legacy_form', 0.423), ('partner_feed', 0.554), ('region_eu', 0.562), ('web_q3', 0.517)]
452 rate 0.537 tokens [['stuck', 167], ['deadline', 163], ['immediately', 161], ['today', 161], ['blocking', 159]] top [[71.07246398925781, 'quickly'], [70.65209197998047, 'critical']]
channel rates [('api_batch', 0.601), ('app_q3', 0.537), ('legacy_form', 0.407), ('partner_feed', 0.55), ('region_eu', 0.522), ('web_q3', 0.516)]
472 rate 0.533 tokens [['stuck', 167], ['deadline', 163], ['immediately', 161], ['today', 161], ['blocking', 159]] top [[47.14896011352539, 'escalate'], [46.9996223449707, 'deadline']]
channel rates [('api_batch', 0.599), ('app_q3', 0.533), ('legacy_form', 0.403), ('partner_feed', 0.547), ('region_eu', 0.518), ('web_q3', 0.511)]
549 rate 0.932 tokens [['<sep>', 481], ['please', 450], ['dispatch', 204], ['kindly', 191], ['fee', 187]] top [[14.270299911499023, 'dossier'], [14.261238098144531, 'monitor']]
channel rates [('api_batch', 0.866), ('app_q3', 0.932), ('legacy_form', 0.912), ('partner_feed', 0.894), ('region_eu', 0.922), ('web_q3', 0.925)]
726 rate 0.517 tokens [['please', 102], ['address', 82], ['tracking', 72], ['freight', 64], ['speaker', 62]] top [[10.08664321899414, 'speaker'], [9.931766510009766, 'credential']]
channel rates [('api_batch', 0.572), ('app_q3', 0.517), ('legacy_form', 0.342), ('partner_feed', 0.569), ('region_eu', 0.512), ('web_q3', 0.493)]
773 rate 0.535 tokens [['stuck', 167], ['deadline', 163], ['immediately', 161], ['today', 161], ['blocking', 159]] top [[52.253658294677734, 'escalate'], [50.80039978027344, 'blocking']]
channel rates [('api_batch', 0.599), ('app_q3', 0.535), ('legacy_form', 0.4), ('partner_feed', 0.545), ('region_eu', 0.535), ('web_q3', 0.512)]
1000 rate 0.37 tokens [['please', 93], ['<eos>', 81], ['keycard', 61], ['invoice', 60], ['tracking', 59]] top [[9.268117904663086, '<eos>'], [8.358132362365723, '<eos>']]
channel rates [('api_batch', 0.439), ('app_q3', 0.37), ('legacy_form', 0.376), ('partner_feed', 0.41), ('region_eu', 0.37), ('web_q3', 0.386)]
step 10 · model
python3 - <<'PY'
import torch,sys,json
sys.path.insert(0,'/task/tools');import detector_lib as D
for sid in ['w1024_k24','w1024_k8','w256_k8','w512_k8']:
ix=json.load(open('/workspace/submission/experiments/J1_'+sid+'_top8.json'))['features'][0]['latents']
print(sid)
for i in ix:
vals=[]
for suffix in ['','_style','_reverse_cue','_reorder']:
c=torch.load('/workspace/J1'+suffix+'_cache.pt',weights_only=False);X=c['X']['sae:'+sid+':max'];y=c['y'];v=D.auroc(X[:,i],y);vals.append(round(v,4))
print(i,vals)
PYstep 10 · tool output (exit 0)
w1024_k24 107 [1.0, 1.0, 1.0, 1.0] 572 [1.0, 0.9995, 1.0, 0.5811] 599 [0.0046, 0.0021, 0.0021, 0.2047] 605 [0.0175, 0.0151, 0.0098, 0.18] 630 [1.0, 1.0, 1.0, 0.…
w1024_k24 107 [1.0, 1.0, 1.0, 1.0] 572 [1.0, 0.9995, 1.0, 0.5811] 599 [0.0046, 0.0021, 0.0021, 0.2047] 605 [0.0175, 0.0151, 0.0098, 0.18] 630 [1.0, 1.0, 1.0, 0.5665] 656 [0.0035, 0.0, 0.0, 0.2929] 705 [0.999, 0.9976, 0.9994, 0.5372] 844 [0.0213, 0.0119, 0.0215, 0.2771] w1024_k8 32 [0.0006, 0.0, 0.0, 0.3325] 131 [1.0, 1.0, 1.0, 0.5335] 194 [0.0003, 0.0011, 0.0003, 0.1578] 251 [0.001, 0.001, 0.0008, 0.1611] 382 [1.0, 1.0, 1.0, 0.7714] 557 [0.0, 0.0, 0.0, 0.1267] 807 [1.0, 1.0, 1.0, 1.0] 984 [1.0, 1.0, 1.0, 0.65] w256_k8 33 [1.0, 1.0, 1.0, 0.5414] 126 [0.1351, 0.487, 0.9857, 0.381] 132 [0.0, 0.0, 0.0, 0.2389] 155 [0.0, 0.0, 0.0, 0.2102] 191 [0.9152, 0.9021, 0.8149, 0.9641] 200 [1.0, 1.0, 1.0, 0.8929] 205 [1.0, 1.0, 1.0, 0.6714] 208 [0.014, 0.0044, 0.0114, 0.1848] w512_k8 157 [0.1937, 0.3248, 0.759, 0.4552] 158 [0.1791, 0.1389, 0.1431, 0.4056] 179 [0.9233, 0.9475, 0.8202, 0.9614] 194 [0.8628, 0.5071, 0.0, 0.5071] 226 [0.0, 0.0, 0.0, 0.2535] 314 [0.955, 0.5932, 1.0, 0.5214] 397 [0.12, 0.5167, 1.0, 0.3884] 418 [1.0, 1.0, 1.0, 0.9643]
step 11 · model
cat > /workspace/augment.py <<'PY'
import torch,sys,json,random
sys.path.insert(0,'/task/tools');import detector_lib as D
torch.set_num_threads(2);ctx=D.Context('/task');rows=D.read_jsonl('/task/data/J2/dev.jsonl');rng=random.Random(3843);aug=[];parent=[]
for i,row in enumerate(rows):
for v in range(6):
ts=[t for t in row['text'].split() if t!='kindly']
# Each original gets absent/present kindly in balanced variants, placed in request body.
if v%2:ts.insert(rng.randint(ts.index('<sep>')+1,len(ts)-3),'kindly')
# alter style for four variants, leave all original substantive tokens unchanged.
if v>=2:
segs=' '.join(ts).split(' <sep> '); ts=('<bos> '+rng.choice(['hello sir','yo','support','greetings dear','hi folks','mate'])+' <sep> '+' <sep> '.join(segs[1:-1])+' <sep> '+rng.choice(['bye','regards yours','later','sincerely','thanks'])+' <eos>').split()
aug.append({'text':' '.join(ts),'label':row['label']});parent.append(i)
with open('/workspace/submission/experiments/J2_augmentation_train.jsonl','w') as f:
for r in aug:f.write(json.dumps(r)+'\n')
texts=[r['text'] for r in aug];hs=ctx.hidden(texts);cache={'texts':texts,'y':torch.tensor([r['label'] for r in aug]),'parent':torch.tensor(parent),'X':{}}
for layer in [0,1,2,3,4]:
for agg in ['mean','last']:
key=f'resid:{layer}:{agg}';cache['X'][key]=D.features(ctx,{'features':[{'type':'resid','layer':layer,'agg':agg}]},texts,hs)
for sid in ctx.S.list_saes('/task/saes'):
for agg in ['mean','max']:
key=f'sae:{sid}:{agg}';cache['X'][key]=D.features(ctx,{'features':[{'type':'sae','sae':sid,'agg':agg,'latents':'all'}]},texts,hs)
torch.save(cache,'/workspace/J2_aug_cache.pt')
PY
python3 /workspace/augment.pystep 11 · tool output (exit 0)
step 12 · model
cat > /workspace/common.py <<'PY'
import sys,torch,json
sys.path.insert(0,'/task/tools');import detector_lib as D
torch.set_num_threads(2)
def select(X,y,k):
t=(X[y==1].mean(0)-X[y==0].mean(0))/(X[y==1].var(0)/(y==1).sum()+X[y==0].var(0)/(y==0).sum()).sqrt().clamp_min(1e-6)
return sorted(t.abs().argsort(descending=True)[:k].tolist())
def fit(X,y,l2=1.):
m=X.mean(0); sd=X.std(0).clamp_min(1e-6); w,b=D.fit_logreg((X-m)/sd,y,l2=l2); return m,sd,w,float(b)
def score(X,f):
m,sd,w,b=f; return (X-m)/sd@w+b
def spec(key,ix,f):
typ,id,agg=key.split(':');feat={'type':'resid','layer':int(id),'agg':agg} if typ=='resid' else {'type':'sae','sae':id,'latents':ix,'agg':agg}
m,sd,w,b=f;return {'features':[feat],'mean':m.tolist(),'std':sd.tolist(),'w':w.tolist(),'b':b}
PY
cat > /workspace/robust_sweep.py <<'PY'
from common import *
aug=torch.load('/workspace/J2_aug_cache.pt',weights_only=False); dev=torch.load('/workspace/J2_cache.pt',weights_only=False); rev=torch.load('/workspace/J2_reverse_cue_cache.pt',weights_only=False);style=torch.load('/workspace/J2_style_cache.pt',weights_only=False);y=dev['y'];p=aug['parent'];a_y=aug['y'];perm=torch.randperm(len(y),generator=torch.Generator().manual_seed(0));folds=[perm[i::5] for i in range(5)];O={}
for key,X in aug['X'].items():
for k in ([0] if key.startswith('resid') else [8,32]):
for l2 in ([1,10] if k==0 else [1]):
name='J2_robust_'+key.replace(':','_')+f'_k{k}_l2{l2}'
cvs={ds:torch.zeros(len(y)) for ds in ['dev','reverse','style']}
for i in range(5):
te=folds[i];tr=(~torch.isin(p,te)).nonzero().flatten();ix=select(X[tr],a_y[tr],k) if k else list(range(X.shape[1]));f=fit(X[tr][:,ix],a_y[tr],l2=l2*6)
for ds,c in [('dev',dev),('reverse',rev),('style',style)]:cvs[ds][te]=score(c['X'][key][te][:,ix],f)
ix=select(X,a_y,k) if k else list(range(X.shape[1])); f=fit(X[:,ix],a_y,l2=l2*6);s=spec(key,ix,f)
scores={ds:D.auroc(vals,y) for ds,vals in cvs.items()}; scores['train_dev']=D.auroc(score(dev['X'][key][:,ix],f),y);scores['train_reverse']=D.auroc(score(rev['X'][key][:,ix],f),y);O[name]=scores
json.dump(s,open('/workspace/submission/experiments/'+name+'.json','w'))
print(name,{k:round(v,4) for k,v in scores.items()},flush=True)
json.dump(O,open('/workspace/submission/experiments/J2_robust_cv_results.json','w'),indent=2)
PY
python3 /workspace/robust_sweep.py > /workspace/robust.log; cat /workspace/robust.logstep 12 · tool output (exit 0)
J2_robust_resid_0_mean_k0_l21 {'dev': 0.8491, 'reverse': 0.868, 'style': 0.8414, 'train_dev': 0.9953, 'train_reverse': 0.9977} J2_robust_resid_0_mean_k0_l210 {'…
J2_robust_resid_0_mean_k0_l21 {'dev': 0.8491, 'reverse': 0.868, 'style': 0.8414, 'train_dev': 0.9953, 'train_reverse': 0.9977}
J2_robust_resid_0_mean_k0_l210 {'dev': 0.8605, 'reverse': 0.8156, 'style': 0.8438, 'train_dev': 0.9661, 'train_reverse': 0.9539}
J2_robust_resid_0_last_k0_l21 {'dev': 0.6941, 'reverse': 0.6041, 'style': 0.6751, 'train_dev': 0.7244, 'train_reverse': 0.6691}
J2_robust_resid_0_last_k0_l210 {'dev': 0.6897, 'reverse': 0.6038, 'style': 0.6651, 'train_dev': 0.7311, 'train_reverse': 0.6602}
J2_robust_resid_1_mean_k0_l21 {'dev': 0.8275, 'reverse': 0.8608, 'style': 0.8131, 'train_dev': 0.9262, 'train_reverse': 0.9614}
J2_robust_resid_1_mean_k0_l210 {'dev': 0.8317, 'reverse': 0.8128, 'style': 0.8172, 'train_dev': 0.9098, 'train_reverse': 0.9136}
J2_robust_resid_1_last_k0_l21 {'dev': 0.8709, 'reverse': 0.5888, 'style': 0.8672, 'train_dev': 0.9225, 'train_reverse': 0.6831}
J2_robust_resid_1_last_k0_l210 {'dev': 0.858, 'reverse': 0.5063, 'style': 0.858, 'train_dev': 0.8995, 'train_reverse': 0.5672}
J2_robust_resid_2_mean_k0_l21 {'dev': 0.8163, 'reverse': 0.8236, 'style': 0.8133, 'train_dev': 0.9236, 'train_reverse': 0.9459}
J2_robust_resid_2_mean_k0_l210 {'dev': 0.8286, 'reverse': 0.7458, 'style': 0.8242, 'train_dev': 0.9166, 'train_reverse': 0.8731}
J2_robust_resid_2_last_k0_l21 {'dev': 0.8764, 'reverse': 0.633, 'style': 0.8391, 'train_dev': 0.9403, 'train_reverse': 0.7442}
J2_robust_resid_2_last_k0_l210 {'dev': 0.8672, 'reverse': 0.5195, 'style': 0.8417, 'train_dev': 0.9214, 'train_reverse': 0.6097}
J2_robust_resid_3_mean_k0_l21 {'dev': 0.8302, 'reverse': 0.8389, 'style': 0.8125, 'train_dev': 0.9372, 'train_reverse': 0.953}
J2_robust_resid_3_mean_k0_l210 {'dev': 0.842, 'reverse': 0.7367, 'style': 0.8261, 'train_dev': 0.9297, 'train_reverse': 0.8664}
J2_robust_resid_3_last_k0_l21 {'dev': 0.8722, 'reverse': 0.6112, 'style': 0.8225, 'train_dev': 0.9369, 'train_reverse': 0.7394}
J2_robust_resid_3_last_k0_l210 {'dev': 0.8544, 'reverse': 0.5253, 'style': 0.8264, 'train_dev': 0.9189, 'train_reverse': 0.6283}
J2_robust_resid_4_mean_k0_l21 {'dev': 0.8256, 'reverse': 0.8159, 'style': 0.8067, 'train_dev': 0.9361, 'train_reverse': 0.9364}
J2_robust_resid_4_mean_k0_l210 {'dev': 0.8317, 'reverse': 0.6866, 'style': 0.8086, 'train_dev': 0.9225, 'train_reverse': 0.828}
J2_robust_resid_4_last_k0_l21 {'dev': 0.8708, 'reverse': 0.5717, 'style': 0.8105, 'train_dev': 0.9405, 'train_reverse': 0.708}
J2_robust_resid_4_last_k0_l210 {'dev': 0.8591, 'reverse': 0.5134, 'style': 0.8225, 'train_dev': 0.9241, 'train_reverse': 0.623}
J2_robust_sae_w1024_k24_mean_k8_l21 {'dev': 0.8153, 'reverse': 0.6677, 'style': 0.8223, 'train_dev': 0.8758, 'train_reverse': 0.7631}
J2_robust_sae_w1024_k24_mean_k32_l21 {'dev': 0.8264, 'reverse': 0.7331, 'style': 0.8145, 'train_dev': 0.9358, 'train_reverse': 0.8766}
J2_robust_sae_w1024_k24_max_k8_l21 {'dev': 0.8227, 'reverse': 0.6989, 'style': 0.8286, 'train_dev': 0.8709, 'train_reverse': 0.752}
J2_robust_sae_w1024_k24_max_k32_l21 {'dev': 0.8342, 'reverse': 0.7789, 'style': 0.8098, 'train_dev': 0.9312, 'train_reverse': 0.9281}
J2_robust_sae_w1024_k8_mean_k8_l21 {'dev': 0.8512, 'reverse': 0.7359, 'style': 0.8464, 'train_dev': 0.8889, 'train_reverse': 0.7881}
J2_robust_sae_w1024_k8_mean_k32_l21 {'dev': 0.7983, 'reverse': 0.7003, 'style': 0.7778, 'train_dev': 0.9456, 'train_reverse': 0.8848}
J2_robust_sae_w1024_k8_max_k8_l21 {'dev': 0.8661, 'reverse': 0.7848, 'style': 0.8608, 'train_dev': 0.8967, 'train_reverse': 0.8289}
J2_robust_sae_w1024_k8_max_k32_l21 {'dev': 0.8089, 'reverse': 0.7077, 'style': 0.8077, 'train_dev': 0.9411, 'train_reverse': 0.8781}
J2_robust_sae_w256_k24_mean_k8_l21 {'dev': 0.8316, 'reverse': 0.4558, 'style': 0.8378, 'train_dev': 0.8938, 'train_reverse': 0.5355}
J2_robust_sae_w256_k24_mean_k32_l21 {'dev': 0.8181, 'reverse': 0.5423, 'style': 0.8259, 'train_dev': 0.9445, 'train_reverse': 0.7142}
J2_robust_sae_w256_k24_max_k8_l21 {'dev': 0.8269, 'reverse': 0.5741, 'style': 0.8255, 'train_dev': 0.8852, 'train_reverse': 0.6844}
J2_robust_sae_w256_k24_max_k32_l21 {'dev': 0.8152, 'reverse': 0.6483, 'style': 0.8414, 'train_dev': 0.9253, 'train_reverse': 0.823}
J2_robust_sae_w256_k8_mean_k8_l21 {'dev': 0.8378, 'reverse': 0.7619, 'style': 0.8239, 'train_dev': 0.9002, 'train_reverse': 0.8327}
J2_robust_sae_w256_k8_mean_k32_l21 {'dev': 0.7931, 'reverse': 0.7281, 'style': 0.777, 'train_dev': 0.9312, 'train_reverse': 0.8975}
J2_robust_sae_w256_k8_max_k8_l21 {'dev': 0.8639, 'reverse': 0.7736, 'style': 0.8641, 'train_dev': 0.9066, 'train_reverse': 0.8466}
J2_robust_sae_w256_k8_max_k32_l21 {'dev': 0.8238, 'reverse': 0.7298, 'style': 0.8303, 'train_dev': 0.9309, 'train_reverse': 0.8933}
J2_robust_sae_w512_k24_mean_k8_l21 {'dev': 0.8528, 'reverse': 0.702, 'style': 0.8366, 'train_dev': 0.8909, 'train_reverse': 0.7753}
J2_robust_sae_w512_k24_mean_k32_l21 {'dev': 0.8123, 'reverse': 0.6766, 'style': 0.8111, 'train_dev': 0.9352, 'train_reverse': 0.8702}
J2_robust_sae_w512_k24_max_k8_l21 {'dev': 0.8427, 'reverse': 0.7591, 'style': 0.8353, 'train_dev': 0.8831, 'train_reverse': 0.7995}
J2_robust_sae_w512_k24_max_k32_l21 {'dev': 0.803, 'reverse': 0.7262, 'style': 0.8044, 'train_dev': 0.9227, 'train_reverse': 0.8839}
J2_robust_sae_w512_k8_mean_k8_l21 {'dev': 0.8303, 'reverse': 0.7553, 'style': 0.8239, 'train_dev': 0.8967, 'train_reverse': 0.8138}
J2_robust_sae_w512_k8_mean_k32_l21 {'dev': 0.7678, 'reverse': 0.7081, 'style': 0.7498, 'train_dev': 0.9287, 'train_reverse': 0.8811}
J2_robust_sae_w512_k8_max_k8_l21 {'dev': 0.8869, 'reverse': 0.7817, 'style': 0.888, 'train_dev': 0.9206, 'train_reverse': 0.8427}
J2_robust_sae_w512_k8_max_k32_l21 {'dev': 0.8592, 'reverse': 0.7686, 'style': 0.8536, 'train_dev': 0.9627, 'train_reverse': 0.9087}
step 13 · model
cat > /workspace/dense_j2.py <<'PY'
from common import *
aug=torch.load('/workspace/J2_aug_cache.pt',weights_only=False);dev=torch.load('/workspace/J2_cache.pt',weights_only=False);rev=torch.load('/workspace/J2_reverse_cue_cache.pt',weights_only=False);style=torch.load('/workspace/J2_style_cache.pt',weights_only=False);y=dev['y'];p=aug['parent'];ay=aug['y'];perm=torch.randperm(len(y),generator=torch.Generator().manual_seed(0));folds=[perm[i::5] for i in range(5)];out={}
# fold scores for corrected dense, originally trained production, and sparse proposal
for name,keys,trainaug,k in [('dense0',['resid:0:mean'],True,0),('dense3',['resid:3:mean'],True,0),('joint03',['resid:0:mean','resid:3:mean'],True,0),('baseline',['resid:3:mean'],False,0),('sae_proposal',['sae:w512_k8:max'],False,8)]:
cvs={n:torch.zeros(len(y)) for n in ['dev','reverse','style']};X=torch.cat([(aug if trainaug else dev)['X'][key] for key in keys],1);yy=ay if trainaug else y
for i in range(5):
te=folds[i];tr=(~torch.isin(p if trainaug else torch.arange(len(y)),te)).nonzero().flatten();ix=select(X[tr],yy[tr],k) if k else list(range(X.shape[1]));f=fit(X[tr][:,ix],yy[tr],l2=6 if trainaug else 1)
for ds,c in [('dev',dev),('reverse',rev),('style',style)]:cvs[ds][te]=score(torch.cat([c['X'][key] for key in keys],1)[te][:,ix],f)
out[name]=cvs
print(name,{ds:round(D.auroc(s,y),4) for ds,s in cvs.items()})
if name=='joint03':
f=fit(X,yy,l2=6);m,sd,w,b=f;sp={'features':[{'type':'resid','layer':L,'agg':'mean'} for L in [0,3]],'mean':m.tolist(),'std':sd.tolist(),'w':w.tolist(),'b':b}
json.dump(sp,open('/workspace/submission/experiments/J2_robust_joint03.json','w'))
# Ensemble robust mean0 and mean3 with equal effective score scale.
for alpha in [.25,.5,.75]:
print('ensemble alpha0',alpha,{ds:round(D.auroc(alpha*out['dense0'][ds]+(1-alpha)*out['dense3'][ds],y),4) for ds in out['dense0']})
if alpha==.5:
s0=json.load(open('/workspace/submission/experiments/J2_robust_resid_0_mean_k0_l21.json'));s3=json.load(open('/workspace/submission/experiments/J2_robust_resid_3_mean_k0_l21.json'))
sp={'features':s0['features']+s3['features'],'mean':s0['mean']+s3['mean'],'std':s0['std']+s3['std'],'w':[v*.5 for v in s0['w']+s3['w']],'b':.5*(s0['b']+s3['b'])};json.dump(sp,open('/workspace/submission/experiments/J2_robust_ensemble03.json','w'))
json.dump({name:{ds:D.auroc(s,y) for ds,s in cv.items()} for name,cv in out.items()},open('/workspace/submission/experiments/J2_grouped_comparison.json','w'),indent=2)
torch.save(out,'/workspace/J2_grouped_predictions.pt')
# Purely descriptive lexical sanity check, not a labelled channel AUROC.
vocab=json.load(open('/task/model/vocab.json'));hostile=set(vocab[70:94]); cnt=torch.tensor([sum(t in hostile for t in txt.split()) for txt in dev['texts']]);print('hostile token count dev',D.auroc(cnt,y));print('hostile fraction dev',D.auroc(cnt/torch.tensor([len(t.split()) for t in dev['texts']]),y))
PY
python3 /workspace/dense_j2.pystep 13 · tool output (exit 0)
dense0 {'dev': 0.8491, 'reverse': 0.868, 'style': 0.8414} dense3 {'dev': 0.8302, 'reverse': 0.8389, 'style': 0.8125} joint03 {'dev': 0.8631, 'reverse': 0.8784, …
dense0 {'dev': 0.8491, 'reverse': 0.868, 'style': 0.8414}
dense3 {'dev': 0.8302, 'reverse': 0.8389, 'style': 0.8125}
joint03 {'dev': 0.8631, 'reverse': 0.8784, 'style': 0.8508}
baseline {'dev': 0.8725, 'reverse': 0.5663, 'style': 0.8466}
sae_proposal {'dev': 0.9156, 'reverse': 0.3278, 'style': 0.9142}
ensemble alpha0 0.25 {'dev': 0.8505, 'reverse': 0.8659, 'style': 0.835}
ensemble alpha0 0.5 {'dev': 0.8611, 'reverse': 0.8781, 'style': 0.8483}
ensemble alpha0 0.75 {'dev': 0.8616, 'reverse': 0.8756, 'style': 0.8466}
hostile token count dev 0.9083593487739563
hostile fraction dev 0.8817968964576721
step 14 · model
cat > /workspace/lexcheck.py <<'PY'
from common import *
ctx=D.Context('/task');E=ctx.model['w']['wte']; vocab=ctx.model['vocab']; h=torch.tensor([float(w in set(vocab[70:94])) for w in vocab]);E=torch.cat([E,torch.ones(len(E),1)],1);pen=torch.eye(129);pen[-1,-1]=0;out={}
for lam in [0.001,.01,.1,1.]:
w=torch.linalg.solve(E.T@E+lam*pen,E.T@h);err=E@w-h
print(lam,'embedding rmse',float(err.square().mean().sqrt()),'pos',float((E@w)[70:94].mean()),'negative',float(torch.cat([(E@w)[:70],(E@w)[94:]]).mean()))
sp={'features':[{'type':'resid','layer':0,'agg':'mean'}],'w':w[:-1].tolist(),'b':float(w[-1])}
metrics={}
for suffix in ['','_style','_reverse_cue','_reorder']:
c=torch.load('/workspace/J2'+suffix+'_cache.pt',weights_only=False);scores=c['X']['resid:0:mean']@w[:-1]+w[-1];metrics[suffix or 'dev']=D.auroc(scores,c['y'])
print(metrics)
json.dump(sp,open('/workspace/submission/experiments/J2_lexical_prior_'+str(lam)+'.json','w'));out[str(lam)]=metrics
json.dump(out,open('/workspace/submission/experiments/J2_lexical_prior_results.json','w'),indent=2)
PY
python3 /workspace/lexcheck.pystep 14 · tool output (exit 0)
0.001 embedding rmse 0.059387706220149994 pos 0.9638668894767761 negative 0.003977988380938768 {'dev': 0.5603125095367432, '_style': 0.551562488079071, '_revers…
0.001 embedding rmse 0.059387706220149994 pos 0.9638668894767761 negative 0.003977988380938768
{'dev': 0.5603125095367432, '_style': 0.551562488079071, '_reverse_cue': 0.6362500190734863, '_reorder': 0.5603125095367432}
0.01 embedding rmse 0.059894662350416183 pos 0.9593834280967712 negative 0.004471569322049618
{'dev': 0.5609375238418579, '_style': 0.5542187690734863, '_reverse_cue': 0.6384375095367432, '_reorder': 0.5609375238418579}
0.1 embedding rmse 0.06619758158922195 pos 0.9328311085700989 negative 0.007394758984446526
{'dev': 0.546093761920929, '_style': 0.5376562476158142, '_reverse_cue': 0.604687511920929, '_reorder': 0.546093761920929}
1.0 embedding rmse 0.09559045732021332 pos 0.8130456805229187 negative 0.020582148805260658
{'dev': 0.56640625, '_style': 0.553906261920929, '_reverse_cue': 0.5395312309265137, '_reorder': 0.56640625}
step 15 · model
cat > /workspace/lexcorrect.py <<'PY'
from common import *
ctx=D.Context('/task');E=ctx.model['w']['wte'];P=ctx.model['w']['wpe'];vocab=ctx.model['vocab'];h=torch.tensor([float(w in set(vocab[70:94])) for w in vocab]);EE=torch.cat([E,torch.ones(len(E),1)],1);pen=torch.eye(129);pen[-1,-1]=0;lam=.01;w=torch.linalg.solve(EE.T@EE+lam*pen,EE.T@h)
# mean features exclude bos, position 0; last token is eos at position T-1.
A=torch.cat([P[1:],torch.ones(len(P)-1,1)],1);target=torch.stack([-P[1:T].mean(0)@w[:-1] for T in range(2,len(P)+1)]); sol=torch.linalg.lstsq(A.double(),target.double(),driver='gelsd').solution.float(); wl=sol[:-1];b=w[-1]+sol[-1]-E[vocab.index('<eos>')]@wl
sp={'features':[{'type':'resid','layer':0,'agg':'mean'},{'type':'resid','layer':0,'agg':'last'}],'w':torch.cat([w[:-1],wl]).tolist(),'b':float(b)}
print('position correction max error',float((A@sol-target).abs().max()))
for suffix in ['','_style','_reverse_cue','_reorder']:
c=torch.load('/workspace/J2'+suffix+'_cache.pt',weights_only=False);scores=c['X']['resid:0:mean']@w[:-1]+c['X']['resid:0:last']@wl+b;print(suffix,D.auroc(scores,c['y']))
json.dump(sp,open('/workspace/submission/experiments/J2_lexical_corrected.json','w'))
PY
python3 /workspace/lexcorrect.pystep 15 · tool output (exit 0)
position correction max error 2.9802322387695312e-08 0.8837500214576721 _style 0.8840625286102295 _reverse_cue 0.874218761920929 _reorder 0.8837500214576721
position correction max error 2.9802322387695312e-08 0.8837500214576721 _style 0.8840625286102295 _reverse_cue 0.874218761920929 _reorder 0.8837500214576721
step 16 · model
cat > /workspace/independent_challenges.py <<'PY'
import sys,json,random,collections
sys.path.insert(0,'/task/tools');import detector_lib as D
rng=random.Random(9371);vocab=json.load(open('/task/model/vocab.json'));hostile=set(vocab[70:94]);covert=set(vocab[106:114]);actions=set(vocab[j] for j in [128,129,144,145,160,161,176,177,192,193,208,209,224,225,240,241]); out={k:[] for k in ['J1_actions','J2_tone']}; manifest=[]
channels=['app_q3','web_q3','api_batch','region_eu','partner_feed','legacy_form']
for channel in channels:
texts=open('/task/traffic/'+channel+'.txt').read().splitlines();rng.shuffle(texts);chosen=[]
# A neutral body's topic determines the controlled data-movement action; use no labelled development requests.
for topic in range(8):
words=set(vocab[114+16*topic:128+16*topic]);candidates=[t for t in texts if not(set(t.split())&(actions|covert|hostile)) and len(set(t.split())&words)>=3 and len(t.split())<=42]
for n,t in enumerate(candidates[:4]):
# retain realistic channel body; covert footer now independent of label.
segs=t.split(' <sep> ');body=max(range(1,len(segs)-1),key=lambda q:len(segs[q].split()));bt=segs[body].split()
for y in [0,1]:
ss=segs.copy();bb=bt.copy()
if y:bb.insert(rng.randrange(len(bb)+1),vocab[128+16*topic+n%2])
ss[body]=' '.join(bb);ss[-1]=rng.choice(['thanks','regards','quietly','offrecord'])+' <eos>'
text=' <sep> '.join(ss);out['J1_actions'].append({'text':text,'label':y});manifest.append({'set':'J1_actions','channel':channel,'topic':topic,'label':y,'source':t})
for y in [0,1]:
ss=segs.copy();bb=[w for w in bt if w!='kindly']
if y:
# Explicit insulting escalation; two distinct hostile words, not the ambiguous one-word boundary.
for word in rng.sample(['ridiculous','incompetent','pathetic','disgrace','scam','liars','useless','garbage','furious','outraged','shameful','clowns','disgusting','worst','nightmare'],2):bb.insert(rng.randrange(len(bb)+1),word)
else:bb.insert(rng.randrange(len(bb)+1),'kindly')
ss[body]=' '.join(bb);text=' <sep> '.join(ss);out['J2_tone'].append({'text':text,'label':y});manifest.append({'set':'J2_tone','channel':channel,'topic':topic,'label':y,'source':t})
for name,rows in out.items():
with open('/workspace/submission/experiments/'+name+'.jsonl','w') as f:
for row in rows:
assert len(row['text'].split())<=48 and set(row['text'].split())<=set(vocab)
f.write(json.dumps(row)+'\n')
print(name,len(rows),sum(r['label'] for r in rows))
json.dump(manifest,open('/workspace/submission/experiments/challenge_provenance.json','w'),indent=2)
PY
python3 /workspace/independent_challenges.py
cat > /workspace/challenge_eval.py <<'PY'
from common import *
import glob,os
ctx=D.Context('/task');out={}
for job,name in [('J1','J1_actions'),('J2','J2_tone')]:
rows=D.read_jsonl('/workspace/submission/experiments/'+name+'.jsonl');texts=[r['text'] for r in rows];y=torch.tensor([r['label'] for r in rows]);hs=ctx.hidden(texts);cache={'texts':texts,'y':y,'X':{}};out[name]={}
dc=torch.load('/workspace/'+job+'_cache.pt',weights_only=False)
for key in dc['X']:
typ,id,agg=key.split(':');feat={'type':'resid','layer':int(id),'agg':agg} if typ=='resid' else {'type':'sae','sae':id,'agg':agg,'latents':'all'}
cache['X'][key]=D.features(ctx,{'features':[feat]},texts,hs)
torch.save(cache,'/workspace/'+name+'_cache.pt')
files=glob.glob('/workspace/submission/experiments/'+job+'*.json')
for fn in files:
sp=json.load(open(fn))
if not isinstance(sp,dict) or 'features' not in sp:continue
if job=='J2' and ('lexical_prior_' in fn or 'robust_sae' in fn or 'robust_resid' in fn):continue
auc=D.auroc(D.score(ctx,sp,texts,hs),y);out[name][os.path.basename(fn)]=auc; print(name,os.path.basename(fn),round(auc,4),flush=True)
if job=='J1':
for sid,i in [('w1024_k24',107),('w1024_k8',807)]:
key='sae:'+sid+':max';f=fit(dc['X'][key][:,[i]],dc['y']);sp=spec(key,[i],f);fn='J1_'+sid+'_single'+str(i)+'.json';json.dump(sp,open('/workspace/submission/experiments/'+fn,'w'));auc=D.auroc(score(cache['X'][key][:,[i]],f),y);out[name][fn]=auc;print(fn,auc)
json.dump(out,open('/workspace/submission/experiments/challenge_results.json','w'),indent=2)
PY
python3 /workspace/challenge_eval.pystep 16 · tool output (exit 0)
J1_actions 384 192 J2_tone 384 192 J1_actions J1_w256_k24_top8.json 1.0 J1_actions J1_w256_k8_top8.json 1.0 J1_actions J1_w1024_k8_top8.json 1.0 J1_actions J1_w…
J1_actions 384 192 J2_tone 384 192 J1_actions J1_w256_k24_top8.json 1.0 J1_actions J1_w256_k8_top8.json 1.0 J1_actions J1_w1024_k8_top8.json 1.0 J1_actions J1_w512_k8_top8.json 1.0 J1_actions J1_w512_k24_top8.json 1.0 J1_actions J1_w1024_k24_top8.json 1.0 J1_actions J1_dense_refit.json 0.8197 J1_w1024_k24_single107.json 1.0 J1_w1024_k8_single807.json 1.0 J2_tone J2_robust_ensemble03.json 0.9848 J2_tone J2_w256_k24_top8.json 0.4151 J2_tone J2_w512_k8_top8.json 0.8461 J2_tone J2_w512_k24_top8.json 0.5154 J2_tone J2_w1024_k24_top8.json 0.5069 J2_tone J2_robust_joint03.json 0.9807 J2_tone J2_w1024_k8_top8.json 0.8572 J2_tone J2_lexical_corrected.json 1.0 J2_tone J2_w256_k8_top8.json 0.6677 J2_tone J2_dense_refit.json 0.6858
step 17 · model
cat > /workspace/j3_audit.py <<'PY'
from common import *
import random
ctx=D.Context('/task');c=torch.load('/workspace/J3_cache.pt',weights_only=False);texts=c['texts'];y=c['y'];hs=ctx.hidden(texts);vocab=ctx.model['vocab'];urg=set(vocab[20:36]);rows=[]
for t,lab in zip(texts,y):
segs=t.split(' <sep> '); segs=[s for s in segs if not set(s.split())<=urg];rows.append({'text':' <sep> '.join(segs),'label':int(lab)})
with open('/workspace/submission/experiments/J3_urgency_masked.jsonl','w') as f:
for r in rows:f.write(json.dumps(r)+'\n')
ct=[r['text'] for r in rows];hct=ctx.hidden(ct);perm=torch.randperm(len(y),generator=torch.Generator().manual_seed(0));folds=[perm[i::5] for i in range(5)];out={}
def cv(X):
pred=torch.zeros(len(y))
for i in range(5):
te=folds[i];tr=torch.cat([folds[j] for j in range(5) if i!=j]);pred[te]=score(X[te],fit(X[tr],y[tr]))
return D.auroc(pred,y)
X=c['X']['resid:2:mean'];out['raw_layer2_cv']=cv(X)
for sid in ctx.S.list_saes('/task/saes'):
sae=ctx.sae(sid);recons=torch.stack([ctx.S.decode(sae,ctx.S.encode(sae,h[2,1:])).mean(0) for h in hs]);error=X-recons
out[sid]={'reconstruction_mean_cv':cv(recons),'error_mean_cv':cv(error),'all_latents_mean_cv':cv(c['X']['sae:'+sid+':mean']),'all_latents_max_cv':cv(c['X']['sae:'+sid+':max'])}
sp=json.load(open('/workspace/submission/experiments/J3_'+sid+'_top8.json'));out[sid]['top8_masked_auroc']=D.auroc(D.score(ctx,sp,ct,hct),y)
print(sid,out[sid],flush=True)
base=json.load(open('/task/baselines/J3.json'));out['baseline_masked_auroc']=D.auroc(D.score(ctx,base,ct,hct),y);print('raw',out['raw_layer2_cv'],'baseline masked',out['baseline_masked_auroc'])
# The repeated urgency latents are highly redundant, not independent corroboration.
ix=[363,452,472,773];Z=c['X']['sae:w1024_k8:max'][:,ix];out['urgency_latents']={'sae':'w1024_k8','indices':ix,'correlation':torch.corrcoef(Z.T).tolist()};uc=torch.tensor([sum(w in urg for w in t.split()) for t in texts]);out['urgency_count_dev_auroc']=D.auroc(uc,y)
json.dump(out,open('/workspace/submission/experiments/J3_representation_audit.json','w'),indent=2)
PY
python3 /workspace/j3_audit.pystep 17 · tool output (exit 0)
w1024_k24 {'reconstruction_mean_cv': 0.7803999781608582, 'error_mean_cv': 0.5634999871253967, 'all_latents_mean_cv': 0.7767000198364258, 'all_latents_max_cv': 0…
w1024_k24 {'reconstruction_mean_cv': 0.7803999781608582, 'error_mean_cv': 0.5634999871253967, 'all_latents_mean_cv': 0.7767000198364258, 'all_latents_max_cv': 0.7443000078201294, 'top8_masked_auroc': 0.7114999890327454}
w1024_k8 {'reconstruction_mean_cv': 0.7897999882698059, 'error_mean_cv': 0.6403999924659729, 'all_latents_mean_cv': 0.7031999826431274, 'all_latents_max_cv': 0.6636999845504761, 'top8_masked_auroc': 0.7818999886512756}
w256_k24 {'reconstruction_mean_cv': 0.7782999873161316, 'error_mean_cv': 0.6128000020980835, 'all_latents_mean_cv': 0.7493000030517578, 'all_latents_max_cv': 0.7440000176429749, 'top8_masked_auroc': 0.43035000562667847}
w256_k8 {'reconstruction_mean_cv': 0.7817000150680542, 'error_mean_cv': 0.5710999965667725, 'all_latents_mean_cv': 0.7771999835968018, 'all_latents_max_cv': 0.7835000157356262, 'top8_masked_auroc': 0.7685999870300293}
w512_k24 {'reconstruction_mean_cv': 0.7860000133514404, 'error_mean_cv': 0.5428000092506409, 'all_latents_mean_cv': 0.6621000170707703, 'all_latents_max_cv': 0.6680999994277954, 'top8_masked_auroc': 0.6636499762535095}
w512_k8 {'reconstruction_mean_cv': 0.7807999849319458, 'error_mean_cv': 0.6129000186920166, 'all_latents_mean_cv': 0.7257000207901001, 'all_latents_max_cv': 0.7026000022888184, 'top8_masked_auroc': 0.7452999949455261}
raw 0.7803000211715698 baseline masked 0.8614000082015991
step 18 · model
cat > /workspace/interventions.py <<'PY'
from common import *
ctx=D.Context('/task');out={}
# J1 action insertion and closing-only changes: all pairs already have identical bodies except action.
rows=D.read_jsonl('/workspace/submission/experiments/J1_actions.jsonl');texts=[]
for r in rows:
seg=r['text'].split(' <sep> ');seg[-1]='thanks <eos>';texts.append(' <sep> '.join(seg))
hs=ctx.hidden(texts);z=D.features(ctx,{'features':[{'type':'sae','sae':'w1024_k24','latents':[107],'agg':'max'}]},texts,hs)[:,0];d=z[1::2]-z[::2];out['J1_action_insertion_107']={'pairs':len(d),'mean_change':float(d.mean()),'min_change':float(d.min()),'positive_change_fraction':float((d>0).float().mean())}
covert=[' <sep> '.join(t.split(' <sep> ')[:-1]+['quietly <eos>']) for t in texts];zc=D.features(ctx,{'features':[{'type':'sae','sae':'w1024_k24','latents':[107],'agg':'max'}]},covert)[:,0];out['J1_footer_change_107']={'mean_absolute_change':float((zc-z).abs().mean()),'max_absolute_change':float((zc-z).abs().max())}
# J2 factorial: all four versions of each held-out traffic body, preserving tone label.
rows=D.read_jsonl('/workspace/submission/experiments/J2_tone.jsonl');factor=[]
for r in rows:
clean=[t for t in r['text'].split() if t!='kindly'];present=clean.copy();present.insert(present.index('<sep>')+1,'kindly')
factor.extend([{'text':' '.join(clean),'label':r['label']},{'text':' '.join(present),'label':r['label']}])
with open('/workspace/submission/experiments/J2_factorial.jsonl','w') as f:
for r in factor:f.write(json.dumps(r)+'\n')
texts=[r['text'] for r in factor];hs=ctx.hidden(texts);sp=json.load(open('/workspace/submission/experiments/J2_w512_k8_top8.json'));ix=sp['features'][0]['latents'];Z=D.features(ctx,sp,texts,hs)
for c,i in enumerate(ix):
# order within body: neutral absent, neutral present, hostile absent, hostile present
V=Z[:,c].reshape(-1,4);out['J2_latent_'+str(i)]={'sae':'w512_k8','mean_kindly_effect':float(((V[:,1]-V[:,0])+(V[:,3]-V[:,2])).mean()/2),'mean_hostility_effect':float(((V[:,2]-V[:,0])+(V[:,3]-V[:,1])).mean()/2)}
for name in ['J2_dense_refit','J2_w512_k8_top8','J2_robust_joint03','J2_lexical_corrected']:
specj=json.load(open('/workspace/submission/experiments/'+name+'.json'));scores=D.score(ctx,specj,texts,hs);out[name]={'factorial_auroc':D.auroc(scores,[r['label'] for r in factor])}
print(json.dumps(out,indent=2));json.dump(out,open('/workspace/submission/experiments/intervention_results.json','w'),indent=2)
PY
python3 /workspace/interventions.pystep 18 · tool output (exit 0)
{ "J1_action_insertion_107": { "pairs": 192, "mean_change": 6.231166362762451, "min_change": 4.717374801635742, "positive_change_fraction": 1.…
{
"J1_action_insertion_107": {
"pairs": 192,
"mean_change": 6.231166362762451,
"min_change": 4.717374801635742,
"positive_change_fraction": 1.0
},
"J1_footer_change_107": {
"mean_absolute_change": 0.0,
"max_absolute_change": 0.0
},
"J2_latent_225": {
"sae": "w512_k8",
"mean_kindly_effect": 0.14994613826274872,
"mean_hostility_effect": 0.37576380372047424
},
"J2_latent_334": {
"sae": "w512_k8",
"mean_kindly_effect": 0.895887553691864,
"mean_hostility_effect": 6.726963043212891
},
"J2_latent_348": {
"sae": "w512_k8",
"mean_kindly_effect": -0.3933888375759125,
"mean_hostility_effect": -0.29138314723968506
},
"J2_latent_382": {
"sae": "w512_k8",
"mean_kindly_effect": 0.3697468936443329,
"mean_hostility_effect": 6.748786926269531
},
"J2_latent_412": {
"sae": "w512_k8",
"mean_kindly_effect": -2.436189651489258,
"mean_hostility_effect": -1.2904337644577026
},
"J2_latent_415": {
"sae": "w512_k8",
"mean_kindly_effect": 10.615894317626953,
"mean_hostility_effect": 0.3700103759765625
},
"J2_latent_455": {
"sae": "w512_k8",
"mean_kindly_effect": -0.9111246466636658,
"mean_hostility_effect": -4.0048346519470215
},
"J2_latent_503": {
"sae": "w512_k8",
"mean_kindly_effect": -0.749896228313446,
"mean_hostility_effect": -0.8081105351448059
},
"J2_dense_refit": {
"factorial_auroc": 0.8090888261795044
},
"J2_w512_k8_top8": {
"factorial_auroc": 0.9308268427848816
},
"J2_robust_joint03": {
"factorial_auroc": 0.9819471836090088
},
"J2_lexical_corrected": {
"factorial_auroc": 1.0
}
}
step 19 · model
python3 - <<'PY'
import sys;sys.path.insert(0,'/workspace');from common import *
c=torch.load('/workspace/J2_cache.pt',weights_only=False);out={}
for ix in [[334],[382],[334,382]]:
key='sae:w512_k8:max';f=fit(c['X'][key][:,ix],c['y']);sp=spec(key,ix,f);name='J2_hostility_latents_'+'_'.join(map(str,ix));json.dump(sp,open('/workspace/submission/experiments/'+name+'.json','w'));vals={}
for n in ['J2','J2_reverse_cue','J2_style','J2_reorder','J2_tone']:
x=torch.load('/workspace/'+n+'_cache.pt',weights_only=False);vals[n]=D.auroc(score(x['X'][key][:,ix],f),x['y'])
print(name,vals);out[name]=vals
json.dump(out,open('/workspace/submission/experiments/J2_pruned_results.json','w'),indent=2)
PYstep 19 · tool output (exit 0)
J2_hostility_latents_334 {'J2': 0.8878124952316284, 'J2_reverse_cue': 0.7342968583106995, 'J2_style': 0.8723437786102295, 'J2_reorder': 0.870312511920929, 'J2_t…
J2_hostility_latents_334 {'J2': 0.8878124952316284, 'J2_reverse_cue': 0.7342968583106995, 'J2_style': 0.8723437786102295, 'J2_reorder': 0.870312511920929, 'J2_tone': 0.9794921875}
J2_hostility_latents_382 {'J2': 0.8271874785423279, 'J2_reverse_cue': 0.7762500047683716, 'J2_style': 0.8267968893051147, 'J2_reorder': 0.8189062476158142, 'J2_tone': 0.9483371376991272}
J2_hostility_latents_334_382 {'J2': 0.8970312476158142, 'J2_reverse_cue': 0.7771875262260437, 'J2_style': 0.8915625214576721, 'J2_reorder': 0.8860937356948853, 'J2_tone': 0.9945204257965088}
step 20 · model
cat > /workspace/uncertainty.py <<'PY'
from common import *
import numpy as np
c=torch.load('/workspace/J3_cache.pt',weights_only=False);y=c['y'];out={'seeds':[]};seed0={}
for seed in range(10):
perm=torch.randperm(len(y),generator=torch.Generator().manual_seed(seed));folds=[perm[i::5] for i in range(5)];res={}
for name,key,k in [('baseline','resid:3:mean',0),('dense0','resid:0:mean',0),('proposal','sae:w1024_k8:max',8)]:
X=c['X'][key];pred=torch.zeros(len(y))
for i in range(5):
te=folds[i];tr=torch.cat([folds[j] for j in range(5) if j!=i]);ix=select(X[tr],y[tr],k) if k else list(range(X.shape[1]));pred[te]=score(X[te][:,ix],fit(X[tr][:,ix],y[tr]))
res[name]=D.auroc(pred,y)
if seed==0:seed0[name]=pred
res['difference']=res['proposal']-res['baseline'];out['seeds'].append(res)
print(out['seeds']);out['mean']={k:float(np.mean([r[k] for r in out['seeds']])) for k in out['seeds'][0]};out['range']={k:[min(r[k] for r in out['seeds']),max(r[k] for r in out['seeds'])] for k in out['seeds'][0]}
# Pairwise matrix permits fast stratified resampling of OOF prediction AUROC differences.
pos=(y==1).nonzero().flatten();neg=(y==0).nonzero().flatten();delta=[];rng=np.random.default_rng(2026)
def pairs(s):
d=(s[pos,None]-s[neg][None,:]).numpy();return (d>0).astype(float)+.5*(d==0)
mat=pairs(seed0['proposal'])-pairs(seed0['baseline'])
for b in range(5000):
p=rng.integers(0,len(pos),len(pos));n=rng.integers(0,len(neg),len(neg));delta.append(mat[np.ix_(p,n)].mean())
out['paired_bootstrap_seed0_difference_ci95']=np.quantile(delta,[.025,.975]).tolist();out['bootstrap_note']='5000 class-stratified resamples of fixed seed-0 OOF predictions; excludes training and model-selection uncertainty.'
print(out['mean'],out['range'],out['paired_bootstrap_seed0_difference_ci95'])
json.dump(out,open('/workspace/submission/experiments/J3_cv_uncertainty.json','w'),indent=2)
# Verify rank AUROC ties against pairwise implementation.
s=torch.tensor([0.,0.,1.,2.,2.,-1.]);lab=torch.tensor([1,0,1,1,0,0]);pair=(s[lab==1,None]-s[lab==0][None,:]);brute=float(((pair>0).float()+.5*(pair==0).float()).mean());assert abs(D.auroc(s,lab)-brute)<1e-7
json.dump({'tie_test_rank_auroc':D.auroc(s,lab),'pairwise_auroc':brute},open('/workspace/submission/experiments/evaluator_check.json','w'),indent=2)
PY
python3 /workspace/uncertainty.pystep 20 · tool output (exit 0)
[{'baseline': 0.7712000012397766, 'dense0': 0.828000009059906, 'proposal': 0.7918999791145325, 'difference': 0.02069997787475586}, {'baseline': 0.76300001144409…
[{'baseline': 0.7712000012397766, 'dense0': 0.828000009059906, 'proposal': 0.7918999791145325, 'difference': 0.02069997787475586}, {'baseline': 0.7630000114440918, 'dense0': 0.7968000173568726, 'proposal': 0.8055999875068665, 'difference': 0.04259997606277466}, {'baseline': 0.7817000150680542, 'dense0': 0.8137000203132629, 'proposal': 0.8061000108718872, 'difference': 0.024399995803833008}, {'baseline': 0.7978000044822693, 'dense0': 0.8009999990463257, 'proposal': 0.802299976348877, 'difference': 0.004499971866607666}, {'baseline': 0.7498999834060669, 'dense0': 0.7896000146865845, 'proposal': 0.7955999970436096, 'difference': 0.045700013637542725}, {'baseline': 0.7791000008583069, 'dense0': 0.8111000061035156, 'proposal': 0.7961000204086304, 'difference': 0.017000019550323486}, {'baseline': 0.7634999752044678, 'dense0': 0.8083999752998352, 'proposal': 0.8033999800682068, 'difference': 0.039900004863739014}, {'baseline': 0.7749000191688538, 'dense0': 0.8025000095367432, 'proposal': 0.7745000123977661, 'difference': -0.0004000067710876465}, {'baseline': 0.7735999822616577, 'dense0': 0.8037999868392944, 'proposal': 0.7870000004768372, 'difference': 0.013400018215179443}, {'baseline': 0.7718999981880188, 'dense0': 0.7961000204086304, 'proposal': 0.8032000064849854, 'difference': 0.03130000829696655}]
{'baseline': 0.7726599991321563, 'dense0': 0.805100005865097, 'proposal': 0.7965699970722199, 'difference': 0.023909997940063477} {'baseline': [0.7498999834060669, 0.7978000044822693], 'dense0': [0.7896000146865845, 0.828000009059906], 'proposal': [0.7745000123977661, 0.8061000108718872], 'difference': [-0.0004000067710876465, 0.045700013637542725]} [-0.0299025, 0.07160249999999996]
step 21 · model
cp /workspace/submission/experiments/J1_w1024_k24_single107.json /workspace/submission/detectors/J1.json
cp /workspace/submission/experiments/J2_robust_joint03.json /workspace/submission/detectors/J2.json
cp /task/baselines/J3.json /workspace/submission/detectors/J3.json
for j in J1 J2 J3; do cp /task/baselines/$j.json /workspace/submission/experiments/${j}_baseline.json; done
cat > /workspace/final_evaluation.py <<'PY'
from common import *
import os,glob
ctx=D.Context('/task');root='/workspace/submission/'; answer={'jobs':{},'experiments':[]}; allresults={}
notes={
'J1':'Adopt a single max-pooled latent 107 of w1024_k24, not the proposed top-8. It separates controlled action insertions across all eight topics and six supplied channel styles, while changing only the covert footer has no effect in the paired audit. Other highly correlated top-8 latents fail the order intervention. This is synthetic/counterfactual shift evidence, not unknown-channel ground truth.',
'J2':'Reject the SAE replacement; deploy an augmented dense probe on mean residuals at layers 0 and 3. Kindly is present in 68/80 positives but only 9/80 negatives in dev. The proposed w512_k8 top-8 probe exploits that cue (especially latent 415); reversing it damages both proposal and baseline. Fit the shipped probe on six variants per original, balancing kindly and varying wrappers, with parent-grouped validation. Independent traffic-body tone challenges support the repair. Synthetic tone labels cover clear extremes, not the ambiguous boundary.',
'J3':'Do not adopt an SAE; retain the production detector byte-for-byte. Correct nested CV reproduces the small w1024_k8 top-8 advantage, but its paired uncertainty includes zero and there is no new channel-level ticket metadata. Several selected latents are redundant urgency features, not priority labels. Shift files preserve the original known ticket label under wrapper/order/urgency edits; these are conditional same-ticket invariance tests, not newly observed metadata outcomes. Dense layer-0 alternatives are promising but also lack independent metadata validation.'}
for job in ['J1','J2','J3']:
rows=D.read_jsonl('/task/data/'+job+'/dev.jsonl');texts=[r['text'] for r in rows];y=torch.tensor([r['label'] for r in rows]);hs=ctx.hidden(texts)
selected=[job+'_baseline',job+'_dense_refit']+[job+'_'+sid+'_top8' for sid in ctx.S.list_saes('/task/saes')]
if job=='J1':selected += ['J1_w1024_k24_single107','J1_w1024_k8_single807']
if job=='J2':selected += ['J2_robust_joint03','J2_robust_ensemble03','J2_robust_resid_0_mean_k0_l21','J2_robust_resid_3_mean_k0_l21','J2_robust_sae_w512_k8_max_k8_l21','J2_hostility_latents_334','J2_hostility_latents_382','J2_hostility_latents_334_382','J2_lexical_corrected']
specs={n:json.load(open(root+'experiments/'+n+'.json')) for n in selected};specs['shipped']=json.load(open(root+'detectors/'+job+'.json'))
dev={n:D.auroc(D.score(ctx,sp,texts,hs),y) for n,sp in specs.items()}; base=dev[job+'_baseline'];file_names=[job+'_style',job+'_reverse_cue',job+'_reorder']
if job=='J1':file_names+=['J1_actions']
if job=='J2':file_names+=['J2_tone','J2_factorial']
if job=='J3':file_names+=['J3_urgency_masked']
results={n:[] for n in specs}
for file in file_names:
rs=D.read_jsonl(root+'experiments/'+file+'.jsonl');ts=[r['text'] for r in rs];yy=[r['label'] for r in rs];hh=ctx.hidden(ts)
for n,sp in specs.items():
auc=D.auroc(D.score(ctx,sp,ts,hh),yy);results[n].append({'file':'experiments/'+file+'.jsonl','auroc':auc})
allresults[job]={'dev':dev,'evals':results}
shift=[]
for n in ['shipped',job+'_baseline',job+('_w1024_k24_top8' if job=='J1' else '_w512_k8_top8' if job=='J2' else '_w1024_k8_top8')]:
for ev in results[n]:shift.append({'detector':'detectors/'+job+'.json' if n=='shipped' else 'experiments/'+n+'.json',**ev})
answer['jobs'][job]={'adopt_sae':job=='J1','detector_kind':'sae' if job=='J1' else 'dense','dev_auroc':dev['shipped'],'baseline_dev_auroc':base,'shift_evidence':shift,'notes':notes[job]}
for n in selected:
kinds=set(f['type'] for f in specs[n]['features']);kind='hybrid' if len(kinds)>1 else 'sae' if 'sae' in kinds else 'dense'
answer['experiments'].append({'name':n,'job':job,'detector':'experiments/'+n+'.json','kind':kind,'dev_auroc':dev[n],'evals':results[n]})
print(job,'shipped dev',dev['shipped'],'baseline dev',base,'shipped evals',results['shipped'],flush=True)
json.dump(answer,open(root+'answer.json','w'),indent=2);json.dump(allresults,open(root+'experiments/final_evaluations.json','w'),indent=2)
PY
python3 /workspace/final_evaluation.pystep 21 · tool output (exit 0)
J1 shipped dev 1.0 baseline dev 0.9980952143669128 shipped evals [{'file': 'experiments/J1_style.jsonl', 'auroc': 1.0}, {'file': 'experiments/J1_reverse_cue.jso…
J1 shipped dev 1.0 baseline dev 0.9980952143669128 shipped evals [{'file': 'experiments/J1_style.jsonl', 'auroc': 1.0}, {'file': 'experiments/J1_reverse_cue.jsonl', 'auroc': 1.0}, {'file': 'experiments/J1_reorder.jsonl', 'auroc': 1.0}, {'file': 'experiments/J1_actions.jsonl', 'auroc': 1.0}]
J2 shipped dev 0.9975000023841858 baseline dev 0.9671875238418579 shipped evals [{'file': 'experiments/J2_style.jsonl', 'auroc': 0.9912499785423279}, {'file': 'experiments/J2_reverse_cue.jsonl', 'auroc': 0.9993749856948853}, {'file': 'experiments/J2_reorder.jsonl', 'auroc': 0.9790624976158142}, {'file': 'experiments/J2_tone.jsonl', 'auroc': 0.980712890625}, {'file': 'experiments/J2_factorial.jsonl', 'auroc': 0.9819471836090088}]
J3 shipped dev 0.8876000046730042 baseline dev 0.8876000046730042 shipped evals [{'file': 'experiments/J3_style.jsonl', 'auroc': 0.8858000040054321}, {'file': 'experiments/J3_reverse_cue.jsonl', 'auroc': 0.887499988079071}, {'file': 'experiments/J3_reorder.jsonl', 'auroc': 0.8619999885559082}, {'file': 'experiments/J3_urgency_masked.jsonl', 'auroc': 0.8614000082015991}]
step 22 · model
python3 - <<'PY'
import json,torch,sys
sys.path.insert(0,'/task/tools');import detector_lib as D
torch.set_num_threads(2);ctx=D.Context('/task')
for job in ['J1','J2','J3']:
rows=D.read_jsonl('/task/data/'+job+'/dev.jsonl');txt=[r['text'] for r in rows];h=ctx.hidden(txt);b=json.load(open('/task/baselines/'+job+'.json'));r=json.load(open('/workspace/submission/experiments/'+job+'_dense_refit.json'));print(job,'max baseline/refit delta',float((D.score(ctx,b,txt,h)-D.score(ctx,r,txt,h)).abs().max()))
a=json.load(open('/workspace/submission/experiments/J3_representation_audit.json'));corr=torch.tensor(a['urgency_latents']['correlation']);print('urgency correlations',corr[torch.triu(torch.ones(4,4),diagonal=1).bool()].tolist(), 'count auc',a['urgency_count_dev_auroc'])
x=json.load(open('/workspace/submission/experiments/traffic_audit.json'))
for ch in x:
c=x[ch]['token_counts'];print(ch,'kindly P(anyhostile)',c['hostile=1,kindly=1']/(c['hostile=1,kindly=1']+c['hostile=1,kindly=0']),'P(nohostile)',c['hostile=0,kindly=1']/(c['hostile=0,kindly=1']+c['hostile=0,kindly=0']))
PY
find /workspace/submission -type f | wc -l; du -sh /workspace/submissionstep 22 · tool output (exit 0)
J1 max baseline/refit delta 0.0 J2 max baseline/refit delta 0.0 J3 max baseline/refit delta 0.0 urgency correlations [0.9953001737594604, 0.9945818781852722, 0.…
J1 max baseline/refit delta 0.0 J2 max baseline/refit delta 0.0 J3 max baseline/refit delta 0.0 urgency correlations [0.9953001737594604, 0.9945818781852722, 0.9993897080421448, 0.9870646595954895, 0.9927451610565186, 0.9965484738349915] count auc 0.6898999810218811 api_batch kindly P(anyhostile) 0.19702970297029704 P(nohostile) 0.18743718592964825 app_q3 kindly P(anyhostile) 0.19860973187686196 P(nohostile) 0.20622177621675866 legacy_form kindly P(anyhostile) 0.2542204568023833 P(nohostile) 0.5418966382338184 partner_feed kindly P(anyhostile) 0.20348837209302326 P(nohostile) 0.2073170731707317 region_eu kindly P(anyhostile) 0.23947895791583165 P(nohostile) 0.2087912087912088 web_q3 kindly P(anyhostile) 0.4995159728944821 P(nohostile) 0.2867310625317743 112 2.5M /workspace/submission
step 23 · model
cat /task/tools/eval_detector.py; ls /workspace/submission/experiments | sed -n '1,130p'
step 23 · tool output (exit 0)
#!/usr/bin/env python3 """Evaluate a detector spec on labelled jsonl files. python3 /task/tools/eval_detector.py SPEC.json FILE.jsonl [FILE2.jsonl ...] -> A…
#!/usr/bin/env python3
"""Evaluate a detector spec on labelled jsonl files.
python3 /task/tools/eval_detector.py SPEC.json FILE.jsonl [FILE2.jsonl ...] -> AUROC, balanced accuracy at threshold, n
Set TASK_ROOT if the fixture is not at /task."""
import json, os, sys
os.environ.setdefault("OMP_NUM_THREADS", "2")
import torch
torch.set_num_threads(2)
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import detector_lib as D
if len(sys.argv) < 3:
raise SystemExit(__doc__)
ctx = D.Context(os.environ.get("TASK_ROOT", "/task"))
spec = D.load_spec(sys.argv[1])
for path in sys.argv[2:]:
rows = D.read_jsonl(path)
s = D.score(ctx, spec, [r["text"] for r in rows]); y = [int(r["label"]) for r in rows]
ba = D.balanced_accuracy(s, y, spec["threshold"]) if spec.get("threshold") is not None else float("nan")
print(json.dumps({"file": path, "n": len(rows), "pos": int(sum(y)), "auroc": round(D.auroc(s, y), 4), "balanced_acc": round(ba, 4)}))
J1_actions.jsonl
J1_baseline.json
J1_dense_refit.json
J1_reorder.jsonl
J1_reverse_cue.jsonl
J1_style.jsonl
J1_w1024_k24_single107.json
J1_w1024_k24_top8.json
J1_w1024_k8_single807.json
J1_w1024_k8_top8.json
J1_w256_k24_top8.json
J1_w256_k8_top8.json
J1_w512_k24_top8.json
J1_w512_k8_top8.json
J2_augmentation_train.jsonl
J2_baseline.json
J2_dense_refit.json
J2_factorial.jsonl
J2_grouped_comparison.json
J2_hostility_latents_334.json
J2_hostility_latents_334_382.json
J2_hostility_latents_382.json
J2_lexical_corrected.json
J2_lexical_prior_0.001.json
J2_lexical_prior_0.01.json
J2_lexical_prior_0.1.json
J2_lexical_prior_1.0.json
J2_lexical_prior_results.json
J2_pruned_results.json
J2_reorder.jsonl
J2_reverse_cue.jsonl
J2_robust_cv_results.json
J2_robust_ensemble03.json
J2_robust_joint03.json
J2_robust_resid_0_last_k0_l21.json
J2_robust_resid_0_last_k0_l210.json
J2_robust_resid_0_mean_k0_l21.json
J2_robust_resid_0_mean_k0_l210.json
J2_robust_resid_1_last_k0_l21.json
J2_robust_resid_1_last_k0_l210.json
J2_robust_resid_1_mean_k0_l21.json
J2_robust_resid_1_mean_k0_l210.json
J2_robust_resid_2_last_k0_l21.json
J2_robust_resid_2_last_k0_l210.json
J2_robust_resid_2_mean_k0_l21.json
J2_robust_resid_2_mean_k0_l210.json
J2_robust_resid_3_last_k0_l21.json
J2_robust_resid_3_last_k0_l210.json
J2_robust_resid_3_mean_k0_l21.json
J2_robust_resid_3_mean_k0_l210.json
J2_robust_resid_4_last_k0_l21.json
J2_robust_resid_4_last_k0_l210.json
J2_robust_resid_4_mean_k0_l21.json
J2_robust_resid_4_mean_k0_l210.json
J2_robust_sae_w1024_k24_max_k32_l21.json
J2_robust_sae_w1024_k24_max_k8_l21.json
J2_robust_sae_w1024_k24_mean_k32_l21.json
J2_robust_sae_w1024_k24_mean_k8_l21.json
J2_robust_sae_w1024_k8_max_k32_l21.json
J2_robust_sae_w1024_k8_max_k8_l21.json
J2_robust_sae_w1024_k8_mean_k32_l21.json
J2_robust_sae_w1024_k8_mean_k8_l21.json
J2_robust_sae_w256_k24_max_k32_l21.json
J2_robust_sae_w256_k24_max_k8_l21.json
J2_robust_sae_w256_k24_mean_k32_l21.json
J2_robust_sae_w256_k24_mean_k8_l21.json
J2_robust_sae_w256_k8_max_k32_l21.json
J2_robust_sae_w256_k8_max_k8_l21.json
J2_robust_sae_w256_k8_mean_k32_l21.json
J2_robust_sae_w256_k8_mean_k8_l21.json
J2_robust_sae_w512_k24_max_k32_l21.json
J2_robust_sae_w512_k24_max_k8_l21.json
J2_robust_sae_w512_k24_mean_k32_l21.json
J2_robust_sae_w512_k24_mean_k8_l21.json
J2_robust_sae_w512_k8_max_k32_l21.json
J2_robust_sae_w512_k8_max_k8_l21.json
J2_robust_sae_w512_k8_mean_k32_l21.json
J2_robust_sae_w512_k8_mean_k8_l21.json
J2_style.jsonl
J2_tone.jsonl
J2_w1024_k24_top8.json
J2_w1024_k8_top8.json
J2_w256_k24_top8.json
J2_w256_k8_top8.json
J2_w512_k24_top8.json
J2_w512_k8_top8.json
J3_baseline.json
J3_cv_uncertainty.json
J3_dense_refit.json
J3_reorder.jsonl
J3_representation_audit.json
J3_reverse_cue.jsonl
J3_style.jsonl
J3_urgency_masked.jsonl
J3_w1024_k24_top8.json
J3_w1024_k8_top8.json
J3_w256_k24_top8.json
J3_w256_k8_top8.json
J3_w512_k24_top8.json
J3_w512_k8_top8.json
challenge_provenance.json
challenge_results.json
cv_results.json
evaluator_check.json
final_evaluations.json
intervention_results.json
shift_results_initial.json
traffic_audit.json
step 24 · model
mkdir -p /workspace/submission/experiments/code
cp /workspace/{common,explore,sweep,shifts,eval_shifts,traffic_audit,augment,robust_sweep,dense_j2,lexcheck,lexcorrect,independent_challenges,challenge_eval,j3_audit,interventions,uncertainty,final_evaluation}.py /workspace/submission/experiments/code/
cat > /workspace/submission/summary.md <<'MD'
## Findings
**Adopt a carefully isolated SAE feature for J1, repair the dense detector for J2, and retain production for J3.** The team's development sweep is reproducible, but does not establish channel robustness. Sparsity, reconstruction fidelity, and a nameable activation are not substitutes for a job-specific shift test.
### Audit of the proposal and tools
I loaded the model and all six SAEs, recomputed features, and refit the production probes. On each job's `/task/data/<job>/dev.jsonl`, the refitted production scores and the supplied `/task/baselines/<job>.json` scores agree exactly. Full-development AUROC is **0.9981 / 0.9672 / 0.8876** for J1/J2/J3. These are training-set evaluations, **not** the CV numbers in NOTES.
`/task/tools/train_probe.py` selects its top-k features **before** its CV loop. Its `--cv` therefore leaks validation labels into feature selection. I implemented fold-local t-statistic selection, standardization, and fitting, using the same seed-0 five folds for every method. Importantly, the numbers in `/task/docs/NOTES.md` match my **correctly nested** implementation to their reported precision; the tool defect is not evidence that that particular table is false.
| Method, correctly nested CV on the original dev files | J1 | J2 | J3 |
|---|---:|---:|---:|
| Production recipe: residual layer 3, mean | .9689 | .8725 | .7712 |
| `w1024_k24`, top-8 max | 1.0000 | .8892 | .7070 |
| `w1024_k8`, top-8 max | 1.0000 | .8816 | .7919 |
| `w256_k24`, top-8 max | 1.0000 | .8825 | .6723 |
| `w256_k8`, top-8 max | 1.0000 | .8961 | .7821 |
| `w512_k24`, top-8 max | 1.0000 | .9059 | .7516 |
| `w512_k8`, top-8 max | 1.0000 | .9156 | .7870 |
For comparison, selecting on all labels before CV gives .9233 instead of .9156 for J2's proposed `w512_k8` probe, and .8044 instead of .7919 for J3's proposed `w1024_k8` probe. Results and all fold-selected indices are in `experiments/cv_results.json`.
I also checked reconstruction on **all** supplied requests in `/task/traffic/*.txt`, not just the config's training statistics. Token-centered FVU across the six channels is:
| SAE | Minimum–maximum measured channel FVU |
|---|---:|
| `w1024_k24` | .00131–.00192 |
| `w1024_k8` | .00499–.00702 |
| `w256_k24` | .00174–.00239 |
| `w256_k8` | .00549–.00727 |
| `w512_k24` | .00150–.00215 |
| `w512_k8` | .00570–.00792 |
These support generally good reconstruction, not uniformly correct latent interpretations or detectors. `experiments/traffic_audit.json` contains per-channel FVU, active-latent counts, selected-latent firing rates, and firing-token histograms, with each SAE and latent explicitly identified.
### J1: isolate the action feature, rather than deploy eight correlated features
In `/task/data/J1/dev.jsonl`, every positive contains one of the topic-specific data-movement/bypass action tokens and no negative contains one. Covert closings occur in 50 of the 70 positives and none of the 90 negatives. The latter is an attractive but unnecessary shortcut.
The proposed `w1024_k24` top-8 probe uses latents **[107, 572, 599, 605, 630, 656, 705, 844]**. Latent **107**, max-pooled, alone separates the dev classes. Its strongest traffic activations occur at a separator following the substantive body: it is a contextual action readout, not simply a keyword-position activation. Naming it a general policy-violation detector without interventions would be too strong.
The input interventions support a narrower, useful interpretation:
* Across 192 paired bodies from all six supplied channels and all eight vocabulary topics, inserting the corresponding action increases max activation of `w1024_k24:107` in every pair. Mean increase is **6.2312**, minimum **4.7174**. These pairs have a common ordinary footer.
* Replacing that footer by `quietly` changes this latent's max activation by **zero** in this audit, including the negative bodies.
* Moving the greeting/closing and reversing the order of body/urgency segments leaves the single-latent detector's AUROC at **1.0000**. The proposed eight-latent detector falls to **.9310** and production to **.8978**. On this same reorder test, individual positive-oriented latents 572, 630 and 705 have AUROCs **.5811, .5665 and .5372**, respectively: dev-equivalent features are not operationally equivalent.
`w1024_k8:807` is another single-latent candidate that passes these tests. I choose `w1024_k24:107`, the strongest original association, with no extra correlated latent weights. These tests establish robustness over the constructed interventions, not every possible policy meaning or unseen syntax.
### J2: a politeness shortcut masquerades as denoising
In `/task/data/J2/dev.jsonl`, `kindly` occurs in **68/80 positives versus 9/80 negatives**. That is not a semantic definition of hostile escalation. The proposed `w512_k8` probe uses **[225, 334, 348, 382, 412, 415, 455, 503]**.
A factorial intervention on independent traffic-derived bodies distinguishes these features. For `w512_k8:415`, the mean effect of inserting `kindly` is **+10.6159**, versus **+0.3700** for inserting two explicit hostile words. In contrast, latent **334** responds **+6.7270** to the hostility manipulation and **+0.8959** to `kindly`; latent **382** responds **+6.7488** and **+0.3697**, respectively. The selected probe mixes tone information with a large politeness shortcut. These are input-sensitivity measurements, not claims that these latents causally control the transformer's output.
Unlabelled traffic warns against transporting the dev correlation. As a descriptive lexical statistic—not an outcome label—`kindly` appears in **19.9%** of `app_q3` requests with any hostile-vocabulary token and **20.6%** without one. In `legacy_form` those fractions are **25.4%** and **54.2%**, respectively. The full six-channel counts are in `traffic_audit.json`. Unlabelled frequencies cannot establish hostile-escalation AUROC, but they do discredit treating `kindly` as an invariant hostile marker.
On the counterfactual dev-copy test that replaces positive `kindly` with `please` and inserts `kindly` in negatives, the proposal falls to **.4062**, versus **.7398** for production. Simply pruning to `w512_k8` latents **[334,382]** improves that to **.7772**, but is not sufficient. I also tried augmented top-8/top-32 SAE probes with mean and max pooling across all six SAEs; no general assumption that all SAE tone information is absent is warranted.
The shipped dense probe is fit on six label-preserving variants per dev request, balancing `kindly` independently of the label and varying greetings/closings. It combines **mean residuals at layers 0 and 3**. Validation holds out entire original-request families, not individual augmented rows:
| Five-fold parent-held-out evaluation | Original text | Reversed `kindly` cue | Changed wrapper |
|---|---:|---:|---:|
| Production recipe, trained on original fold | .8725 | .5663 | .8466 |
| Proposed `w512_k8` top-8, fold-local selection | .9156 | .3278 | .9142 |
| Shipped dense recipe, augmented training fold | **.8631** | **.8784** | **.8508** |
This explicitly trades some app-channel advantage for much less dependence on the bad cue. The final fitted detector's nearly perfect dev/edited-dev numbers below are **not** estimates of generalization; the grouped CV values are the more honest comparison. Even those values have model-selection optimism because I compared multiple recipes.
On separately constructed, clear-tone requests using previously unlabelled traffic bodies, the shipped detector gets **.9807**, versus **.6858** for production and **.8461** for the proposal. These deliberately unambiguous examples omit the difficult one-hostile-word boundary. A hand-built, position-corrected lexical dense prior even gets **1.0000** here, but only **.8838** on dev; I did not deploy it. A benchmark generated around explicit insulting words can flatter precisely that prior. The shipped recipe instead uses the human labels and does not train on these synthetic challenge labels.
### J3: insufficient independent metadata evidence to replace production
The proposed `w1024_k8` top-8 indices are **[161, 363, 452, 472, 549, 726, 773, 1000]**. In the traffic audit, **363, 452, 472 and 773** fire strongly on urgency words such as `deadline`, `stuck`, `critical`, and `escalate`. Their pairwise dev activation correlations are **.9871–.9994**: four latent weights are not four independent corroborating concepts. Urgency-token count alone has dev AUROC **.6899**. Neither urgency nor a compelling latent name reveals an operations metadata label.
The correctly nested seed-0 gain over production is **.0207**. A paired, class-stratified bootstrap of those fixed out-of-fold predictions gives a 95% difference interval **[-.0299, +.0716]**; this excludes training/model-selection uncertainty and is not a channel-generalization interval. Across ten fold seeds, mean CV is **.7727** for production and **.7966** for the proposal. Thus the sparse candidate is genuinely promising on this channel; I am not dismissing its improvement as a numerical error. A layer-0 mean dense alternative also averages **.8051**, illustrating that sparsity is not the only plausible improvement.
Nor does the reconstruction audit show that SAE encoding has simply destroyed the priority information. At layer 2, raw-mean CV is **.7803**, versus **.7804** after `w1024_k24` reconstruction and **.7898** after `w1024_k8` reconstruction. The sparse selection, pooling and small-sample estimation all matter. Details are in `J3_representation_audit.json`.
There are **no independent labelled ticket outcomes** for another channel. Edited versions of the same ticket text can test a conditional invariance assumption, not supply new outcome observations. I retain production pending linked channel-level ticket metadata rather than certify either sparse or dense replacement from this evidence.
## Decision
| Job | Adopt SAE? | Shipped detector | Full-dev AUROC | Production full-dev AUROC |
|---|---|---|---:|---:|
| J1 | **Yes** | `w1024_k24`, latent **107**, max; one fitted coefficient | **1.0000** | .9981 |
| J2 | **No** | Dense mean residuals **layers 0 + 3**, augmented supervised training | **.9975** | .9672 |
| J3 | **No** | **Unchanged** production layer-3 mean dense probe | **.8876** | .8876 |
The artifacts actually shipped are `detectors/J1.json`, `detectors/J2.json`, and `detectors/J3.json`. J3 is a byte-for-byte copy of `/task/baselines/J3.json`. `answer.json` contains unrounded, directly recomputed metrics and references to all reported evaluation files and principal alternatives.
Selected shift measurements (full-dev-trained detectors; **edited-dev tests retain training-request identities**):
| Job / file under `experiments/` | Shipped | Production | Team's proposed SAE |
|---|---:|---:|---:|
| J1 `J1_reverse_cue.jsonl` | 1.0000 | .8163 | 1.0000 |
| J1 `J1_reorder.jsonl` | 1.0000 | .8978 | .9310 |
| J1 `J1_actions.jsonl` — traffic-derived pairs | 1.0000 | .8197 | 1.0000 |
| J2 `J2_reverse_cue.jsonl` | .9994 | .7398 | .4062 |
| J2 `J2_tone.jsonl` — traffic-derived pairs | .9807 | .6858 | .8461 |
| J2 `J2_factorial.jsonl` — same bodies, crossed cues | .9819 | .8091 | .9308 |
| J3 `J3_style.jsonl` | .8858 | .8858 | .8238 |
| J3 `J3_reorder.jsonl` | .8620 | .8620 | .8101 |
| J3 `J3_urgency_masked.jsonl` | .8614 | .8614 | .7819 |
“Team's proposed SAE” means the fully fitted top-8 `w1024_k24`, `w512_k8`, and `w1024_k8` probes for J1, J2, and J3 respectively, with the indices identified above.
I would deploy the J1/J2 **ranking scores**, monitor their paired disagreement with production by channel, and obtain fresh labelled audits before fixing channel operating points. New detectors deliberately omit the optional threshold: neither operational error costs nor held-out prevalence were supplied, and AUROC does not determine a threshold. J3's existing threshold is preserved. No accuracy, calibration, or unknown-channel AUROC is claimed here.
## How I computed this
### Feature extraction, fitting and validation
* Used `/task/model/model.py`, `/task/saes/sae_lib.py`, and `/task/tools/detector_lib.py` with two torch threads. All SAE configs specify **residual layer 2**; this is distinct from the production probes' layer 3. Aggregation excludes leading `<bos>` and includes `<eos>`, exactly as the serving evaluator does. No implicit token insertion or alternative pooling definition was used.
* Recomputed all three production scores directly. Checked rank AUROC against pairwise comparison, including ties. The sweep's folds are `torch.randperm(n, seed=0)[i::5]`, not stratified folds. Within each fold, select top absolute t-statistics on training examples only, estimate training mean/std, and fit L2 logistic regression with `detector_lib.fit_logreg`. Full-data fits are separate from out-of-fold estimates.
* The J1 final one-feature fit uses the original J1 dev labels and L2=1. The feature was chosen using the inspection and intervention program, so the later shift tests are development evidence, not a pristine preregistered confirmatory trial.
* The J2 final fit uses `J2_augmentation_train.jsonl`: **960 rows**, six variants of each original J2 row. Three variants lack `kindly` and three contain it, regardless of class. Four variants also have resampled wrappers. All hostile and substantive body tokens are retained. Mean/std and the logistic weights are fit on the augmented data. L2=6 compensates for the sixfold replication: the penalty coefficient is 6/960, equal to the original recipe's 1/160. The grouped validation never trains on another variant of a held-out parent. The traffic-derived synthetic challenges were **not** training data.
* J3 uncertainty uses ten five-fold seeds, with selection repeated inside every fold. The bootstrap resamples positive and negative original requests separately, 5,000 times, pairing the two models' fixed seed-0 out-of-fold predictions.
* Channel FVU is `sum(||x-decode(encode(x))||²) / sum(||x-channel_token_mean||²)`, over all non-BOS real positions. It is neither the config's training FVU nor an uncentered error. All six channel files contain 3,000 requests and all were used.
### Constructed labels and their limitations
All submitted labelled files contain only in-vocabulary tokens, explicit boundary tokens, at most 48 tokens per request, both classes, and at least 40 rows. The construction programs and `challenge_provenance.json` specify the source requests.
* **`J1/J2/J3_style.jsonl`**: respectively 160/160/200 rows, copied from each job's dev set with informal greetings and ordinary closings substituted. The substantive body and urgency content are unchanged; original labels are retained. J1 covert closings are intentionally removed.
* **`J1_reverse_cue.jsonl`**: 160 dev-derived rows. Ordinary footer for positives; covert footer for negatives; body/action unchanged. The policy judgement follows the actual requested action, not the choice of closing.
* **`J2_reverse_cue.jsonl`**: 160 dev-derived rows. Replace `kindly` with `please`, then insert `kindly` into negatives. The label remains the human judgement of the same hostile/non-hostile request. A politeness marker alone is not treated as a class-changing action.
* **`J3_reverse_cue.jsonl`**: despite the common filename, this is **not** a reversed priority label or invented priority proxy. It is a second, formal-wrapper rendering of the same 200 tickets, with their known labels retained.
* **`J1/J2/J3_reorder.jsonl`**: respectively 160/160/200 dev-derived rows. Swap greeting and closing, and reverse the sequence of interior segments (body versus urgency), retaining token order inside each segment. This deliberately probes sensitivity to request layout.
* **`J3_urgency_masked.jsonl`**: 200 dev-derived rows. Remove segments consisting entirely of urgency words; retain the original ticket label. This tests the conditional proposition “same underlying ticket, urgency decoration omitted,” **not** that changing text would leave a future operations decision unchanged in reality. No J3 label was inferred from unlabelled traffic, model predictions, or urgency words. All J3 shift evidence is limited by this same-ticket assumption and dependence on existing dev identities.
* **`J1_actions.jsonl`**: 384 rows, 192 positive. Start with four neutral bodies per topic per channel, from all six `/task/traffic/<channel>.txt` files. Bodies have no action, covert, or hostile tokens. Each has a negative version and a positive version with one corresponding action inserted, while a footer is sampled independently. The action pairs are **offsite/mirror; reroute/divert; forward/duplicate; sideload/clone; tunnel/relay; export/dump; extract/siphon; bypass/delegate**, associated with the eight contiguous topic vocabularies in `/task/model/vocab.json`. These are controlled policy-action labels based on the job definition and checked against the perfect action/label agreement in J1 dev—not asserted human annotations of arbitrary real traffic. Their policy interpretation is specific to this fixture's requests; it need not hold for every ordinary-language use of those words.
* **`J2_tone.jsonl`**: 384 rows, 192 positive, from those neutral traffic bodies. A neutral version with `kindly` is labelled 0; a version with two explicit insulting/escalating words and without `kindly` is labelled 1. This is my controlled tone annotation under `/task/docs/jobs.md`, not a retrieved traffic label. The script lists the insulting vocabulary. Single-word ambiguous examples are deliberately not newly labelled.
* **`J2_factorial.jsonl`**: 768 rows, 384 positive. Cross absent/present `kindly` with those same neutral/hostile bodies, independently of label. Labels follow the controlled tone intervention. Rows sharing a body are dependent; these are not 768 independent tickets.
The synthetic challenges reuse realistic channel bodies but cover only the interventions described. Their success cannot establish performance on the grader's unknown channels. Selection on this experimental suite also limits unbiased performance claims. In particular, **independent cross-channel J3 metadata evidence is unavailable**, not implicitly replaced by text-derived pseudo-labels.
### Reproduction artifacts
`experiments/code/` contains the exact scripts used, including `sweep.py`, `shifts.py`, `augment.py`, `robust_sweep.py`, `dense_j2.py`, `traffic_audit.py`, `independent_challenges.py`, `interventions.py`, `j3_audit.py`, `uncertainty.py`, and `final_evaluation.py`. They read `/task` and use `/workspace` for intermediate caches; `common.py` supplies shared fitting routines. `explore.py` creates the initial dev feature caches, and `eval_shifts.py` creates the edited-dev caches. These intermediate tensors are not required to serve any submitted detector.
Primary machine-readable records are `cv_results.json`, `J2_grouped_comparison.json`, `J2_robust_cv_results.json`, `traffic_audit.json`, `intervention_results.json`, `J3_representation_audit.json`, `J3_cv_uncertainty.json`, and `final_evaluations.json`, all under `experiments/`. `answer.json` references the deployable specs and actual labelled evaluation files, not cached predictions. For example:
```bash
TASK_ROOT=/task python3 /task/tools/eval_detector.py \
/workspace/submission/detectors/J2.json \
/task/data/J2/dev.jsonl \
/workspace/submission/experiments/J2_tone.jsonl
```
MDstep 24 · tool output (exit 0)
step 25 · model
cat > /workspace/submission/experiments/code/validate_submission.py <<'PY'
import sys,os,json,torch,hashlib,math
sys.path.insert(0,'/task/tools');import detector_lib as D
torch.set_num_threads(2);root='/workspace/submission/';ctx=D.Context('/task');vocab=set(ctx.model['vocab']);a=json.load(open(root+'answer.json'));report={'files':{},'metrics_checked':0,'by_channel':{}}
# Validate every submitted labelled file, including augmentation rows not used for evaluation.
for fn in os.listdir(root+'experiments'):
if not fn.endswith('.jsonl'):continue
rows=D.read_jsonl(root+'experiments/'+fn);assert len(rows)>=40;assert set(r['label'] for r in rows)=={0,1}
for r in rows:
t=r['text'].split();assert len(t)<=48 and set(t)<=vocab;assert t[0]=='<bos>' and t[-1]=='<eos>'
report['files'][fn]={'rows':len(rows),'positive':sum(r['label'] for r in rows),'max_tokens':max(len(r['text'].split()) for r in rows)}
# Schema, dimensions, finite values, file references.
refs=[]
for j,d in a['jobs'].items():
sp=json.load(open(root+'detectors/'+j+'.json'));types=set(f['type'] for f in sp['features']);assert d['detector_kind']==('hybrid' if len(types)>1 else 'sae' if 'sae' in types else 'dense');assert d['adopt_sae']==('sae' in types)
for ev in d['shift_evidence']:refs.append((ev['detector'],ev['file'],ev['auroc']))
rows=D.read_jsonl('/task/data/'+j+'/dev.jsonl');texts=[r['text'] for r in rows];y=[r['label'] for r in rows];h=ctx.hidden(texts)
for fn,metric in [('detectors/'+j+'.json',d['dev_auroc']),('experiments/'+j+'_baseline.json',d['baseline_dev_auroc'])]:
ss=json.load(open(root+fn));auc=D.auroc(D.score(ctx,ss,texts,h),y);assert abs(auc-metric)<1e-6;report['metrics_checked']+=1
for e in a['experiments']:
assert os.path.isfile(root+e['detector'])
for ev in e['evals']:refs.append((e['detector'],ev['file'],ev['auroc']))
for spname in set(fn for fn,_,_ in refs):
sp=json.load(open(root+spname));dim=sum(ctx.model['cfg']['d_model'] if f['type']=='resid' else ctx.sae(f['sae'])['cfg']['width'] if f['latents']=='all' else len(f['latents']) for f in sp['features']);assert len(sp['w'])==dim;assert all(math.isfinite(v) for v in sp['w']);assert math.isfinite(sp['b'])
if sp.get('mean') is not None:assert len(sp['mean'])==dim==len(sp['std']) and all(s>0 and math.isfinite(s) for s in sp['std'])
assert os.path.isfile(root+spname)
for f in set(fn for _,fn,_ in refs):
assert os.path.isfile(root+f)
rows=D.read_jsonl(root+f);txt=[r['text'] for r in rows];ys=[r['label'] for r in rows];hh=ctx.hidden(txt)
for spname,ff,reported in set(refs):
if ff!=f:continue
auc=D.auroc(D.score(ctx,json.load(open(root+spname)),txt,hh),ys);assert abs(auc-reported)<1e-6,(spname,f,auc,reported);report['metrics_checked']+=1
# Per-channel audit of the paired traffic-body challenge, using stored construction provenance.
prov=json.load(open(root+'experiments/challenge_provenance.json'))
for j,name,sid in [('J1','J1_actions','w1024_k24'),('J2','J2_tone','w512_k8')]:
rows=D.read_jsonl(root+'experiments/'+name+'.jsonl');pr=[r for r in prov if r['set']==name];assert len(pr)==len(rows);report['by_channel'][j]={}
for ch in sorted(set(p['channel'] for p in pr)):
rr=[r for r,p in zip(rows,pr) if p['channel']==ch];txt=[r['text'] for r in rr];yy=[r['label'] for r in rr];hh=ctx.hidden(txt);res={}
for n,spname in [('shipped','detectors/'+j+'.json'),('baseline','experiments/'+j+'_baseline.json'),('proposed','experiments/'+j+'_'+sid+'_top8.json')]:res[n]=D.auroc(D.score(ctx,json.load(open(root+spname)),txt,hh),yy)
report['by_channel'][j][ch]=res
assert open('/task/baselines/J3.json','rb').read()==open(root+'detectors/J3.json','rb').read()
report['J3_baseline_identical']=True
json.dump(report,open(root+'experiments/validation_report.json','w'),indent=2)
print(json.dumps(report['by_channel'],indent=2));print('PASS',report['metrics_checked'],'metric checks')
PY
python3 /workspace/submission/experiments/code/validate_submission.pystep 25 · tool output (exit 0)
{ "J1": { "api_batch": { "shipped": 1.0, "baseline": 0.8740234375, "proposed": 1.0 }, "app_q3": { "shipped": 1.0, "b…
{
"J1": {
"api_batch": {
"shipped": 1.0,
"baseline": 0.8740234375,
"proposed": 1.0
},
"app_q3": {
"shipped": 1.0,
"baseline": 0.9091796875,
"proposed": 1.0
},
"legacy_form": {
"shipped": 1.0,
"baseline": 0.744140625,
"proposed": 1.0
},
"partner_feed": {
"shipped": 1.0,
"baseline": 0.7685546875,
"proposed": 1.0
},
"region_eu": {
"shipped": 1.0,
"baseline": 0.826171875,
"proposed": 1.0
},
"web_q3": {
"shipped": 1.0,
"baseline": 0.845703125,
"proposed": 1.0
}
},
"J2": {
"api_batch": {
"shipped": 0.9521484375,
"baseline": 0.654296875,
"proposed": 0.7841796875
},
"app_q3": {
"shipped": 0.994140625,
"baseline": 0.7275390625,
"proposed": 0.9033203125
},
"legacy_form": {
"shipped": 0.9990234375,
"baseline": 0.712890625,
"proposed": 0.8388671875
},
"partner_feed": {
"shipped": 0.99609375,
"baseline": 0.7021484375,
"proposed": 0.8349609375
},
"region_eu": {
"shipped": 0.982421875,
"baseline": 0.71484375,
"proposed": 0.875
},
"web_q3": {
"shipped": 0.9833984375,
"baseline": 0.6240234375,
"proposed": 0.8408203125
}
}
}
PASS 176 metric checks
step 26 · model
python3 - <<'PY'
p='/workspace/submission/summary.md'
s=open(p).read().replace('**`J1/J2/J3_style.jsonl`**','**`J1_style.jsonl`, `J2_style.jsonl`, `J3_style.jsonl`**').replace('**`J1/J2/J3_reorder.jsonl`**','**`J1_reorder.jsonl`, `J2_reorder.jsonl`, `J3_reorder.jsonl`**')
s=s.replace('These deliberately unambiguous examples omit the difficult one-hostile-word boundary.', 'Within each of the six source-channel strata, the shipped score also beats production and the proposal; its stratum AUROCs range from **.9521 to .9990** (`experiments/validation_report.json`, 64 constructed rows per stratum). These deliberately unambiguous examples omit the difficult one-hostile-word boundary.')
s=s.replace('No accuracy, calibration, or unknown-channel AUROC is claimed here.', 'No accuracy, calibration, or unknown-channel AUROC is claimed here. A one-weight SAE probe still requires the full TopK encoder to compute its feature; I have not certified serving latency or claimed a speedup.')
open(p,'w').write(s)
PY
cat > /workspace/submission/experiments/code/pruned_j2.py <<'PY'
from common import *
c=torch.load('/workspace/J2_cache.pt',weights_only=False);out={}
for ix in [[334],[382],[334,382]]:
key='sae:w512_k8:max';f=fit(c['X'][key][:,ix],c['y']);sp=spec(key,ix,f);name='J2_hostility_latents_'+'_'.join(map(str,ix));json.dump(sp,open('/workspace/submission/experiments/'+name+'.json','w'));vals={}
for n in ['J2','J2_reverse_cue','J2_style','J2_reorder','J2_tone']:
x=torch.load('/workspace/'+n+'_cache.pt',weights_only=False);vals[n]=D.auroc(score(x['X'][key][:,ix],f),x['y'])
out[name]=vals
json.dump(out,open('/workspace/submission/experiments/J2_pruned_results.json','w'),indent=2)
PY
cat > /workspace/submission/experiments/code/reproduce.sh <<'SH'
#!/bin/bash
# Run inside the provided sandbox; all scratch caches are written under /workspace.
# This re-runs the exploratory development sequence, then recreates the final metrics.
set -euo pipefail
export TASK_ROOT=/task OMP_NUM_THREADS=2 OPENBLAS_NUM_THREADS=2 PYTHONDONTWRITEBYTECODE=1
cd /workspace/submission/experiments/code
for p in explore sweep shifts eval_shifts traffic_audit augment robust_sweep dense_j2 lexcheck lexcorrect independent_challenges challenge_eval pruned_j2 j3_audit interventions uncertainty; do
python3 "$p.py"
done
cp /workspace/submission/experiments/J1_w1024_k24_single107.json /workspace/submission/detectors/J1.json
cp /workspace/submission/experiments/J2_robust_joint03.json /workspace/submission/detectors/J2.json
cp /task/baselines/J3.json /workspace/submission/detectors/J3.json
for j in J1 J2 J3; do cp /task/baselines/$j.json /workspace/submission/experiments/${j}_baseline.json; done
python3 final_evaluation.py
python3 validate_submission.py
SH
chmod +x /workspace/submission/experiments/code/reproduce.sh
python3 - <<'PY'
import json,hashlib,os
r='/workspace/submission';m={}
for dp,ds,fs in os.walk(r):
for f in fs:
p=os.path.join(dp,f)
if f=='sha256.json':continue
m[os.path.relpath(p,r)]=hashlib.sha256(open(p,'rb').read()).hexdigest()
json.dump(m,open(r+'/experiments/sha256.json','w'),indent=2)
a=json.load(open(r+'/answer.json')); print({j:{k:v for k,v in d.items() if k in ['adopt_sae','detector_kind','dev_auroc','baseline_dev_auroc']} for j,d in a['jobs'].items()});print('experiments',len(a['experiments']))
PYstep 26 · tool output (exit 0)
{'J1': {'adopt_sae': True, 'detector_kind': 'sae', 'dev_auroc': 1.0, 'baseline_dev_auroc': 0.9980952143669128}, 'J2': {'adopt_sae': False, 'detector_kind': 'den…
{'J1': {'adopt_sae': True, 'detector_kind': 'sae', 'dev_auroc': 1.0, 'baseline_dev_auroc': 0.9980952143669128}, 'J2': {'adopt_sae': False, 'detector_kind': 'dense', 'dev_auroc': 0.9975000023841858, 'baseline_dev_auroc': 0.9671875238418579}, 'J3': {'adopt_sae': False, 'detector_kind': 'dense', 'dev_auroc': 0.8876000046730042, 'baseline_dev_auroc': 0.8876000046730042}}
experiments 35
step 27 · model
python3 - <<'PY'
import json
r='/workspace/submission';p=json.load(open(r+'/experiments/challenge_provenance.json'))
for j,name in [('J1','J1_actions'),('J2','J2_tone')]:
dev={json.loads(x)['text'] for x in open('/task/data/'+j+'/dev.jsonl')};sources={x['source'] for x in p if x['set']==name};print(j,'exact source/dev overlap',len(dev&sources))
print('required sections:')
s=open(r+'/summary.md').read()
for k in ['## Findings','## Decision','## How I computed this']:print(k,k in s)
PYstep 27 · tool output (exit 0)
J1 exact source/dev overlap 0 J2 exact source/dev overlap 0 required sections: ## Findings True ## Decision True ## How I computed this True
J1 exact source/dev overlap 0 J2 exact source/dev overlap 0 required sections: ## Findings True ## Decision True ## How I computed this True
step 28 · model
[finish] Completed all deliverables under /workspace/submission and independently validated 176 reported metric checks. Adopt SAE w1024_k24 latent 107 alone for J1: it passes action, footer, and layout interventions, unlike some correlated top-8 features. Reject the SAE proposal for J2 and ship a dense layer-0/layer-3 mean probe trained with label-preserving, cue-balanced augmentation; grouped validation and traffic-derived challenges expose and reduce the original kindly shortcut. Retain J3's production detector byte-for-byte because the modest sparse-probe CV advantage lacks independent cross-channel ticket-metadata validation. answer.json contains measured AUROCs and reproducible shift-evidence references; summary.md explains construction assumptions, uncertainty, selection leakage in the shipped training tool, and why synthetic evaluations do not certify unknown-channel performance. Reproduction scripts, alternative specs, labelled challenge files, and audit results are included.
Agent's final summary.
Completed all deliverables under /workspace/submission and independently validated 176 reported metric checks. Adopt SAE w1024_k24 latent 107 alone for J1: it passes action, footer, and layout interventions, unlike some correlated top-8 features. Reject the SAE proposal for J2 and ship a dense layer-0/layer-3 mean probe trained with label-preserving, cue-balanced augmentation; grouped validation and traffic-derived challenges expose and reduce the original kindly shortcut. Retain J3's production detector byte-for-byte because the modest sparse-probe CV advantage lacks independent cross-channel ticket-metadata validation. answer.json contains measured AUROCs and reproducible shift-evidence references; summary.md explains construction assumptions, uncertainty, selection leakage in the shipped training tool, and why synthetic evaluations do not certify unknown-channel performance. Reproduction scripts, alternative specs, labelled challenge files, and audit results are included.
Generated 2026-11-10 19:24 UTC from /shared/allie/rsi-build-20261110. Papers in the task titles are the source material; every fixture is a fresh synthetic replay.