fan-out: ForkScore CLI · authorship warrant ladder · 5F Phase 1c
Three streams in one commit since they're independent and each is
small.
#000012 Phase 1b — ForkScore CLI surface
========================================
`arborist v8 score` already existed; this adds `--out` for JSON-
artifact emission so CI / downstream graders / mesh peers can
ingest without parsing stdout. New Makefile targets:
- `make bench-fork-baseline` — pins current bench-suite output as
the ForkScore parent (one-shot per iteration).
- `make bench-fork-score` — runs bench-suite again, scores child
vs pinned parent, writes bench/results/fork_score_report.json.
Exit 1 on REJECT so CI can gate.
`FORK_PARENT` / `FORK_CHILD` / `FORK_REPORT` env-vars override
default paths. New regression test pins the --out contract:
stdout and file are byte-identical artifacts; --out auto-creates
parent directories.
#000026 Phase 3 — authorship warrant ladder
============================================
Sidecar classifier in `arborist/qa/warrant_authorship.py`. Six
tiers strongest-to-weakest: AUTHOR_PACKAGE_METADATA →
AUTHOR_REPOSITORY_OWNER → AUTHOR_PAGE_BYLINE →
AUTHOR_PRIMARY_PAGE_TITLE → AUTHOR_COPYRIGHT_FOOTER →
AUTHOR_SECONDARY_SOURCE. Plus NO_AUTHORSHIP_SIGNAL when the
question doesn't smell like authorship (sidecar stays quiet).
Detector regexes for each tier:
- Tier 1: `author = "X"` simple form + TOML inline-table
`authors = [{ name = "X" }]` form (PEP 621).
- Tier 2: github.com / gitlab.com / codeberg.org / bitbucket.org
URL pattern.
- Tier 3: "By NAME" / "Author: NAME" prose + <meta name="author">.
Inline-flag regex keeps the prefix case-insensitive while the
capitalized-name capture stays case-sensitive.
- Tier 4: cited evidence is the entity's own primary page (host
tokens overlap title + answer; third-party indexers like
wikipedia.org explicitly excluded).
- Tier 5: `© NAME` / `Copyright YYYY NAME` (the current
`virt-back` warrant).
- Tier 6: fall-through when authorship-shaped question hits cited
evidence with no direct markers.
Sidecar discipline: never enters proof path; never raises;
returns dict with `tier`, `tier_rank` (1=strongest, 99=quiet),
`signals`, `candidate_names`, `note`. 20 tests cover each tier
+ noise filtering + sidecar contract + tier-ordering (strongest
wins when multiple fire).
Wiring into `arborist inspect` sidecar output + audit-line
render-tail is queued as a follow-up — sidecar itself ready.
#000025 5F Phase 1c — fixture catalog expansion
================================================
Synthetic side of all five 5F sub-batteries expanded 10 → 30:
function — varied claim_count, pointer_set, threshold cases
falsification — 13 violation tags (WARRANT_MISSING, TITLE_MISMATCH,
FORMAT_COLLAPSED, NO_EVIDENCE_POINTER, BARE_NAME_CLAIM,
LAZY_ANCHOR_DEMOTED, etc.) + 7 fail cases
feedback-loop — 10 chain templates × 2 cycles
finetuning — 20 capability transitions across all 5S/5T/5F/5R
sub-batteries + canonical math/logic
formulate — 12 lattice shapes × 2 (with deliberate fail cases)
150/150 fixtures pass through `bench-5f-*` runners.
test_session_integration.py total updated 462 → 562. Pinned
test_5f_*_runs counts updated 10 → 30 across all assertions.
Tests
=====
Full suite: 1388 passed, 36 skipped (was 1367; +21 — 20 warrant
tests + 1 ForkScore --out test).