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 |
| **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
as CI-runnable and T4 as not, which is right for extraction (where T3 is slow CPU
inference and T4 is GPU). jRay has only two CI tiers and one live tier, so its
non-CI tier is numbered **T4** to match that shared constant rather than
renumbering it. Calling jRay's live tier "T3" would make the gate count
live-only requirements as covered — the exact class of error the 158% coverage
bug belongs to.
**T3 is deliberately unused.** Executable tiers are declared per repo in
[`../traceability.toml`](../traceability.toml), so the numbering is a local
choice — but jRay keeps **T4** for "no CI host can run this" because that is
what T4 means in `scene-actor-extraction`. A tier number should mean the same
thing when read across repos; reusing T3 for a live tier here would make a
cross-repo reader count live-only requirements as covered.
`Jellyfin.Plugin.JRay.Tests` (xUnit, in the solution) carries the T1 tier. It
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
The shared extractor now takes the three things that vary per repo as arguments,
so this repo needs **no fork of it** — there must only ever be one
implementation:
The extractor is shared and vendored, never forked — there must only ever be one
implementation. Everything that varies per repo lives in
[`../traceability.toml`](../traceability.toml), so the invocation carries no
flags to drift out of sync between a developer's shell and CI:
```sh
python3 scripts/vendor/jray-project/scripts/traceability/extract_traces.py \
--root . \
--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
--root . --format coverage
```
`scripts/checks` is scanned so the static checks carry their own TRACES tags —
an enforcement script is evidence for a requirement exactly as a unit test is.
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.
That config declares the `JR` prefix, the languages, the source roots, the
CI-executable tiers, and the path to the vendored system spec.
Refresh the pinned tooling with
`git submodule update --remote scripts/vendor/jray-project`.
**Naming conflict to resolve.** The tool's header comment expects
`jRay → UR/DR`. This register uses `JR`, decided deliberately: `JRay-public-server`
already ships `UR-001…018` and `DR-001…014`, so a second repo using the same
prefixes would make `UR-007` ambiguous across registers — and `UR-007` is
precisely the ID the server's own register asks the plugin to cross-reference
(see JR-025). Either the comment or this register is wrong; the comment is the
cheaper of the two to change.
Two choices in it are worth knowing about. `scripts/checks` is scanned so the
**static checks carry their own TRACES tags** — an enforcement script is
evidence for a requirement exactly as a unit test is. And the source roots are
listed individually rather than as `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.
`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"