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
3 changes: 3 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ external sources, and add its navigation link to the owning README. See the
sidecar or registry, commit, then run
`python tools/build_skill_index.py --source-revision <committed-revision>`; a
hand edit there is reverted by the next run and only `--check` reports it.
A one-skill edit regenerates only that skill's record, the shared
`_provenance.json` snapshot and the coverage view; see the
[knowledge contribution workflow](knowledge-contribution-workflow.md).
Do not maintain a second per-entry Markdown summary.
Keep IDs stable, omit PR links, retain source attribution and negative results,
and qualify new backends independently. See the
Expand Down
5 changes: 4 additions & 1 deletion docs/knowledge-base.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,10 @@ recipes; native execution and efficacy remain not_run.
The complete library is the single content owner. Maintain stable paths and
backend classifications in `skill-index.json`, then refresh generated records
and navigation with `tools/build_skill_index.py`; do not hand-edit generated
cards. Its source-revision and consistency checks prevent attributing edited
cards. Stored cards keep only their own fields and resource hashes, and the shared
`_provenance.json` snapshot holds the source revision and registry hash; the
catalog resolves them into the public records
([contribution workflow](knowledge-contribution-workflow.md)). Its source-revision and consistency checks prevent attributing edited
metadata to an older snapshot. Preserve existing states, provenance, notices,
`UNKNOWN` licenses and the two matrices' authority. Migration and installed-package
checks do not establish licensing, empirical verification or automatic execution.
Expand Down
101 changes: 101 additions & 0 deletions docs/knowledge-contribution-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Knowledge contribution workflow

