Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Audit Crossrefs

ASecurity

Use when a manuscript's supra/infra cross-references need to stop being hand-typed numbers — 'my supra notes point at the wrong footnote', 'the cross-references broke after I added a footnote', 'convert supra notes to fields', 'make cross-references auto-update', 'fix the infra cites', 'sync the crossrefs after editing footnotes', 'tie the supras to the bibliography'. Load as Phase 7 of a bluebook audit, or standalone after any Word session that added or reordered footnotes.

21 stars
0 votes
0 copies
0 views
Added 9/19/2026
researchpythonrustgoshellbash

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add edwinhu/workflows --skill audit-crossrefs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Audit Crossrefs?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Audit Crossrefs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/edwinhu-audit-crossrefs/badge)](https://www.skillsdirectory.com/skills/edwinhu-audit-crossrefs)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: audit-crossrefs
description: "Use when a manuscript's supra/infra cross-references need to stop being hand-typed numbers — 'my supra notes point at the wrong footnote', 'the cross-references broke after I added a footnote', 'convert supra notes to fields', 'make cross-references auto-update', 'fix the infra cites', 'sync the crossrefs after editing footnotes', 'tie the supras to the bibliography'. Load as Phase 7 of a bluebook audit, or standalone after any Word session that added or reordered footnotes."
user-invocable: false
disable-model-invocation: true
---

# Phase 7: Cross-References

**What this skill carries** — grep `references/` for any subject the names below miss:
!`d=${CLAUDE_SKILL_DIR}; command -v skill-toc >/dev/null 2>&1 && exec skill-toc "$d"; s=$HOME/.claude/skills/plugin-utils/bin/skill-toc; [ -x "$s" ] && exec "$s" "$d"; echo "(skill-toc unavailable: references and scripts are NOT listed here — install the plugin-utils plugin, or start a new session so its bin/ reaches PATH)"`

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 the document project's `references/sources.bib` so the bibliography becomes the semantic identity layer.

## Canonical 3-script pipeline

```
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/`.

### Maintenance one-liner

After a Word session that added/edited footnotes (including new hand-typed
`<X>, supra note N` text), run:

```bash
"${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 |

## Initial conversion (one-time)

Convert hardcoded `<X>, supra note N` text to NOTEREF cross-reference fields.

```bash
# 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>
```

## Workflow

1. **Bootstrap the bib** (only if no `references/sources.bib` yet):
   ```bash
   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.
2. **Dry run create_crossrefs** — review the cross-reference map and bookmark plan
3. **Apply create_crossrefs** — the script backs up the original before writing
4. **Audit + retarget** — run `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`.
5. **Bibkey-tag** — run `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).
6. **Verify in Word** — open the DOCX, spot-check 5-10 supras. Cmd+A → `fn+F9` (Mac) or `Ctrl+A → F9` (Windows) to force-refresh fields if needed.
7. **Renumber test** (optional) — add a footnote before a referenced target and confirm the supra numbers update.

### `audit_crossref_targets.py` (drift correction, also runnable standalone)

```bash
# 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 --apply   # --model overrides the resolved role
uv run … --docx <path> --gemini --apply
```

### `bib_integrate.py` (bibkey-tag sync, fully deterministic)

```bash
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:

1. Parses `sources.bib`.
2. For each bib entry, derives signature tokens (author surnames + distinctive title words + institutional bibkey prefix) and finds the docx footnote whose body text contains all of them. This re-derives the `fn_id → bibkey` map from current docx content — sidesteps any drift between bib's `note={fnN}` tag and current numbering.
3. For each supra/infra NOTEREF, picks the best matching bibkey (target-fn bonus + global token scoring).
4. Creates `_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.
5. Rewrites each NOTEREF instr text to point at its bibkey-named bookmark.
6. Pre-computes cached NOTEREF display values (using `--bio-count`, default 3 for `*, †, ‡` author bios that don't consume display numbers when `numRestart=eachSect` is set).
7. Emits `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)

