# `docs/jss-guide/` — citation index for the JSS author guide

This directory holds the single source of truth for how
`jss-lint` cites the [JSS author guide](https://www.jstatsoft.org/about/submissions)
on every reported violation. Two files live here:

- **`index.json`** — section label → URL map. Read by every
  renderer (terminal, JSON, SARIF, HTML), the explain
  subcommand, and the catalogue contract test. The keys are the
  same strings the catalogue stores in `Rule.guide_section`.
- **`rule-renames.json`** — historical rename map for
  `jss-lint diff`, so a renamed rule does not appear as one
  fix + one introduce. Currently empty (no renames recorded);
  see the file's own `_about` / `_history` for details.

## Why this is one file, not three

Spec 007 chose centralised indirection over per-rule URL
storage:

- **Single edit on republication.** When the JSS author
  guide is moved or restructured, every renderer's URL output
  updates from one diff to `index.json` rather than ~50 edits
  scattered across `_catalogue_data.RULES`.
- **Auditable.** The map is small and reviewable; orphan
  catalogue citations fail the
  `test_guide_urls_resolve_through_index` contract test.
- **Cross-format consistency.** Terminal `(see ...)`, SARIF
  `helpUri`, JSON `guide_url`, and HTML `<a href>` all read
  through the same lookup, so they can never disagree.

## Re-publication flow

The JSS author guide is republished irregularly (every 1–3
years). When it happens:

### 1. Audit the new published guide

For every section currently in `index.json`, find the
canonical URL on the new publication. The section label
itself usually stays stable (`§3.2 Citations` reflects an
editorial structure JSS keeps across revisions). The URL or
its anchor fragment is the part that drifts.

### 2. Update `index.json`

Edit the URL value beside each section label. Keys
(section labels) stay the same UNLESS a section was actually
renamed in the new publication — in which case follow the
"label rename" subsection below.

### 3. Run the contract tests

```
pytest tests/unit/journals/jss/test_catalogue_citations.py -v
```

Three invariants run automatically:

- `test_guide_index_loads` — `index.json` parses, every
  value starts with `https://`.
- `test_backfilled_rules_resolve_through_index` — every rule
  whose `guide_section` is set has its `guide_url` matching
  `index.json[guide_section]`.
- `test_every_citable_rule_is_backfilled` — every citable
  rule has both fields populated. (Tool-side rules — `parse`,
  `internal` — are exempted via the sentinel pattern.)

If any rule's URL has drifted out of sync with the index, the
second test fails with a message naming the offending rule.
Fix in `specs/003-jss-rule-catalogue/catalogue.yaml` (the
generated `_catalogue_data.py` is regenerated by
`python -m tools.generate_catalogue_data`).

### 4. Verify the renderers

```
pytest tests/integration/test_cli_sarif_guide.py \
       tests/integration/test_cli_html.py::TestGuideSectionAnchor \
       tests/integration/test_cli_author_terminal.py::TestGuideSectionSuffix \
       tests/integration/test_cli_json.py::TestJsonShape -v
```

Every render path that links to the guide passes the new
URL through.

### 5. Commit

```
git add docs/jss-guide/index.json
git commit -m "docs(jss-guide): refresh URLs for <publication date>"
```

## Label rename

When a JSS-guide section is *renamed* (e.g. the guide
formally changes "§3.2 Citations" to "§3.2 References to
Software"):

1. Add the **new** key in `index.json` with the new URL.
2. Update every `Rule.guide_section` in
   `specs/003-jss-rule-catalogue/catalogue.yaml` that cited
   the old key to the new one.
3. Regenerate via `python -m tools.generate_catalogue_data`.
4. Remove the old key from `index.json` once no rule cites it.
5. Run the contract tests; the
   `test_guide_urls_resolve_through_index` test fails on any
   rule that was missed.

## Adding a new section

When a brand-new rule lands that cites a section not yet in
the index:

1. Add the section label + URL to `index.json`. Keep keys in
   section-number order to make diffs reviewable.
2. Add `guide_section` + `guide_url` to the new rule in
   `catalogue.yaml`. The two values must match what
   `index.json` declares.
3. Run the contract tests.

## File format

Both `index.json` and `rule-renames.json` are plain JSON
(no comments, no trailing commas). The `_about` and
`_history` keys are conventional documentation fields the
loaders strip; they don't appear in the runtime data.
