Adopt the config-driven extractor
🏗️ Build Plugin / build (push) Successful in 28s
Latest Release / latest-release (push) Successful in 41s
🧪 Test Plugin / test (push) Successful in 25s

jray-project replaced the extractor's per-repo CLI flags with a traceability.toml
at each component root, so the invocation this repo documented -- --types,
--suffixes, --scan-roots -- no longer exists. Bumps the submodule to 17106f3 and
moves those settings into config.

The gate is now `extract_traces.py --root . --format coverage`, with nothing
per-repo on the command line to drift between a developer's shell and CI.

Two settings carry reasons worth keeping. Source roots are listed individually
rather than as "scripts", because the latter walks scripts/vendor and harvests
the AR-nnn examples in the extractor's own docstrings as orphan tags.
ci_executable_tiers omits T4: tiers are per-repo now, but T4 keeps the meaning
it has in scene-actor-extraction -- "no CI host can run this" -- so a tier
number reads the same across repos.

Drops the note about the tool expecting jRay to use UR/DR. Its example config
now names jRay: ["JR"], so the prefix is settled in all three repos.

Same numbers as before the change: 21 tags, 25/46, 0 orphans.

TRACES: JR-021 | PR-004

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 21:20:57 +02:00
co-authored by Claude Opus 5
parent 2d043aeee3
commit f4e8fb5dea
3 changed files with 58 additions and 34 deletions
+26 -33
View File
@@ -179,13 +179,12 @@ every requirement above except the live-integration ones is executable in CI.
| **T4 — Live** | **No** | Real Jellyfin + File Transformation + web client; real manifest server round-trip | | **T4 — Live** | **No** | Real Jellyfin + File Transformation + web client; real manifest server round-trip |
| **static** | Yes | Grep/analyzer checks — e.g. no injection path into `index.html` (JR-021) | | **static** | Yes | Grep/analyzer checks — e.g. no injection path into `index.html` (JR-021) |
**T3 is deliberately unused.** The gate's `CI_EXECUTABLE_TIERS` treats T1/T2/T3 **T3 is deliberately unused.** Executable tiers are declared per repo in
as CI-runnable and T4 as not, which is right for extraction (where T3 is slow CPU [`../traceability.toml`](../traceability.toml), so the numbering is a local
inference and T4 is GPU). jRay has only two CI tiers and one live tier, so its choice — but jRay keeps **T4** for "no CI host can run this" because that is
non-CI tier is numbered **T4** to match that shared constant rather than what T4 means in `scene-actor-extraction`. A tier number should mean the same
renumbering it. Calling jRay's live tier "T3" would make the gate count thing when read across repos; reusing T3 for a live tier here would make a
live-only requirements as covered — the exact class of error the 158% coverage cross-repo reader count live-only requirements as covered.
bug belongs to.
`Jellyfin.Plugin.JRay.Tests` (xUnit, in the solution) carries the T1 tier. It `Jellyfin.Plugin.JRay.Tests` (xUnit, in the solution) carries the T1 tier. It
builds clean alongside the plugin. builds clean alongside the plugin.
@@ -275,38 +274,32 @@ which is exactly why it can be the binding check rather than an aspiration.
## Running the gate ## Running the gate
The shared extractor now takes the three things that vary per repo as arguments, The extractor is shared and vendored, never forked — there must only ever be one
so this repo needs **no fork of it** — there must only ever be one implementation. Everything that varies per repo lives in
implementation: [`../traceability.toml`](../traceability.toml), so the invocation carries no
flags to drift out of sync between a developer's shell and CI:
```sh ```sh
python3 scripts/vendor/jray-project/scripts/traceability/extract_traces.py \ python3 scripts/vendor/jray-project/scripts/traceability/extract_traces.py \
--root . \ --root . --format coverage
--requirements docs/requirements.md \
--system-spec scripts/vendor/jray-project/SPEC.md \
--types JR \
--suffixes .cs,.js,.sh \
--scan-roots Jellyfin.Plugin.JRay,Jellyfin.Plugin.JRay.Tests,scripts/checks \
--format coverage
``` ```
`scripts/checks` is scanned so the static checks carry their own TRACES tags — That config declares the `JR` prefix, the languages, the source roots, the
an enforcement script is evidence for a requirement exactly as a unit test is. CI-executable tiers, and the path to the vendored system spec.
The scan root is `scripts/checks` and **not** `scripts`, because the latter would
walk `scripts/vendor/jray-project` and harvest the `AR-nnn` examples in the
extractor's own docstrings as orphan tags.
`--root` must be **absolute or `.`**; the scan roots resolve beneath it. Both the
extractor and the system spec come from the submodule, so the only thing this
repo supplies is its own register and the three per-repo arguments.
Refresh the pinned tooling with Refresh the pinned tooling with
`git submodule update --remote scripts/vendor/jray-project`. `git submodule update --remote scripts/vendor/jray-project`.
**Naming conflict to resolve.** The tool's header comment expects Two choices in it are worth knowing about. `scripts/checks` is scanned so the
`jRay → UR/DR`. This register uses `JR`, decided deliberately: `JRay-public-server` **static checks carry their own TRACES tags** — an enforcement script is
already ships `UR-001…018` and `DR-001…014`, so a second repo using the same evidence for a requirement exactly as a unit test is. And the source roots are
prefixes would make `UR-007` ambiguous across registers — and `UR-007` is listed individually rather than as `scripts`, because the latter would walk
precisely the ID the server's own register asks the plugin to cross-reference `scripts/vendor/jray-project` and harvest the `AR-nnn` examples in the
(see JR-025). Either the comment or this register is wrong; the comment is the extractor's own docstrings as orphan tags.
cheaper of the two to change.
`JR` is now what the shared tooling expects too — its example config names
`jRay: ["JR"]` — so the prefix is settled across all three repos. It was chosen
because `JRay-public-server` already ships `UR-001…018` and `DR-001…014`, and a
second repo reusing those prefixes would make `UR-007` ambiguous across
registers, which is precisely the ID the server's own register asks this one to
cross-reference (see JR-025).
+31
View File
@@ -0,0 +1,31 @@
# traceability.toml — per-repo configuration for the shared trace extractor.
# The extractor itself is vendored at scripts/vendor/jray-project.
# Flat, rather than split by theme as scene-actor-extraction is. The plugin is
# one deployable with one audience, and JRay-public-server already ships UR/DR
# — a second repo using those prefixes would make UR-007 ambiguous across
# registers, and UR-007 is precisely the ID the server asks this register to
# cross-reference (see JR-025).
requirement_types = ["JR"]
languages = ["csharp", "javascript"]
# The static checks carry TRACES tags of their own. An enforcement script is
# evidence for a requirement exactly as a unit test is — JR-021 is a
# prohibition, and a prohibition can only be verified by absence.
source_suffixes = [".sh"]
# Explicit roots rather than "scripts", which would walk scripts/vendor and
# harvest the AR-nnn examples in the extractor's own docstrings as orphan tags.
source_roots = [
"Jellyfin.Plugin.JRay",
"Jellyfin.Plugin.JRay.Tests",
"scripts/checks",
]
# jRay has two CI tiers and one live tier. T3 is deliberately unused: T4 keeps
# the meaning it has in scene-actor-extraction — "no CI host can run this" —
# so a tier number means the same thing when read across repos.
ci_executable_tiers = ["T1", "T2", "static"]
system_spec = "scripts/vendor/jray-project/SPEC.md"