Traust Metrics
Paths. analysis-results/… and progress-tracker/… in this skill are the
default workspace layout. They resolve through locations.yaml in
$TRAUST_CONFIG_HOME (docs/setup.md, Storage locations); substitute your
configured roots.
Maintain one Markdown scoreboard — progress-tracker/metrics/traust-metrics.md —
holding every number the team quotes in leadership decks and
status reports, so those numbers are regenerated from the pipeline's own
artifacts instead of being copied around and going stale.
The skill never authors a metric. collect_harness_metrics.py parses each value
from a generated artifact (or counts it from the harness tree) and cites the
source next to it; anything it cannot find renders as "—" and is flagged in
the data-freshness table. Narrative claims no artifact can compute live in a
manual block that survives regeneration.
Input
$ARGUMENTS is optional and may be any combination of:
| Token |
Meaning |
--workspace-root <dir> |
Parent workspace holding the sibling repos (default: the harness checkout's parent) |
--out <file> |
Output path (default: progress-tracker/metrics/traust-metrics.md) |
--refresh-sources |
Before collecting, rebuild stale upstream artifacts (see step 2). Skill-level token — interpreted by the agent running this skill, NOT an argparse flag on the collector script |
Procedure
Run the collector:
python3 traust/harnessing/traust-metrics/scripts/collect_harness_metrics.py
It writes the scoreboard and exits non-zero if any source artifact is
missing (the file is still written, with the gaps flagged).
Check the Data freshness table in the output. Each source row shows the
artifact's own Generated: date. If a source is missing, or older than the
latest audit activity and the user asked for --refresh-sources (or asks
for current numbers), rebuild it with the owning skill first, then rerun
the collector:
The collector reads eleven sources (this table mirrors its sources
dict — keep them in sync; docs-verification 2026-07-31 found it
documenting 4 of 11):
| Stale source |
Rebuild with |
progress-tracker/metrics/dashboards/Executive-summary-findings.metrics.json (machine sidecar; the .md is the human companion) |
/executive-summary-findings |
progress-tracker/metrics/dashboards/census/census.json |
/census |
progress-tracker/metrics/dashboards/insecure-patterns/insecure-patterns.json |
/insecure-patterns |
progress-tracker/metrics/dashboards/benchmark/benchmark.json |
/recall-benchmark (a full benchmark run — never rebuild casually; report staleness) |
progress-tracker/metrics/dashboards/trends/trends.json |
/findings-trends |
progress-tracker/metrics/dashboards/Live-validation-fuzz-dashboard.md |
/validation-fuzz-dashboard |
fuzz campaign sidecar (fuzz-campaign.json, beside the validation dashboard) |
/validation-fuzz-dashboard |
progress-tracker/metrics/dashboards/threat-register/threat-register.md |
/threat-register |
progress-tracker/tracking/opened-tickets.md |
human-curated by the filing flow (/file-security-defect reporting) — report staleness, never rebuild |
cloud-config lane (findings.db) |
/census (findings-db projection) |
| harness repo tree/git metadata |
nothing to rebuild — read live |
When several sources are stale at once, prefer the full chain over
per-artifact rebuilds: /refresh-dashboards
(python3 -m traust.cli dashboard refresh) rebuilds every deterministic
dashboard in dependency order and runs this collector last.
Report back. Read the generated file and give the user the headline
numbers grouped as the file groups them (scale, impact, validation,
delivery, maturity), calling out: any MISSING sources, any source whose
Generated: date is more than ~a week old, and any metric that moved
sharply since the previous version of the file (use git -C progress-tracker diff traust-metrics.md when the file is tracked).
Manual block (optional). A hand-added <!-- MANUAL:BEGIN/END --> block is
preserved verbatim across runs. If the user supplies narrative claims
(cost comparisons, remediation stories, the ask), edit them inside that
block only — never hand-edit generated rows; fix the upstream artifact
instead.
Metrics history — the append-only improvement ledger
Every run (unless --no-history) appends one immutable snapshot row to
progress-tracker/metrics/metrics-history.jsonl and re-renders
metrics/metrics-history.md — a metrics × snapshots table with per-snapshot
notes. This is the campaign's as-reported record: prior rows are NEVER
revised, so the original raw numbers (e.g. the 2026-07-14 pre-triage baseline)
survive every counting-policy change, and methodology shifts appear as
explained steps (via --note "...") instead of silent rewrites. This matters
because every other view rewrites history by design: regenerated dashboards
overwrite in place, and findings-trends replays by occurred_at, so late
event ingestion (e.g. a ledger backfill) retroactively changes past buckets.
Pass --note with one line of context whenever a run follows a methodology
or pipeline change. Never hand-edit or prune the JSONL.
Output
progress-tracker/metrics/traust-metrics.md — sections: Scale & coverage ·
Findings & impact · Empirical validation · Delivery & adoption · Platform
maturity & reliability · optional manual block (preserved if present) · Data freshness.
Notes
- Deterministic at metric time: like the dashboards, this skill only
replays already-derived artifacts — no model call participates in producing
a number, so reruns are reproducible and diffs are meaningful.
- The maturity metrics (version, commits, releases, LoC, test count) are
counted live from the harness checkout, so they are correct even when no
campaign artifact has been rebuilt recently.
- Severity counts quote the executive summary's totals (occurrences) and note
unique counts alongside, matching how that report itself leads.
Spend metrics (separate dashboard, not harvested here)
The collector does not read spend data and the scoreboard carries
no spend section — spend lives in its own dashboard
(progress-tracker/metrics/dashboards/spend/, rebuilt by
python3 -m traust.cli metrics spend, stage 14 of /refresh-dashboards).
An earlier revision of this skill claimed the scoreboard harvested
model-spend:* ledger rows; no such code ever existed
(docs-verification 2026-07-31, wiring c5). When reporting scoreboard
numbers, point spend questions at the spend dashboard; treat a
7-day-old spend dashboard as stale and rebuild via
/refresh-dashboards. Real-time view and the full tracking chain live in your
deployment's private configuration repository, if it keeps one.
1---2name: traust-metrics3description: Use when the user asks for campaign metrics, a leadership scoreboard, or to (re)build/refresh progress-tracker/metrics/traust-metrics.md. Deterministically harvests headline numbers from the campaign's derived artifacts (executive summary, validation/fuzz dashboard, threat register, progress-tracker control files) and the harness's own tree/git metadata into one consistently-updatable Markdown scoreboard.4---56# Traust Metrics78> **Paths.** `analysis-results/…` and `progress-tracker/…` in this skill are the9> default workspace layout. They resolve through `locations.yaml` in10> `$TRAUST_CONFIG_HOME` (`docs/setup.md`, Storage locations); substitute your11> configured roots.121314Maintain one Markdown scoreboard — `progress-tracker/metrics/traust-metrics.md` —15holding every number the team quotes in leadership decks and16status reports, so those numbers are regenerated from the pipeline's own17artifacts instead of being copied around and going stale.1819The skill never authors a metric. `collect_harness_metrics.py` parses each value20from a generated artifact (or counts it from the harness tree) and cites the21source next to it; anything it cannot find renders as "—" and is flagged in22the data-freshness table. Narrative claims no artifact can compute live in a23manual block that survives regeneration.2425## Input2627`$ARGUMENTS` is optional and may be any combination of:2829| Token | Meaning |30|---|---|31| `--workspace-root <dir>` | Parent workspace holding the sibling repos (default: the harness checkout's parent) |32| `--out <file>` | Output path (default: `progress-tracker/metrics/traust-metrics.md`) |33| `--refresh-sources` | Before collecting, rebuild stale upstream artifacts (see step 2). Skill-level token — interpreted by the agent running this skill, NOT an argparse flag on the collector script |3435## Procedure36371. **Run the collector:**3839 ```bash40 python3 traust/harnessing/traust-metrics/scripts/collect_harness_metrics.py41 ```4243 It writes the scoreboard and exits non-zero if any source artifact is44 missing (the file is still written, with the gaps flagged).45462. **Check the Data freshness table** in the output. Each source row shows the47 artifact's own `Generated:` date. If a source is missing, or older than the48 latest audit activity and the user asked for `--refresh-sources` (or asks49 for current numbers), rebuild it with the owning skill first, then rerun50 the collector:5152 The collector reads eleven sources (this table mirrors its `sources`53 dict — keep them in sync; docs-verification 2026-07-31 found it54 documenting 4 of 11):5556 | Stale source | Rebuild with |57 |---|---|58 | `progress-tracker/metrics/dashboards/Executive-summary-findings.metrics.json` (machine sidecar; the `.md` is the human companion) | `/executive-summary-findings` |59 | `progress-tracker/metrics/dashboards/census/census.json` | `/census` |60 | `progress-tracker/metrics/dashboards/insecure-patterns/insecure-patterns.json` | `/insecure-patterns` |61 | `progress-tracker/metrics/dashboards/benchmark/benchmark.json` | `/recall-benchmark` (a full benchmark run — never rebuild casually; report staleness) |62 | `progress-tracker/metrics/dashboards/trends/trends.json` | `/findings-trends` |63 | `progress-tracker/metrics/dashboards/Live-validation-fuzz-dashboard.md` | `/validation-fuzz-dashboard` |64 | fuzz campaign sidecar (`fuzz-campaign.json`, beside the validation dashboard) | `/validation-fuzz-dashboard` |65 | `progress-tracker/metrics/dashboards/threat-register/threat-register.md` | `/threat-register` |66 | `progress-tracker/tracking/opened-tickets.md` | human-curated by the filing flow (`/file-security-defect` reporting) — report staleness, never rebuild |67 | cloud-config lane (`findings.db`) | `/census` (findings-db projection) |68 | harness repo tree/git metadata | nothing to rebuild — read live |6970 When several sources are stale at once, prefer the full chain over71 per-artifact rebuilds: `/refresh-dashboards`72 (python3 -m traust.cli dashboard refresh) rebuilds every deterministic73 dashboard in dependency order and runs this collector last.74753. **Report back.** Read the generated file and give the user the headline76 numbers grouped as the file groups them (scale, impact, validation,77 delivery, maturity), calling out: any **MISSING** sources, any source whose78 `Generated:` date is more than ~a week old, and any metric that moved79 sharply since the previous version of the file (use `git -C80 progress-tracker diff traust-metrics.md` when the file is tracked).81824. **Manual block (optional).** A hand-added `<!-- MANUAL:BEGIN/END -->` block is83 preserved verbatim across runs. If the user supplies narrative claims84 (cost comparisons, remediation stories, the ask), edit them **inside that85 block only** — never hand-edit generated rows; fix the upstream artifact86 instead.8788## Metrics history — the append-only improvement ledger8990Every run (unless `--no-history`) appends one immutable snapshot row to91`progress-tracker/metrics/metrics-history.jsonl` and re-renders92`metrics/metrics-history.md` — a metrics × snapshots table with per-snapshot93notes. This is the campaign's **as-reported record**: prior rows are NEVER94revised, so the original raw numbers (e.g. the 2026-07-14 pre-triage baseline)95survive every counting-policy change, and methodology shifts appear as96explained steps (via `--note "..."`) instead of silent rewrites. This matters97because every other view rewrites history by design: regenerated dashboards98overwrite in place, and findings-trends replays by `occurred_at`, so late99event ingestion (e.g. a ledger backfill) retroactively changes past buckets.100Pass `--note` with one line of context whenever a run follows a methodology101or pipeline change. Never hand-edit or prune the JSONL.102103## Output104105`progress-tracker/metrics/traust-metrics.md` — sections: Scale & coverage ·106Findings & impact · Empirical validation · Delivery & adoption · Platform107maturity & reliability · optional manual block (preserved if present) · Data freshness.108109## Notes110111- **Deterministic at metric time**: like the dashboards, this skill only112 replays already-derived artifacts — no model call participates in producing113 a number, so reruns are reproducible and diffs are meaningful.114- The maturity metrics (version, commits, releases, LoC, test count) are115 counted live from the harness checkout, so they are correct even when no116 campaign artifact has been rebuilt recently.117- Severity counts quote the executive summary's totals (occurrences) and note118 unique counts alongside, matching how that report itself leads.119120## Spend metrics (separate dashboard, not harvested here)121122The collector does **not** read spend data and the scoreboard carries123no spend section — spend lives in its own dashboard124(`progress-tracker/metrics/dashboards/spend/`, rebuilt by125python3 -m traust.cli metrics spend, stage 14 of `/refresh-dashboards`).126An earlier revision of this skill claimed the scoreboard harvested127`model-spend:*` ledger rows; no such code ever existed128(docs-verification 2026-07-31, wiring c5). When reporting scoreboard129numbers, point spend questions at the spend dashboard; treat a130>7-day-old spend dashboard as stale and rebuild via131`/refresh-dashboards`. Real-time view and the full tracking chain live in your132deployment's private configuration repository, if it keeps one.