Claude
Skills
Sign in
Back

audit-crossrefs

Included with Lifetime
$97 forever

Phase 7: Convert hardcoded cross-references to auto-updating NOTEREF fields

Security

What this skill does


# Phase 7: Cross-References

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.

## 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 --model gemini-3.1-flash-lite-preview --apply
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; `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`)
- 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/`:
- `cros

Related in Security