This is the short path for a change to one skill in `src/inferrsi/data/skill_library/`.
It implements the representation accepted in
[issue #355](https://github.com/InferMatrixLab/InferRSI/issues/355#issuecomment-6730172305).

## What you write and what tools derive

| You write | Tools derive |
| --- | --- |
| Skill body, references, cases, `metadata.json`, registry entry | Per-skill catalog records, resource hashes, `_provenance.json`, navigation |
| Matrix rows in `docs/reference-matrix.md` and `docs/searchspace-matrix.md` | `docs/skill-coverage.md` |
| The PR's knowledge authorship declaration: every material AI author's actual tool, model and effort, or `human_only` | The head SHA and the exact protected, policy and generated path lists |

Tooling never infers authorship, model, effort, human contribution or an exception
decision.

## Steps

1. Edit the canonical skill files and the matrices, then commit them. This commit is
the source revision.
2. Regenerate from that commit and check:

```bash
python tools/build_skill_index.py --source-revision <source-commit>
python tools/build_skill_coverage.py
python tools/build_skill_index.py --source-revision <source-commit> --check
python tools/build_skill_coverage.py --check
```

3. Commit the generated changes. List the declaration paths for the final head:

```bash
python tools/knowledge_declaration_paths.py --base origin/main --head HEAD
```

The path lists overlap: under the current policy every generated path is also a
protected path. Do not add their counts.

4. Write the declaration in the PR body with the reported `head_sha`. Update it after
every new commit.

## Stored format

Stored skill records are schema 2. They keep each skill's own fields and resource
hashes. The shared `knowledge/_provenance.json` holds the full source revision and
the registry hash:

```json
{
"schema_version": 1,
"repository": "https://github.com/InferMatrixLab/InferRSI",
"source_revision": "<40-hex commit>",
"registry": {"path": "src/inferrsi/data/skill_library/skill-index.json", "sha256": "<64-hex>"}
}
```

`inferrsi.catalog` resolves each stored record into a public schema-1 record with
the same fields and field order as before: the `sources` entry with the full commit
URL, and `source_files` including the registry hash. Search, `knowledge show`,
Collect and installed wheels keep reading schema 1. The generator refuses to write a
record that does not resolve back to the record it rendered.

The one-time migration regenerated all 80 records at the previous pin
`d648f25732dee1c974da62a94c46a642ad52cef8`; each resolved record was byte-identical
to the previous stored record. It then moved the pin to
`56c500367d5495fdd9f0e35030c9cd957f70eac5`, the squash commit on `main` with the
same skill-library bytes, because the previous pin is a pre-squash branch commit
and not an ancestor of `main`. Resolved records therefore differ from the previous
records only in `sources[0].commit` and `sources[0].url`; every content hash and
the registry hash are unchanged. To check the stored hashes, run
`python tools/build_skill_index.py --source-revision <source_revision> --check` with
the `source_revision` from `_provenance.json`.

## What changes per contribution

Before the shared snapshot, every skill record repeated the repository-wide source
commit and registry hash, so a one-skill edit rewrote all 80 records. Measured on
`main` at `56c50036` with one appended line in `performance-ceiling-analysis`, the
old generator changed 82 generated files (80 records, the README and the coverage
view). The new generator changes 3: that skill's record, `_provenance.json` and the
coverage view. Editing the registry or a declared status also changes the README.

Two PRs that change different skills share only `_provenance.json` and the coverage
view's input digest among generated files, so those are the expected conflicts.
Integrate the second on top of the first, keep both canonical changes, commit them
as the new source revision and regenerate; regeneration rewrites both shared files
and no unrelated record is hand-edited. Divergent edits to the same skill, or to the
same matrix row, remain ordinary content conflicts that must be resolved by hand.

## Limits

- After a squash merge, the recorded source revision is a branch commit that is not
an ancestor of `main`. The packaged content still resolves, and `--check` still
works when that commit is available. Git-backed SkillEval planning reports the pin
as unavailable. This already happened with the previous format: the projections
on `main` before this change pinned a squashed branch commit.
- Raw stored records changed from schema 1 to schema 2. Code that reads the JSON
files directly must use `inferrsi.catalog` or `inferrsi._source_snapshot.resolve`.
- Generated files are protected knowledge paths. Regenerating them is material
authorship work and needs a valid declaration.
5 changes: 3 additions & 2 deletions docs/skill-eval-pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ The author and independent reviewer must disposition that relevance explicitly.

For canonical library or generated-index changes, the planner may show the existing
`python tools/build_skill_index.py --source-revision <declared-commit> --check`
with an **actual** immutable pin. It reads the known generated README as bounded
Git data, requires one declared source commit in the frozen head's ancestor closure,
with an **actual** immutable pin. It reads the declared pin as bounded Git data from
the generated `_provenance.json` snapshot, or from the generated README when no
snapshot exists, requires that source commit in the frozen head's ancestor closure,
and checks that the entire canonical library has identical Git bytes/modes at that
pin and the PR head. It does not
execute the generator or establish that generated records are correct. Plan and
Expand Down
88 changes: 88 additions & 0 deletions src/inferrsi/_source_snapshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from __future__ import annotations

import re
from typing import Any

# One shared snapshot keeps the repository-wide source revision and registry digest out of
# per-owner records, so a one-owner edit regenerates only that owner's record.
MANIFEST = "_provenance.json"
REPOSITORY = "https://github.com/InferMatrixLab/InferRSI"
LIBRARY = "src/inferrsi/data/skill_library"
REGISTRY = f"{LIBRARY}/skill-index.json"
STORED_SCHEMA = 2


def manifest(revision: str, registry_sha256: str) -> dict[str, Any]:
return {
"schema_version": 1,
"repository": REPOSITORY,
"source_revision": revision,
"registry": {"path": REGISTRY, "sha256": registry_sha256},
}


def _snapshot(value: Any) -> tuple[str, str]:
if (
not isinstance(value, dict)
or set(value) != {"schema_version", "repository", "source_revision", "registry"}
or type(value["schema_version"]) is not int
or value["schema_version"] != 1
or value["repository"] != REPOSITORY
or not isinstance(value["source_revision"], str)
or not re.fullmatch(r"[0-9a-f]{40}", value["source_revision"])
):
raise ValueError("Invalid knowledge source snapshot")
registry = value["registry"]
if (
not isinstance(registry, dict)
or set(registry) != {"path", "sha256"}
or registry["path"] != REGISTRY
or not isinstance(registry["sha256"], str)
or not re.fullmatch(r"[0-9a-f]{64}", registry["sha256"])
):
raise ValueError("Invalid knowledge source snapshot registry")
return value["source_revision"], registry["sha256"]


def compact(record: dict[str, Any]) -> dict[str, Any]:
"""Store a generated schema-v1 record without its snapshot-wide fields."""
stored = {key: value for key, value in record.items() if key != "sources"}
stored["schema_version"] = STORED_SCHEMA
stored["source_files"] = {
path: digest for path, digest in record["source_files"].items() if path != REGISTRY
}
return stored


def resolve(stored: dict[str, Any], snapshot: Any) -> dict[str, Any]:
"""Rebuild the public schema-v1 record from a stored record and the shared snapshot."""
revision, registry_sha256 = _snapshot(snapshot)
if stored.get("schema_version") != STORED_SCHEMA or "sources" in stored:
raise ValueError("Stored skill record is not a schema-v2 projection")
files = stored.get("source_files")
documents = stored.get("skill_documents")
if (
not isinstance(files, dict) or REGISTRY in files
or not isinstance(documents, dict) or not isinstance(documents.get("original"), str)
):
raise ValueError(f"Invalid stored skill record: {stored.get('id')}")
entry = "src/inferrsi/" + documents["original"]
if entry not in files:
raise ValueError(f"Stored skill record lacks its entry hash: {stored.get('id')}")
hashes = dict(sorted({**files, REGISTRY: registry_sha256}.items()))
source = {
"type": "git",
"url": f"{REPOSITORY}/blob/{revision}/{entry}",
"commit": revision,
"paths": list(hashes),
"content_sha256": hashes[entry],
}
record = {}
for key, value in stored.items():
record[key] = 1 if key == "schema_version" else value
if key == "origin":
record["sources"] = [source]
if "sources" not in record:
raise ValueError(f"Stored skill record lacks origin: {stored.get('id')}")
record["source_files"] = hashes
return record
15 changes: 14 additions & 1 deletion src/inferrsi/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from importlib.resources import files
from typing import Any

from inferrsi import _source_snapshot

REPO_TYPES = ("vllm", "vllm_omni", "afd_plugin", "vllm_rlt", "strata", "sglang", "sglang_omni")
# Learning scope does not imply that a repository has a runnable target adapter.
# Legacy repository-pack records retain their contribution tier; an independent
Expand Down Expand Up @@ -98,10 +100,21 @@ def knowledge_records() -> list[dict[str, Any]]:
)
if not knowledge.is_dir():
continue
snapshot = knowledge.joinpath(_source_snapshot.MANIFEST)
snapshot = (
json.loads(snapshot.read_text(encoding="utf-8")) if snapshot.is_file() else None
)
for parts, item in _walk(knowledge):
if not item.name.endswith(".json"):
if not item.name.endswith(".json") or parts == (_source_snapshot.MANIFEST,):
continue
record = json.loads(item.read_text(encoding="utf-8"))
# Generated skill records store schema v2; readers always receive schema v1.
if isinstance(record, dict) and record.get("schema_version") == (
_source_snapshot.STORED_SCHEMA
):
if snapshot is None:
raise ValueError(f"Knowledge record lacks its source snapshot: {repo}")
record = _source_snapshot.resolve(record, snapshot)
_validate_record(record, repo, parts, tier)
if record["id"] in seen:
raise ValueError(f"Duplicate knowledge ID: {record['id']}")
Expand Down
11 changes: 8 additions & 3 deletions src/inferrsi/data/repo_packs/inferrsi/knowledge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ These are knowledge abstracts (`--kind knowledge`), with namespaced package
IDs distinct from explicitly selected `checkout_ref` skills. Ascend/CUDA
procedures use their corresponding backend; shared methods use `common`.

