okf-mcp 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.okf/capabilities/index.md +9 -0
- data/.okf/capabilities/resources-and-prompts.md +45 -0
- data/.okf/capabilities/tools.md +73 -0
- data/.okf/capabilities/transports.md +39 -0
- data/.okf/design/index.md +11 -0
- data/.okf/design/kernel-first.md +42 -0
- data/.okf/design/one-entry-point.md +36 -0
- data/.okf/design/ruby-floor.md +43 -0
- data/.okf/design/runtime-dependencies.md +45 -0
- data/.okf/design/the-tool-set.md +408 -0
- data/.okf/index.md +37 -0
- data/.okf/log.md +15 -0
- data/.okf/overview.md +57 -0
- data/.okf/structure/doors.md +50 -0
- data/.okf/structure/http-bridge.md +56 -0
- data/.okf/structure/index.md +13 -0
- data/.okf/structure/served-set.md +58 -0
- data/.okf/structure/server-definition.md +72 -0
- data/.okf/testing/adding-a-tool.md +65 -0
- data/.okf/testing/index.md +9 -0
- data/.okf/testing/layers.md +56 -0
- data/CHANGELOG.md +54 -4
- data/README.md +10 -0
- data/lib/okf/mcp/version.rb +1 -1
- metadata +28 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 44ae2c50c714bc127ac861756a46e998d20f4310c77165ddcb616f7600c75517
|
|
4
|
+
data.tar.gz: 9fec8976e46b7bbe983bd0261eba453a4b25c700dcde8085df36f7a0df3f924a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7989702891ac272f637306102cadbd68f9e14f458b5cf81b373b681e3f9a8970fc248526f65038c449d498508820e143a2c9795b074ce456e3372882fd51889a
|
|
7
|
+
data.tar.gz: 0a9f01ba82b4bf10592c23666051617f9be55f80848925cbd029a8ad7e42753d3f597491ea71e45f2a97c817c6d8acbf9203890d4b7afd28a17a6dd4c526207a
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Capabilities
|
|
2
|
+
|
|
3
|
+
What this server offers a host, and what implements each of them. This area is
|
|
4
|
+
the catalog an agent reads instead of opening `lib/okf/mcp/server.rb` to find
|
|
5
|
+
out whether something already exists.
|
|
6
|
+
|
|
7
|
+
* [The fourteen tools](tools.md) - Every tool: what it answers, the kernel call behind it, and the CLI verb it is kin to.
|
|
8
|
+
* [Resources and prompts](resources-and-prompts.md) - What the protocol offers that a tool does not: bundles and concepts as resources, completions, and the two consuming prompts.
|
|
9
|
+
* [Transports](transports.md) - stdio, Streamable HTTP, and any Rack 3 server — one definition behind all three.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Capability
|
|
3
|
+
title: Resources, completions and prompts
|
|
4
|
+
description: What the protocol offers that a tool call does not — bundles and concepts as addressable resources, argument completion, and the two prompts shipped in-gem and read at get-time.
|
|
5
|
+
tags: [mcp, resources, prompts, completion]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: lib/okf/mcp/resources.rb
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Resources: addressable, not just callable
|
|
13
|
+
|
|
14
|
+
A tool is something a host *invokes*; a resource is something it can *attach*.
|
|
15
|
+
Both bundles and concepts are exposed as resources, so a host can put a concept
|
|
16
|
+
into a conversation without spending a tool call on it.
|
|
17
|
+
|
|
18
|
+
`Resources.list` enumerates served bundles, `templates` declares the concept
|
|
19
|
+
template, and `read` resolves one URI. The URI grammar is parsed by hand rather
|
|
20
|
+
than templated — see
|
|
21
|
+
[the server definition](../structure/server-definition.md) for why the SDK's
|
|
22
|
+
matcher cannot do it.
|
|
23
|
+
|
|
24
|
+
`Resources.complete` backs argument completion, which is what makes a concept
|
|
25
|
+
id typeable in a host that offers completion at all. `concept_ids` and
|
|
26
|
+
`prefixed` are its two halves.
|
|
27
|
+
|
|
28
|
+
# Prompts: the consuming pair
|
|
29
|
+
|
|
30
|
+
Two, shipped as markdown in `lib/okf/mcp/prompts/` and named by
|
|
31
|
+
`Server::PROMPTS`:
|
|
32
|
+
|
|
33
|
+
| prompt | for |
|
|
34
|
+
| ------ | --- |
|
|
35
|
+
| `search` | answering a question from a bundle, token-lean: the map, then the finder, then only the winning bodies |
|
|
36
|
+
| `consume` | using a bundle as context for a task |
|
|
37
|
+
|
|
38
|
+
They are read at get-time by `Server.prompt_text`, so booting never pays for
|
|
39
|
+
their bodies and editing one is not a code change. They are written in **tool
|
|
40
|
+
vocabulary** — they name the tools above, not CLI verbs — because the host
|
|
41
|
+
reading them has no shell.
|
|
42
|
+
|
|
43
|
+
`test/integration/prompts_test.rb` walks both, and
|
|
44
|
+
`test/integration/resources_test.rb` and `completions_test.rb` cover the
|
|
45
|
+
resource surface.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Capability
|
|
3
|
+
title: The fourteen tools
|
|
4
|
+
description: Every tool this server defines — what it answers, what it is kin to on the CLI, and the builder that constructs it — as one table, so nothing gets rebuilt for want of knowing it exists.
|
|
5
|
+
tags: [mcp, tools, catalog, search, retrieval]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: lib/okf/mcp/server.rb
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# The catalog
|
|
13
|
+
|
|
14
|
+
Fourteen, and the number is a decision rather than a resting point: tool-list
|
|
15
|
+
weight is a real cost on every host, so adding one is a design decision. Check
|
|
16
|
+
this table first — `dirs` + `index` + `search` compose to most retrieval, and
|
|
17
|
+
the commonest mistake is building a fifteenth tool for something three of these
|
|
18
|
+
already answer together.
|
|
19
|
+
|
|
20
|
+
Every one is a **read-only lens**: `readOnlyHint` and a `title` on all fourteen,
|
|
21
|
+
`additionalProperties: false` on every input schema, and a declared output shape
|
|
22
|
+
looked up by name (`read_concept` alone has none — it answers markdown).
|
|
23
|
+
|
|
24
|
+
| tool | answers | builder |
|
|
25
|
+
| ---- | ------- | ------- |
|
|
26
|
+
| `list_bundles` | what exists: every bundle this server knows — slug, title, root, concept count | `list_bundles_tool` |
|
|
27
|
+
| `dirs` | the first move: a bundle's shape, one row per directory | `dirs_tool` |
|
|
28
|
+
| `index` | the §8 index map, one directory at a time: authored `index.md` bodies, rollups, listings | `index_tool` |
|
|
29
|
+
| `search` | find concepts: every term must match (AND) across title, id, tags, type and body | `search_tool` |
|
|
30
|
+
| `read_concept` | one concept's full markdown, frontmatter and body, live from disk | `read_concept_tool` |
|
|
31
|
+
| `catalog` | per-concept metadata for a whole bundle, projectable down to the fields asked for | `catalog_tool` |
|
|
32
|
+
| `tags` | the tag index: every tag with its count and concepts, ordered by count | `tags_tool` |
|
|
33
|
+
| `types` | the type index: every type with its count and concepts, ordered by count | `types_tool` |
|
|
34
|
+
| `stats` | bundle rollups in one answer: concepts, dirs, types, cross-links, distinct tags | `stats_tool` |
|
|
35
|
+
| `log` | the append-only history: every `log.md`, root scope first | `log_tool` |
|
|
36
|
+
| `validate` | the spec §11 conformance verdict, with every error | `validate_tool` |
|
|
37
|
+
| `lint` | the curation report: reachability, backlog, completeness, freshness, provenance | `lint_tool` |
|
|
38
|
+
| `graph` | the knowledge graph in three bounded views — never with concept bodies | `graph_tool` |
|
|
39
|
+
| `references` | the `references/` tree (§6.3): every file, its citers, and every pointer that resolves to nothing | `references_tool` |
|
|
40
|
+
|
|
41
|
+
Each builder lives in [the server definition](../structure/server-definition.md)
|
|
42
|
+
and calls the kernel. None of them analyses anything itself.
|
|
43
|
+
|
|
44
|
+
# Kin to a CLI verb, and that is the point
|
|
45
|
+
|
|
46
|
+
Every row above has a counterpart in `okf <verb>`, and the answers are the same
|
|
47
|
+
because both call the same kernel method. That is the
|
|
48
|
+
[kernel-first rule](../design/kernel-first.md) doing its job: a host and a
|
|
49
|
+
terminal cannot disagree about whether a bundle is conformant.
|
|
50
|
+
|
|
51
|
+
So the way to add a capability is usually **not** to add a tool here. It is to
|
|
52
|
+
add it to the kernel, where the CLI, the graph server, the TUI and this shell
|
|
53
|
+
all reach it.
|
|
54
|
+
|
|
55
|
+
# What every list answer carries
|
|
56
|
+
|
|
57
|
+
`total` appears on every list answer and means one thing everywhere: **how many
|
|
58
|
+
rows the request matched, before any `limit` cut them**. There is no silent
|
|
59
|
+
truncation anywhere in this gem, and a new tool that returns rows owes the same
|
|
60
|
+
field with the same meaning.
|
|
61
|
+
|
|
62
|
+
Domain failures become tool errors carrying the kernel's own sentences — never
|
|
63
|
+
a bare `-32603` — and both channels always: the JSON text an older client reads
|
|
64
|
+
and the same object as `structuredContent`.
|
|
65
|
+
|
|
66
|
+
`test/unit/bundle_catalog_test.rb` fails if this table and the tools
|
|
67
|
+
`server.rb` defines ever disagree, in either direction.
|
|
68
|
+
|
|
69
|
+
# The doctrine is elsewhere
|
|
70
|
+
|
|
71
|
+
*Why* each tool exists, what was rejected, and the reasoning behind the
|
|
72
|
+
bounded-output rules is [the tool set](../design/the-tool-set.md). This table
|
|
73
|
+
is the catalog; that concept is the argument. Neither restates the other.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Capability
|
|
3
|
+
title: Three transports, one definition
|
|
4
|
+
description: stdio by default, Streamable HTTP behind `--http`, and any Rack 3 server through `OKF::MCP.app` — all three built at one seam so they cannot compose the server differently.
|
|
5
|
+
tags: [mcp, transports, stdio, http, rack]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: lib/okf/mcp/app.rb
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# The three
|
|
13
|
+
|
|
14
|
+
| transport | how | who owns it |
|
|
15
|
+
| --------- | --- | ----------- |
|
|
16
|
+
| stdio | the default for `okf mcp` | `CLI#serve_stdio` |
|
|
17
|
+
| Streamable HTTP | `okf mcp --http` — the WEBrick bridge, stateless JSON mode | [`HTTP`](../structure/http-bridge.md) |
|
|
18
|
+
| any Rack 3 server | `run OKF::MCP.app` in a `config.ru` | [`App`](../structure/doors.md) |
|
|
19
|
+
|
|
20
|
+
stdio is the default because it is what an agent host launches; nothing has to
|
|
21
|
+
be bound, and there is no port to collide.
|
|
22
|
+
|
|
23
|
+
# One construction site
|
|
24
|
+
|
|
25
|
+
All three reach the transport through `App.build` / `App.transport`. This is
|
|
26
|
+
worth protecting: the moment two callers construct their own, they begin to
|
|
27
|
+
disagree about `allowed_hosts`, `allowed_origins` or the engine, and the
|
|
28
|
+
disagreement shows up as a security difference between `--http` and a Rack
|
|
29
|
+
deployment rather than as a test failure.
|
|
30
|
+
|
|
31
|
+
`test/integration/http_harness.rb` is the same idea one layer up — the three
|
|
32
|
+
HTTP test files share it so they cannot drift in how they compose the bridge.
|
|
33
|
+
|
|
34
|
+
# No rackup file of its own
|
|
35
|
+
|
|
36
|
+
This gem ships no `config.ru`. The reader's server is the reader's dependency:
|
|
37
|
+
`OKF::MCP.app` is a complete Rack application, and naming a server here would
|
|
38
|
+
add a dependency to satisfy a convenience. The bridge behind `--http` uses
|
|
39
|
+
WEBrick, which arrives through okf rather than being named in this gemspec.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Design
|
|
2
|
+
|
|
3
|
+
The rules a change has to keep. `AGENTS.md` states them as a contract in a
|
|
4
|
+
handful of lines; this is where each one's argument lives, so that a rule
|
|
5
|
+
questioned is a rule you can re-read rather than re-derive.
|
|
6
|
+
|
|
7
|
+
* [The tool set, and why it is this one](the-tool-set.md) - The doctrine: what each tool exists for, the bounded-output argument, and the posture the whole surface takes.
|
|
8
|
+
* [The inherited Ruby floor](ruby-floor.md) - 2.7, the `mcp` SDK's, not okf's 2.4 — and what that admits and forbids.
|
|
9
|
+
* [Two runtime dependencies](runtime-dependencies.md) - Exactly `mcp` and `okf`, with floors that track what the suite proves.
|
|
10
|
+
* [Kernel-first](kernel-first.md) - This shell restates nothing the kernel can answer, which is what stops the CLI and MCP answers drifting apart.
|
|
11
|
+
* [One entry point](one-entry-point.md) - `okf mcp` through the plugin seam, and why the executable was removed before the first release.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Constraint
|
|
3
|
+
title: Kernel-first — this shell restates nothing
|
|
4
|
+
description: Logic a tool needs lands in the kernel and is read from there, so a host's answer and a terminal's answer cannot drift apart; the corollary is that most new capabilities are not new tools.
|
|
5
|
+
tags: [architecture, kernel, drift, constraint]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: lib/okf/mcp/server.rb
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# The rule
|
|
13
|
+
|
|
14
|
+
Every tool is a library call. Logic a tool needs that the kernel does not have
|
|
15
|
+
yet — `Bundle#tag_groups`, `Bundle#stats`, the cutoff grammar — is added *to
|
|
16
|
+
the kernel* and read from there, never implemented in this shell.
|
|
17
|
+
|
|
18
|
+
The reason is drift, and it is not hypothetical: the CLI, the graph server, the
|
|
19
|
+
TUI and this gem all answer the same questions about the same bundles. The
|
|
20
|
+
moment two of them compute an answer independently, they begin to disagree
|
|
21
|
+
under conditions nobody tested, and the disagreement surfaces as a user
|
|
22
|
+
reporting that `okf lint` and their agent say different things.
|
|
23
|
+
|
|
24
|
+
# The corollary that saves the most work
|
|
25
|
+
|
|
26
|
+
**Most new capabilities are not new tools here.** If a host needs something,
|
|
27
|
+
ask first whether the kernel could answer it — because if it could, the CLI and
|
|
28
|
+
the TUI want it too, and one kernel method serves all four surfaces.
|
|
29
|
+
|
|
30
|
+
This is also the repository's standing rule, stated at the seam: every
|
|
31
|
+
user-facing capability lands in the base gem first, and no addon owns semantics
|
|
32
|
+
the base lacks.
|
|
33
|
+
|
|
34
|
+
# What legitimately lives here
|
|
35
|
+
|
|
36
|
+
Three things, and it is a short list: **schema** (input shapes, declared output
|
|
37
|
+
shapes), **bounded-output arithmetic** (`total`, the log slicing, projection),
|
|
38
|
+
and **protocol translation** (tool errors carrying the kernel's own sentences,
|
|
39
|
+
both content channels, resource URIs). None of them is analysis.
|
|
40
|
+
|
|
41
|
+
If a change adds a fourth kind, that is the signal to stop and ask whether it
|
|
42
|
+
belongs in the kernel instead.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Constraint
|
|
3
|
+
title: One entry point, and no executable
|
|
4
|
+
description: "`okf mcp` through the kernel's plugin seam is the only door; the `exe/` that only aliased it was removed before the first release, and adding one back needs an argument stronger than symmetry."
|
|
5
|
+
tags: [cli, plugin, packaging, constraint]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: lib/okf/plugin.rb
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# No `exe/`
|
|
13
|
+
|
|
14
|
+
`lib/okf/plugin.rb` registers `okf mcp` with the kernel's command registry, and
|
|
15
|
+
that is the gem's entire entry surface. `spec.executables` is empty by
|
|
16
|
+
omission, and `test/unit/packaging_test.rb` and `test/integration/cli_plugin_test.rb`
|
|
17
|
+
hold the line from opposite ends — one that nothing ships, one that the verb
|
|
18
|
+
works when spawned as a real process.
|
|
19
|
+
|
|
20
|
+
The removed executable did nothing but call the same `CLI.run`. It went before
|
|
21
|
+
the first release, while dropping a name still cost nobody anything. What it
|
|
22
|
+
would have cost forever: a second name to install, document, keep working and
|
|
23
|
+
keep in step with the verb's argument grammar.
|
|
24
|
+
|
|
25
|
+
`okf-tui` made the same call for the same reason, and `okf-pro` made it for a
|
|
26
|
+
sharper one — its hook wrapper has to recognise exactly one `okf` binary.
|
|
27
|
+
|
|
28
|
+
# The dispatcher adds nothing
|
|
29
|
+
|
|
30
|
+
Between `okf mcp` and `OKF::MCP::CLI.run` there is argv and the streams, and
|
|
31
|
+
nothing else. That is what makes the plugin seam honest: a verb behaves like a
|
|
32
|
+
built-in because it *is* dispatched like one, and nothing about being an addon
|
|
33
|
+
shows up in how it is invoked or how it exits.
|
|
34
|
+
|
|
35
|
+
Adding a binary back needs an argument stronger than symmetry with gems that
|
|
36
|
+
have one.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Constraint
|
|
3
|
+
title: The floor is 2.7, and it is inherited
|
|
4
|
+
description: The `mcp` SDK's floor, taken rather than chosen — so okf's 2.4 API list does not bind here, and nothing past 2.7 may appear in lib/ or test/.
|
|
5
|
+
tags: [ruby, floor, constraint]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: okf-mcp.gemspec
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# 2.7, from the SDK
|
|
13
|
+
|
|
14
|
+
The floor is the `mcp` gem's, inherited rather than argued. That makes it
|
|
15
|
+
different in kind from okf's 2.4, which is a *position* — the tool should run
|
|
16
|
+
on the Ruby an OS already ships. Nothing here can run below what the SDK
|
|
17
|
+
supports, so there is no version of this gem that reaches okf's floor.
|
|
18
|
+
|
|
19
|
+
# What it admits, and what it still forbids
|
|
20
|
+
|
|
21
|
+
A sibling's floor is its own: **okf's 2.4 API list — `@okf design/ruby-floor` —
|
|
22
|
+
does not bind here.** `filter_map`, `tally`, `Dir.glob(base:)`, `transform_keys`,
|
|
23
|
+
`Struct.new(keyword_init:)` and numbered block params are all available and
|
|
24
|
+
used.
|
|
25
|
+
|
|
26
|
+
What is forbidden is anything *past* 2.7, in `lib/` **and** in `test/`:
|
|
27
|
+
endless method definitions, hash-literal shorthand (`{x:}`), `Data.define`,
|
|
28
|
+
`it` as a block parameter, and the rest of 3.x. RuboCop's `TargetRubyVersion`
|
|
29
|
+
catches syntax; it does not catch APIs, so a 3.x method that parses fine on 2.7
|
|
30
|
+
is the failure mode to watch.
|
|
31
|
+
|
|
32
|
+
The suite is the check that matters — CI runs 2.7 through the current stable,
|
|
33
|
+
one job for this gem, and a 3.x-only spelling fails on the oldest column. That
|
|
34
|
+
is the same rule the [dependency floors](runtime-dependencies.md) are held to:
|
|
35
|
+
the floor tracks what the suite proves.
|
|
36
|
+
|
|
37
|
+
# The trap the floor sets in the HTTP bridge
|
|
38
|
+
|
|
39
|
+
`ThreadError` on a mutex in trap context is a 2.7 behaviour, and it is why the
|
|
40
|
+
signal trap in [the HTTP bridge](../structure/http-bridge.md) hands teardown to
|
|
41
|
+
a thread instead of doing it inline. That is a floor constraint expressed as
|
|
42
|
+
code, and it is the one place the floor is load-bearing rather than merely
|
|
43
|
+
declared.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Constraint
|
|
3
|
+
title: Exactly two runtime dependencies
|
|
4
|
+
description: "`mcp` and `okf`, nothing else — rack and webrick arrive through okf and must never be named here — with both floors held to one rule: the floor tracks what the suite proves."
|
|
5
|
+
tags: [dependencies, gemspec, constraint]
|
|
6
|
+
generated:
|
|
7
|
+
by: human:maintainer
|
|
8
|
+
at: 2026-08-19T12:00:00Z
|
|
9
|
+
resource: okf-mcp.gemspec
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# The two
|
|
13
|
+
|
|
14
|
+
`mcp` (the official SDK) and `okf` (the kernel). That is the whole list, and
|
|
15
|
+
`test/unit/gemspec_test.rb` pins it.
|
|
16
|
+
|
|
17
|
+
**rack and webrick arrive via okf.** Naming either one here would be the
|
|
18
|
+
mistake that looks like diligence: this gem uses both — the Rack seam and the
|
|
19
|
+
WEBrick bridge — but it uses them *because okf already depends on them*, and a
|
|
20
|
+
second declaration is a second version constraint to keep in sync with a gem
|
|
21
|
+
that owns the answer.
|
|
22
|
+
|
|
23
|
+
A third runtime dependency is a design decision, held to the same bar the
|
|
24
|
+
kernel holds its own: argue it, do not add it for convenience — and
|
|
25
|
+
[kernel-first](kernel-first.md) is usually the reason one is not needed.
|
|
26
|
+
|
|
27
|
+
# The floor tracks what the suite proves
|
|
28
|
+
|
|
29
|
+
One rule covers both, and it is the reason the pins are not round numbers.
|
|
30
|
+
|
|
31
|
+
**`mcp` is pinned pessimistically (`~>`)**, and the suite fails the day the
|
|
32
|
+
lockfile resolves past it. The listen and modern-path tests exercise the
|
|
33
|
+
SEP-2575 wire, which 1.0 and 1.1 never served — against those versions the
|
|
34
|
+
tests fail, so the floor cannot admit them. The floor is not a guess about
|
|
35
|
+
compatibility; it is the oldest version the tests actually pass on.
|
|
36
|
+
|
|
37
|
+
**The `okf` floor may lead the kernel checkout but never lag it.** It names the
|
|
38
|
+
kernel version that ships what this shell rides — `Search.prepare/with/across`,
|
|
39
|
+
registry groups, project-local discovery, `dirs`, `Bundle#directories`, the
|
|
40
|
+
slug grammar. An earlier floor once admitted a kernel this code raises
|
|
41
|
+
`NoMethodError` against, because `Bundle#directories` did not exist there: the
|
|
42
|
+
gem installed cleanly and broke on the first `dir` refusal.
|
|
43
|
+
|
|
44
|
+
That is the failure the rule closes, and why the floor moves when the code
|
|
45
|
+
starts calling something new — in the same commit, not at the next release.
|