```bash
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; the `bulk` role by 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`)
- Location: `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 status
- `crossref_remap.json` — Gemini's proposed corrections (with confidence)
- `CROSSREF_AUDIT.md` — human-readable diff report

The 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.

### Recommended pipeline order

1. **`--grep` first.** Cheapest, deterministic, ~98% precision on `unique`
   matches. Resolves ~half the refs at $0 cost.
2. **`--batch`** (Vertex AI, per-ref independence) on the deferred set.
3. **Manual first-cite verification** on remaining mechanical flags (Step 4 below).

### How `--grep` works

A cross-reference reads `<short-form identifier>, supra/infra note N`. The
identifier can be any Bluebook short form, not just author surnames:

- author group:        `Hu, Malenko & Zytnick`
- hereinafter tag:     `GAO Report`, `CRS Report`, `Rosenberg`, `2020 SEC Regulation`
- institutional doc:   `Best Practice Principles`, `Policies and Procedures`, `Senate Banking Committee Letter`
- case name:           `ISS v. SEC`
- title fragment:      `Choi, Fisch & Kahan, Power of Proxy Advisors`

For each reference the script:

1. Tokenizes the identifier (filters Bluebook signals like `See`, `But see`, `E.g.`).
2. Strips every `<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.
3. Searches every footnote — except the source — for one whose post-supra-strip text contains all the identifier tokens with word-boundary matches.
4. If **exactly one** footnote matches → `unique`, apply deterministically.
5. If **multiple** match → `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).
6. If **none** match → `no_match`, defer to LLM (which has the catalog and can guess, or correctly say "not in document").

### Step 4 (mandatory): Manual first-cite verification on residuals

**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:
- **Single-batched call**: model returns uniform "medium" confidence — a smoking-gun signal it didn't reason per-reference.
- **Per-reference Vertex Batch**: model returns uniform "high" with detailed reasoning, but still confidently picks **wrong** targets when:
  - the cited work isn't in the doc (model hallucinates a plausible-sounding nearby match)
  - the first cite is buried mid-footnote in a `See also` or multi-cite list (model misses it and picks a different paper by the same author)
  - the reference is to a self-referencing pattern (model returns the source footnote itself)
- **Mechanical surname check**: only inspects the leading 250 chars of the target footnote, so first cites buried after `See`/`hereinafter`/inline-discussion lead-ins are flagged as mismatches even when correct.

#### Recipe

1. **Compare both Gemini passes**, taking the intersection where they agree as the high-confidence consensus. Apply that subset first.
2. **For each disagreement**, search the doc for the **first non-supra cite** of the disputed surname / title fragment. The script's regex below catches mid-footnote occurrences:
   ```python
   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])
   ```
3. **Build a manual remap** of `(source_fn, surnames, current_bookmark) → correct_fn_id`, save as `crossref_remap_manual.json`, and apply with `--remap PATH --apply`.
4. **For the "no first cite in document" residue** (works the author cites without ever having introduced):
   - Search broadly first — the first cite is often mid-footnote in a `See also`/multi-cite list.
   - Only if truly absent: flag for an author edit. Write `SUPRA_UNRESOLVED.md` listing the source FN, surnames, and the search patterns tried.
5. **Final re-audit** will still show "mechanical mismatches" for the false-positive cases — verify each by spot-checking the target footnote content. Do not retarget these.

#### Gate

- [ ] Consensus retargets applied (intersection of `--gemini` and `--batch`)
- [ ] Manual remap built and applied for disagreements
- [ ] Each surviving "mismatch" flag spot-checked against actual target content
- [ ] No supra/infra reference points at an unrelated footnote
- [ ] `SUPRA_UNRESOLVED.md` written (or empty if all resolved)

## What Gets Converted

| 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 |

## What Is NOT Converted (Phase 2 — Future)

- Part/Section references (`supra Section I.A.`, `infra Part III`)
- These require a heading-to-bookmark mapping strategy since heading numbering is partially auto-generated

## Gate: Exit Cross-References

- [ ] Dry run reviewed — cross-reference map is correct
- [ ] NOTEREF fields created for all supra/infra note references
- [ ] **Target audit passed** — `audit_crossref_targets.py` run + Step 4 manual verification complete; no NOTEREF points at an unrelated footnote
- [ ] Backup DOCX exists
- [ ] Word field update (Ctrl+A, F9) confirms correct numbers

## Workflow Complete

Present final summary to user:
- Total formatting corrections applied (from Phase 4)
- Total URLs archived (from Phase 6)
- Total NOTEREF fields created (from Phase 7)
- Final DOCX file path

Attribution

edwinhuedwinhu
View sourceMore from edwinhu →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Competitor Analysis

This skill provides comprehensive analysis of competitor SEO and GEO strategies, revealing what's working in your market and identifying opportunities to outperform the competition.

1823 votes

Deep Research

Universal deep research agent team. 13-agent pipeline for rigorous academic research on any topic. 7 modes: full research, quick brief, paper review, lit-review, fact-check, Socratic guided research dialogue, and systematic review with optional meta-analysis. Covers research question formulation, Socratic mentoring, methodology design, systematic literature search, source verification, cross-source synthesis, risk of bias assessment, meta-analysis, APA 7.0 report compilation, editorial review...

452202 votes

Paperclip Distill

Use when an operation issue is a Paperclip cursor-window, distill, or backfill — `operationType: "distill"` or `"backfill"` and the body references a Paperclip source bundle for a project or root issue. Turn raw Paperclip activity into a wiki-insightful project page, decisions log, and history note. This skill exists specifically to replace the stiff, datestamp-heavy templated output that the deterministic distiller produces.

798221 votes

Academic Pipeline

Orchestrator for the full academic research pipeline: research -> write -> integrity check -> review -> revise -> re-review -> re-revise -> final integrity check -> finalize. Coordinates deep-research, academic-paper, and academic-paper-reviewer into a seamless 10-stage workflow with mandatory integrity verification, two-stage peer review, and reproducible quality gates. Triggers on: academic pipeline, research to paper, full paper workflow, paper pipeline, end-to-end paper, research-to-publi...

452201 votes

Exa Search

Semantic search, similar content discovery, and structured research using Exa API

304951 votes
View all in research →