Source snapshot: [d648f25732dee1c974da62a94c46a642ad52cef8](https://github.com/InferMatrixLab/InferRSI/tree/d648f25732dee1c974da62a94c46a642ad52cef8/src/inferrsi/data/skill_library).
`_provenance.json` holds the shared source snapshot: the full source
revision and the registry hash. Stored records (schema 2) keep only their own
fields and resource hashes; the catalog restores the schema-1 `sources` entry and
registry hash from the snapshot, so editing one skill regenerates only its record
and the snapshot.

```bash
inferrsi knowledge search 'profiling' --repo-type inferrsi --limit 50
Expand All @@ -29,10 +33,11 @@ contain the current input paths and bytes (Git checkout filters are respected).

```bash
python tools/build_skill_index.py --source-revision <committed-source-revision>
python tools/build_skill_index.py --source-revision d648f25732dee1c974da62a94c46a642ad52cef8 --check
python tools/build_skill_index.py --source-revision <committed-source-revision> --check
```

`--check` detects missing, stale and unexpected generated records without writing.
`--check` detects missing, stale and unexpected generated records without writing;
use the `source_revision` recorded in `_provenance.json`.
References and cases ship with their owning skill, not as duplicate knowledge abstracts.

| Skill | Backend | Original declared status |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"schema_version": 1,
"repository": "https://github.com/InferMatrixLab/InferRSI",
"source_revision": "56c500367d5495fdd9f0e35030c9cd957f70eac5",
"registry": {
"path": "src/inferrsi/data/skill_library/skill-index.json",
"sha256": "7904275c3383380db179287171e1430617aaa9ac4f439291eff8a71426987fbb"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"schema_version": 1,
"schema_version": 2,
"id": "inferrsi.ascend.skills.ascend_aclgraph_capture_replay",
"title": "ascend-aclgraph-capture-replay",
"repo": "inferrsi",
Expand All @@ -18,20 +18,6 @@
"origin": [
"external"
],
"sources": [
{
"type": "git",
"url": "https://github.com/InferMatrixLab/InferRSI/blob/d648f25732dee1c974da62a94c46a642ad52cef8/src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/SKILL.md",
"commit": "d648f25732dee1c974da62a94c46a642ad52cef8",
"paths": [
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/SKILL.md",
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/metadata.json",
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/references/source-notes.md",
"src/inferrsi/data/skill_library/skill-index.json"
],
"content_sha256": "d494fc7e539cbb7388189bd7b3f04bb5c4983fdd7a82484348aad1cee7f741f2"
}
],
"index_type": "packaged-skill",
"skill_documents": {
"original": "data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/SKILL.md"
Expand All @@ -40,8 +26,7 @@
"source_files": {
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/SKILL.md": "d494fc7e539cbb7388189bd7b3f04bb5c4983fdd7a82484348aad1cee7f741f2",
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/metadata.json": "3ac69dd82ae798450092c830b62f4958dc2f5b1c7000f9c3f822f2b0693f8af4",
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/references/source-notes.md": "6ffbfb68cc7e04923b4fbca2a73a7555b7c3b45a6f40819bb5f3213ef05cf88d",
"src/inferrsi/data/skill_library/skill-index.json": "7904275c3383380db179287171e1430617aaa9ac4f439291eff8a71426987fbb"
"src/inferrsi/data/skill_library/hardware/ascend/ascend-aclgraph-capture-replay/references/source-notes.md": "6ffbfb68cc7e04923b4fbca2a73a7555b7c3b45a6f40819bb5f3213ef05cf88d"
},
"skill_metadata": {
"name": "ascend-aclgraph-capture-replay",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"schema_version": 1,
"schema_version": 2,
"id": "inferrsi.ascend.skills.ascend_device_health",
"title": "ascend-device-health",
"repo": "inferrsi",
Expand All @@ -20,28 +20,14 @@
"origin": [
"external"
],
"sources": [
{
"type": "git",
"url": "https://github.com/InferMatrixLab/InferRSI/blob/d648f25732dee1c974da62a94c46a642ad52cef8/src/inferrsi/data/skill_library/hardware/ascend/ascend-device-health/SKILL.md",
"commit": "d648f25732dee1c974da62a94c46a642ad52cef8",
"paths": [
"src/inferrsi/data/skill_library/hardware/ascend/ascend-device-health/SKILL.md",
"src/inferrsi/data/skill_library/hardware/ascend/ascend-device-health/metadata.json",
"src/inferrsi/data/skill_library/skill-index.json"
],
"content_sha256": "03829039860ece35519f2e4c339a48b5014ec25e07a2c150a3efb6a3a4e35b4a"
}
],
"index_type": "packaged-skill",
"skill_documents": {
"original": "data/skill_library/hardware/ascend/ascend-device-health/SKILL.md"
},
"checkout_ref": "checkout:ascend-device-health",
"source_files": {
"src/inferrsi/data/skill_library/hardware/ascend/ascend-device-health/SKILL.md": "03829039860ece35519f2e4c339a48b5014ec25e07a2c150a3efb6a3a4e35b4a",
"src/inferrsi/data/skill_library/hardware/ascend/ascend-device-health/metadata.json": "f643185563dbf528a5a1f2b0561685ae34302a9efc9900c6753a7168b4e8b329",
"src/inferrsi/data/skill_library/skill-index.json": "7904275c3383380db179287171e1430617aaa9ac4f439291eff8a71426987fbb"
"src/inferrsi/data/skill_library/hardware/ascend/ascend-device-health/metadata.json": "f643185563dbf528a5a1f2b0561685ae34302a9efc9900c6753a7168b4e8b329"
},
"skill_metadata": {
"name": "ascend-device-health",
Expand Down
Loading
Loading