31 Commits

Author SHA1 Message Date
Edward Cheng-I Wu f1a57bbcab fix: shared file-lock helper with msvcrt backend for the remaining fcntl sites (#845) (#847)
* fix: shared file-lock helper with msvcrt backend for the six fcntl sites (#845)

scripts/file_lock.py owns the backend choice (fcntl.flock on POSIX,
msvcrt.locking on byte 0 on Windows) and routes adjudication_activity,
inquiry_branch_ledger, review_criteria_binding, and ars_mark_read through
acquire()/release(). POSIX lock sequences are unchanged. Per-site Windows
decisions: adjudication reads degrade to exclusive with a 5 s bounded wait;
the review-criteria manifest lock is capped at 30 s on Windows only; the
inquiry ledger alpha keeps refusing non-POSIX hosts. Two finally blocks that
released an unacquired lock now release only what they acquired. SETUP docs
state the best-effort Windows posture; no Windows CI job is added.

Refs #845, #843, #844.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131cZMWBPPeEFiqgEPFZ3X2

* fix(file_lock): interrupted attempts honour the deadline; pin adjudication wait policy (#845)

Cross-model review round 1 (gpt-6-astra, xhigh): a persistent
InterruptedError could retry past the bound; the Windows-shape test did
not exercise adjudication's reader-waits / writer-does-not-wait policy;
the adjudication contention message now names LockTimeout instead of
BlockingIOError, recorded in the CHANGELOG rather than masked.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131cZMWBPPeEFiqgEPFZ3X2

* refactor(file_lock): held() context manager, single BACKEND source, one fake msvcrt (#845)

/simplify pass (four cleanup reviewers): the release-only-if-acquired
invariant moves into file_lock.held() and review_criteria_binding /
inquiry_branch_ledger use it; runtime branches key off BACKEND and
SHARED_LOCKS_SUPPORTED is dropped; EINTR joins the retryable errno set and
the unreachable EDEADLK entry goes; backend calls are deduplicated; all four
consumers try the sibling import first so one module instance is shared;
the Windows fake lives once in tests/fake_msvcrt.py; test scaffolding is
folded into a lock_pair fixture and a parametrized wait test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131cZMWBPPeEFiqgEPFZ3X2

* fix(file_lock): keep lock acquisition and the guarded body in separate try blocks (#845)

Cross-model review round 3 (gpt-6-astra, xhigh): wrapping the body in the
same handler that translates LockTimeout meant a contended inner lock inside
the body was reported as the outer manifest/passport lock failing. Both
consumers now acquire in their own try block and release only after a
successful acquire; held() is dropped from the helper. The subprocess test
pins that a LockTimeout raised inside the binding body surfaces as itself.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131cZMWBPPeEFiqgEPFZ3X2

* test(file_lock): let the body LockTimeout leave _locked() so the attribution check bites (#845)

Cross-model review round 4: the inner LockTimeout was caught inside the
binding body, so the erroneous outer translation would still have passed.
Verified by mutation: restoring the outer translation fails this test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131cZMWBPPeEFiqgEPFZ3X2

* ci(673): whitelist scripts/test_file_lock.py as a non-consumer importer of the activity runtime (#845)

The shared file-lock test imports adjudication_activity in a subprocess to
exercise its lock backend under a fake msvcrt; it never reads or writes an
activity store. The exact-owner whitelist is the lint's route for that.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0131cZMWBPPeEFiqgEPFZ3X2

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:47:26 +08:00
Edward Cheng-I Wu 6b7ee6dcae fix: Astra request compat, no-delegation citation transport, hedge/quota prompt repairs, audit provenance (#823–#826) (#827)
* fix: Astra request compatibility, no-delegation citation transport, hedge/quota prompt repairs, audit provenance (#823 #824 #825 #826)

#823 — OpenAI request builders (smoke entrypoint + documented example) drop
`temperature`, which GPT-6 Astra rejects; the per-model effort vocabulary
lives in scripts/cross_model_verification/openai_effort_guard.sh, sourced by
both, and an unsupported explicit Astra value fails before curl. Hermetic
fake-curl test runs both surfaces.

#824 — the contained Codex citation transport rejects effort=ultra with
REASONING_EFFORT_REQUIRES_DELEGATION before detection/auth/tempdir/launch on
both entry paths (codex-cli 0.153.4 defines ultra as the multiAgentMode
replacement). Model-independent by design.

#825 — hedging can no longer rescue an unsupported claim (writer recovery
tree, CER fallback row, temporal rule 5 in writer + both compiler mirrors,
writer contract D2); universal prose quotas in the writer, compilers,
writing_quality_check.md, academic-paper/SKILL.md, and contract D6 become
diagnostics subordinate to author/venue requirements. Audit inventory
corrected in place; held-out seed evals/heldout/unsupported_claim_recovery
(NOT_RUN) registered.

#826 — run_codex_audit.sh pins gpt-6-astra/xhigh and records both in a new
sidecar `model` block; claim_audit_pipeline binds an unknown judge identity
to a run-local cache key (no cross-run reuse) instead of defaulting to
gpt-5.5-xhigh.

Review: /simplify (4 angles), codex gpt-5.6-sol xhigh 2 rounds (r1: 1 P1 +
1 P2 + 2 P3 fixed; r2: 0 P1/P2), /security-review 0 findings; all 102
spec-consistency steps + pytest manifest replayed locally.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BNKiXpdHx1T5F5RbXT2Ueu

* docs(claude): record the #824 ultra reversal in the v3.21.2 key-additions line

The v3.21.2 bullet still said the contained Codex citation transport accepts
ultra; #824 on this branch rejects it as a delegation request. Add the
reversal so the live instruction surface matches the transport.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K7emV5r2aqZDJzAyYVuuDo

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 08:08:30 +09:00
Edward Cheng-I Wu 0861bc8538 chore(models): align docs and guardrails to Claude Fable 5.1 and GPT-6 Astra (#819) (#820)
* chore(models): align docs and guardrails to Claude Fable 5.1 and GPT-6 Astra

Read both vendor system cards in full and applied the model-update pass:

- Claude Fable 5.1 named as the current frontier model (PERFORMANCE en/zh-TW
  with a dated list-price re-derivation; cross-model primary-row example).
- gpt-6-astra listed as a provisional cross-model verifier on both transports
  and recommended under the #783 lifecycle policy; gpt-5.6-sol keeps its
  validated status on the ChatGPT-subscription citation transport. Entry-gate
  smoke PASS on that transport (2026-09-05, codex-cli 0.153.4). SETUP en/zh-TW
  example sets, id-status allowlist, bakeoff baseline text, and .claude/CLAUDE.md
  move together.
- Codex citation transport: `ultra` joins the closed reasoning-effort set as a
  named constant, with a test pinning turn/start forwarding and fail-closed
  rejection of unknown values.
- New guardrail: checkpoint decision provenance (authority in the pipeline
  state machine, operational mirror in the orchestrator), indexed as risk R11;
  both content-lock hashes updated in this commit.
- Provider-side monitoring / safety interventions named as a never-a-verdict
  case in the cross-model doc and the degradation registry row.
- Model tiering records that the resolved tier is the declared model; risk
  register R1/R4/R5/R6 residual gaps updated.
- Harness-retirement audit for the model change:
  audits/harness-retirement-2026-09-model-update.md (0 prompt retirements,
  4 applied currency fixes, 2 deferred, 8 keep-as-debt annotations).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sWwwG3oCbtL4cGhRsr5US

* docs(changelog): align the model-update entries with the final text

The [Unreleased] entries were written before the simplify pass moved the
checkpoint-decision authority into the pipeline state machine, reused the
existing transport-failure markers for provider-side interventions, and
de-numbered the model-tiering note. Wording now matches the files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sWwwG3oCbtL4cGhRsr5US

* test: scope the checkpoint-authority section out of the v3.6.7 orchestrator line budget

The v3.6.7 Phase 6.6 budget test measures the orchestrator prompt minus every
later independent extension, each with its own bounded cap. The new
`## Checkpoint authority fidelity` section (13 lines) pushed the v3.6.7-attributed
count to 652 against a 639 ceiling. Following the existing convention, the
section gets its own measurement helper, an 18-line cap (5 lines of headroom),
a dedicated test, and is subtracted from the historical budget.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011sWwwG3oCbtL4cGhRsr5US

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 00:46:14 +09:00
Edward Cheng-I Wu 9469fc4d07 fix: fail check_surface_form_parity with an environment error when pyyaml is missing (#801 follow-up) (#803)
With the manifest present but pyyaml unimportable, _load_manifest
returned None and main() misdiagnosed it as "manifest ... empty / null /
non-mapping", pointing the reader at the wrong file. The import failure
is now a distinct _YamlUnavailableError; the lint exits 1 naming pyyaml
and the requirements-dev.txt remedy. Regression test pins the message
(45 tests, all green; lint itself still passes).

Also de-enumerate the stale "(PyYAML + jsonschema ...)" dependency
parenthetical in docs/SETUP.md and docs/SETUP.zh-TW.md (both language
files together, per bilingual-parity discipline).


Claude-Session: https://claude.ai/code/session_013R81d1YwGvJAznkPKk9gNw

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 11:32:24 +08:00
Edward Cheng-I Wu b6062c1401 feat: first Promotion Bakeoff run — gpt-5.6-sol validated for the codex subscription transport (#788)
* feat: first Promotion Bakeoff run — gpt-5.6-sol validated for the codex subscription transport (#787)

Probe set: 30 refs (10 easy DOI-keyed journal articles; 10 hard: 3 arXiv,
2 DOI-less NeurIPS, 5 non-English; 10 fabrications), every real row
resolver-confirmed same-day, every fabrication negative-checked. 180
same-day paired calls (30 x 3 repeats x 2 models), majority verdicts.

Result: all five measures PASS with superiority — recall 1.00 vs 0.80,
grounded completion 0.933 vs 0.900, p95 latency 26.5s vs 58.7s, zero
guard misfires, false disagreement 0.00 = 0.00. Transport-qualified:
gpt-5.6-sol stays provisional on the first-party API route (jq guards
unexercised; allowlist unchanged). Report + probe-set sha256 under
audits/; per-call index committed beside the probe set.

Campaign side-product (transport): page-open webSearch items
(action.type != "search") are skipped for binding instead of failing the
stream (opened-page URLs still can never become bound sources), and
DEVELOPER_INSTRUCTIONS requires an empty sources array for
NOT_FOUND/NOT_SEARCHED. 52 transport tests green. Defective-tool run 1
archived unscored; three probe-row transcription errors were flagged
MISMATCH by both models, independently re-verified, corrected, re-run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: narrow the page-open exemption to the observed action.type == "other" shape (#788 codex P2)

An empty action object, unknown action type, or non-dict action on a
webSearch item is stream-fatal again; only the observed page-open shape
is skipped. Mutation test sweeps four bad shapes (52 -> 53 tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: anchor the page-open exemption to the first-party closed WebSearchAction set

Run-3 surfaced a third real shape ({"type": "openPage", "url": ...}) that
the single-observation exemption rejected, tool-suppressing the baseline's
measures (13 EVENT_STREAM_INVALID cells). The exempt set is now exactly
the non-search members of the app-server protocol's closed WebSearchAction
oneOf — {other, openPage, findInPage} plus the Responses-API spellings —
verified against `codex app-server generate-json-schema` on 0.147.0.
Unknown shapes stay stream-fatal (mutation sweep unchanged); 54 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs: score preregistered run 4 as the gate result; runs 1-3 recorded as exploratory

Run 4 (frozen fixture @ 3fc6ddb, frozen parser @ c9c865d, both pushed
pre-run): all five measures PASS, zero misfires on BOTH models, recall
1.00 vs 0.80, grounded completion 0.933 vs 0.867, p95 27.5s vs 51.1s.
Report rewritten with the preregistration statement and the full
exploratory-round accounting; call index replaced with run-4 data;
claim surfaces and CHANGELOG updated to run-4 numbers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs(code): pin the bare-discriminator decision against the first-party schema (#788 codex round-2 P2 rejected with evidence)

The round-2 finding claimed openPage/findInPage require url/pattern; the
protocol schema (generate-json-schema, 0.147.0) marks every non-search
variant required:["type"] with url/pattern nullable optionals. Demanding
optional fields is the exact false-fatality class that invalidated
bakeoff runs 1 and 3. Decision recorded in the comment and pinned by
bare-discriminator test rows (54 tests, +2 param rows).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix+docs: close codex round-3 findings — ordering, replayability, exposure analysis

P2 (ordering): webSearch action-shape validation now runs BEFORE the
MODEL_RETURNED_NOT_SEARCHED early return, so a model NOT_SEARCHED verdict
can never mask response-shape drift; mutation test added (55 tests).
P2 (replayability): the 180 full receipt rows, the offline scorer
(verified to reproduce the gate byte-for-byte from committed artifacts
alone), and the parameterized fleet runner are committed beside the
probe set; the report states the replayability boundary plainly (raw
event streams are digest-only by transport design).
P1 (answer-key exposure): empirical scan across all 540 retained
receipts finds zero repo-referencing bound queries/sources; report gains
an exposure-analysis section with scope caveats and corroboration; the
structural fix (sealed hash-commit preregistration, fresh fabrication
pool per run) is filed as #789 for future bakeoffs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-4 P2s — fleet gate, timeout margin, fresh-probe rule, nearest-rank p95

Scorer refuses truncated/duplicated/partial fleets (exactly one row per
(ref_id, repeat) across 30x3) before computing any measure; p95 moves to
the nearest-rank order statistic (51.13/27.46 -> 51.20/28.09, matching
the review's own recomputation; gate unchanged) and the method is named
on every surface. Runner outer timeout raised above the transport's
inner 300s deadline so its finally-block cleanup always fires first.
The canonical recorded-run note and report outcome now require a FRESH
probe set for the API-route run per #789 (this set's labels are public),
resolving the self-contradiction with the exposure analysis.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-5 P2s — scorer consumes runner output + binds receipt identity

score_run.py now scores either the committed run-4 JSONLs (default) or a
fleet-runner output directory (argv[1]), so a reproduced fleet can never
silently re-report the old result; every scored row must pass identity
binding (outer model/ref/repeat, receipt.model, receipt.request_id, and
a request_digest recomputed from the probe set via the transport's
canonical form), refusing mis-associated or edited fleets. Verified:
committed data reproduces the gate unchanged, results-dir mode scores
the live run-4 cells, and a cross-model receipt swap is refused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-6 P2s — dual-fleet hard-zero + unambiguous shape code

Measure 4 now requires zero guard misfires in BOTH fleets (a baseline
suppressed by tool misfires cannot anchor a fair comparison — the run-3
lesson, now enforced by the scorer). The transport emits
EVENT_STREAM_INVALID for a non-null non-list search `results` value
instead of silently skipping into NO_BOUND_SEARCH_RESULTS
(wrong_search_shape fixture expectation updated in lockstep), and the
scorer's shape family is trimmed to exactly the emitted shape codes with
the behavior-family classification documented. Provably no effect on the
scored run: run-4 contains zero rows in any affected code family (only
SOURCE_NOT_IN_SEARCH_RESULTS 12/6, a behavior code) and both fleets
already sit at zero misfires; all gate numbers unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-7 P2s — results-shape check before verdict return + same-day fleet enforcement

The results-shape validation joins the pre-verdict scan loop so a model
NOT_SEARCHED verdict can never mask dict-shaped search results (mutation
test added: wrong_search_shape + NOT_SEARCHED -> EVENT_STREAM_INVALID;
56 tests). The runner refuses to resume over cells from an earlier date,
and the scorer refuses mixed-date fleets across both models (run-4 is
single-date; gate numbers unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-8 P2s — complete pre-verdict search validation + runner failure semantics

The pre-verdict scan now performs the COMPLETE search-item strict
validation (query type/length/control chars + results shape), covering
legacy action-less items — the round-7 placement validated only
action-typed items, which also made the round-7 mutation test fail (a
red test my verification pipeline masked via tail; committed here only
with PYTEST_EXIT=0 verified directly). Runner: a fleet with any failed
call now exits nonzero instead of printing ALL DONE, and an outer-
timeout kill sweeps the adapter's orphaned temp dirs (the detached
app-server exits on stdin EOF; the ephemeral auth copy is what the
verifier's skipped finally-block would have removed). 56 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-9 P2s — NOT_SEARCHED source contract, retry-not-skip, quiescent sweep, dated rows

Transport: NOT_SEARCHED with a populated sources array fails closed as
FINAL_OUTPUT_INVALID before the early return (mutation test; 57 tests).
Runner: a same-day cell that recorded a failure is discarded and retried
on resume instead of silently counting as complete; the orphan-tempdir
sweep runs only after the executor drains so it can never delete a live
worker's ephemeral CODEX_HOME. Scorer: every row must carry a real ISO
date — an undated fleet cannot satisfy the same-day gate on empty
strings. Committed run-4 data re-verified green under all new gates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-10 findings — single-path validation, scorer gate exit, probe-hash pin

P1 root treatment: the entire search-processing pipeline (cap, strict
per-item validation, reference-bound filter, URL binding incl. the
result-entry object-shape check) now runs BEFORE any verdict branch, so
every shape-fatal path fires identically regardless of the model's
answer — the verdict-masking bug class (rounds 3/7/8/9/10) is closed by
construction, not by another patch. Emptiness outcomes stay verdict-
conditional (an honest NOT_SEARCHED with no bound search remains model
behavior). Mutation test: bound search with a non-object result entry +
NOT_SEARCHED verdict -> EVENT_STREAM_INVALID (58 tests).
Scorer: refuses a probe set whose whole-file sha256 differs from the
frozen hash (labels now inside the scoring identity), and exits nonzero
when any gate fails. The P1's rerun demand is accepted: a run-5 fleet
under this frozen parser follows as the scored gate run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs: run 5 under the frozen final instrument is the gate result (#788 codex round-10 P1 accepted)

Fleet rerun 2026-08-20 under parser+scorer db6ed67 (pushed pre-run):
all five measures PASS with zero misfires on both fleets — recall 0.90
vs 0.80, grounded completion 0.911 vs 0.889, p95 26.1s vs 47.6s. Run 4
reclassified as a prior-instrument exploratory round; committed
receipts/index/scorer default swapped to run-5 data (committed scorer
replays the gate from repo artifacts alone, exit 0); all claim surfaces
carry run-5 numbers and the cross-fleet consistency note (candidate led
measures 1/2/5 in every full paired fleet).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-11 P1s — no failed-trial erasure + full-fleet entry validation (instrument fixpoint)

Runner: a recorded failed trial is never deleted on resume; it is
carried into the failure count and forces a nonzero exit, so the only
path past a failure is rerunning the ENTIRE fleet fresh — selective
retry-until-green is structurally impossible. (Provably no scored fleet
was affected: runs 4 and 5 each completed in a single invocation with
zero failures and no retry/carried lines in their logs.)
Transport: the strict pre-verdict loop now validates every consumed
field of EVERY search item — id, query, results-list shape, and each
entry's object shape, bound or unbound — reaching the instrument
fixpoint: no field the pipeline reads is unvalidated, so no future
verdict-masking variant of this class exists. Mutation tests for
unbound-malformed-entries and id shapes (60 tests). A run-6 fleet under
this frozen instrument follows as the gate run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs: run 6 under the fixpoint instrument is the gate result

Fleet rerun 2026-08-20 under adf18f9 (parser fixpoint + no-erasure
runner + full-gate scorer, all pushed pre-run): 5/5 PASS, zero misfires
both fleets — recall 1.00 vs 0.70, grounded completion 0.911 vs 0.867,
p95 28.8s vs 43.3s. Run 5 reclassified prior-instrument; artifacts and
scorer default swapped to run-6; leak scan clean across all 900 retained
receipts (runs 2-6); candidate led measures 1/2/5 in all four full
paired fleets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-12 P2s — pinned effort, fleet-private temp root, split disclosure

Runner pins ARS_CROSS_MODEL_REASONING_EFFORT to the provider default
(explicitly unset per call, recorded per row) and routes all transport
temp dirs into a fleet-private mkdtemp root so the timeout sweep can
never touch another invocation's dirs. The audit now discloses the one
run-6 1-1-1 split (baseline fab-05: MISMATCH/NOT_SEARCHED/NOT_FOUND ->
INDETERMINATE, conservative miss) and names the actual baseline misses
(fab-01, fab-08 majority NOT_SEARCHED; fab-05 split) — verified against
the committed receipts, correcting a stale carried-over sentence. The
effort variable was verified unset for every fleet (shell env + profile
carry no export); gate numbers unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-13 P2s — receipt-contract validation, effort-marker gates, always-sweep

Scorer validates every non-null receipt against the closed contract
(required keys, verdict/searched types, positive-verdict grounding with
fully-bound sources, empty sources on NOT_FOUND/NOT_SEARCHED, queries
present when searched) before any metric trusts it, and results-dir
scoring requires the pinned-effort marker on every row (committed
gate-run rows predate the marker; the audit attests their configuration).
Runner refuses carried cells without the marker and sweeps the
fleet-private temp root in a finally-block on every outcome — a
signal/OOM-killed verifier no longer leaves its ephemeral auth copy.
Committed gate scoring still exits 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-14 P2s — per-verdict receipt invariants + runner rejects malformed parsed receipts

Scorer: grounded verdicts (VERIFIED/MISMATCH/NOT_FOUND) require
searched=true and a null reason_code; NOT_SEARCHED requires
searched=false and a reason from the transport's closed emitted set —
a fabricated NOT_FOUND-without-search or NOT_SEARCHED-with-search row
can no longer contribute to recall or completion. Runner: a verifier
exiting 0 with parsed-but-malformed output records RECEIPT_INVALID,
counts as a failure, and forces nonzero exit. Committed run-6 gate
scoring re-verified: exit 0, numbers unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-15 P2s — uniform item-field validation + shared receipt contract (axis terminal)

Transport: every webSearch item — page-opens included — now has its
action payload validated against the closed WebSearchAction variant
types (url/pattern/query string-or-null, queries string-array), plus
uniform id and results/entry shape checks; a recognized discriminator
with a wrong-typed payload is stream-fatal (mutation sweep; 60 tests).
Tooling: the full closed receipt contract (exact key set, transport/
auth_mode/containment, digest formats, per-verdict cross-field
invariants) moves into a shared receipt_contract.py imported by BOTH
run_fleet.py and score_run.py — one implementation, applied to fresh
cells, resumed cells, and every scored row, so the two consumers cannot
diverge. This terminates the validation axis: every field of every
webSearch item and every key of every receipt is now checked; committed
run-6 gate scoring re-verified exit 0 with numbers unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix+docs: close codex round-16 — strict source bindings; instrument-freeze boundary pinned (P1 declined with recorded rationale)

receipt_contract.py enforces the full canonical source-binding shape
(closed 4-key object, non-trivial https URL, non-empty item id,
result_index 0-127 with bool exclusion) — committed run-6 data passes
unchanged. The round-16 rerun demand is DECLINED under a pinned
maintainer boundary, recorded in the report and the canonical
recorded-run note: runs 4/5 were discarded because consumed-data gaps
could alter scored outcomes; post-run-6 hardening validates only
surfaces outside every consumed path and cannot change any verdict,
binding, latency, or measure of a past fleet — such hardening applies
from the next fleet. The disagreement is recorded, not hidden.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-17 P2s — complete schema mirror + latency-sample validation

receipt_contract.py is now a COMPLETE stdlib mirror of the canonical
receipt schema: identifier/event-id/https-url patterns and length
bounds, array caps (queries<=32, sources<=16), closed entry objects,
auth_mode const, NOT_SEARCHED => empty queries+sources with a mandatory
reason, unknown reason codes refused globally. Scorer refuses boolean,
negative, non-numeric, or absurd wall_seconds before the percentile
gate. Committed run-6 gate scoring re-verified: exit 0, numbers
unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-18 P2s — hashability, boolean identity, SIGTERM cleanup

Validator: array/object verdict or reason_code becomes a contract
failure instead of an uncaught TypeError (which would have escaped the
runner's SystemExit handling and re-opened the no-reroll gap);
containment flags are checked by identity (`is True`) so integer 1
cannot satisfy the schema's boolean constants. Runner: SIGTERM/SIGINT
raise SystemExit so the finally-block sweep of the fleet-private auth
copies also runs on cancellation. Mutation-verified (3/3 caught);
committed run-6 scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-19 P2s — discriminator hashability, integer repeats, real ISO timestamps

Transport: the WebSearchAction discriminator is type-checked before set
membership in both _is_page_open and the uniform loop — an array/object
type fails closed as EVENT_STREAM_INVALID instead of crashing the
verifier past shape accounting. Scorer: repeat must be an exact int in
1..3 (1.0 satisfied the completeness Counter while minting ...-r1.0),
and ts must parse as a full ISO timestamp with offset instead of a
digit-shaped prefix. Committed run-6 scoring exit 0 unchanged; 60
transport tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-20 — source-query binding, midnight guard; null-action P2 declined with schema evidence

receipt_contract.py rejects sources whose search_item_id has no retained
entry in search_queries (unretained evidence never counts as grounding).
run_fleet.py fails visibly BEFORE reporting success when a fresh fleet's
cells span two calendar dates. The explicit-null-action P2 is declined
on first-party evidence: ThreadItem types action as
anyOf[WebSearchAction, null] (generate-json-schema, 0.147.0), so null is
protocol-legal and follows the legacy path where the item still faces
the complete strict validation — fatal-izing it is the run-1/run-3
false-fatality class; decision pinned in the code comment. Run-6
scoring exit 0 unchanged; 60 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-21 — cancellation stops queued quota burn, worker failures persist; open-variant P2 declined with schema evidence

P1: SIGTERM/SIGINT set a STOP event making every queued job a no-op
(marked [CANCELLED], counted as failure), so shutdown waits only for
the at-most-3 in-flight calls instead of burning the rest of a paid
180-call fleet. P2: a worker exception after the paid call persists a
failed cell with the job identity, so a resume can never treat the
consumed trial as missing and re-roll it. The closed-variant P2 is
declined on first-party evidence: no WebSearchAction variant sets
additionalProperties, so extra fields are schema-legal and rejecting
them would make any future informational field fleet-fatal; decision
pinned in the code comment, known fields stay type-checked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-22 P1 — stray STOP=None placeholder no longer nullifies the cancellation event

The round-21 placeholder assignment landed AFTER the Event creation in
module order, resetting STOP to None and disabling queued-call
cancellation exactly as the review read it. The placeholder is removed;
the Event created before worker start is the one the signal handler
sets. Static check pins that no STOP=None assignment remains.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-23 P2 — refuse contradictory receipt+error rows

A row carrying both a valid receipt and a truthy error is structurally
impossible from the runner and is refused as corrupted/external instead
of being scored as grounded evidence; error rows with a null receipt
stay counted as misfires. Committed run-6 scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-24 P2s — output-contract precedence, portable probe digest, runner preflight

Transport: NOT_FOUND carrying sources is FINAL_OUTPUT_INVALID even when
the stream also lacks a bound search — output-contract violations now
outrank emptiness outcomes so the shape event cannot be misfiled as a
behavior code. Probe digest verification moves into the shared module
with CRLF->LF normalization (a Windows autocrlf checkout is not probe
drift) and the runner runs the same preflight BEFORE any paid call, so
180 subscription calls can never be spent on a fixture the scorer will
refuse. Run-6 scoring exit 0 unchanged; 60 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-25 — scorer-equivalent resume preflight + exclusive fleet lock

validate_row (shared receipt_contract) now carries the COMPLETE row
validation — contradiction, outer identity, exact-integer repeat, full
ISO timestamp, sane latency, receipt identity binding to the probe row,
closed receipt contract — and is the single implementation used by both
the scorer and the runner's resume preflight, so a misnamed or copied
cell fails before any further quota is spent. The runner takes an
exclusive flock on the output dir, refusing a second concurrent
invocation that would duplicate paid calls and race cell writes.
Committed run-6 scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-26 — URL-binding drift hits measure 4; cross-platform fleet lock

Transport: a bound search whose non-empty result entries yield no
extractable URL is EVENT_STREAM_INVALID (provider moved/renamed the URL
key = response-shape drift), no longer the behavioral
NO_BOUND_SEARCH_RESULTS; the pre-existing pin of the old classification
is updated in lockstep and a canonical_url regression test added (62
tests). Runner: the fleet lock falls back to msvcrt.locking on Windows,
keeping the documented reproduction path viable.

Note: run-6's receipts contain zero NO_BOUND_SEARCH_RESULTS /
SOURCE_NOT-with-empty-binding rows of the reclassified kind (reason
distribution: only SOURCE_NOT_IN_SEARCH_RESULTS with non-empty
bindings and clean rows), so the gate numbers are provably unaffected;
the change also falls under the pinned instrument-freeze boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-27 P2s — key-drift/value split, full resume validation, Windows invoke, UTF-8 I/O

Transport: EVENT_STREAM_INVALID for empty bindings now requires that NO
recognized URL key exists across the bound entries (true key drift); a
recognized key with an unusable value stays behavioral — both sides
test-pinned (62 tests). Runner: every resumed cell, failed ones
included, faces validate_row + the effort check before further quota is
spent; the transport is invoked via sys.executable (Windows honors no
shebang); all subprocess/artifact text I/O pinned to strict UTF-8 in
runner and scorer. Run-6 scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-28 P2 — URL-key drift determined pre-verdict

The key-drift determination (bound entries present, no recognized URL
key anywhere) moves before the NOT_SEARCHED early return, so a model
NOT_SEARCHED answer can no longer mask renamed-URL-key response drift;
the post-verdict emptiness branch keeps only behavioral outcomes.
Masking regression test added (63 tests); run-6 scoring exit 0
unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-29 P1 — fleet runner gated to POSIX

The #630 transport's process-group containment (start_new_session +
os.killpg in _stop_process) is POSIX-only, so a native-Windows fleet
would consume paid calls while every cell fails during cleanup — the
rounds-26/27 surface accommodations implied support the deeper stack
never had. The runner now refuses non-POSIX up front with a WSL
pointer; the dead msvcrt lock branch is removed (the scorer, which is
genuinely offline and portable, keeps its CRLF-tolerant digest and
UTF-8 reads). Run-6 scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix+docs: close codex round-30 — receipt-level invariance proof replaces live-validation claim; session isolation; stray-file preflight

P1 resolved by PROOF rather than a third rerun: run 6's 180 receipts
carry exactly two reason states (null; SOURCE_NOT_IN_SEARCH_RESULTS
12/8) with zero receipt-less, error, NO_BOUND, NO_REFERENCE,
FINAL_OUTPUT_INVALID, MODEL_RETURNED_NOT_SEARCHED, or
EVENT_STREAM_INVALID rows — each post-run-6 transport change either
touches unconsumed surfaces or only relabels cells in code families
that provably never occurred, so no run-6 cell can differ under the
shipped parser. The stale "run 6 live-validates the shipped parser" and
"instrument FIXPOINT / no masking path remains" sentences are replaced
with the precise provable statements; the freeze policy now REQUIRES
this proof standard (no proof on a consumed path = rerun, as runs 4/5
were). P2s: verifier subprocesses start in their own session so an
interactive Ctrl-C cannot turn in-flight calls into resume-poisoning
EXIT failures; the runner refuses unexpected result files before
spending quota.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-31 P2s — orphaned .tmp cells refused, fresh cells identity-bound

The preflight refuses orphaned atomic-write temp files (a crash between
write and rename must not silently re-roll a completed paid trial), and
fresh cells face the same validate_row identity binding as resumed
cells and the scorer before being persisted as success — a receipt with
the wrong model/request_id/digest becomes a recorded RECEIPT_INVALID
failure. Run-6 scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* feat: counterbalanced interleaved scheduling for the bakeoff fleet (#788 round-32 P1 accepted)

The two models' calls for each (reference, repeat) cell are adjacent in
the queue with deterministic parity-alternating pair order, so model
identity is decorrelated from execution time — provider load or
web-search drift during the fleet can no longer masquerade as a model
effect. A counterbalanced run-7 follows as the scored gate run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs: counterbalanced run 7 is the gate result; run 6 superseded for order confound

Run 7 under frozen instrument 69cd04a (interleaved parity-alternating
pair scheduling): all five measures PASS — recall 0.90 vs 0.80, p95
25.0s vs 49.6s (median 14.8 vs 17.5), grounded completion tied at
0.900, zero misfires both fleets, two 1-1-1 splits disclosed and scored
as conservative misses. Honesty note carried on every claim surface:
the sequential fleets' grounded-completion edge did NOT survive
counterbalancing and is not claimed; recall and latency led in all five
paired fleets. Artifacts and scorer default swapped to run-7 (committed
scorer replays the gate, exit 0); leak scan clean across 1,080 retained
receipts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-33 P1 — resume refuses half-complete counterbalanced pairs

Every (reference, repeat) pair must be wholly present or wholly missing
on resume: a one-sided pair would run the counterpart far from its
partner and silently reintroduce the model-vs-time confound. Run 7 is
unaffected (single uninterrupted invocation); scoring exit 0 unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs: close codex round-34 P2 — recorded-run note limited to the measured superiority (2 and 5, tie on 1)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 07:13:23 +08:00
Edward Cheng-I Wu 075390a5c3 docs: cross-model recommendation surfaces follow generation currency (#784)
* docs: cross-model recommendation surfaces follow generation currency (#783)

Recommendation decoupled from validation status: gpt-5.6-sol (current
OpenAI flagship) becomes the lead OpenAI example while staying
provisional — a dated lifecycle note records the flip carries no
measurement claim; the Promotion Bakeoff remains the only route to
validated. gpt-5.5 / gpt-5.5-pro demoted to validated previous-generation
rows (measured bakeoff baseline unchanged). Gemini 3.1 Pro stays
recommended (first-party check 2026-08-19: still Google's most capable
Pro model). SETUP en/zh-TW quick-setup blocks updated in lockstep
(parity lint green); the #630 guard's recommendation witness re-pinned
to the new policy sentence with its mutation test updated in the same
commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-1 P2s — evidence-ceiling wording + policy-body witness

P2-1: "measured bakeoff baseline" overstated the evidence (no bakeoff run
has ever been recorded); gpt-5.5 is the designated baseline, validated =
allowlist status only. Reworded on all four surfaces (canonical doc,
SETUP en/zh-TW, CHANGELOG).
P2-2: the #630 recommendation-policy witness pinned only the heading; the
guard now pins the two load-bearing body clauses (no-measurement-claim,
bakeoff-only route to validated) with mutation tests for each (29 -> 31).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* fix: close codex round-2 P2 — superiority claim requires an observed measure

The rewritten outcome bullet's "or operational benefit" branch let a
measured-superiority claim rest on an unmeasured benefit; superiority now
requires observed superiority on one of the five measures, and operational
benefits are scoped to recommendation policy. Header no longer says "two
distinct promotions" for what is now one promotion plus a claim rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

* docs: close codex round-3 P2 — name the subscription-transport exception

The citation-only codex subscription blocks (canonical + SETUP en/zh-TW)
keep gpt-5.5 deliberately; a comment now names this as a transport-specific
exception to the generation-currency recommendation and points at the codex
smoke test before swapping ids.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mo3QXHj2yzwNQ3VQKVEM2j

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 18:00:30 +08:00
Edward Cheng-I Wu cdd48d916d docs: DATA_FLOWS.md — single map of network touchpoints + local stores (#758) (#770)
* docs: single data-flow map + DF-1..DF-3 coverage lint (#758)

Add docs/DATA_FLOWS.md — one row per network touchpoint (trigger,
payload class, recipient, credentials, off switch) and one row per
local store (path, content, TTL, deletion), with an explicit scope
statement (the Claude session itself is platform-governed; nothing
publishes autonomously). Covers the four gate resolvers, the
standalone Chinese-literature resolver (NOT in the gate), the
consent-bound claim-standing discovery adapters, both cross-model
transports (API and citation-only Codex subscription), the SessionStart
update check, the manual smoke tests, and the v3.9.4 timeline
bootstrap — the last one surfaced by the new lint itself on first run
(it was absent from the #758 issue enumeration).

Inbound links from README, SECURITY.md (in-scope exfiltration anchor),
and THIRD_PARTY.md (core-suite vs third-party contrast).

Lint (same-PR drift-point discipline): scripts/check_data_flows.py —
DF-1 every non-test scripts/*.py importing a network module (AST scan,
so no-call guards naming urllib.request in strings do not count) must
be named on the map; DF-2 same for curl-invoking shell scripts; DF-3
README/SECURITY/THIRD_PARTY keep a rendered resolving inbound link
(fences + HTML comments stripped with the semantics converged in the
PR #768 review; consolidation into a shared helper is follow-up).
12 mutation tests; wired into spec-consistency.yml + pytest manifest.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* refactor: apply /simplify pass (4-agent, deduped) (#758)

Doc: the four gate resolvers collapse into a 4-column sub-table under
one shared trigger/payload/off-switch lead (the wide table kept only
heterogeneous touchpoints); the exhaustiveness sentence is bounded to
what DF-1/DF-2 actually detect (direct imports + curl; spawned-CLI and
session-tooling paths held by review); "Nothing here publishes" now
inherits POSITIONING.md and its not-a-runtime-guarantee qualifier; the
subscription-free note is trimmed to its rationale; Related gains the
SETUP bullet as the tunables authority.

Coverage: docs/SETUP.md becomes the fourth DF-3-pinned inbound surface
(pointer added in the cache section); the four translated READMEs
mirror the README pointer; docs/DATA_FLOWS.md registers into
check_spec_consistency.py relative-link validation.

Lint: DF-1 module vocabulary rebuilt as the network subset of the
no-call envelope FORBIDDEN_IMPORTS (deviations documented: dotted
urllib.request/http.client instead of bare urllib/http; ssl excluded);
scan is now recursive into scripts/ subpackages. Tunable constants in
verification_cache.py gain update-both comments.

Tests: the three hollow assert-baseline tests become real mutations
(name-based test exemption, uncomment-curl, from-urllib idiom);
recursive-scan and SETUP-surface tests added (17 total).

Skipped with reason: endpoint-hostname lint (near-zero event rate,
composed-URL false-fire risk); row-id shrink constant (review-owned per
degradation-registry precedent); markdown-helper consolidation with
check_control_availability.py (whichever PR merges second extracts the
shared module — recorded in both PR bodies).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R1 findings — 8 P2 + 4 P3 (#758)

Doc accuracy (6): Chinese-literature row rewritten (callable client, no
CLI; PubMed path sends the required NCBI contact email + bibliographic
search coordinates); codex-transport payload names citation_context
(can contain unpublished manuscript text); update check documented as
one curl transfer per 24 h with redirects and the
ARS_UPDATE_CHECK_REMOTE_URL override; retraction-status SQLite cache
added to local stores (caller-supplied path, 30-day stale threshold,
no auto-expiry); discovery adapters credentials corrected (fixed
User-Agent, resolver env keys not consumed); resolver payload narrowed
to identifiers + title query strings; update-check state content
corrected (state label + two version strings).

Lint mis-pass/mis-fire (4): DF-1/DF-2 coverage now requires the full
repo-relative path (basename-substring collision closed); DF-2 is
recursive over scripts/ and hooks/, recognizes path-qualified curl,
and masks quoted spans before the comment strip; DF-3 strips inline
code spans before link extraction (a backticked link does not render).
Five mutation tests added (22 total). The code-span rule is a
divergence from check_control_availability.py to be carried over at
the declared helper consolidation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R2 findings — 4 P2 + 1 P3 (#758)

- DF-2 scans command-substitution bodies BEFORE quote masking, so
  resp="$(curl ...)" — a real network call inside double quotes — fires
  (mutation test added; suite now genuinely 22, correcting the prior
  commit message which said 22 when 21 were collected).
- Map gains the Codex audit wrapper row (scripts/run_codex_audit.sh:
  human/CI/hook-invoked only, sends deliverable + supporting file
  contents through the local Codex CLI login).
- Update check re-bounded: at most one SUCCESSFUL check per 24 h; a
  failed attempt writes no state and may retry next session.
- Cache TTL wording corrected: expiry is a cache miss, not deletion;
  expired rows persist until invalidated or the file is deleted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: full comment lines execute nothing — DF-2 substitution scan (#758)

The R2 command-substitution scan ran before any comment handling, so a
full comment line containing $(curl ...) false-fired — surfaced by the
codex R3 pass (timed out mid-review, but its transcript had already
demonstrated the false fire). Comment-only lines are now skipped before
the substitution scan; a $(curl) inside a trailing inline comment
remains a documented accepted edge. Mutation test added (23 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R3 findings — command-position curl + image links + retention wording (#758)

- DF-2 rebuilt around COMMAND POSITION: curl counts only as the first
  non-assignment token of a segment (pipes/separators/substitution
  openers), so `command -v curl` preflights and `echo curl` no longer
  false-fire; VAR=x curl still fires; wrapper-prefixed invocations
  (sudo/timeout) are documented accepted edges.
- DF-3 link grammar excludes image syntax — ![map](...) renders no
  anchor and cannot keep the acceptance criterion green.
- Cache retention wording includes the overwrite path: expired rows
  persist until overwritten by re-verification, invalidated, or the
  file is deleted.
- Three mutation tests added (26 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R4 finding — curl behind shell control words (#758)

The command-position head-token scan now skips shell control words
(if/elif/while/until/then/else/do/!/time/exec) before naming the head,
so `if curl …; then` and `while ! curl …; do` fire while `if true;
then` stays quiet. Two mutation tests (28 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R5 finding — option tokens after control words (#758)

`time -p curl …` / option-bearing exec forms: the head scan now skips
`-`-prefixed option tokens alongside assignments and control words, so
the option cannot shadow the command head. Mutation test added (29
total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R6 finding — harness spawned-CLI paths scoped out (#758)

Three maintainer-only measurement scripts reach the network through
locally authenticated CLIs (dispatch_e4_panel via claude -p,
run_review_criteria_constructive_value via Codex, check_ranking_lift
via gh api). They are not user-facing feature paths, so instead of
diluting the touchpoint tables they are now an explicit named scope
exclusion — the exhaustiveness claim no longer silently spans them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R7 finding — boundary count wording (#758)

"Two boundaries" became three after the R6 harness exclusion; the count
is removed rather than maintained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 00:28:24 +08:00
Edward Cheng-I Wu 43a02bf7e2 docs: per-channel control-availability matrix (#757) (#768)
* docs: per-channel control-availability matrix (#757)

Add docs/CONTROL_AVAILABILITY.md — one row per enforcement mechanism,
one column per install channel (plugin / skills copy / repo clone /
Cowork / claude.ai Project / Claude Science / Pi), with honest
active / conditional / absent cells, per-channel notes citing the
existing scattered sources (README Requirements, SETUP methods,
pi/README.md, hooks/run_guard.sh), and the guard's environment
degradation table. Linked from README (Requirements + SETUP pointer)
and SETUP (Installation methods intro).

Evidence re-verified against the working tree: the channel set has
grown past the six named in the issue (SETUP now also documents
Cowork and the claude.ai 4a/4b split), so the matrix covers all
seven documented channels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* refactor: apply /simplify pass + add CA-1..CA-3 defrift lint (#757)

Simplify round (4-agent review, findings deduped):
- Drop the 'How to read an integrity claim' section (it had already
  drifted from the matrix) and the all-identical Upstream row; both
  replaced by one legend sentence and one paragraph.
- Move channel-scoped caveats (Cowork / claude.ai / Claude Science / Pi)
  from per-cell footnotes into a 'Channel-wide limitation' column of the
  channel table; notes drop from 11 to 7.
- De-drift row labels: no inline allowlist contents (canonical list is
  pinned by check_tools_allowlist.py), no exhaustive feature list, no
  hard-coded Claude Code minimum version (lives in SETUP Method 0).
- README: single slimmed pointer (second link and both enumerations
  removed); pointer mirrored to the four translated READMEs and
  docs/SETUP.zh-TW.md.
- Degradations table scoped to actual guard degradations (the slash-form
  version row was misfiled); registry backpointer added; guard-launcher
  registry registration split to #769.

Lint (per the new-claim-surface-needs-lint-in-same-PR discipline):
- scripts/check_control_availability.py — CA-1 links/anchors resolve,
  CA-2 every SETUP '### Method' heading reachable from the channel
  table, CA-3 README + SETUP inbound links pinned. Cell semantics stay
  owned by code review (degradation-registry posture).
- 9 mutation tests; wired into spec-consistency.yml + pytest manifest
  (150 entries).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R1 findings — 4 P2 accuracy corrections (#757)

- SessionStart announce/update-reminder row: Conditional, not Active
  (bash launcher on Windows needs Git Bash; reminder needs curl) — new
  note 8.
- Cross-model note 6 no longer claims credentials+curl universally; the
  citation-only Codex subscription transport is named as the alternative
  transport behind the same consent boundary.
- Pi channel limitation reworded: the wrapper supplies no orchestration
  but uses an installed Pi capability when available.
- 'Enforcement mechanisms' claim language aligned to 'controls' in the
  purpose statement and all five README pointers (consistent with note
  7's trust-based posture).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R2 findings — lint mis-pass cases + note-8 wording (#757)

- CA-1 link grammar accepts optional quoted titles so a titled dead
  link cannot silently skip the check.
- CA-2 counts only fragments on links whose resolved destination IS
  docs/SETUP.md — a same-slug anchor into a copied file no longer
  satisfies method coverage.
- CA-3 checks resolved link destinations, not a filename substring — a
  label that keeps the filename while the target moves now fails.
- Note 8: singular SessionStart hook (hooks.json defines one; the
  announce script runs the update check internally).
- 3 new mutation tests pinning each mis-pass case (12 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R3 finding — commented-out markdown counts for nothing (#757)

Strip HTML comments before extracting links and headings in all three
invariants: a commented-out inbound link no longer satisfies CA-3, a
commented-out SETUP method heading no longer demands CA-2 coverage, and
a commented-out dead link no longer fires CA-1. Two mutation tests pin
both directions (14 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R4 finding — GFM type-2 HTML-block semantics (#757)

A line beginning with <!-- opens a raw-HTML block through the --> line
(including trailing text on the closing line) or to EOF if unclosed;
nothing on those lines renders. The comment stripper now models that
line-level behavior before the inline-span strip, so a link after -->
on a comment line cannot satisfy CA-3 and a dead link after an unclosed
comment cannot fire CA-1. Two mutation tests pin both (16 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* test: fix R4 mutation scenario — line-start vs inline comment (#757)

The previous commit's CA-3 HTML-block test inserted the comment mid-line
(inside the blockquote), where GFM renders the link normally and the
lint correctly stays quiet — the test scenario was wrong, not the lint.
Replaced with a whole-line mutation that actually begins with <!--, and
added the inline-comment symmetry case (link still renders → CA-3
satisfied). 17 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R5 finding — block-quoted HTML-block lines (#757)

The type-2 HTML-block rule applies to block-quote content: the stripper
now looks through leading '> ' markers before the line-start test, so
'> <!-- note --> [link]' cannot satisfy CA-3. Deeper CommonMark
laminations are declared out of scope in the docstring (the surfaces do
not use them; a full parser is out of proportion for a maintainer-slip
guard). 18 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R6 finding — repo-containment on CA-1 targets (#757)

A relative link that resolves outside the repository root now fails
CA-1 even when the host path exists — an over-deep ../.. slip must not
be masked by an existing host file. Mutation test added (19 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R7 finding — fenced code excluded from extraction (#757)

Fenced code regions render literally, and README/SETUP use fences
today, so they are in-scope: a link inside a fence no longer satisfies
CA-3, and a sample "### Method" heading inside a SETUP fence no longer
demands CA-2 coverage. Fence stripping runs before the comment pass so
a comment opener inside a fence stays literal. Two mutation tests (21
total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

* fix: close codex R8 finding — CommonMark fence-length closing rule (#757)

The fence stripper now tracks the opening run character and length: a
closer must be a same-character run at least that long with only
trailing whitespace, so a four-backtick fence demonstrating an inner
triple-backtick block is no longer closed early. Mutation test added
(22 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EosnA4RdUYgbF2KmZ1DTmc

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 23:57:07 +08:00
Edward Cheng-I Wu 54507ece69 fix: harden v3.20 review and integrity contracts (#747)
Closes #734
Closes #735
Closes #736
Closes #737
Closes #738
Closes #739
Closes #740
2026-08-15 15:04:28 +08:00
Edward Cheng-I Wu f4d5c7a282 Add contained Codex subscription transport for citation integrity (#705)
Add a closed-schema, citation-only Codex subscription transport with structured app-server web-search provenance, hermetic containment, fail-visible degradation, producer wiring, tests, and CI guards.

Supersedes #567 and closes #630.

Co-authored-by: dcs-scd <dcs-scd@github.com>
2026-08-11 12:56:01 +08:00
Edward Cheng-I Wu b1b2f7af78 docs(setup): standing preferences via CLAUDE.md — documented design position (#634) (#649)
* docs(setup): standing preferences via CLAUDE.md — documented design position (#634)

Adds the SETUP en/zh-TW section per the #634 decision record: template,
the two honest limitations (model-judgment journal tiers; no
output-directory setting by design), the search_strategy boundary, and
the re-evaluation triggers. Env-flags table cross-references it. Docs
only.

Closes #634

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JMdNxZFKxzm6koV5tB4gG

* fix(docs): #649 codex round-1 — search_strategy owner is the Schema 2 Annotated Bibliography, not the RQ Brief; zh-TW clause-comma fixes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JMdNxZFKxzm6koV5tB4gG

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 14:51:42 +08:00
Edward Cheng-I Wu 49e79a7c99 feat(commands): expose bare /ars-* aliases via explicit frontmatter name (#635)
* feat(commands): expose bare /ars-* aliases via explicit frontmatter name (#633)

All 16 commands/ars-*.md declare name: == filename stem so Claude Code
>= 2.1.216 plugin installs resolve the bare /ars-<mode> alias the
SessionStart announce already advertises; the namespaced form stays
canonical. Pre-2.1.216 tradeoff (name replaces the whole command name,
bare-only surface, namespaced autocomplete lost) accepted and documented
in SETUP en/zh-TW. New check_command_frontmatter_name.py lint (10 tests,
manifest-registered) wired into the command-invariants workflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LjhVWRdN55ugpgVzYQgNg

* fix(lint): close YAML-equivalent name-key re-spelling channel (codex P2)

A bare 'name:' line scan misses '"name":' / 'name :' variants, so a
later YAML-equivalent duplicate could override the resolved command name
while CI stays green. The lint now detects every name-like key variant
and accepts exactly one canonical 'name: <stem>' line; all re-spellings
fail closed. +4 mutation tests (quoted duplicate, spaced-colon duplicate,
sole non-canonical spelling, quoted value).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LjhVWRdN55ugpgVzYQgNg

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 11:56:12 +08:00
Edward Cheng-I Wu 276afa1d05 docs(setup): de-drift Method 4a description-length figure (440-842 → durable comparative form) (#564)
The hardcoded character range had drifted from reality (descriptions now
run 566-986). Replace with the comparison that motivates the section and
cannot go stale: each description exceeds claude.ai's 200-char upload cap
while staying under Claude Code's 1,024-char allowance.


Claude-Session: https://claude.ai/code/session_01EA3EvegVqKrkM62u7k9PHF

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 06:41:43 +08:00
Edward Cheng-I Wu bbc0659272 docs(release): align all doc surfaces for v3.18.0 [skip-closes-check] (#560)
- CHANGELOG: promote [Unreleased] to [3.18.0] - 2026-07-18 (empty
  [Unreleased] kept for the coverage gate)
- README + 4 translated READMEs (zh-TW/zh-CN/ja-JP/ko-KR): version badge to
  v3.18.0, new v3.18.0 changelog-summary section per language, Academic
  Pipeline heading to v3.18.0
- .claude/CLAUDE.md: new "v3.18 Key Additions" section (self-improvement
  survey integration: #547 scope advisory, #548 search-bounded novelty,
  #549 risk-stratified claim gate, #541 cache staleness + live re-validation,
  #540 cross-model reviewer track, #539 judge independence, #550 robustness
  evals, #542 docs anchor), skills table + Version Info to 3.18.0 / 2026-07-18
- academic-pipeline/SKILL.md: frontmatter + Version Info + last_updated to
  3.18.0 / 2026-07-18; whole-file sha256 lock updated same-commit
- .claude-plugin/plugin.json + marketplace.json: version to 3.18.0
- MODE_REGISTRY.md: Last updated to v3.18.0 (2026-07-18)
- docs/ARCHITECTURE.md: title + pipeline component refs to v3.18.0
  (historical v3.17.0 quality-gate row markers preserved)
- docs/SETUP.md + SETUP.zh-TW.md: #541 env rows promoted Unreleased ->
  v3.18.0; stale #517 row corrected Unreleased -> v3.16.0
- scripts/check_spec_consistency.py + its unittest suite: version/date pins
  bumped to 3.18.0 / 2026-07-18 in the same commit (release-prep convention)

Verified locally: check_version_consistency.py (plain + --tag v3.18.0),
check_changelog_covers_merges.py, check_pipeline_boundary_semantics.py
(+66 mutation tests), check_spec_consistency.py + unittest suite,
check_setup_cross_model_parity.py, and the full pytest suite
(3421 passed, 3 skipped, 1 xfailed) all green.


Claude-Session: https://claude.ai/code/session_01Hi625UBf6GX7aeWJpJpSnE

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 15:15:34 +08:00
Edward Cheng-I Wu f38d73f8c1 feat(cache): #541 staleness advisory + opt-in live re-validation for the citation-verification cache (#557)
* feat(cache): #541 staleness advisory + opt-in live re-validation for the citation-verification cache

VerificationCache gains entry_age_days/stale_report (oldest-live-row age per
citation; ARS_CACHE_STALE_ADVISORY_DAYS threshold, default 30, 0 disables,
malformed falls back). Phase A A0.5 emits ADV-CACHE-<n> advisory rows for
stale cache-served verifications (checkpoint display via the #547 template;
never gates); ARS_CACHE_REVALIDATE=1 verifies HIGH-IMPACT-supporting stale
references live (#549 tier composition). Invalidation cascade documented at
the command + gate. Summary schema gains optional cache_age_days +
cache_stale_advisory. 5 new pytest cases; SETUP en/zh-TW document both envs.

External motivation: Ren et al. (2026, arXiv:2607.13104 §6.2.3) — scheduled
review and attenuation; staleness/inconsistency as the signature failure mode
of integrated external knowledge.

Closes #541

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hi625UBf6GX7aeWJpJpSnE

* fix(cache): #541 codex round 1 — real cache-through wiring at the gate, robustness hardening, prose aligned to executable reality

P1: verify_citation/verify_passport run cache-through by default (closes the
#182 Delta-2 forward-decl): four resolvers route via new detailed
contamination-signals wrappers (interoperable cache keys; queried_by kept on
hits; bool-only signal layer preserved byte-for-byte via require_queried_by
parametrization); CLI gains --no-cache; ARS_CACHE_REVALIDATE=1 re-verifies
stale rows live per-row at the gate. P1: the HIGH-IMPACT tier coupling is
dropped (tiers are assigned at E1, unavailable at A0; gate-level stale-row
revalidation replaces it, cost documented). P2s: naive timestamps read as UTC,
malformed rows are misses, clock-skew clamps to 0, advisory flag computed from
the emitted rounded value; conservative oldest-live-row contract stated in the
schema; checkpoint template vocabulary extended to ADV-CACHE-<n> (lock
re-hashed); cascade made unconditional; §6.2.3 framed as design inference.
CLI tests isolated from the real user cache (autouse tmp fixture).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hi625UBf6GX7aeWJpJpSnE

* fix(cache): #541 codex round 2 — omitted-argument sentinel defaults + typed hit validation for the gate

P1: verify_citation/verify_passport use an _UNSET sentinel — omission
constructs the default VerificationCache and derives revalidation from
ARS_CACHE_REVALIDATE; explicit cache=None stays the live opt-out. The
documented non-CLI gate path now caches/revalidates by default. P2: gate
callers require typed hit payloads (matched: real bool, queried_by in
{id,title}) so a malformed row can never launder into lookup_verified; the
bool signal wrapper keeps its historical looser criteria. Gate/transport test
suites gain autouse tmp-cache isolation (default-on can never touch the real
user cache) + sentinel/env-revalidation/malformed-payload cases (145 green).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hi625UBf6GX7aeWJpJpSnE

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 14:30:49 +08:00
Edward Cheng-I Wu a4088f46c9 feat(plugin): #544 SessionStart update-available reminder for plugin installs
Closes #544 (follow-up to #543).

New scripts/ars_update_check.sh + SessionStart announce integration: plugin
installs behind main get a one-line session-start reminder pointing at
/plugin update academic-research-skills. 24h cache, 3s network ceiling,
ARS_UPDATE_CHECK=0 kill switch, every failure path silent, announce
byte-identical when current / disabled / not a plugin install.

Security: the version value that flows into SessionStart additionalContext is
validated by an allow-known grammar (bounded numeric core + at most one
recognized release marker, 32-char cap) at every entry point (remote, local,
both cache fields) before it is cached or emitted, closing a prompt-injection /
JSON-envelope-corruption path. Converged to 0 P1/P2 across three rounds of
parallel codex (gpt-5.6-sol xhigh) + security-review + adversarial checks.

37-test hermetic suite (manifest id 544-update-reminder); SETUP en/zh-TW +
CHANGELOG updated. Spec: docs/design/2026-07-18-544-update-reminder-spec.md.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-18 11:16:31 +08:00
Edward Cheng-I Wu 48bde6a0b1 feat(tiering): #517 model tiering — judgment/execution split, two opt-in directions, default untouched (#520)
* feat(tiering): #517 model tiering — judgment/execution split, two opt-in directions, default untouched

One tiering mechanism per the frozen #517 design (Lance Martin, "Cost
effective harnesses with Fable", 2026-07-10):

- Default (ARS_MODEL_TIERING unset): byte-equivalent — every agent stays
  model: inherit. Same opt-in philosophy as terminal_policies.
- economy (frontier session): 13 execution-type agents dispatch one tier
  below the session model, floor Opus-class, never Sonnet; draft_writer
  flagged as the highest-savings / most quality-sensitive downgrade.
- quality-boost (below-frontier session): judgment-type agents at the
  Stage 2.5/4.5 gates + final-review surfaces step up to the frontier
  tier; nothing is ever downgraded.
- Both directions carry explicit no-op announcements; unknown values
  warn once and behave as unset. Tiers are relative positions, never
  hard-pinned model ids (v3.7.0 opus-floor lesson).

Classification: 39 agents (26 judgment / 13 execution; issue header's
25/12 arithmetic corrected, membership unchanged) in
scripts/model_tiering_manifest.json + the canonical table in
shared/model_tiering.md, pinned to each other and to the *_agent.md
files on disk by scripts/check_model_tiering.py (11 mutation tests;
wired into spec-consistency.yml + local pytest manifest, 60 -> 61).

Consumers: compact "## Model Tiering (#517, optional)" block in the four
SKILL.md files; SETUP en/zh-TW env-table rows; prompt-caching guidance
(same-stage calls reuse the same worker) in the canonical doc.

No agent-file edits (sha256-locked bibliography_agent.md untouched),
no schema change, no hook.

Spec: docs/design/2026-07-12-517-model-tiering-spec.md
All CI lints + 61-entry pytest manifest green locally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(tiering): #517 round-1 codex fixes — dispatch-as-subagent mechanism, exact-set lint, caching scope, wording unification

Addresses the round-1 codex review (2 P1 + 6 P2; 2 no-change with reasons):

- P1 routing reality: canonical doc now states the mechanism honestly —
  a tier is selectable only at subagent dispatch; when a direction
  applies to an inline role, the session dispatches it as a subagent
  pinned to the target tier (that IS the mechanism); impossible-dispatch
  falls open to inline-on-session-model with a one-line announcement.
  PERFORMANCE.md en/zh "no separate model routing layer" reconciled.
- P2 caching-vs-default: same-worker guidance scoped to active
  directions; unset default byte-equivalent incl. dispatch shapes.
- P2 semantics drift: quality-boost = jump TO the frontier (not one
  increment); warn-once wording unified; SETUP rows name the
  final-review surfaces.
- P2 lint subset-only + hardcoded dirs: exact per-(tier,skill)
  token-set comparison (missing/extra/duplicate tokens, per-row counts,
  duplicate rows) + repo-wide stray sweep; tests 11 -> 15.
- P2 stale verification record: 60 -> 61 manifest entries in the spec.
- No-change (documented): the PR-body session link is the repo's
  established harness attribution convention (48 occurrences in recent
  main history); Lance Martin/Anthropic is published-source author
  attribution consistent with the repo's citation norm.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(tiering): #517 round-2 codex fixes — dispatch-time tier resolver, claim-ref audit surface, Stage 3' roster, PERFORMANCE cost qualification

- P1 tier resolver: new "Resolving a tier at dispatch time" section — the
  no-hard-pinning rule governs repo files; the dispatch call resolves the
  relative target from the runtime's own model information (alias or
  current-generation id, ephemeral only); unresolvable -> announced no-op.
- P1 claim_ref_alignment_audit: quality-boost surface corrected to its
  real dispatch slot (opt-in Stage 4->5, ARS_CLAIM_AUDIT=1), removed from
  the 2.5/4.5 gate list; SKILL blocks + SETUP rows updated.
- P2 Stage 3' roster: canonical text now matches ARCHITECTURE (narrow
  re-review team; judgment roles there = eic + editorial_synthesizer);
  caching example rewritten accordingly.
- P2 PERFORMANCE en/zh: plugin-agent cost-unchanged claim qualified with
  the unset condition + economy behavior for plugin-exposed execution
  agents (report_compiler).
- P2 PR body refreshed (dispatch-as-subagent wording, 15 tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(tiering): #517 round-3 P2 residuals — caching example covers the full 3' narrow team; PR body audit surface

- Caching example names the authoritative Stage 3' re-review roster
  (field_analyst + eic + editorial_synthesizer) and states the reuse
  rule is tier-independent — field_analyst is the economy-affected role.
- PR body quality-boost bullet gains the opt-in Stage 4→5 claim-ref
  audit surface (was omitted after the round-2 canonical correction).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 03:51:12 +08:00
Edward Cheng-I Wu 6cee432e6a feat(cross-model): #518 gate hardening — risk-stratified sampling, blind disagreement checkpoints, id-status allowlist, promotion bakeoff (#519)
* feat(cross-model): #518 gate hardening — risk-stratified sampling, blind disagreement checkpoints, id-status allowlist, promotion bakeoff

Four upgrades to shared/cross_model_verification.md + consumers, per the
2026-07-11 cross-model consult frozen in #518:

1. Integrity-gate cross-model sample: uniform random 30% (min 5 max 15) →
   risk stratification (100% of high-impact refs uncapped + 10% random
   remainder min 3 max 10; Stage 4.5 adds 100% of new/changed-claim refs
   + control sample). integrity_verification_agent updated in lockstep;
   results table gains a Tier column.
2. Blind disagreement checkpoints at the two irreversible decisions
   (research_architect design freeze; editorial_synthesizer final
   decision): independent structured cross-model decision, anchoring-
   blind, divergence = targeted rebuttal + user escalation — review
   trigger, never a vote, never averaged. Sprint-contract boundary kept
   closed (drivers never enter the scoring matrix).
3. "6th reviewer — Planned" retired, not deferred (counterproductive-
   conditions list matches documented anti-patterns); live mirrors
   (.claude/CLAUDE.md, raise_framework, SETUP en/zh-TW) drop the claim;
   historical release notes untouched.
4. Detection snippet separates endpoint routing from id trust:
   CROSS_MODEL_ID_STATUS=validated|provisional|unlisted with explicit
   unlisted-id warning; routing byte-identical (grounded precedence
   preserved). Plus §Promotion Bakeoff operationalizing the gpt-5.6-sol
   provisional→validated non-inferiority run (5 thresholds, smoke-test
   entry gate).

Spec: docs/design/2026-07-12-518-cross-model-gate-hardening-spec.md
All CI lints + 60-entry pytest manifest green locally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(cross-model): #518 round-2 codex fixes — NEW-CHANGED tier, primary pre-commitment, panel_size N, bakeoff reproducibility + validated-vs-default split

Addresses all 6 findings from the round-1 codex review (gpt-5.6-sol, xhigh):

- Stage 4.5 tier gap: 4-tier set (HIGH-IMPACT > NEW-CHANGED > CONTROL/RANDOM),
  mutually exclusive by precedence, one verification per reference; CONTROL
  replaces RANDOM at the final gate.
- Cap contradiction: stale "max 15 survives" sentence removed; RANDOM/CONTROL
  capped at 10 each, 10% round-up rounding pinned.
- Design-freeze primary decision: architect commits the same enum + drivers
  BEFORE the blind call, with criteria per enum value; blueprint Output Format
  gains a Design-Freeze Checkpoint Audit section.
- Sprint-contract integration: editorial checkpoint is explicitly post-Step-3
  (never extends the three-step arithmetic); input is the panel's panel_size N
  usable cards (5 full-mode / 2 methodology_focus), not a hardcoded five.
- Bakeoff reproducibility: versioned, labeled, sha256-recorded probe-set
  fixture is a precondition; >=2/3 majority verdict with conservative
  1-1-1-split handling defined.
- Non-inferiority != default flip: full pass earns provisional->validated;
  the recommended default flips only with a stated superiority or
  operational-benefit reason.

Spec + CHANGELOG updated to as-built; agents/ mirror re-copied.
All CI lints + 60-entry pytest manifest green locally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(cross-model): #518 round-2 verify fixes — blindness leak, promotion wording, audit transport-error, cost bounds, SETUP tier coverage

Addresses all 6 findings from the round-2 codex verify (1 P1 + 5 P2):

- P1 blindness leak: the architect now commits its structured decision
  SEPARATELY from the blueprint and sends the cross-model a sanitized
  payload with the audit section stripped; the audit section is populated
  only after the comparison.
- Two remaining canonical statements implying non-inferiority => default
  flip aligned to the validated-vs-default split.
- Design-Freeze Checkpoint Audit gains unavailable / transport-error
  representations.
- Cost table: bounded ranges replaced with a worked example (17 calls)
  + explicit no-fixed-upper-bound statement.
- SETUP en/zh-TW feature rows now mention the Stage 4.5 NEW-CHANGED tier.
- Spec Files-touched inventory adds the agents/ mirror; review-round
  annotations normalized (round 1 = first review, round 2 = verify).

All CI lints + 60-entry pytest manifest green locally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(cross-model): #518 round-3 P2 residuals — audit N/A fields on transport failure, Limitations tier phrasing

- Design-Freeze Checkpoint Audit: drivers/confidence gain explicit
  none/N/A values when the cross-model is unavailable; step 5 failure
  representation aligned to the schema.
- Limitations §2 rewritten per-gate: RANDOM at Stage 2.5, NEW-CHANGED +
  CONTROL at Stage 4.5.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 03:07:04 +08:00
Edward Cheng-I Wu 93481c37ac feat(cross-model): list gpt-5.6-sol as provisional verifier + explicit reasoning-effort control (#515)
* feat(cross-model): list gpt-5.6-sol as provisional verifier + explicit reasoning-effort control

Verified first-party against OpenAI's model page and GPT-5.6 guide
(2026-07-11): Responses API + hosted web_search supported; effort enum
none|low|medium|high|xhigh|max (default medium); premium is
reasoning.mode "pro" on the standard slug (no -pro model id); standard
rates identical to gpt-5.5. ARS-specific behavior is unvalidated, so
gpt-5.5 stays the recommended default and gpt-5.6-sol is labeled
provisional. New ARS_CROSS_MODEL_REASONING_EFFORT (default medium) makes
the verifier's effort explicit; SETUP en/zh-TW mirror the example lines
(parity lint green). New scripts/cross_model_smoke_test.sh is the manual
live promotion gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(cross-model): apply codex review P2s — preserve provider effort default, whole-word verdict match, fail-closed effort echo

Unset ARS_CROSS_MODEL_REASONING_EFFORT now omits the reasoning field
entirely (provider default preserved per model) instead of forcing
medium; smoke test matches verdict tokens whole-word (UNVERIFIED can no
longer false-pass as VERIFIED) and fails closed when a requested effort
comes back without an echo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* docs(changelog): fill in PR number #515

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

* fix(cross-model): smoke test enforces single-occurrence verdict token (codex re-review P2)

A repeated verdict token now fails the gate instead of warning — the
fixture prompt demands exactly one verdict, and a model that cannot
comply with that instruction is itself a gate signal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FczvB1WJjfumdJTg9YyL3X

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 02:06:59 +08:00
Edward Cheng-I Wu cf973a8f7f fix(harness): retire expired scaffolds from 17-agent continuation audit (2 P1 + 9 P2) (#490)
* fix(harness): retire expired scaffolds from 17-agent continuation audit (#489)

Apply the 11 user-accepted findings from audits/harness-retirement-2026-07-04.md
(4-batch Fable 5 audit + codex cross-model challenge; 2 P1 + 9 P2):

- B2-F01/B2-F02 (P1): deep-research socratic_mentor — delete stale 10/15-round
  constants contradicting the v3.0 40/60 + exploratory carve-out; merge the
  duplicated Auto-End machinery into one 6-condition authority
- B3-F02 (P1, threshold=30 per user): academic-paper socratic_mentor — Auto-End
  Rules table becomes the single authority; conflicting 15-round bullets removed
- B3-F01: 12-row question-template tables -> 1 canonical example per type
- B3-F03: visualization Steps 2-6 narration -> pointer lines (6.5/6.6 untouched)
- B1-F01/B1-F02: orchestrator — drop happy-path resume example; dispatch
  sub-list -> Checkpoint Confirmation Semantics pointer; add missing
  `view progress` row; fix duplicate step numbering
- B1-F03: state_tracker — compress zero-information stage "2"/"3p" exemplars
- B2-F03: report_compiler — trim basic citation few-shot, keep non-obvious rules
- B4-F01: stale "prompt-level only / hook deferred to #134" enforcement sentence
  rewritten at 23 agents + 4 SKILL.md (guard shipped in #294); mirrors resynced
- B4-F02: SETUP.md + zh-TW — gpt-5.4/Opus-4.8 lineup drift (6 lines each)

User-rejected: B3-F04 (keyword mapping table stays), B4-F03 (field_analyst
examples stay). 2026-06-10 F-007 closed as verified-no-rewrite-needed.

Verification: run_ci_pytest_manifest 58/58 green; phase-boundary, write-scope,
spec-consistency, collaboration-depth, mirror-sync lints green; personal-boundary
scan 991 files / 0 violations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YBdGUAb184hmuiRiWAm4A9

* fix(harness): carry stop-here/change-settings aliases into semantics table (codex review P2)

The B1-F02 dedup made the Checkpoint Confirmation Semantics table the single
authority but dropped two aliases documented only in the deleted dispatch
sub-list. Table is now a strict superset of the removed copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YBdGUAb184hmuiRiWAm4A9

* refactor(harness): /simplify pass — tighten enforcement sentence, fix pointer label

- S1/Efficiency: enforcement sentence body 39->35 words across 23 agents
  (+2 mirrors resynced); drops non-semantic slack (~16 tok/dispatch x 24
  surfaces), keeps all five load-bearing facts and spec vocabulary
  (deterministic, rescope). Lint pins only the prefix marker — green.
- S2: visualization Step 4 pointer label aligned to the actual heading
  "Figure Numbering and Captions (APA 7.0)".
- ALT-1 (defrift lock: canonical-string pin in the phase-boundary lint +
  SETUP model-token parity) deliberately NOT done here — tracked as #491.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YBdGUAb184hmuiRiWAm4A9

* chore(lint): bump bibliography_agent F2 baseline hash after B4-F01 sentence rewrite

The v3.9.4 F2 ownership guard pins bibliography_agent.md by sha256 so any
edit forces review. Reviewed: the B4-F01 apply changed only the Phase
Boundary enforcement-status sentence; no M6 citation-provenance / M5
version-family / temporal logic moved, so the invariant holds. Baseline
updated per the lint's documented procedure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YBdGUAb184hmuiRiWAm4A9

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 13:08:39 +08:00
Edward Cheng-I Wu 8157a15b3b docs(release): align all doc surfaces for v3.14.0 (#481)
* docs(release): align all doc surfaces for v3.14.0

- CHANGELOG: new [3.14.0] entry (#480 Claude Science importability, #479
  eval-comment renderer, #478/#477 prompt-debt retirement, #473 platform-port
  reminder, #464/#465/#469/#471 docs) + roll the 16-entry [Unreleased]
  backlog (code landed before the v3.13.0 tag) into the versioned record
  with a provenance note.
- All five READMEs: version badge -> v3.14.0, pipeline version, translated
  v3.14.0 changelog entry, Claude Science import paragraph, five->six
  installation methods. (ja/ko/zh-CN entries machine-translated pending
  native review.)
- docs/SETUP.md + SETUP.zh-TW.md: new Method 5 — Claude Science import
  (steps, snapshot semantics, what transfers / what does not).
- .claude/CLAUDE.md: v3.14 Key Additions + suite version + table.
- Version metadata: plugin.json, marketplace.json, academic-pipeline
  SKILL.md frontmatter/title/version table, CITATION.cff (version +
  date-released), POSITIONING.md citation, copilot-instructions.

check_version_consistency passes (8 invariants); no eval/gate/skill
behavior changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jcH7gEkVTQ1baMbVedSZp

* docs(release): bump spec-consistency pins + remaining v3.14.0 surfaces

CI caught the surfaces the first pass missed: check_spec_consistency.py's
expected-literal pins (+ its test fixtures), MODE_REGISTRY.md last-updated,
academic-pipeline SKILL.md Version Info date, docs/ARCHITECTURE.md
current-component markers (7 spots incl. mermaid node), and the ja README's
full-width pipeline heading.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jcH7gEkVTQ1baMbVedSZp

* docs(i18n): apply agy review P3s — byte-identical zh-TW, restore "prompt" in ja/ko

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jcH7gEkVTQ1baMbVedSZp

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 10:33:02 +08:00
Edward Cheng-I Wu c086f19d87 docs(release): align all release docs to v3.11.0 (#182) [skip-closes-check] (#321)
* docs(release): align all release docs to v3.11.0 (#182) [skip-closes-check]

The #182 citation-verification-gate feature code merged across PR-A/B/C1 but
the release docs still said v3.10.0 and the CHANGELOG [Unreleased] body was
empty. This aligns the 6 release-discipline invariants to v3.11.0.

- CHANGELOG: convert [Unreleased] → [3.11.0] entry covering all five #182 deltas
  + C-V6 + lint (invariant 1).
- README (en/zh-TW/zh-CN/ja-JP): version badge → v3.11.0; "Academic Pipeline"
  heading → v3.11.0; zh-TW adds a faithful v3.11 changelog entry; en/zh-CN/ja-JP
  sync version markers only (invariants 2/3/5).
- .claude/CLAUDE.md: Skills Overview pipeline row → v3.11.0; Suite version →
  3.11.0; Last Updated → 2026-06-04; add "v3.11 Key Additions" section.
- docs/ARCHITECTURE.md: title + 6 pipeline-version markers → v3.11.0; evolution
  timeline gains v3.10.0 (a prior-release omission) + v3.11.0; Stage 5 FINALIZE
  gate now documents formatter rule 11 (v3.10 HIGH-BLOCK) + rule 12 (v3.11
  citation_existence strict).
- docs/SETUP{,.zh-TW}: add the citation-verification-cache section + the
  ARS_VERIFICATION_CACHE_PATH optional flag; correct the stale Opus 4.7 → 4.8
  model recommendation.
- docs/PERFORMANCE{,.zh-TW}: note that the #182 gate calls external APIs (no
  Claude token cost) + the cache amortization; correct Opus 4.7 → 4.8.
- academic-pipeline/SKILL.md + plugin manifests: version → 3.11.0 (invariant 6).

Only academic-pipeline tracks the suite version; the other three skill versions
are unchanged. #182 was closed earlier (2026-06-02), so this does not re-close it.

Version-consistency lint passes; full suite 2078 passed / 3 skipped. No tag in
this PR — tagging is a separate, deliberate step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(release): sync version-mirror lint + fixtures + MODE_REGISTRY to v3.11.0 [skip-closes-check]

The first PR-C2 commit aligned the human-facing docs but missed three mirrored
surfaces that CI's spec-consistency lint guards — caught by the CI run, not the
local check_version_consistency lint (which reads CHANGELOG dynamically; the
spec lint hardcodes expected version strings).

- MODE_REGISTRY.md: "Last updated: v3.10.0" → v3.11.0 (the 15th release doc,
  outside the original sweep).
- scripts/check_spec_consistency.py: expected-string assertions bumped to
  v3.11.0 (badge / tag link / Suite version / "Academic Pipeline (vX)" heading /
  MODE_REGISTRY last-updated). Changelog-entry assertions ADD v3.11.0 while
  KEEPING the v3.10.0 history-guard line (these assert past entries still exist,
  so they must not be replaced).
- scripts/test_check_spec_consistency.py: fixture templates parameterize the
  "Academic Pipeline (vX)" heading and carry both v3.11.0 + v3.10.0 changelog
  entries; aligned/stale fixtures and drift assertions rebased to v3.11.0 so the
  stale-badge regression tests still exercise real drift.
- README.zh-CN.md + README.ja-JP.md: add the v3.11 changelog entry the lint now
  requires, each marked [machine-translated] pending native-contributor review
  (zh-TW was authored natively and is unmarked).

Spec lint + its self-tests pass; version-consistency lint passes; full suite
2078 passed / 3 skipped. Mutation-checked: reverting a badge to v3.10.0 still
fails the lint (not accept-all).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 17:13:12 +08:00
Edward Cheng-I Wu 57507ef7a0 docs(SETUP): fix Method 3 (Cowork) — zip upload, not ~/.claude/skills/ (#309)
Method 3 told users to symlink/copy the four skill folders into
~/.claude/skills/ and enable a toggle under Customize → Skills. That
path is Claude Code's; Cowork does not read it, so the skills never
appeared (reported in discussion #306). PR #307's "verified" root cause
was incorrect.

Verified first-hand against the on-disk skill store: Cowork loads skills
uploaded via Settings → Capabilities → Skills, each as its own zip,
registered by a server-issued skill ID. Uploading deep-research this way
installs cleanly with the full description intact and /deep-research in
the palette.

- Rewrite Method 3 in SETUP.md + SETUP.zh-TW.md: zip-per-skill build +
  Settings upload + use + the orchestration trade-off vs Claude Code.
- Fix a stale line claiming Method 3 keeps orchestration intact.
- Fix QUICKSTART wording that listed Cowork next to ~/.claude/skills/.
- EN/zh-TW H4 structure kept in parity.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 19:08:23 +08:00
Edward Cheng-I Wu 8316192358 docs(SETUP): add Cowork enable-skill step + fix command-palette wording (#307)
Method 3 (Cowork) registered the four skills via symlink but never said
they must be enabled in Customize → Skills before they appear in the `/`
command palette or get invoked. Verified by direct testing in Claude
Desktop: a registered-but-not-enabled personal skill does not show in the
palette; toggling it on (panel shows "Enabled") makes it appear.

- Add step 6: enable each of the four skills in Customize → Skills.
- Fix the "type / and select an available skill" line, which implied a
  freshly registered skill is selectable in the palette without enabling.
- Mirror both changes in SETUP.zh-TW.md (H2 / step structure preserved).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 23:40:00 +08:00
Edward Cheng-I Wu ea87019b33 docs: signpost Codex users to ars-codex sibling distribution (#92)
Strengthen the existing ars-codex link by switching from a passive
"sibling distribution" mention to a direct "Using Codex CLI?" call-out
in README.md, mirror the same call-out into README.zh-TW.md (which was
missed in 8988ca4), and replace the  Codex CLI bullet in both
SETUP.md and SETUP.zh-TW.md with an active ➡️ signpost so Codex users
see a recommendation, not a "not supported" framing.

No content scope change: same canonical URL, same Platform ports
policy in CONTRIBUTING.md, same POSITIONING.md framing.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 21:09:39 +08:00
Edward Cheng-I Wu 6006c5b5fa feat(v3.7.0 Phase 1 MVP): Claude Code plugin packaging — manifest + skills/ symlinks + dual-track install (3 codex rounds, 0 findings) (#68)
* docs(design): add v3.7.0 plugin packaging roadmap

Phase 1 MVP (1-2h): .claude-plugin/plugin.json + marketplace.json + skills/ symlinks
Phase 2 (1-2d): 10 slash commands + 7 agent council members + hooks (codex audit pipeline)
Phase 3 (0.5d): marketplace publish + auto-update guidance + version bump checklist update
Phase 4: traffic monitoring (clones / install ratio post-plugin)

Verified facts via claude-code-guide agent:
- Plugin auto-update: third-party plugins default OFF, user toggles per marketplace
- Platform support: CC CLI / VS Code / JetBrains only — claude.ai web / cowork / API NO
- Codex CLI: incompatible (separate AGENTS.md ecosystem); use academic-research-skills-codex fork
- Min manifest: name + description (+ optional version)

Isolation from concurrent v3.6.7 session: 0 path overlap, fetch-before-push.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(v3.7.0): patch roadmap with v3.6.7-derived updates + verified plugin spec facts

Post-v3.6.7 ship retrospective patch (2026-05-05). Added "Update note" block at top of roadmap that supersedes parts of the original 2026-04-30 draft:

- Verified plugin manifest spec facts (claude-code-guide query 2026-05-05): skills/ auto-discovery confirmed, symlinks resolve transparently per docs, min manifest = name only, marketplace.json shape uses source.{source: directory, path: ...} not plugins[].path.
- Phase 2 hooks must wrap scripts/run_codex_audit.sh (already on main from v3.6.7 Phase 6.1), not reinvent codex audit.
- Phase 2 agent council shrinks 7→3 (synthesis_agent / research_architect_agent / report_compiler_agent) per v3.6.7 Phase 6.7 inversion sweep.
- Phase 2 plugin agent prompts must symlink or single-source from repo agents to avoid Pattern C3 attack surface re-introduction.
- Phase 3 version sweep grows 7→9 categories (.claude-plugin/plugin.json added).
- Bash 4+ hook safety reminder for macOS stock Bash 3.2 users.
- Phase 0 inserted: spec verification + SKILL.md frontmatter check + CI baseline. Done as of this commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(v3.7.0 Phase 1 MVP): Claude Code plugin packaging — manifest + skills/ symlinks + dual-track install docs

Phase 1 of plugin packaging roadmap (docs/design/2026-04-30-ars-v3.7.0-plugin-packaging-roadmap.md). Lets users install ARS via `/plugin marketplace add Imbad0202/academic-research-skills` + `/plugin install academic-research-skills` while preserving the existing clone+symlink install path for the 4.3k clone+symlink user base.

What lands:
- .claude-plugin/plugin.json: name, version 3.7.0, description (covers v3.6.7 audit gate + v3.6.8 generator-evaluator contract), author, repo metadata, CC-BY-NC-4.0 license, 9 keywords.
- .claude-plugin/marketplace.json: self-hosted marketplace shape per code.claude.com docs (source.{source: directory, path: .}); supersedes the speculative plugins[].path shape in the original roadmap.
- skills/: relative symlinks pointing to the four sibling skill directories (deep-research, academic-paper, academic-paper-reviewer, academic-pipeline). Plugin loader resolves symlinks transparently per docs; legacy clone+symlink users unchanged.
- docs/SETUP.md + docs/SETUP.zh-TW.md: new "Method 0: Claude Code Plugin (v3.7.0+, recommended)" section with auto-update guidance + platform-scope caveats (CC CLI/IDE only; claude.ai web/Claude for Work/API not supported; Codex CLI uses fork).
- README.md + README.zh-TW.md: top of "Setup & installation" surfaces the one-line plugin install for Claude Code CLI/IDE users.

Verified pre-commit:
- python3 -c "import json; json.load(...)" parses both .claude-plugin/*.json.
- ls -la skills/ shows 4 relative symlinks; readability check on each `<skill>/SKILL.md` resolves OK.
- Repo regression: 742 pytest passed + 3 skipped (Bash 3.2 E2E gate) + 251 unittest = 993 green.
- spec_consistency + version_consistency lint scripts pass.
- No PII / hei-platform / HEEACT references in diff.

Phase 2 (slash commands + agent mirrors + hooks wrapping run_codex_audit.sh) and Phase 3 (marketplace publish + auto-update) ship as separate PRs per roadmap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(v3.7.0 Phase 1): codex review round 1 — 2 P1 + 1 P2 closed

Round 1 trajectory: P1×2 + P2×1 + P3×0 → 0 (target).

Closures (codex empirically validated via `claude plugin validate .`):
- F-001 P1 marketplace_missing_owner: `claude plugin validate .` rejects with `owner: Invalid input: expected object, received undefined`. Earlier claude-code-guide spec query (2026-05-05) didn't surface owner as required. Fix: add top-level `"owner": {"name": "Cheng-I Wu", "url": "https://github.com/Imbad0202"}` per validator.
- F-002 P1 marketplace_invalid_source_shape: `plugins[0].source` is a RELATIVE PATH STRING starting with `./`, not the object shape `{"source": "directory", "path": "."}` that earlier docs query reported. Validator output: `plugins.0.source: Invalid input`. Fix: source → "./".
- F-003 P2 roadmap_documents_invalid_schema: roadmap update note's "Correct shape" block was based on the same erroneous spec. Fix: update note now shows the empirically-validated shape (owner + source as path string), explicitly marks the original Task 1.3 snippet below as obsolete.

References: code.claude.com/docs/en/plugins-reference, code.claude.com/docs/en/plugin-marketplaces, plus empirical `claude plugin validate .` run by codex.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(v3.7.0 Phase 1): codex review round 2 — 1 P2 closed (validator clean)

Round 2 trajectory: P2×1 → 0.

Closure:
- F-004 P2 plugin_update_command_misuse: docs used `/plugin marketplace update <name>` for manual plugin refresh, but that command only refreshes the marketplace source list — it doesn't update installed plugins. Correct command for refreshing an installed plugin is `/plugin update <name>`. Fix: docs/SETUP.md + docs/SETUP.zh-TW.md + roadmap Task 3.1 + Task 3.2 prose all updated to use `/plugin update` for plugin refresh, with a clarifying parenthetical about the marketplace-update distinction.

Codex empirically validated this round:
- `claude plugin validate .` passes
- `claude plugin validate .claude-plugin/plugin.json` passes
- `claude plugin tag --dry-run .` passes
- 4 symlinks resolve to all SKILL.md files

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:52:27 +08:00
Edward Cheng-I Wu 602af4bd36 fix(v3.6.5.2): mark claude.ai Method 4a not recommended for this Claude Code-native suite (#46)
* spec(v3.6.5.2): brief — claude.ai Method 4a scope clarification

Repositions v3.6.5.2 from the originally planned `SKILL.md` description
trim to a SETUP doc clarification. The trim direction was abandoned
because (1) only claude.ai's Custom Skills upload UI enforces 200 chars
(spec and Claude Code allow 1024), (2) ARS depends on Claude Code-only
Task / subagent dispatch and Material Passport cross-session handoffs
that are not part of the documented claude.ai Custom Skill runtime, and
(3) trimming would weaken Claude Code and Cowork routing — the platforms
ARS was built for — to unblock a path that delivers an unverified
partial fit.

Brief drafted, 5-round codex meta-review reaches zero P1 + zero P2 ship
gate. Patches the SETUP doc + CHANGELOG, no SKILL.md / agent / schema /
script / test changes.

* fix(v3.6.5.2): mark claude.ai Method 4a not recommended for this suite

SETUP.md Method 4 supersection rewritten:
- Method 4b (Project + GitHub integration) now presented first as the
  recommended claude.ai path. Brings repo into Project knowledge for
  reading and citation without losing fidelity.
- Method 4a (Custom Skill upload) marked not recommended for this suite
  with rationale: ARS depends on Claude Code's Task / subagent dispatch
  and Material Passport cross-session handoffs that are not part of the
  documented claude.ai Custom Skill runtime, and trimming descriptions
  to fit claude.ai's 200-char cap would weaken Claude Code and Cowork
  routing in exchange for an unverified partial fit.
- Method 4a install commands kept in place for users who want to try
  it anyway, framed as "if you want to try this path despite the
  limitations". Zip-root packaging constraint reinstated.
- Prerequisites split per sub-method, citing Anthropic's plan
  availability and code-execution requirement docs for Method 4a, and
  Projects availability docs for Method 4b.
- Forward-looking caveat ("we have not run a live upload to characterise
  this in detail") added so the recommendation is grounded in the
  documented runtime scope, not in measured failure.

SETUP.zh-TW.md mirrors the English changes end-to-end.

CHANGELOG.md adds a v3.6.5.2 entry and reframes the v3.6.5.1 entry's
forward-promise of a description trim as "originally forecast … but
v3.6.5.2 instead documents Method 4a as not recommended."

No SKILL.md (frontmatter or body), no agent file, no schema, no script,
no test, no workflow, no version bump, no .claude/CLAUDE.md changes.

Refs: issue #44, brief commit b865371.
2026-04-27 22:16:30 +08:00
Edward Cheng-I Wu aea9d24e2f fix(v3.6.5.1): SETUP doc correctness — install paths, claude.ai distinction, prereqs (#45)
* docs(SETUP): add known-broken warning banners to Method 3 + Method 4

Issue #44 (philpav, 2026-04-27): Cowork install does not register
skills, claude.ai install does not work as documented. Codex audit
on docs/SETUP.md found the root causes:

- Method 3 instructions clone the whole repo to .claude/skills/
  academic-research-skills/, burying every internal SKILL.md one
  level too deep — Cowork's discovery (.claude/skills/<skill>/
  SKILL.md) never finds them.
- Method 4 frames claude.ai's GitHub integration as a Skill install
  path, but it actually loads files into Project knowledge (static
  retrieval context), not the Skills system. Real Skill upload needs
  per-skill zip via Settings → Capabilities → Skills, and current
  description fields exceed the 200-char cap and would be rejected.

Banner-first hotfix (Codex second-opinion advice 2026-04-27):
add prominent WARNING banners on both methods immediately so users
stop following broken instructions. Includes the 4-symlink Cowork
workaround inline + cross-machine cp -R caveat. Full SETUP.md
rewrite (v3.6.5.1) and SKILL.md description trim (v3.6.5.2) follow.

This commit only adds banners; it does not yet rewrite the broken
instructions below them. Users following the banner workaround will
succeed; users skipping the banner and reading the original
instructions will still fail (those will be fixed in v3.6.5.1).

* spec(v3.6.5.1): SETUP fix implementation brief — 3-round codex meta-review

Brief defines the constraint contract for the v3.6.5.1 SETUP.md
rewrite. Given to a future Codex run as the non-negotiable spec
sheet covering ARS-specific invariants, F1-F7 fix targets,
authoritative Anthropic doc URLs, validation gate, and ship rules.

Codex meta-review convergence (per
feedback_codex_iterative_spec_review_to_zero.md discipline):

- Round-1: 10 findings (3 P1 + 5 P2 + 2 P3); verdict: brief
  needs revisions before use. Issues spanned authoritative-source
  ordering (issue #44 reply was top, no inline content), validation
  realism (required Claude Code session unavailable in single-machine
  dev), §1.6 vs §4 sweep contradiction, banner removal commit
  authority, F2 wording self-contradiction, F3-F7 missing source
  URLs, F1 consolidation rule conflict with §8 drafter zone, §5
  developer-environment risk, §6 ship gate too absolute.

- Round-2: 2 cascade P2 (Fix-γ §1.6/§4 still conflicting; Fix-κ §6
  ship gate too lenient with reject-with-rationale on P1+P2);
  verdict: do not ship.

- Round-3: PASS (0 findings, 7/7 YES, ship verdict SHIP).

Brief structure:
- §1 Non-negotiable invariants (skill folder layout, discovery rule,
  Method 4 sub-method split, public repo Ruleset, authoritative
  source order with all 9 Anthropic doc URLs + verbatim issue #44
  reply, allowed-edit set with sweep/edit boundary)
- §2 F1-F7 fix specs (each with authoritative source URL)
- §3 Banner removal (drafter prepares diff, human commits)
- §4 Sweep checklist (sweep broad, edit only allowed)
- §5 Validation gate (5.0 env protection mandatory; 5.1 required
  filesystem path-shape; 5.2 optional live discovery; 5.3 report)
- §6 Codex review iteration + ship gate (P1/P2 zero non-negotiable,
  P3 either fixed or accepted-with-rationale-in-PR)
- §7 PR body template
- §8 Drafter judgement zone (explicit delegation list)

Next: feed brief + audit raw + current SETUP.md to Codex as drafting
input. Codex outputs SETUP.md rewrite. Iterate to ship gate.

* fix(SETUP v3.6.5.1): rewrite Method 3 + Method 4 per implementation brief

Issue #44 (philpav, 2026-04-27) — Cowork install does not register
skills, claude.ai install does not work as documented.

Rewrites docs/SETUP.md per the v3.6.5.1 implementation brief
(commit ca21242), addressing 7 audit findings:

- F1 (P0) Method 3 install path: Option A (symlink) and Option B
  (copy) now install each of the four skill folders separately
  into ~/.claude/skills/, producing the discovery shape
  ~/.claude/skills/<skill-name>/SKILL.md instead of one level
  deeper. Hard rule applied: every install command names all four
  skills explicitly (no for loop) so readers cannot misuse.
  Option A includes the cross-machine cp -R caveat for cloud-
  synced ~/.claude/skills.

- F2 (P0) Method 4 conceptual split: Method 4a is the real
  Custom Skill upload path (Settings → Capabilities → Skills,
  one zip per skill, top-level entry <skill-name>/SKILL.md);
  Method 4b is the GitHub-integration fallback knowledge mode
  with explicit "this is NOT a Skill install" framing. Method 4a
  is documented in advance with a known-blocker note that the
  200-char description cap unblocks in v3.6.5.2.

- F3 (P1) Method 3 prerequisites: latest Desktop, internet,
  app stays open during execution, folder permissions, paid
  plan, org-level controls.

- F4 (P1) Method 4 prerequisites: split into 4a (no GitHub auth)
  and 4b (Anthropic GitHub App authorisation, Team/Enterprise
  owner enablement).

- F5 (P2) Cowork UI literal labels: mode selector (Chat / Cowork),
  Tasks, Use an existing folder, Cowork Project. No paraphrasing.

- F6 (P2) Skill invocation: description-based routing as primary
  mechanism + / command palette + + capability picker as explicit
  UI surfaces. Removes the trigger-phrase-only oversimplification.

- F7 (P2) Method 4b directory table: scripts/ row added (adapter
  + validator workflows). Capacity rationale rewritten against
  current Anthropic Project file limits (per-file 30 MB, count
  unlimited).

Removes the d176578 banners (their purpose was harm reduction
during the patch interval; now superseded by correct instructions).

Codex iteration:
- Round-1: Codex drafted from brief + audit raw + current SETUP.md.
- Reviewer applied two manual fixes — Method 4a "immediately after"
  loosened to "in a follow-up patch"; Method 4b table demoted .claude/
  to Optional (avoids redundancy with recommended Project Instructions).
- Round-2: 2 P2 missing source URLs (Cowork Projects + Projects
  static knowledge). Both added.
- Round-3: PASS (0 P1+P2). Ship verdict SHIP.

Sweep + validation + PR follow as separate commits.

* fix(QUICKSTART v3.6.5.1): align Step 1 install commands with new SETUP.md

QUICKSTART.md:14 had the same buried-skill bug as docs/SETUP.md
Method 3 — cloning into .claude/skills/academic-research-skills/
puts every SKILL.md one level too deep, so Claude Code/Cowork
never discover them.

Replaces with the four-skill symlink approach matching SETUP.md
Method 3 Option A (per F1 hard rule: explicit per-skill commands,
no for loop). Adds backpointer to SETUP.md for the copy-based
alternative and other install methods.

Sweep follow-up to commit ff935db (SETUP.md rewrite).

* fix(SETUP zh-TW v3.6.5.1): mirror English rewrite, full Method 1-4 update

Mirrors docs/SETUP.md (commit ff935db) into zh-TW. Rewrites Method
1-4 with the same F1-F7 fixes; preserves the existing Chinese
phrasing for non-install sections (literature_corpus adapters,
optional env flags, cross-model verification) where those are
not contradicted by the English audit.

Translation discipline (per user's writing rules):
- No em dashes (——) in Chinese prose (only inside shell/code comments).
- No formal-document connectors as paragraph openers (然而, 此外,
  因此, 值得注意的是 etc.).
- No 吾人 archaic pronoun.
- No translation-style padding ("一個重要的考量是" etc.).
- Skill / Cowork / Project Knowledge use the established Chinese
  terms (Skill, Cowork untranslated; Project 知識庫; 設定 → 功能 → Skills).
- UI literal labels kept in English with Chinese gloss in parens
  (e.g. "Use an existing folder"(使用既有資料夾)) so users can
  match what they click in the actual UI.
- agentic kept untranslated, consistent with ARS English terminology.
- All 9 Anthropic doc URLs from English version preserved.
- Bash code blocks identical to English (4 skills explicit, no for loop).

Codex iteration:
- Round-1: codex drafted Chinese mirror under the 8 writing-rule constraints.
- Reviewer applied 5 polish fixes:
    * Removed "請請" typo + retired 控制項 → 設定 (Microsoft .NET wording)
    * Owner-level connector enablement properly localised
    * "not artificially capped at 200" rephrased to clearer Chinese logic
- Round-2: PASS (0 P1+P2). 1 P3 accepted (em dashes only in shell
  comments, not Chinese prose).

Sweep follow-up to commits ff935db (SETUP.md) + 3ece187 (QUICKSTART).

* docs(v3.6.5.1): CHANGELOG entry for SETUP doc correctness patch

Doc-only patch summarising the F1-F7 fixes already shipped in commits
ff935db (SETUP.md), 3ece187 (QUICKSTART.md), and 06f6b71 (SETUP.zh-TW.md):

- Method 3 install paths fixed (per-skill folders into ~/.claude/skills/)
- Method 4 split into 4a (Custom Skill upload) and 4b (Project + GitHub)
- Method 3 + Method 4 prerequisites expanded
- Cowork UI terminology refreshed
- Skill invocation framing clarified (description-based + / + + UI)
- Method 4 directory table includes scripts/; capacity guidance refreshed

Issue #44 (philpav) reports the SETUP problems on Cowork and claude.ai;
this patch fixes the doc, and v3.6.5.2 will trim the four SKILL.md
descriptions to clear the claude.ai upload blocker.
2026-04-27 21:18:27 +08:00
Edward Cheng-I Wu 33f39f136b docs: refresh ARCHITECTURE / SETUP / PERFORMANCE to v3.6.5 (fast-follow) (#43)
* docs: refresh ARCHITECTURE.md to v3.6.5 (covers v3.5.1-v3.6.5)

ARCHITECTURE.md had drifted 5 minor releases behind main: titled v3.5.1
with skill versions v2.9.1 / v3.1.0 / v1.8.1 / v3.5.1. None of v3.5.1
reading-check probe, v3.6.2 sprint contract, v3.6.3 passport reset
boundary, v3.6.4 literature_corpus[] input port, or v3.6.5 corpus
consumers were documented. Codex /codex review on v3.6.5 PR-B did not
flag this because design doc §6.3 seven-touchpoint sweep didn't include
ARCHITECTURE.md. Adding to feedback_version_bump_sweep_checklist.md
backlog.

Sweep:

- Title v3.5.1 → v3.6.5
- All skill version pins synced: deep-research v2.9.1 → v2.9.2 (corpus
  reader); academic-paper v3.1.0 → v3.1.1 (corpus reader); reviewer
  v1.8.1 → v1.9.0; pipeline v3.5.1 → v3.6.5. Pins updated in §3 matrix
  (every row), §6 mermaid skill graph, §9 modes table.
- §3 Stage 1 RESEARCH: bibliography_agent flagged as v3.6.5+ corpus
  reader; socratic_mentor_agent flagged as v3.5.1 reading-check probe
  layer (opt-in); Search Strategy artifact gains PRE-SCREENED block;
  gate column gains corpus-first flow + 4 Iron Rules + F3/F4 mention.
- §3 Stage 2 WRITE: literature_strategist_agent flagged as v3.6.5+
  corpus reader; Literature Search Report artifact gains PRE-SCREENED
  block; gate column gains corpus-first flow.
- §3 Stage 3 REVIEW: editorial_synthesizer_agent flagged with v3.6.2
  three-step mechanical protocol + forbidden-ops list; gate column
  gains v3.6.2 Schema 13 sprint contract two-phase protocol with
  paper-blind Phase 1 / paper-visible Phase 2 via <phase1_output>
  data delimiter.
- New §5 "Material Passport literature_corpus[] Flow (v3.6.4 input
  port + v3.6.5 consumers)": producer / passport / consumer mermaid
  diagram, five-step shared flow narrative, four Iron Rules with full
  text, PRE-SCREENED block description with F3/F4 reference, scope
  exclusions (citation_compliance v3.6.6+ defer; source_pointer URI
  resolution future). Section numbering shifted: old §5 → §6, §6 → §7,
  §7 → §8, §8 → §9. §1 "How to read" updated accordingly + new bullet
  for §5 corpus flow.
- §6 Skill Dependency Graph Shared block: added sprint_contract.schema,
  reset_ledger_entry, literature_corpus_entry, rejection_log, and the
  two reviewer contract templates (full / methodology_focus).
- §7 Quality Gates: 4 new entries — Reading-check probe (v3.5.1 opt-in),
  Sprint Contract hard gate (v3.6.2), Passport reset boundary (v3.6.3
  opt-in), Corpus consumer protocol (v3.6.5).
- §8 Timeline: title from "ARS v3.3.x incremental additions" to "ARS
  evolution timeline"; v3.3.1-v3.3.6 collapsed into one entry (drift
  fixes era); v3.5.1 / v3.6.2 / v3.6.3 / v3.6.4 / v3.6.5 each get
  3-4 bullets.

Verification:
- check_spec_consistency.py exit 0 (markdown links re-validated)
- check_corpus_consumer_protocol.py exit 0
- pytest scripts/ 331 passed

Fast-follow on v3.6.5 (PR #42 merged main 3e953ce). No new tag — this
is doc reconcile with no version semver impact; v3.6.5 release tag
already covers the architectural surface that this doc now describes.

* docs: include resume_from_passport in §9 modes table (codex R1 [P2])

ARCHITECTURE.md §9 said academic-pipeline had "no standalone modes",
but MODE_REGISTRY.md:54 lists resume_from_passport=<hash> as a real
mode and the new §7 reset boundary entry above describes it. §9 is
the invocation reference, so the omission was a self-contradiction
within the same doc.

Now describes academic-pipeline modes as orchestrator + resume_from_passport
with the v3.6.3 ARS_PASSPORT_RESET opt-in qualifier.

All three lints + 331 tests still green.

* docs: fix two contract inaccuracies in ARCHITECTURE refresh (codex R2)

[P3] Resume mode does not require ARS_PASSPORT_RESET=1 — corrected §9
modes row to align with academic-pipeline/SKILL.md:56-57: the flag is
required to *emit* boundary entries in the producing session; resume
itself requires no flag. Setting the flag merely to invoke resume would
unintentionally enable boundary mode for the resumed session's later
FULL checkpoints.

[P3] Stage 3 row mode name `methodology_focus` corrected to public
`methodology-focus` (hyphen) per academic-paper-reviewer/SKILL.md:62 —
the underscore form is the template filename (`methodology_focus.json`),
not the user-facing mode name. The other underscore mentions in §6 / §7 /
§8 refer to the JSON template filename and are correct as-is.

All three lints + 331 tests still green.

* docs: bring SETUP + PERFORMANCE up to v3.6.5

Same drift class as ARCHITECTURE.md — design doc §6.3 seven-touchpoint
sweep didn't include these files, so v3.5.1 / v3.6.2 / v3.6.3 / v3.6.4 /
v3.6.5 features were undocumented in the user-facing setup and
performance guides.

SETUP.md + SETUP.zh-TW.md:
- New §"Material Passport literature_corpus[] adapters (v3.6.4+, optional)":
  install, 3 reference adapter invocation examples (folder_scan / zotero /
  obsidian), passport.yaml + rejection_log.yaml output description,
  pointer to adapter contract for user-written adapters; v3.6.5 consumer
  wiring pointer.
- New §"Optional environment flags (v3.5.1+)": single table covering
  ARS_CROSS_MODEL (v3.0), ARS_SOCRATIC_READING_PROBE (v3.5.1),
  ARS_PASSPORT_RESET (v3.6.3 — with the same emit-vs-resume distinction
  the codex R2 caught in ARCHITECTURE.md), ARS_CROSS_MODEL_SAMPLE_INTERVAL
  (v3.5.0).

PERFORMANCE.md + PERFORMANCE.zh-TW.md:
- New §"v3.6.2 Sprint Contract reviewer cost (always-on for full /
  methodology-focus)": Phase 1 + Phase 2 two-turn shape per reviewer,
  ~+30-40% input bump per reviewer × 5 in `full` mode, synthesizer
  +~2-3K. Empirical measurement pending real review runs.
- New §"v3.6.5 corpus consumer cost (presence-gated)": per-consumer
  Step 1 pre-screening cost scaling (50/200/500 entries), parse failure
  cost, Step 2 search-fills-gap offset. Empirical net delta pending
  real systematic-review run instrumentation.

Reading-check probe (v3.5.1) intentionally not given a cost section —
opt-in, max-once-per-session, single Socratic turn; the impact is
negligible relative to existing pipeline cost.

Verification:
- check_spec_consistency.py exit 0 (markdown link checker re-validates)
- check_corpus_consumer_protocol.py exit 0
- pytest scripts/ 331 passed

Continuing the docs/architecture-v3.6.5-refresh fast-follow PR.

* docs: fix adapter CLI flags + reviewer mode spelling (codex R4)

[P2] SETUP corpus adapter commands had `--out passport.yaml` but the
shipped CLIs (`folder_scan.py`, `zotero.py`, `obsidian.py`) all require
`--passport <out>` AND `--rejection-log <out>` (both required, not
defaulted). Users copying the documented commands would have hit
argparse errors immediately. Fixed in both SETUP.md and SETUP.zh-TW.md
with both flags spelled out per command.

[P3] `re_review` (underscore) corrected to `re-review` (hyphen) per
MODE_REGISTRY.md:43 + academic-paper-reviewer/SKILL.md. Three locations:
ARCHITECTURE.md:259 (Sprint Contract gate row reserved-modes list),
PERFORMANCE.md:43 (Sprint Contract reviewer cost reserved-modes list),
PERFORMANCE.zh-TW.md:43 (parallel zh row). Underscore form matches no
public mode; the same pattern that codex R2 caught for
`methodology_focus` → `methodology-focus`.

All three lints + 331 tests still green.

* docs(ARCHITECTURE): add passport_as_reset_boundary backpointer (CI fix)

CI failure caught by check_passport_reset_contract.py: every file that
mentions ARS_PASSPORT_RESET must co-locate a reference to
academic-pipeline/references/passport_as_reset_boundary.md (v3.6.3
contract — see the lint script and the protocol doc itself).

The §7 Quality Gates row for "Passport reset boundary" mentioned the
flag but only pointed to the *validator script*, not the *authoritative
protocol*. Added the inline link.

This lint isn't part of my local fast loop — it's only wired into
.github/workflows/spec-consistency.yml. Adding to the local pre-push
mental checklist (check_spec_consistency / check_corpus_consumer_protocol /
check_passport_reset_contract / pytest scripts/).

CI should now go green.
2026-04-27 11:14:10 +08:00
Imbad0202 5c6de49840 docs: align model references with Opus 4.7 + adaptive thinking
- Upgrade all model IDs from claude-opus-4-6 to claude-opus-4-7 across
  performance guides, setup docs, cross-model verification protocol,
  reproducibility pattern, and example passport.
- disclosure_mode_protocol: switch the example AI-usage statement from
  a hard-coded "Claude Opus 4.6" to a [MODEL_VERSION] placeholder, with
  a note instructing agents to pull the identifier from session metadata
  rather than bake in a version that drifts.
- PERFORMANCE docs: drop the "extended-thinking configuration" phrasing
  in favor of a one-line note on Opus 4.7 adaptive thinking.
- pipeline_orchestrator_agent: rewrite "Concise and clear, not verbose"
  (Opus 4.6 era negative framing) as a positive direction per the
  Opus 4.7 best-practices guide.

All changes are documentation / example-config updates; test_check_repro_lock
still passes (6/6) and no behavior change in the skills themselves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 04:15:39 +08:00
Imbad0202 a4420853c6 docs: streamline README, add SETUP/PERFORMANCE sub-docs (v3.3.6)
README cleanup rides on the ARCHITECTURE.md doc that PR #18 merged. Moves
long-form setup, performance, and installation content into docs/ sub-pages
so the READMEs read as entry points rather than manuals.

New docs:
- docs/SETUP.md + docs/SETUP.zh-TW.md — prerequisites, API key, Pandoc/
  tectonic, cross-model verification (ARS_CROSS_MODEL), four install methods.
- docs/PERFORMANCE.md + docs/PERFORMANCE.zh-TW.md — per-mode token budgets
  and recommended Claude Code settings (Agent Team / Ralph Loop / Skip
  Permissions).

README changes:
- Removed the ASCII pipeline diagram and the 16-point key-feature list
  (superseded by ARCHITECTURE.md §2/§3).
- Skill Details section anchors version numbers and routes readers to
  ARCHITECTURE.md §3 for per-agent rosters; the four "### <Skill> (vX.Y)"
  headings are preserved so existing spec-consistency checks still pass.
- Cross-Model Verification / Performance Notes / Prerequisites / Installation
  sections linked out instead of inlined.
- Line counts: 816 → 459 EN (-44%), 791 → 444 ZH (-44%).

Version bump to v3.3.6 across:
- README.md + README.zh-TW.md (badge, release-tag link, changelog entry)
- .claude/CLAUDE.md (suite version)
- MODE_REGISTRY.md (last-updated line)
- CHANGELOG.md (new [3.3.6] entry)

CI adjustments:
- scripts/check_spec_consistency.py: bumped expected version to v3.3.6 in
  both EN and ZH README checks; moved the DOCX contract assertions from the
  READMEs to the new docs/SETUP.* docs via a new check_setup_docs() step.

No functional change to any skill. Pure documentation reorganization.
2026-04-15 18:29:13 +08:00