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
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,19 @@ jobs:
run: python3 utils/check-diagnostic-prefix.py
- name: check-diagnostic-prefix self-tests (explicit)
run: python3 -m unittest -q utils/check-diagnostic-prefix-test.py
# Defensive twin for the safety-doc pin gate (#1057): the
# module doc of big-code-analysis-py/src/node.rs is the
# canonical soundness argument for this workspace's only
# sanctioned `unsafe` block, and it reasons about a named
# tree-sitter release. A bump that leaves the literal behind
# leaves an argument that reads as verified against a crate
# nobody compiles. Its self-tests run as their own step for the
# usual reason: a source-scanning gate that stops matching
# reports a clean tree.
- name: check-safety-doc-pin (explicit)
run: python3 utils/check-safety-doc-pin.py
- name: check-safety-doc-pin self-tests (explicit)
run: python3 -m unittest -q utils/check-safety-doc-pin-test.py
# Defensive twin for the grammar-marker-sync gate (#400): bumping
# the notification-only marker in tree-sitter-{mozjs,mozcpp}/
# Cargo.toml without re-running the matching generate-*.sh
Expand Down
25 changes: 25 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,31 @@ repos:
entry: python3 -m unittest -q utils/check-diagnostic-prefix-test.py
pass_filenames: false

# Safety-doc pin gate — the module doc of
# big-code-analysis-py/src/node.rs is the canonical soundness
# argument for this workspace's only sanctioned `unsafe` block,
# and it reasons about a named tree-sitter release. #1057: the
# pin moved twice while the literal stayed at `=0.26.9`, leaving
# an argument that read as verified against a crate nobody was
# compiling. Fires on the root manifest as well as the file, so
# a bump cannot land without the citation being re-checked.
- id: check-safety-doc-pin
name: check-safety-doc-pin
language: system
files: '^(Cargo\.toml|big-code-analysis-py/src/node\.rs|utils/check-safety-doc-pin\.py)$'
entry: python3 utils/check-safety-doc-pin.py
pass_filenames: false

# Self-tests for the safety-doc-pin gate, for the same reason as
# the diagnostic-prefix pair above: a source-scanning gate that
# stops matching reports a clean tree.
- id: check-safety-doc-pin-test
name: check-safety-doc-pin-test
language: system
files: '^utils/check-safety-doc-pin(-test)?\.py$'
entry: python3 -m unittest -q utils/check-safety-doc-pin-test.py
pass_filenames: false

# The `enums/` crate is workspace-excluded, so the workspace
# clippy/test hooks above never touch it. Add a dedicated check
# so warnings here cannot drift (see #164).
Expand Down
25 changes: 22 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ and `cargo run -p big-code-analysis-web --`.
by `make pre-commit` / `make ci`: `check-versions.py`,
`check-snapshot-anchors.py`, `check-rustfmt-bail.py`,
`check-manpage-assets.py`, `check-manpage-drift.py`,
`check-diagnostic-prefix.py`,
`check-diagnostic-prefix.py`, `check-safety-doc-pin.py`,
`check-grammar-marker-sync.py`, `check-enums-codegen-drift.sh`,
`check-grammar-crate.py`, `check-grammars-crates.sh`,
`check-excluded-manifests.py`, `check-ruff-lockstep.py`,
Expand Down Expand Up @@ -200,7 +200,12 @@ and `cargo run -p big-code-analysis-web --`.
keeping the owning tree alive through a strong `Py<...>` handle. The
canonical soundness argument lives at
`big-code-analysis-py/src/node.rs` (the `# Safety` module doc and
`detach`). Any `unsafe` outside this exact pattern remains banned and
`detach`), and the node/`Ast` pairing that argument depends on is
enforced by the `owned` module boundary there — private fields, so a
handle can only be built by `wrap` / `rewrap` / `rooted_at` and not by
a struct literal that pairs a node with the wrong tree (#1057). The
version the doc names is gated by `make check-safety-doc-pin`. Any
`unsafe` outside this exact pattern remains banned and
needs a deliberate amendment to this rule. (The PyO3-macro-generated
FFI shims under `#![allow(unsafe_op_in_unsafe_fn)]` in `src/lib.rs`
are source-level `unsafe`-free and not covered by this exception.)
Expand Down Expand Up @@ -274,7 +279,12 @@ modified, deleted, **and** newly added pages, the last of which
`git diff` alone cannot see, #1249), the diagnostic-prefix gate
(`make check-diagnostic-prefix`, which blocks a capitalised
`Warning:` / `Error:` / `Note:` string literal — see "Rust
conventions"), the bca self-scan threshold gate at both
conventions"), the safety-doc pin gate
(`make check-safety-doc-pin`, which fails when the `tree-sitter`
version cited by the `unsafe` soundness argument in
`big-code-analysis-py/src/node.rs` is not the version
`[workspace.dependencies]` pins, or when the citation is dropped
altogether — #1057), the bca self-scan threshold gate at both
tiers (`make self-scan` mirroring the `Threshold gate` step in
`.github/workflows/pages.yml`, plus `make self-scan-headroom`
which scales every limit by `BCA_HEADROOM` — default `0.95` — so
Expand Down Expand Up @@ -722,6 +732,15 @@ pins it at `=0.26.12` with the workspace resolving. Its ABI version is
also what each vendored `parser.c` was generated against, so an
accidental bump is precisely the drift the gate exists to catch.

A runtime bump also has to carry the `unsafe` soundness argument with
it. `big-code-analysis-py/src/node.rs` reasons about a *named*
tree-sitter release — `Tree(NonNull<ffi::TSTree>)`,
`Node<'tree>(ffi::TSNode, PhantomData<&'tree ()>)`,
`Tree::edit(&mut self)`, `Send + Sync` — and `make
check-safety-doc-pin` fails until the literal in that doc matches the
new pin. Re-read the argument against the new release before editing
the line; the forced diff is the prompt, not the fix (#1057).

Treat the pinned version as fixed:

- Do not loosen pins to a range without explicit user approval.
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ for historical reference.
by a comment alone and had already drifted silently once (`v0.15.14`
against a lockfile resolving 0.15.22), which stays invisible until the two
versions disagree and then presents as "works locally, red in CI" (#1230).
- A `check-safety-doc-pin` gate (`make check-safety-doc-pin`, wired into
`make lint` / `pre-commit` / `ci`, the pre-commit hooks, and its own CI
step) holds the `tree-sitter` version cited by the `unsafe` soundness
argument in `big-code-analysis-py/src/node.rs` equal to the version
`[workspace.dependencies]` pins. That module doc is the canonical
justification for the workspace's only sanctioned `unsafe` block and
reasons about a *named* release — the `Node<'tree>` layout, `Tree::edit`
taking `&mut self`, `Send + Sync` — so a pin that moves while the literal
does not leaves an argument reading as verified against a crate nobody
compiles. The gate also fails when the literal is dropped altogether,
since a version-free phrasing hides the staleness rather than fixing it.
No library behaviour changes (#1057).

- **web:** `error_kind` token `vcs_invalid_author_hash_key`. The
`STABILITY.md` vocabulary list also gains `not_acceptable` and
Expand Down
Loading