Two changes, one theme: what a reader needs in order to cite is a property of
the PRODUCER, so neither the excerpt nor the skill may hard-code a list of the
producers someone thought of.
The pass-through rule is now the `source_` PREFIX, not the five keys this
library writes. Measured on the N500 bundle currently on disk: 269 of 274
concepts carry `source_element_id`, a locator that repository chose under this
chain's own rule ("the key says what it indexes") and that this library never
writes. The allowlist dropped it, and an excerpt that names a document without
naming the place in it is the defect this work exists to close. A prefix and
never a substring - `resource_owner` contains the literal and is not a locator,
and promoting it would be fabricated provenance produced by a matching bug. The
known-negative is tested: `bundle_id`, `type` and `ingested_at` do not travel.
Contract 8.5 states the rule as a prefix rather than a list.
K2 control, re-measured against the frozen tool at b6a8c8b, same question and
same k: the RANKING is untouched - same 8 ids in the same order, identical
`text_sha256`, identical `withheld`, denominators 629 = 621 + 8. The FIELD moved:
payload 108 877 -> 113 143 B (+3.92 %), spent 18 606 -> 22 210 (+450.5 B per
excerpt), excerpt members 9 -> 17, 99 changed lines. Known-positive follows the
contract document's bytes again: 12 049 -> 12 563 measured, 11 719 -> 12 227
raw, delta 330 -> 336.
`tools/okf_skill.py` instantiates the template for one bundle: id, ref, concept
count, the conditional-field table with a denominator per field (the `source_*`
rows DISCOVERED from the bundle, not listed), the whole-bundle cost by the gate's
own instrument, the share one measured answer spent, the concept count at which
the withheld bookkeeping alone reaches the limit, and the index-walk-against-
directory control - run once at generation time, never on the question path.
The form was chosen on a measurement that came out against the obvious gate:
the contract checker passes the UNFILLED template against a real payload, and
passes a skill built for a different bundle against this one's. It cannot tell
the two forms apart, so conformance could not decide it. What decides it is that
5's denominators, 6.4's conditional fields and 7.6's breaking point are
per-bundle numbers - a generic skill either leaves them as holes (the template's
own definition of unfinished) or states another corpus's numbers, which is worse
than a gap. Every gate the checker lacks is therefore a test here: no placeholder
survives, the skill names its own bundle's id and ref and not another's, its
commands are absolute and point at files that exist, and it refuses a directory
with no index (exit 1, `bundle_unreadable`), an index with no `bundle_id`
(`bundle_id_missing`), an empty bundle, and an occupied target without --force.
It lives in `tools/` for the reason `okf_consume.py` and `okf_contract_check.py`
state for themselves - outside `src/`, so no consumer's install surface changes -
and because a wheel-installed `okf skill` would emit a command pointing at
`tools/okf_consume.py`, which the wheel does not contain.
Suite 1372 (1347 before), ruff clean, mypy src clean.
Co-Authored-By: Claude <claude-opus-5>
589 lines
24 KiB
Python
589 lines
24 KiB
Python
"""Instantiate the consumption skill template for ONE named OKF bundle.
|
|
|
|
`skills/okf-consume-template/SKILL.md` is a template whose own rule is that a
|
|
copy leaving a `<PLACEHOLDER>` unfilled "is not configured, it is unfinished".
|
|
Filling it by hand is what produced `skills/okf-consume/` for one corpus. This
|
|
command does the same thing for any bundle, from values it measures rather than
|
|
values someone remembered.
|
|
|
|
**Why a generator rather than one generic skill.** Measured 2026-09-08: the
|
|
contract checker passes the UNFILLED template against a real payload (exit 0, 15
|
|
rules, 0 findings), and passes a skill built for a different bundle against this
|
|
one's payload. So the checker cannot tell the two forms apart, and the choice
|
|
could not be made on conformance. It was made on what the skill has to state:
|
|
§ 5's denominators, § 7.6's breaking point and § 6.4's conditional-field list
|
|
are all per-bundle numbers. A generic skill can either leave them as holes -- the
|
|
template's own definition of unfinished -- or carry another corpus's numbers,
|
|
which is worse, because a stated cost that is false for this bundle is a
|
|
measurement failure and not merely a gap. Instantiating is what makes them true.
|
|
And with several bundles connected at once, a generic skill has nothing to
|
|
select on: each generated skill carries the bundle's id in its own name.
|
|
|
|
**Zero model calls, zero network, no clock.** The same bundle bytes produce the
|
|
same skill bytes. It lives outside `src/`, so it never enters a wheel and no
|
|
consumer's install surface changes because it exists -- and a wheel-installed
|
|
`okf skill` would emit a command pointing at `tools/okf_consume.py`, which the
|
|
wheel does not contain.
|
|
|
|
Exit codes are three, as elsewhere in this chain: 0 the skill was written, 1 the
|
|
run happened and refused, 2 the run did not happen.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import re
|
|
import sys
|
|
from collections import Counter
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
|
|
import okf_consume # noqa: E402
|
|
|
|
from llm_ingestion_okf.profiles import BundleProfile # noqa: E402
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
TEMPLATE = PROJECT_ROOT / "skills" / "okf-consume-template" / "SKILL.md"
|
|
CONTRACT = PROJECT_ROOT / "docs" / "consumption-contract.md"
|
|
PRE_PASS = PROJECT_ROOT / "tools" / "okf_consume.py"
|
|
CHECKER = PROJECT_ROOT / "tools" / "okf_contract_check.py"
|
|
|
|
#: The profile the pre-pass reads a bundle under, spelled so the generated skill
|
|
#: can name it in § 9.2's sentence. The pre-pass's own default; a bundle built
|
|
#: under another profile needs a copy of this tool that says so.
|
|
PROFILE_NAME = "SEGMENTED_OKF_V0_2"
|
|
|
|
#: The conditional frontmatter keys the generated skill reports a denominator
|
|
#: for. Every one of them is written by SOME producer and not by others, which
|
|
#: is exactly what § 6.4 says a consumer must be told about rather than left to
|
|
#: infer from an absence.
|
|
CONDITIONAL_FIELDS = (
|
|
"adjudication",
|
|
"bundle_id",
|
|
"verified",
|
|
"req_number",
|
|
"sources",
|
|
)
|
|
|
|
#: Tokens too short to carry a question. The same floor the pre-pass's own
|
|
#: matcher uses, so the derived example question cannot be shorter than what the
|
|
#: ranker can see.
|
|
MIN_QUESTION_TOKEN = 5
|
|
|
|
|
|
class SkillError(Exception):
|
|
"""The generator refused. Carries the code, like the rest of this chain."""
|
|
|
|
def __init__(self, message: str, *, code: str) -> None:
|
|
super().__init__(message)
|
|
self.code = code
|
|
|
|
|
|
# --- The blocks the template hands over verbatim ------------------------------
|
|
|
|
#: Every template block this generator rewrites WHOLE, by exact string. Held to
|
|
#: the template by a test: an edit that moves one of these would otherwise
|
|
#: produce a skill silently missing that rewrite, which is the drift the
|
|
#: instantiated copy exists to avoid.
|
|
TEMPLATE_HEADER = """**This file is a template.** Every `<PLACEHOLDER>` is a hole a per-corpus copy
|
|
fills; none of them has a default, and a copy that leaves one unfilled is not
|
|
configured, it is unfinished. The section headings are fixed:
|
|
`tools/okf_contract_check.py` reads them, and a missing one makes the skill
|
|
non-conformant rather than merely thin."""
|
|
|
|
TEMPLATE_PRE_PASS = """```sh
|
|
<PRE_PASS_COMMAND> --bundle-root <BUNDLE_ROOT> --ref <REF> --out <PAYLOAD_PATH>
|
|
```"""
|
|
|
|
TEMPLATE_CHECK = """```sh
|
|
python3 tools/okf_contract_check.py --skill <SKILL_PATH> --payload <PAYLOAD_PATH>
|
|
```"""
|
|
|
|
TEMPLATE_CONTRACT_LINE = (
|
|
"The contract this skill is held to is `docs/consumption-contract.md`. Where this"
|
|
)
|
|
|
|
TEMPLATE_EXTENSIONS = """**Extensions, if this corpus needs any.** `<EXTENSION_MARKINGS: for each, the
|
|
literal, what it means here, and which of the five it would otherwise collapse
|
|
into. Write "none" if there are none.>`"""
|
|
|
|
TEMPLATE_CONDITIONAL = """**Conditionally-written fields in this corpus.** `<CONDITIONAL_FIELDS: each
|
|
field this profile writes only when a build-time condition held, and what its
|
|
absence does and does not mean. Absence is a measurement, not a fact.>`"""
|
|
|
|
TEMPLATE_SCALING = """**Scaling.** `<COST_SCALING: whether cost tracks the question or the corpus, what
|
|
the whole bundle at this ref costs by the same instrument, and the corpus size
|
|
at which this strategy stops fitting the budget.>`"""
|
|
|
|
TEMPLATE_DENOMINATORS = """The payload reports three counts — `considered`, `withheld`, `delivered` — and
|
|
`considered == withheld + delivered`. Carry them into your output."""
|
|
|
|
TEMPLATE_ENUMERATION = (
|
|
"- **No directory enumeration** unless `<PROFILE_NAME>` says the index is derived."
|
|
)
|
|
|
|
TEMPLATE_OUTPUT = "Write to `<OUT>`. It must carry: the bundle ref; the findings, each with a"
|
|
|
|
REPLACED_BLOCKS = (
|
|
TEMPLATE_HEADER,
|
|
TEMPLATE_PRE_PASS,
|
|
TEMPLATE_CHECK,
|
|
TEMPLATE_CONTRACT_LINE,
|
|
TEMPLATE_EXTENSIONS,
|
|
TEMPLATE_CONDITIONAL,
|
|
TEMPLATE_SCALING,
|
|
TEMPLATE_DENOMINATORS,
|
|
TEMPLATE_ENUMERATION,
|
|
TEMPLATE_OUTPUT,
|
|
)
|
|
|
|
|
|
# --- What the generator measures ----------------------------------------------
|
|
|
|
|
|
def slug(value: str) -> str:
|
|
"""A Claude Code skill name from a bundle id: lowercase, hyphen-joined."""
|
|
reduced = re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")
|
|
return reduced or "okf"
|
|
|
|
|
|
def example_question(titles: list[str]) -> str:
|
|
"""A question this bundle really answers, derived rather than invented.
|
|
|
|
The most frequent long token across the concepts' own titles, byte-sorted on
|
|
a tie. Derived because the shipped payload has to be one this bundle
|
|
produces: a question sharing no token with any concept is withheld under
|
|
`no_lexical_match` and the pre-pass refuses, so a hand-picked constant would
|
|
fail on the first bundle that does not happen to contain it.
|
|
"""
|
|
counts: Counter[str] = Counter()
|
|
for title in titles:
|
|
counts.update(
|
|
{token for token in okf_consume.normalise(title) if len(token) >= MIN_QUESTION_TOKEN}
|
|
)
|
|
if not counts:
|
|
# Every title is short or empty. Fall back to the longest title as it
|
|
# stands, which by construction matches at least its own concept.
|
|
longest = max(titles, key=lambda title: (len(title), title), default="")
|
|
if not longest:
|
|
raise SkillError(
|
|
"no concept in this bundle carries a title, so no example "
|
|
"question can be derived from it; pass --example-question",
|
|
code="no_example_question",
|
|
)
|
|
return longest
|
|
top = min(counts.items(), key=lambda item: (-item[1], item[0]))[0]
|
|
return f"Hva sier denne bundelen om {top}?"
|
|
|
|
|
|
def field_counts(concepts: list[okf_consume.Concept]) -> dict[str, int]:
|
|
"""How many concepts carry each conditional field. Set membership, never a
|
|
guess from two equal totals.
|
|
|
|
The `source_*` rows are DISCOVERED from the bundle rather than listed here,
|
|
for the same reason the excerpt carries them by prefix: a fixed list reports
|
|
a denominator for the producers someone thought of, and says nothing about
|
|
the locator this producer actually chose.
|
|
"""
|
|
discovered = sorted(
|
|
{
|
|
key
|
|
for concept in concepts
|
|
for key in concept.frontmatter
|
|
if key.startswith(okf_consume.SOURCE_KEY_PREFIX)
|
|
}
|
|
)
|
|
fields = (*CONDITIONAL_FIELDS, *discovered)
|
|
counts = {field: 0 for field in fields}
|
|
for concept in concepts:
|
|
for field in fields:
|
|
if concept.frontmatter.get(field, "").strip() or (
|
|
field == "sources" and concept.sources_present
|
|
):
|
|
counts[field] += 1
|
|
return counts
|
|
|
|
|
|
def whole_bundle_cost(concepts: list[okf_consume.Concept]) -> int:
|
|
"""What every concept in this bundle would cost by the gate's own
|
|
instrument, if a single answer delivered all of them."""
|
|
total = 0
|
|
for concept in concepts:
|
|
excerpt = okf_consume.excerpt_for(concept)
|
|
if excerpt is not None:
|
|
total += okf_consume.excerpt_weight(excerpt)
|
|
return total
|
|
|
|
|
|
def directory_control(bundle_root: Path, *, profile: BundleProfile) -> tuple[int, int]:
|
|
"""The index walk against the method § 9.2 forbids the CONSUMER from using.
|
|
|
|
Run HERE, once, at generation time -- never on the question path. § 9.2
|
|
binds a consumer reaching for context at query time; a build-time control is
|
|
what turns "the walk loses nothing" from an assumption into a number the
|
|
generated skill can quote.
|
|
"""
|
|
walked = len(okf_consume.enumerate_concepts(bundle_root, profile=profile))
|
|
suffix = profile.paths.concept_suffix
|
|
reserved = {profile.index.name, "log.md"}
|
|
on_disk = len([path for path in bundle_root.rglob(f"*{suffix}") if path.name not in reserved])
|
|
return walked, on_disk
|
|
|
|
|
|
# --- The instantiation --------------------------------------------------------
|
|
|
|
|
|
def render(
|
|
bundle_root: Path,
|
|
*,
|
|
out: Path,
|
|
profile: BundleProfile = okf_consume.DEFAULT_PROFILE,
|
|
question: str | None = None,
|
|
) -> tuple[str, dict[str, object]]:
|
|
"""The skill text and the example payload that proves it, for one bundle."""
|
|
bundle_root = bundle_root.resolve()
|
|
bundle_id = okf_consume.root_bundle_id_of(bundle_root, profile=profile)
|
|
ref = okf_consume.bundle_ref(bundle_root, profile=profile)
|
|
concept_ids = okf_consume.enumerate_concepts(bundle_root, profile=profile)
|
|
concepts = [
|
|
okf_consume.read_concept(
|
|
bundle_root / f"{concept_id}{profile.paths.concept_suffix}",
|
|
bundle_root=bundle_root,
|
|
root_bundle_id=bundle_id,
|
|
)
|
|
for concept_id in concept_ids
|
|
]
|
|
if not concepts:
|
|
raise SkillError(
|
|
f"{bundle_root} has an index but no concept under it; a skill for an "
|
|
"empty bundle would state denominators of zero it never measured",
|
|
code="bundle_empty",
|
|
)
|
|
total = len(concepts)
|
|
asked = question or example_question([concept.title for concept in concepts])
|
|
payload = okf_consume.build_payload(bundle_root, question=asked, profile=profile)
|
|
counts = field_counts(concepts)
|
|
walked, on_disk = directory_control(bundle_root, profile=profile)
|
|
cost = whole_bundle_cost(concepts)
|
|
denominators = payload["denominators"]
|
|
assert isinstance(denominators, dict)
|
|
budget = payload["budget"]
|
|
assert isinstance(budget, dict)
|
|
withheld = payload["withheld"]
|
|
assert isinstance(withheld, list)
|
|
bookkeeping = okf_consume.measure(json.dumps(withheld, ensure_ascii=False))
|
|
per_withheld = bookkeeping / len(withheld) if withheld else 0.0
|
|
breaking = int(okf_consume.DEFAULT_LIMIT / per_withheld) if per_withheld else 0
|
|
|
|
name = f"{slug(bundle_id)}-consume"
|
|
text = TEMPLATE.read_text(encoding="utf-8")
|
|
text = text.split("---\n", 2)[2]
|
|
text = _rewrite(
|
|
text,
|
|
bundle_root=bundle_root,
|
|
skill_path=out.resolve() / "SKILL.md",
|
|
bundle_id=bundle_id,
|
|
ref=ref,
|
|
name=name,
|
|
total=total,
|
|
counts=counts,
|
|
walked=walked,
|
|
on_disk=on_disk,
|
|
cost=cost,
|
|
asked=asked,
|
|
spent=int(budget["spent"]),
|
|
delivered=int(denominators["delivered"]),
|
|
bookkeeping=bookkeeping,
|
|
breaking=breaking,
|
|
)
|
|
header = f"---\nname: {name}\ndescription: {_description(bundle_id, total, ref)}\n---\n"
|
|
return header + text, payload
|
|
|
|
|
|
def _description(bundle_id: str, total: int, ref: str) -> str:
|
|
return (
|
|
f"Answer one question about the OKF bundle `{bundle_id}` ({total} concepts, "
|
|
f"ref {ref}) from a bounded payload assembled by a deterministic pre-pass, "
|
|
"marking every claim with its source, its title and its provenance locator. "
|
|
"Use whenever a question is about what that bundle's documents require, say "
|
|
"or contain. Generated by tools/okf_skill.py; every value below is measured "
|
|
"against this bundle at this ref."
|
|
)
|
|
|
|
|
|
def _rewrite(
|
|
text: str,
|
|
*,
|
|
bundle_root: Path,
|
|
skill_path: Path,
|
|
bundle_id: str,
|
|
ref: str,
|
|
name: str,
|
|
total: int,
|
|
counts: dict[str, int],
|
|
walked: int,
|
|
on_disk: int,
|
|
cost: int,
|
|
asked: str,
|
|
spent: int,
|
|
delivered: int,
|
|
bookkeeping: int,
|
|
breaking: int,
|
|
) -> str:
|
|
replacements: list[tuple[str, str]] = [
|
|
(
|
|
TEMPLATE_HEADER,
|
|
"**This file is an instantiated copy of "
|
|
"`skills/okf-consume-template/SKILL.md`,** generated by "
|
|
f"`tools/okf_skill.py` for one bundle: `{bundle_id}` at ref\n"
|
|
f"`{ref}`. Every value below was measured against those bytes. If the\n"
|
|
"bundle moves, the ref moves with it and this file is stale — regenerate\n"
|
|
"it rather than editing a number here. The section headings are fixed:\n"
|
|
"the contract checker reads them by name.",
|
|
),
|
|
(
|
|
TEMPLATE_PRE_PASS,
|
|
"```sh\n"
|
|
f"python3 {PRE_PASS} \\\n"
|
|
f" {bundle_root} \\\n"
|
|
' --question "your question" \\\n'
|
|
f" --ref {ref} \\\n"
|
|
" --out /tmp/payload.json\n"
|
|
"```\n\n"
|
|
"`--ref` is an **assertion**, never an override: the identity is computed\n"
|
|
"from the bytes either way, and a mismatch refuses. Read the pre-pass's\n"
|
|
"own exit status, which carries three values: **0** a payload was written,\n"
|
|
"**1** the run happened and refused, **2** the run did not happen at all.",
|
|
),
|
|
(
|
|
TEMPLATE_CHECK,
|
|
"```sh\n"
|
|
f"python3 {CHECKER} \\\n"
|
|
f" --skill {skill_path} \\\n"
|
|
" --payload /tmp/payload.json\n"
|
|
"```",
|
|
),
|
|
(
|
|
TEMPLATE_CONTRACT_LINE,
|
|
f"The contract this skill is held to is `{CONTRACT}`. Where this",
|
|
),
|
|
(
|
|
TEMPLATE_EXTENSIONS,
|
|
"**Extensions, if this corpus needs any: none.** This generated skill adds\n"
|
|
"no marking to the required five. § 4.3 makes the undeclared extension the\n"
|
|
"defect, so the absence is stated rather than left to be inferred — and a\n"
|
|
"corpus that does need a sixth needs a hand-edited copy that declares it.",
|
|
),
|
|
(
|
|
TEMPLATE_CONDITIONAL,
|
|
_conditional_table(total, counts),
|
|
),
|
|
(
|
|
TEMPLATE_SCALING,
|
|
_scaling(
|
|
total=total,
|
|
cost=cost,
|
|
asked=asked,
|
|
spent=spent,
|
|
delivered=delivered,
|
|
bookkeeping=bookkeeping,
|
|
breaking=breaking,
|
|
),
|
|
),
|
|
(
|
|
TEMPLATE_DENOMINATORS,
|
|
_denominators(total, asked=asked, delivered=delivered),
|
|
),
|
|
(
|
|
TEMPLATE_ENUMERATION,
|
|
_enumeration(walked, on_disk),
|
|
),
|
|
(
|
|
TEMPLATE_OUTPUT,
|
|
"Write to the path the caller names, or to your answer if none was named.\n"
|
|
"It must carry: the bundle ref; the findings, each with a",
|
|
),
|
|
("`<CORPUS>` bundle", f"`{bundle_id}` bundle"),
|
|
("# <CORPUS> consumption", f"# {bundle_id} consumption"),
|
|
("<BUDGET_LIMIT>", str(okf_consume.DEFAULT_LIMIT)),
|
|
("<BUDGET_UNIT>", okf_consume.BUDGET_UNIT),
|
|
("<BUDGET_INSTRUMENT>", okf_consume.BUDGET_INSTRUMENT),
|
|
("<KNOWN_POSITIVE_CASE>", okf_consume.KNOWN_POSITIVE_CASE),
|
|
("<KNOWN_POSITIVE_EXPECTED>", str(okf_consume.KNOWN_POSITIVE_EXPECTED)),
|
|
]
|
|
for old, new in replacements:
|
|
if old not in text:
|
|
raise SkillError(
|
|
f"the template no longer carries the block this generator rewrites: {old[:70]!r}",
|
|
code="template_drift",
|
|
)
|
|
text = text.replace(old, new)
|
|
assert name # kept in the signature so a caller cannot forget to name the skill
|
|
return text
|
|
|
|
|
|
def _conditional_table(total: int, counts: dict[str, int]) -> str:
|
|
rows = "\n".join(
|
|
f"| `{field}` | **{count} of {total}** | "
|
|
f"{'the producer wrote none for that concept' if count else 'no concept in this bundle carries it'} | "
|
|
"that the source document lacks what the field asserts |"
|
|
for field, count in counts.items()
|
|
)
|
|
return (
|
|
"**Conditionally-written fields in this bundle, with what each absence does\n"
|
|
"and does not mean.** Every count is over the same denominator — "
|
|
f"**{total} concepts**, the set the index walk reaches. § 6.4: absence is a\n"
|
|
"measurement about the producer, never a fact about the source.\n\n"
|
|
"| Field | Present on | Absence means | Absence does NOT mean |\n"
|
|
"|---|---|---|---|\n"
|
|
f"{rows}\n\n"
|
|
"A field present on **0 of "
|
|
f"{total}** is a measured zero, not an unmeasured one: the count was taken\n"
|
|
"over every concept, and it is reported so a negative claim resting on it\n"
|
|
"carries its denominator."
|
|
)
|
|
|
|
|
|
def _scaling(
|
|
*,
|
|
total: int,
|
|
cost: int,
|
|
asked: str,
|
|
spent: int,
|
|
delivered: int,
|
|
bookkeeping: int,
|
|
breaking: int,
|
|
) -> str:
|
|
share = (spent / cost * 100) if cost else 0.0
|
|
return (
|
|
"**Scaling. Cost tracks the question, not the corpus.** Measured on this\n"
|
|
f"bundle at generation time, with the question `{asked}`: the delivered set\n"
|
|
f"was **{delivered} excerpts** costing **{spent} {okf_consume.BUDGET_UNIT}**,\n"
|
|
f"against a whole bundle that would cost **{cost}** by the same instrument if\n"
|
|
f"one answer delivered all {total} concepts — so that answer was about\n"
|
|
f"**{share:.1f} %** of the corpus. One question is one measurement: a\n"
|
|
"different question moves `spent` and this figure with it.\n\n"
|
|
"**The breaking point, stated so it can be observed to have been passed.**\n"
|
|
"The `withheld` list carries one entry per considered concept and grows\n"
|
|
f"linearly: here it is **{bookkeeping} bytes** for {total} concepts. At roughly\n"
|
|
f"**{breaking} concepts** the bookkeeping alone reaches the "
|
|
f"{okf_consume.DEFAULT_LIMIT}-byte\n"
|
|
"limit, and although it is not counted against `spent`, a payload whose\n"
|
|
"bookkeeping dwarfs its content has stopped being a cut. The pre-pass also\n"
|
|
"reads every concept body on every run, so the same growth is a wall-clock\n"
|
|
"cost with no precomputed index behind it."
|
|
)
|
|
|
|
|
|
def _denominators(total: int, *, asked: str, delivered: int) -> str:
|
|
return (
|
|
"The payload reports three counts — `considered`, `withheld`, `delivered` — and\n"
|
|
"`considered == withheld + delivered`. Carry them into your output.\n\n"
|
|
f"For this bundle `considered` is **{total}**, every concept the index walk\n"
|
|
"reaches, never the post-ranking shortlist. A concept dropped at the ranking\n"
|
|
"stage is `withheld` **with its rule**, not invisible, and the rules are a\n"
|
|
"closed set of six: `verdict_layer_excluded` (a verdict-layer file, § 9.1),\n"
|
|
"`verified_unreadable` (a `verified` value this reader cannot decode, so no\n"
|
|
"tier can be derived), `no_lexical_match` (the concept shares no token with\n"
|
|
"the question), `over_budget_alone` (one excerpt exceeds the whole limit),\n"
|
|
"`below_k` (ranked outside the shortlist the cut considers) and\n"
|
|
"`over_budget_after_knapsack` (it ranked inside the shortlist and the pack\n"
|
|
"had no room). Naming the rule is what makes a drop visible.\n\n"
|
|
"**One limitation to carry into every negative claim.** `no_lexical_match` is\n"
|
|
'a per-concept relevance drop, not a whole-question "this bundle has no\n'
|
|
f'answer" gate: on the generation question `{asked}` it still returned\n'
|
|
f"{delivered} excerpts. **An empty `excerpts` list is evidence of absence; a\n"
|
|
"full one is not evidence of presence.** When the delivered excerpts do not\n"
|
|
"actually answer the question, say `[sourced-not-sufficient]` and report that\n"
|
|
"the cut found nothing responsive."
|
|
)
|
|
|
|
|
|
def _enumeration(walked: int, on_disk: int) -> str:
|
|
agreement = (
|
|
f"which costs nothing here: the walk reaches **{walked}** concepts and a\n"
|
|
f" directory walk finds **{on_disk}**"
|
|
if walked == on_disk
|
|
else f"and the two disagree — the walk reaches **{walked}** concepts where a\n"
|
|
f" directory walk finds **{on_disk}**, so some concept is unreachable through\n"
|
|
" the index and the bundle's producer should be told"
|
|
)
|
|
return (
|
|
"- **No directory enumeration.** This bundle is read under the\n"
|
|
f" `{PROFILE_NAME}` profile, whose index policy declares\n"
|
|
" `entries_match_directory = False`, so § 9.2's permission does not apply.\n"
|
|
f" The pre-pass walks the **index tree** instead, {agreement}\n"
|
|
" (controlled once at generation time, never on the question path). Do not\n"
|
|
" enumerate a directory yourself either."
|
|
)
|
|
|
|
|
|
def generate(
|
|
bundle_root: Path,
|
|
*,
|
|
out: Path,
|
|
profile: BundleProfile = okf_consume.DEFAULT_PROFILE,
|
|
question: str | None = None,
|
|
force: bool = False,
|
|
) -> Path:
|
|
"""Write `out/SKILL.md` and its reference payload. Returns the skill path."""
|
|
target = out / "SKILL.md"
|
|
if target.exists() and not force:
|
|
raise SkillError(
|
|
f"{target} already exists; pass --force to replace it. A silent "
|
|
"overwrite would destroy a hand-edited copy whose extra measurements "
|
|
"this generator cannot reproduce",
|
|
code="target_occupied",
|
|
)
|
|
text, payload = render(bundle_root, out=out, profile=profile, question=question)
|
|
(out / "references").mkdir(parents=True, exist_ok=True)
|
|
target.write_text(text, encoding="utf-8")
|
|
(out / "references" / "example-payload.json").write_text(
|
|
okf_consume.serialise(payload), encoding="utf-8"
|
|
)
|
|
return target
|
|
|
|
|
|
def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
|
|
)
|
|
parser.add_argument("bundle", type=Path, help="the OKF bundle to instantiate a skill for")
|
|
parser.add_argument(
|
|
"--out", type=Path, required=True, help="the skill directory to write (SKILL.md inside)"
|
|
)
|
|
parser.add_argument(
|
|
"--example-question",
|
|
default=None,
|
|
help="the question the shipped reference payload answers. Derived from the "
|
|
"bundle's own titles when omitted",
|
|
)
|
|
parser.add_argument(
|
|
"--force", action="store_true", help="replace an existing SKILL.md at --out"
|
|
)
|
|
return parser.parse_args(argv)
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
args = parse_args(argv)
|
|
try:
|
|
written = generate(
|
|
args.bundle, out=args.out, question=args.example_question, force=args.force
|
|
)
|
|
except okf_consume.ConsumeError as exc:
|
|
print(f"refused ({exc.code}): {exc}")
|
|
return 1
|
|
except SkillError as exc:
|
|
print(f"refused ({exc.code}): {exc}")
|
|
return 1
|
|
except OSError as exc:
|
|
print(f"the run did not happen: {exc}")
|
|
return 2
|
|
print(f"wrote {written}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|