Files
Ktao 99ceffe93e feat(disclosure): add medical venue policies and fail-closed rendering (#599)
* docs(disclosure): add medical venue entries incl. first Chinese-language venues (#596)

venue_disclosure_policies.md moves to v2, growing from 6 to 15 venues:
the ICMJE umbrella recommendations (referral baseline for its member
journals, mirroring the EMNLP->ACL referral structure), NEJM, The
Lancet, JAMA, BMJ, PLOS, Frontiers, and the database's first two
Chinese-language entries — Chinese Nursing Journals Publishing House
(中华护理杂志社) and International Eye Science (国际眼科杂志), with
verbatim policy language kept in the original Chinese plus English
paraphrase.

Every Source URL is official (never a third-party summary): 6 entries
live-verified 2026-07-27; NEJM / The Lancet / JAMA serve bot-protection
challenges to non-browser clients, so their official URLs are verified
against Internet Archive snapshots of those same URLs (noted per-row).

Venue-count surfaces synced: Scope line, disclosure_mode_protocol
dispatch table + venue input + failure cases + references,
academic-paper/SKILL.md venue list, /ars-disclosure command text,
mode_selection_guide, ARCHITECTURE stage table, and the 5 READMEs
(release-history lines kept intact, amended with a since-expanded
note).

Held back on purpose: the Chinese Medical Association Publishing House
GenAI regulation. Its primary text was verified first-hand on the
publisher's official WeChat channel, but only session-signed URLs
exist and archive capture is captcha-blocked, so there is no durable
official URL to cite. Accuracy over completeness.

No policy-anchor track changes (4-anchor inventory closed), no
format-profile content (#439 boundary), no detection-threshold numbers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(disclosure): address medical venue review feedback (#596)

* fix(disclosure): harden medical venue policy gates (#596)

* docs: credit medical disclosure contribution (#596)

* fix(disclosure): close medical venue review gaps (#596)

---------

Co-authored-by: 直播 <zhibo@zhibodeMacBook-Air.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: ktao732084-arch <254419203+ktao732084-arch@users.noreply.github.com>
2026-08-01 20:44:19 +08:00

145 lines
7.8 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# version: 1.2.0
#
# SessionStart hook script for the ARS Claude Code plugin (v3.7.0+).
#
# Reads the SessionStart event JSON on stdin and emits a hookSpecificOutput
# JSON with `additionalContext` describing what ARS provides in this session.
# The plugin loader injects that context into the LLM's first turn so the
# user (and Claude) can see, on session start, that ARS is loaded and which
# slash commands and plugin agents are available.
#
# Allowed invokers: Claude Code's plugin loader (SessionStart event).
# This script is safe to run from any context; it does not invoke codex,
# does not write outside its own stdout, and produces no side effects on
# the working tree.
#
# Exit codes:
# 0 Always — even on parse failure, fall back to the long-form announce.
# 2 Reserved (not used; SessionStart cannot block).
set -euo pipefail
# ---------------------------------------------------------------------------
# This script intentionally avoids Bash 4+ features (no associative arrays,
# no indirect expansion via `${!var}`, no `<<<` here-strings on the hot
# path). It runs cleanly on macOS stock /bin/bash 3.2 so plugin users
# don't have to `brew install bash` just to see the SessionStart announce.
# `run_codex_audit.sh` does need Bash 4+ — that wrapper guards itself.
# ---------------------------------------------------------------------------
# Read SessionStart event JSON from stdin and pull `source` (one of
# startup / resume / clear / compact) without taking a hard dependency on
# jq — many ARS users won't have it installed and we want this hook to
# work out of the box.
# ---------------------------------------------------------------------------
INPUT=""
if [[ ! -t 0 ]]; then
INPUT=$(cat)
fi
SOURCE="startup"
if [[ -n "${INPUT}" ]]; then
# Match `"source": "<value>"` with optional whitespace; tolerate single-line
# or multi-line JSON. Falls through to default `startup` on any parse miss.
if [[ "${INPUT}" =~ \"source\"[[:space:]]*:[[:space:]]*\"([a-z]+)\" ]]; then
SOURCE="${BASH_REMATCH[1]}"
fi
fi
# ---------------------------------------------------------------------------
# For `compact` and `resume` we keep the announce minimal: the LLM already
# has prior ARS context from the resumed transcript or carried-over summary,
# and re-injecting the full slash-command list every resume burns context.
# `startup` and `clear` get the full version.
# ---------------------------------------------------------------------------
case "${SOURCE}" in
compact|resume)
ANNOUNCE="ARS plugin still loaded after ${SOURCE}. Slash commands: /ars-full /ars-plan /ars-outline /ars-revision /ars-revision-coach /ars-rebuttal-audit /ars-abstract /ars-lit-review /ars-3w /ars-reviewer /ars-format-convert /ars-citation-check /ars-disclosure /ars-mark-read /ars-unmark-read /ars-cache-invalidate. Plugin agents: synthesis_agent, research_architect_agent, report_compiler_agent."
;;
startup|clear|*)
# -----------------------------------------------------------------
# #544 update reminder. The checker is consulted INSIDE this arm so
# compact/resume structurally never run it (no network mid-session).
# Any checker failure degrades to "no reminder" — the announce must
# never break. Wording lives here, not in the checker (single wording
# surface; ASCII "->" keeps the JSON escaping path trivial).
# -----------------------------------------------------------------
UPDATE_LINE=""
if [[ -n "${CLAUDE_PLUGIN_ROOT:-}" ]]; then
_UPD=$(bash "${CLAUDE_PLUGIN_ROOT}/scripts/ars_update_check.sh" 2>/dev/null || true)
_UPDATE_RE='^UPDATE_AVAILABLE[[:space:]]([^[:space:]]+)[[:space:]]([^[:space:]]+)$'
if [[ "${_UPD}" =~ ${_UPDATE_RE} ]]; then
UPDATE_LINE="ARS update available: v${BASH_REMATCH[2]} (installed: v${BASH_REMATCH[1]}). Run /plugin update academic-research-skills, or enable auto-update in /plugin -> Marketplaces.
"
fi
fi
ANNOUNCE="${UPDATE_LINE}ARS (academic-research-skills) plugin loaded.
Slash commands (16) — light modes pin sonnet in frontmatter; the three heavy modes inherit the session model (the v3.7.0 opus floor was retired in the 2026-06 harness pass):
/ars-full inherit Full pipeline (research → write → review → revise → finalize)
/ars-revision-coach inherit Parse reviewer comments → Revision Roadmap + Response Letter skeleton
/ars-reviewer inherit academic-paper-reviewer full mode — simulated peer-review panel
/ars-plan sonnet Socratic chapter-by-chapter planning
/ars-outline sonnet Detailed outline + evidence map (no full draft)
/ars-revision sonnet Revised draft + R&R responses
/ars-rebuttal-audit sonnet QA an existing rebuttal draft against reviewer comments (advisory)
/ars-abstract sonnet Bilingual abstract + keywords
/ars-lit-review sonnet Annotated bibliography in paper format
/ars-3w sonnet WHY / HOW / WHAT three-way paper scan (lighter than lit-review)
/ars-format-convert sonnet Convert paper between LaTeX / DOCX / PDF / Markdown
/ars-citation-check sonnet Citation error report
/ars-disclosure sonnet venue status bundle / policy-anchor render
/ars-mark-read sonnet Record human-read signal for one or more citation keys
/ars-unmark-read sonnet Rescind a prior human-read mark for one or more citation keys
/ars-cache-invalidate sonnet Drop cached verification rows for one or more citation keys
Plugin agents (3, v3.6.7-hardened, model: inherit, tools allowlist: Read/Write/Edit/Grep/Glob per #514) — dispatched by ARS pipeline:
synthesis_agent Cross-source integration, contradiction resolution, gap analysis
research_architect_agent Methodology blueprint (paradigm, method, data strategy)
report_compiler_agent APA 7.0 report drafting (Phase 4 + Phase 6)
Other ARS agents (bibliography_agent, literature_strategist_agent, field_analyst_agent, etc.) remain in-skill prompt templates loaded via SKILL.md, not plugin agents.
Token budget reference: docs/PERFORMANCE.md (a single full pipeline run ≈ \$46, order-of-magnitude; measured on Opus 4.x)."
;;
esac
# ---------------------------------------------------------------------------
# Emit the JSON. We assemble it with a here-doc and a sentinel substitution
# rather than printf/jq to keep the output stable across Bash patch versions.
# additionalContext must be a JSON string — escape backslashes, double quotes,
# newlines.
# ---------------------------------------------------------------------------
escape_json() {
local raw="$1"
raw="${raw//\\/\\\\}"
raw="${raw//\"/\\\"}"
raw="${raw//$'\n'/\\n}"
raw="${raw//$'\r'/}"
# Defense-in-depth (belt-and-suspenders): the #544 checker's strict, bounded
# version grammar already blocks control bytes upstream, but strip any
# remaining raw C0 control bytes (0x01-0x1f) here too so nothing can corrupt
# the JSON envelope. Real newlines were already converted to the literal
# two-char `\n` above (bytes 0x5C 0x6E), so this drops only stray control
# bytes, never legitimate text — and never the reminder's `\n\n` separator.
#
# `tr` is POSIX but not guaranteed on a constrained PATH (e.g. PATH=/bin on
# macOS, where tr lives in /usr/bin): guard on `command -v tr` so the strip
# is skipped when tr is absent rather than blowing up the whole pipeline and
# returning an empty additionalContext (P2-b). Skipping is safe — this pass
# is defense-in-depth on top of the upstream grammar, not the sole barrier.
if command -v tr >/dev/null 2>&1; then
raw="$(printf '%s' "${raw}" | LC_ALL=C tr -d '\001-\037')"
fi
printf '%s' "${raw}"
}
ESCAPED=$(escape_json "${ANNOUNCE}")
cat <<JSON
{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"${ESCAPED}"}}
JSON
exit 0