Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .claude/skills/llp-create/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,19 @@ Invoke as `/llp-create <title>` with an optional title, or `/llp-create` and the

### 1. Determine the next LLP number

Scan all files in `llp/` (including subdirectories and `llp/tombstones/`) that match the pattern `NNNN-*.md`. Extract the numeric prefix of each. The next number is `max(existing) + 1`, zero-padded to four digits.
Run `node scripts/llp-numbers.js next` and use what it prints.

If another LLP tree exists in a non-standard location (some projects use `docs/site/content/llp/` or similar), include it in the scan. Check the project's root LLP or `CLAUDE.md` / `AGENTS.md` for any documented LLP locations.
**Do not read the number off the tree you have checked out.** The branch you are on is not the corpus: numbers are minted on every branch at once, and a document minted on a branch you cannot see claims its number just as firmly as one on the default branch. Three branches cut from the same master each took `max(llp/) + 1`, each got the same answer, and git reported no conflict because their slugs differed ([issue #907](https://github.com/hyparam/hypaware/issues/907)). LLP 0156 settles the rule: a fresh number sits above the highest claimed **anywhere**, including branches without an open PR, and including `llp/tombstones/`, because a retired number is never reused.

`scripts/llp-numbers.js` is that rule:

- `next` prints the next free number across every ref that could still merge and the working tree, zero-padded. A document you created a minute ago and have not committed claims its number too, so two calls in one session do not collide.
- `check` exits nonzero when a number this branch mints is already claimed elsewhere. It runs in CI (`.github/workflows/llp-check.yml`) and in `npm test`.
- `survey` lists every collision across every ref, including the settled ones stale branches still carry.

Fetch first or the scan only sees the refs you already had: `git fetch --prune --unshallow` on a shallow clone, `git fetch --no-tags --prune origin '+refs/heads/*:refs/remotes/origin/*'` on a complete one (`--unshallow` aborts there). The script warns when it can tell that it is reading a shallow or single-branch checkout, and `check` refuses outright rather than passing on a corpus it never saw.

Fall back to `max(existing) + 1` over `llp/`, **and say that you did so the number is known to be a guess**, in the three cases the script cannot cover: the repository has no `scripts/llp-numbers.js` (it is a HypAware file, not part of LLP itself), the repository is not a git checkout, or LLP documents live somewhere the script does not look. The script scans `llp/` only. If another LLP tree exists in a non-standard location (some projects use `docs/site/content/llp/` or similar), scan it by hand and take the higher of the two answers. Check the project's root LLP or `CLAUDE.md` / `AGENTS.md` for any documented LLP locations.

### 2. Ask the user for the metadata if not provided

Expand Down
5 changes: 4 additions & 1 deletion .claude/skills/ref-check/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ Scan `llp/` (and any other configured LLP trees) for all documents. For each, ex

Build a map from `(LLP number) → (file path, title, {anchor: heading text})`.

Also record where the same number is claimed by **more than one** file. A duplicate number makes `@ref LLP NNNN#anchor` ambiguous, and a checker that keeps only the last file it walked will report every reference aimed at the other one as broken. Resolve an anchor against **any** claimant, and report the duplicate itself as a `WARNING` on the corpus.
Also record where the same number is claimed by **more than one** file. A duplicate number makes `@ref LLP NNNN#anchor` ambiguous, and a checker that keeps only the last file it walked will report every reference aimed at the other one as broken. Resolve an anchor against **any** claimant, so that the references keep resolving, and report the duplicate itself as `BROKEN` on the corpus: one number resolving to two documents is a defect in its own right, not a hint, and it is repaired by renumbering the later claimant (LLP 0156).

**The tree you are scanning is one branch of the corpus.** Two branches can each mint the same number cleanly, and nothing in a single tree can see it: the collision appears only when the second one merges (issue #907). `node scripts/llp-numbers.js survey` reports duplicates across every ref, `check` fails when the branch you are on mints a number claimed elsewhere, and `next` gives the number a new document should take. Run `git fetch --prune` first, or the scan only sees the refs you already had.

### 4. Validate each reference

Expand Down Expand Up @@ -183,6 +185,7 @@ For scripting (this skill can be invoked from CI):

- Exit 0 if no broken references
- Exit 1 if any broken references
- Exit 1 if any LLP number resolves to more than one document
- Warnings and hints do not cause a non-zero exit code

## Output formats
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/llp-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,22 @@ jobs:
for n in $dups; do find llp -path llp/reviews -prune -o -name "$n-*.md" -print >&2; done
echo "Fix: renumber the doc that landed second to the next free number across all branches (tombstones count - numbers are never reused), and update the @refs that meant it." >&2
exit 1

# The in-tree job above only sees a collision once both documents are in one
# tree, which is after the second merge. Three branches minting the same number
# in parallel is not visible from any one of them (issue #907), so this job
# fetches every branch and asks whether the number this one mints is already
# claimed somewhere else. It reports only the numbers this branch adds, so a
# collision already settled on master, still carried by a stale branch that
# predates the repair, does not redden pull requests party to none of it.
cross-branch-numbers:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch every branch that could merge
run: git fetch --no-tags --prune origin '+refs/heads/*:refs/remotes/origin/*'
- name: No newly minted LLP number is claimed elsewhere
run: node scripts/llp-numbers.js check
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ actually shipped in V1.
rationale-order view; `/llp-create <title>` scaffolds a new doc; `/llp-list`
surveys the corpus; `/llp-grill` stress-tests a plan against the LLP corpus
before you write code.
- **A new number comes from `node scripts/llp-numbers.js next`**, after a
`git fetch --prune`. Numbers are minted on every branch at once, so the tree
you have checked out is not the corpus: three branches each read
`max(llp/) + 1` and each got the same answer (issue #907). The same script
gates it: `check` in the `cross-branch-numbers` CI job, which fetches every
branch first, and in `npm test` wherever the clone carries them (a shallow or
single-branch checkout skips it and says so). `survey` shows every collision
across every ref.

## Code Style

Expand Down
Loading
Loading