用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ThomasMoreAI/legal-skills-open --skill audit-crossrefs命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Use when retrieving arbitration institutional rules (ICC, LCIA, SCC, SIAC, HKIAC, VIAC, МКАС/МАК при ТПП України, UNCITRAL) — fetching current version, verifying redaction applicable to the date of arbitration agreement, constructing URLs for official rule texts
Use when choosing the Polish legal regime for letters, requests, applications, complaints, petitions, public-information requests, KPA filings, PPSA complaints, RODO access requests, registry extracts, court-file access, tax/ZUS/cudzoziemcy/USC procedures, or professional lawyer letters. Prevents mixing UDIP, KPA, PPSA, RODO, registry, special-procedure, and advocate/radca letter regimes.
Use when preparing applications for recognition and enforcement of foreign arbitral awards in Poland, applications for setting aside arbitral awards under KPC art. 1205–1211, or opposing such applications — mapping Article V of the 1958 New York Convention to art. 1214–1215 of the Polish KPC, identifying grounds for refusal, structuring public policy arguments
基于 SOC 职业分类
正在显示 SKILL.md
| name | audit-crossrefs |
| title | Phase 7: Cross-References |
| description | Phase 7: Convert hardcoded cross-references to auto-updating NOTEREF fields |
| author | edwinhu |
| author_url | https://github.com/edwinhu/workflows/tree/main/skills/bluebook-audit/skills/audit-crossrefs |
| license | MIT |
| version | 0.1.0 |
| execution_mode | open |
| jurisdiction | general |
| practice | general |
| language | en |
Convert hardcoded supra/infra note numbers to NOTEREF field codes that auto-update when footnotes are renumbered, then tie each cross-reference to a bibkey from references/sources.bib so the bibliography becomes the semantic identity layer.
sources.bib ← make_bib_from_docx.py # BOOTSTRAP (once per paper, Gemini)
↓
docx ← create_crossrefs.py # ONE-TIME conversion of hand-typed text
↓
docx ← audit_crossref_targets.py --grep --apply # DRIFT CORRECTION (deterministic)
↓
docx ← bib_integrate.py --bib references/sources.bib # BIBKEY-TAG SYNC (deterministic)
(also pre-computes cached display values)
All four live in ${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/.
After a Word session that added/edited footnotes (including new hand-typed
<X>, supra note N text), run:
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/sync_crossrefs.sh" \
draft.docx references/sources.bib
The shell wrapper runs create_crossrefs → audit_crossref_targets → bib_integrate in sequence. All three are idempotent and fully deterministic — re-running on a clean doc does nothing; ~5 seconds total runtime.
| Stage | Script | Gemini? | When |
|---|---|---|---|
| Bootstrap | make_bib_from_docx.py | Yes (one-off batch) | Paper has hand-typed footnotes and no sources.bib yet |
| Initial conversion | create_crossrefs.py | No | Convert hardcoded supra note N text → NOTEREF fields |
| Drift correction | audit_crossref_targets.py --grep | No | After footnote edits — fix any supras whose target drifted |
| Drift correction (ambiguous) | audit_crossref_targets.py --batch | Yes | Only for refs grep can't resolve uniquely |
| Bibkey-tag sync | bib_integrate.py | No | After cross-refs settle — rename bookmarks to _RefBib_<bibkey> and pre-compute cached display |
Convert hardcoded <X>, supra note N text to NOTEREF cross-reference fields.
# Preview
uv run python3 "${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/create_crossrefs.py" --docx <path> --dry-run
# Apply
uv run python3 "${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/create_crossrefs.py" --docx <path>
references/sources.bib yet):
uv run --with lxml --with google-genai --with google-cloud-storage python3 \
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/make_bib_from_docx.py" \
--docx <path> --out references/sources.bib
Walks the docx footnotes, skips supra-only / bio fns, sends each first-cite candidate to Gemini Vertex Batch, emits BibTeX with note = {fnN} linking each entry to its source footnote.audit_crossref_targets.py --grep --apply (see below). Hand-typed supra note N numbers go stale as footnotes are added or reordered; the create_crossrefs script faithfully bookmarks the literal N, which can be silently wrong for every reference. Grep resolves the easy cases deterministically; only ambiguous refs need --batch.bib_integrate.py --bib references/sources.bib --apply. Renames bookmarks to _RefBib_<bibkey>, retargets supras by bibkey, and pre-computes cached display values so the doc renders correctly on first read (no F9 needed).fn+F9 (Mac) or Ctrl+A → F9 (Windows) to force-refresh fields if needed.audit_crossref_targets.py (drift correction, also runnable standalone)# Mechanical audit only — flags refs whose surnames don't appear in the target footnote
uv run --with lxml python3 \
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/audit_crossref_targets.py" \
--docx <path>
# Deterministic first pass — grep each reference for its first cite. No LLM cost.
# On a 138-ref test set: resolved 62 refs unique with 98% accuracy, deferred
# 76 truly ambiguous cases. Always run this BEFORE invoking Gemini/Batch — it
# strips the easy cases and saves LLM calls.
uv run --with lxml python3 \
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/audit_crossref_targets.py" \
--docx <path> --grep --apply
# Grep + production LLM batch for the residue (recommended for full pipeline)
uv run --with lxml --with google-genai --with google-cloud-storage python3 \
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/audit_crossref_targets.py" \
--docx <path> --grep --batch --apply --location global
# LLM-only paths (skip grep — coverage-risky for --gemini):
uv run … --docx <path> --batch --model gemini-3.1-flash-lite-preview --apply
uv run … --docx <path> --gemini --apply
bib_integrate.py (bibkey-tag sync, fully deterministic)uv run --with lxml python3 \
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/bib_integrate.py" \
--docx <path> --bib references/sources.bib --apply
What it does:
sources.bib.fn_id → bibkey map from current docx content — sidesteps any drift between bib's note={fnN} tag and current numbering._RefBib_<bibkey> bookmarks wrapping body footnoteReferences. Multi-cite footnotes get multiple bookmarks (one per source) — each pointing at the same body footnoteReference, so the displayed number stays the same; only the bookmark name differs by source.--bio-count, default 3 for *, †, ‡ author bios that don't consume display numbers when numRestart=eachSect is set).SUPRA_BIB_AUDIT.md listing any supras whose surnames don't match the picked bibkey's haystack (author + title + howpublished + bibkey).Fully deterministic — no LLM calls. Idempotent on re-runs.
make_bib_from_docx.py (bootstrap, Gemini)uv run --with lxml --with google-genai --with google-cloud-storage python3 \
"${CLAUDE_SKILL_DIR}/../../../../skills/bluebook-audit/scripts/make_bib_from_docx.py" \
--docx <path> --out references/sources.bib
Walks the docx footnotes, splits multi-cite footnotes on ;, sends each first-cite candidate to a Vertex AI Batch job (one independent request per citation; gemini-3.1-flash-lite-preview default). Emits BibTeX entries with bibkey conventions firstauthorlastYEAR for academic works and short slugs (gao2017, crs2024, secReg2020) for institutional sources.
Each entry includes note = {fnN} linking back to the source footnote.
Once sources.bib exists, maintain it directly — do not regenerate. Edits to the bib (typos, missing fields, new sources) should be in-place.
Vertex AI batch requires:
gcloud auth application-default login for ADC--project (default $GOOGLE_CLOUD_PROJECT or activist-defense-nal)--gcs-bucket (default $GEMINI_BATCH_BUCKET or nal-batch-extraction)us-central1 (default)For gemini-3.x models, thinkingLevel: MINIMAL is set automatically — without it, batch responses silently return empty content (see /gemini-batch SKILL gotcha 12).
Output written to <docx-dir>/scratch/:
crossref_audit.json — every cross-reference with current target + match statuscrossref_remap.json — Gemini's proposed corrections (with confidence)CROSSREF_AUDIT.md — human-readable diff reportThe audit is safe to run standalone without re-running the rest of the bluebook-audit workflow. Use it any time create_crossrefs has been run and you want to validate that hand-typed supra/infra numbers were correct.
--grep first. Cheapest, deterministic, ~98% precision on unique
matches. Resolves ~half the refs at $0 cost.--batch (Vertex AI, per-ref independence) on the deferred set.--grep worksA cross-reference reads <short-form identifier>, supra/infra note N. The
identifier can be any Bluebook short form, not just author surnames:
Hu, Malenko & ZytnickGAO Report, CRS Report, Rosenberg, 2020 SEC RegulationBest Practice Principles, Policies and Procedures, Senate Banking Committee LetterISS v. SECChoi, Fisch & Kahan, Power of Proxy AdvisorsFor each reference the script:
See, But see, E.g.).<X>, supra/infra note <N> phrase from each candidate footnote, so a footnote that merely cites the same identifier via supra doesn't count as the first cite.unique, apply deterministically.ambiguous, defer to LLM (picking the earliest is wrong ~17% of the time — typically when the identifier appears in passing in one footnote and as a first cite in another).no_match, defer to LLM (which has the catalog and can guess, or correctly say "not in document").Iron Law: Neither Gemini pass is fully trustworthy on its own. A two-batch consensus is high-confidence, but the residual disagreements ALWAYS require human first-cite verification. Do not stop after --apply.
The failure modes we observed on a real 248-footnote draft:
See also or multi-cite list (model misses it and picks a different paper by the same author)See/hereinafter/inline-discussion lead-ins are flagged as mismatches even when correct.for fn in fns.findall('.//w:footnote'):
txt = ''.join(t.text or '' for t in fn.iter('w:t'))
if re.search(r'<surname-pattern>', txt) and 'supra' not in txt[:300].lower():
print(fn.get('w:id'), txt[:200])
(source_fn, surnames, current_bookmark) → correct_fn_id, save as crossref_remap_manual.json, and apply with --remap PATH --apply.See also/multi-cite list.SUPRA_UNRESOLVED.md listing the source FN, surnames, and the search patterns tried.--gemini and --batch)SUPRA_UNRESOLVED.md written (or empty if all resolved)| Pattern | Example | Result |
|---|---|---|
| Single supra | supra note 42 | NOTEREF to FN42 bookmark |
| Single infra | infra note 188 | NOTEREF to FN188 bookmark |
| Range | infra notes 209-210 | Two NOTEREFs with separator |
| With pincite | supra note 42, at 15 | NOTEREF + roman , at 15 |
| Existing NOTEREF | (already converted) | Skipped |
supra Section I.A., infra Part III)audit_crossref_targets.py run + Step 4 manual verification complete; no NOTEREF points at an unrelated footnotePresent final summary to user: