feat: docs/ carries the operator's how-to guides, a configuration reference and the architecture and telemetry explanations carved out of README.md, INSTALL.md, INSTALL-MCP.md and EVALS.md; the last two retired (#190)
Files changed: - .gitea/workflows/ci.yml - .gitignore - .vibe/hooks.toml - AGENTS.md - CHANGES.md - EVALS.md - INSTALL-MCP.md - INSTALL.md - README.md - VERSION - docs/dev/development.md - docs/explanation/README.md - docs/explanation/architecture.md - docs/explanation/language-boundaries.md - docs/explanation/telemetry-and-evaluation.md - docs/how-to/README.md - docs/how-to/browse-with-obsidian.md - docs/how-to/capture-repository-docs.md - docs/how-to/export-guidelines.md - docs/how-to/ingest-a-source.md - docs/how-to/maintain-the-wiki.md - docs/how-to/query-the-wiki.md - docs/how-to/run-the-weekly-review.md - docs/how-to/set-up-the-mcp-server.md - docs/how-to/trace-and-score-sessions.md - docs/how-to/troubleshoot.md - docs/how-to/update-an-instance.md - docs/reference/README.md - docs/reference/commands/distribution-and-versioning.md - docs/reference/commands/instance-health.md - docs/reference/commands/raw-material-and-uploads.md - docs/reference/commands/telemetry.md - docs/reference/commands/types-instructions-and-docs.md - docs/reference/configuration.md - instructions/dev/dev-setup.md - instructions/dev/doc-pull-through.md - instructions/dev/stack-build/SKILL.md - instructions/dev/testing-conventions.md - instructions/dev/version-parts.md - instructions/setup-instance.md - instructions/upgrade-instance.md - reports/CONTRACT.md - tools/.coveragerc - tools/CONTRACT.md - tools/README.md - tools/chemenu/commands/dist_cmd.py - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/eval_cmd.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/upload_cmd.py - tools/chemenu/commands/version_cmd.py - tools/chemenu/evals/__init__.py - tools/chemenu/evals/scorecard.py - tools/chemenu/evals/trajectory.py - tools/chemenu/telemetry/policy.py - tools/chemenu/tests/test_dist_cmd.py - tools/chemenu/tests/test_git_publish.py - tools/chemenu/tests/test_instructions_shell.py - tools/chemenu/tests/test_pipeline_l0.py - tools/chemenu/toc.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
1 parent
cff7df4ffa
commit
f9056c04f7
61 files changed
+2169
-1772
No files matched your search
@@ -88,17 +88,14 @@ DIST_TEMPLATES_DIR = Path(__file__).resolve().parent.parent / "dist_templates"
|
||||
# `.claude/settings.json` does - a distributed instance running that harness
|
||||
# would otherwise start every session without the control plane.
|
||||
#
|
||||
# `INSTALL-MCP.md` ships beside `INSTALL.md` and for the same reason: the MCP
|
||||
# read server is part of what an instance *has*, even though its dependency is
|
||||
# optional. A distribution whose server is present but undocumented is one
|
||||
# whose operator finds the module by reading the source.
|
||||
#
|
||||
# The developer documentation (the release workflow, the development
|
||||
# environment) is not a root file at all: it lives under `docs/dev/`, which
|
||||
# `build_plan` excludes the way it excludes `instructions/dev/` - see
|
||||
# DOCS_DEV_ONLY.
|
||||
# The rest of the human documentation is not a root file at all: it lives under
|
||||
# `docs/`, which ships whole - the operator's how-to guides (the MCP read
|
||||
# server's setup among them), the reference and the explanation pages. The one
|
||||
# exception is the developer documentation (the release workflow, the
|
||||
# development environment) under `docs/dev/`, which `build_plan` excludes the
|
||||
# way it excludes `instructions/dev/` - see DOCS_DEV_ONLY.
|
||||
ROOT_FILES = (
|
||||
"AGENTS.md", "CLAUDE.md", "README.md", "EVALS.md", "INSTALL.md", "INSTALL-MCP.md",
|
||||
"AGENTS.md", "CLAUDE.md", "README.md", "INSTALL.md",
|
||||
".gitignore", ".gitattributes", "VERSION",
|
||||
*config.LICENSE_FILES,
|
||||
*config.PERSONALIZATION_TEMPLATES,
|
||||
@@ -114,7 +111,8 @@ ROOT_FILES = (
|
||||
REQUIRED_ROOT_FILES = config.LICENSE_FILES
|
||||
|
||||
# Harness-specific session-tracing config: generic machinery (feeds
|
||||
# tools/chemenu/telemetry/ and tools/trace_ingest.py via EVALS.md), not
|
||||
# tools/chemenu/telemetry/ and tools/trace_ingest.py, see
|
||||
# docs/explanation/telemetry-and-evaluation.md), not
|
||||
# personal state - unlike `.obsidian/`/`.vscode/`, which are never copied.
|
||||
HOOK_DIRS = (".github/hooks", ".vibe")
|
||||
|
||||
@@ -632,7 +630,7 @@ def _write_plan(target: Path, plan: dict[str, PlannedFile]) -> None:
|
||||
notes=(
|
||||
"Writes a contentless, distributable copy of this repo's machinery into an empty or "
|
||||
"new `<target>` directory.",
|
||||
"Ships `AGENTS.md`/`README.md`/`EVALS.md` with any `dist:strip-start`...`dist:strip-end` "
|
||||
"Ships `AGENTS.md`/`README.md`/`INSTALL.md` with any `dist:strip-start`...`dist:strip-end` "
|
||||
"marker region removed, `instructions/` (minus `instructions/dev/`), `types/` (the "
|
||||
"`root: kb` page type-specs, their schemas and their subtype templates "
|
||||
"`types/<type>.<value>.md` re-keyed as `.template`, the stack's own verbatim), `docs/` "
|
||||
@@ -1518,7 +1516,7 @@ def _report_plan(
|
||||
"`wikitool version check` - finds out whether an update exists",
|
||||
"`wikitool version notes` - the notes of the release `--expect` should name",
|
||||
"`instructions/upgrade-instance.md` - the order after the swap",
|
||||
"`INSTALL.md` § \"Version und Updates\" - which release, whether to take it, where "
|
||||
"`docs/how-to/update-an-instance.md` - which release, whether to take it, where "
|
||||
"the tarball comes from",
|
||||
"`wikitool migrate status` - the migrations the report names",
|
||||
),
|
||||
@@ -1580,7 +1578,7 @@ def upgrade_command(
|
||||
Refuses on a missing local release stamp, a downgrade, a pre-release
|
||||
source without `--pre`, a dirty working tree, or a `--take-release` path
|
||||
that is not locally changed. Never touches git.
|
||||
See Gitea #7 and `INSTALL.md` § "Eine Instanz aktualisieren"."""
|
||||
See Gitea #7 and `docs/how-to/update-an-instance.md`."""
|
||||
run_upgrade(
|
||||
source,
|
||||
dry_run=dry_run,
|
||||
|
||||
@@ -1484,8 +1484,8 @@ def verify():
|
||||
"`<name>.template` it ships as, where one exists.",
|
||||
"The scope is computed from those categories rather than listed, so a file added later "
|
||||
"is in scope without a code change.",
|
||||
"Out of scope: every `SKILL.md`, the human docs (`README.md`, `CHANGES.md`, "
|
||||
"`EVALS.md`, `INSTALL.md`, `tools/README.md`), and every subtype template "
|
||||
"Out of scope: every `SKILL.md`, the human docs at the root and beside the code "
|
||||
"(`README.md`, `CHANGES.md`, `INSTALL.md`, `tools/README.md`), and every subtype template "
|
||||
"`types/<type>.<value>.md` - `new` copies it into a page, so it never carries a region "
|
||||
"whatever its length.",
|
||||
"Dry-run by default (prints which files would change); `--apply` writes. Idempotent: a "
|
||||
|
||||
@@ -805,8 +805,8 @@ def run_doctor() -> list[Check]:
|
||||
see_also=(
|
||||
"`instructions/setup-instance.md` - the setup steps most findings point back to",
|
||||
"`instructions/preflight.md` - what `tool-paths` and `install-dir` point back to",
|
||||
"`INSTALL.md` § \"Konfiguration\" - the per-checkout configuration files",
|
||||
"`EVALS.md` - telemetry state and caps",
|
||||
"`docs/reference/configuration.md` - the per-checkout configuration files",
|
||||
"`docs/explanation/telemetry-and-evaluation.md` - telemetry state and caps",
|
||||
"`instructions/session-setup.md` - setting `WIKITOOL_SESSION_ID`",
|
||||
),
|
||||
))
|
||||
|
||||
@@ -20,7 +20,7 @@ from chemenu.session import session_id as current_session_id
|
||||
from chemenu.telemetry import reader
|
||||
from chemenu.telemetry.writer import trace_root
|
||||
|
||||
app = typer.Typer(help="Score a traced session (see EVALS.md).")
|
||||
app = typer.Typer(help="Score a traced session (see docs/explanation/telemetry-and-evaluation.md).")
|
||||
|
||||
EVALS_DIR = config.REPORTS_DIR / "evals"
|
||||
|
||||
@@ -48,7 +48,7 @@ EVALS_DIR = config.REPORTS_DIR / "evals"
|
||||
),
|
||||
see_also=(
|
||||
"`wikitool eval score` - scores one of them",
|
||||
"`EVALS.md` - how telemetry and evaluation work",
|
||||
"`docs/explanation/telemetry-and-evaluation.md` - how telemetry and evaluation work",
|
||||
),
|
||||
))
|
||||
def sessions_command(
|
||||
@@ -113,7 +113,7 @@ def sessions_command(
|
||||
),
|
||||
see_also=(
|
||||
"`wikitool eval sessions` - which session ids exist",
|
||||
"`EVALS.md` - the scoring levels",
|
||||
"`docs/explanation/telemetry-and-evaluation.md` - the scoring levels",
|
||||
),
|
||||
))
|
||||
def score_command(
|
||||
|
||||
@@ -480,7 +480,7 @@ FILE_GROUPS: tuple[tuple[str, tuple[str, ...], str], ...] = (
|
||||
("Tooling", ("tools/",), "the compiler itself"),
|
||||
("Harness config", (".claude/", ".github/", ".vibe/", ".agents/"),
|
||||
"hooks and permissions - affects what the harness lets an agent do"),
|
||||
("Human docs", ("README.md", "INSTALL.md", "EVALS.md", "CHANGES.md"), "prose, no runtime effect"),
|
||||
("Human docs", ("README.md", "INSTALL.md", "CHANGES.md", "docs/"), "prose, no runtime effect"),
|
||||
("Workshop", ("work/",), "scratch state, deleted when the run closes"),
|
||||
)
|
||||
OTHER_GROUP = ("Other", (), "")
|
||||
|
||||
@@ -58,7 +58,7 @@ def _call(fn, *args, **kwargs):
|
||||
),
|
||||
see_also=(
|
||||
"`wikitool upload show` - one submission's manifest",
|
||||
"`INSTALL-MCP.md` § \"Schritt 7: Optional - den `submit`-Pfad freischalten\"",
|
||||
"`docs/how-to/set-up-the-mcp-server.md` § \"Optional: the submit path\"",
|
||||
),
|
||||
))
|
||||
def upload_list_command(
|
||||
|
||||
@@ -170,7 +170,7 @@ def show_command(
|
||||
"built-in origin. `$WIKITOOL_UPDATE_TOKEN` is only needed if that feed is not readable "
|
||||
"anonymously.",
|
||||
"For `update` or `migration` it prints that applying the release is a separate, manual "
|
||||
"step (`INSTALL.md` § \"Eine Instanz aktualisieren\").",
|
||||
"step (`docs/how-to/update-an-instance.md`).",
|
||||
"Read-only; exempt from the Iteration Budget Gate.",
|
||||
),
|
||||
failures=(
|
||||
@@ -196,7 +196,7 @@ def show_command(
|
||||
see_also=(
|
||||
"`wikitool dist upgrade` - applies the update this reports",
|
||||
"`wikitool version notes` - prints the release notes",
|
||||
"`INSTALL.md` § \"Version und Updates\" - what the operator decides before an update",
|
||||
"`docs/how-to/update-an-instance.md` - what the operator decides before an update",
|
||||
),
|
||||
))
|
||||
@app.command("check")
|
||||
@@ -262,8 +262,8 @@ def check_command(
|
||||
console.print(f"release: {status.release_url}")
|
||||
if status.state in ("update", "migration"):
|
||||
console.print(
|
||||
"Applying it is a separate, manual step - see INSTALL.md "
|
||||
"§ 'Eine Instanz aktualisieren'."
|
||||
"Applying it is a separate, manual step - see "
|
||||
"docs/how-to/update-an-instance.md."
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
"""Scoring a traced session. See EVALS.md for the levels and what they mean."""
|
||||
"""Scoring a traced session.
|
||||
|
||||
See docs/explanation/telemetry-and-evaluation.md for the levels and what
|
||||
they mean.
|
||||
"""
|
||||
from chemenu.evals.scorecard import failed, render_markdown, score, structural_score
|
||||
|
||||
__all__ = ["failed", "render_markdown", "score", "structural_score"]
|
||||
@@ -9,7 +9,8 @@ Two levels, deliberately both hard-oracle:
|
||||
way. This is the half unit tests cannot reach.
|
||||
|
||||
There is no judge here and no rubric. Soft-oracle scoring waits until a failure
|
||||
taxonomy exists - see EVALS.md on the phase gate.
|
||||
taxonomy exists - see docs/explanation/telemetry-and-evaluation.md on the
|
||||
phase gate.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class Rule:
|
||||
severity: str = "error"
|
||||
findings: list[dict] = field(default_factory=list)
|
||||
# A rule this trace cannot answer - not a pass, and never a fail. The
|
||||
# degradation rule (EVALS.md): a harness that cannot report the event a
|
||||
# degradation rule (docs/explanation/telemetry-and-evaluation.md): a harness that cannot report the event a
|
||||
# rule depends on must read as "cannot say", never as a silent zero that
|
||||
# looks like a clean pass or a finding that looks like a violation.
|
||||
skipped: bool = False
|
||||
|
||||
@@ -11,7 +11,8 @@ this module, see AGENTS.md invariant 8).
|
||||
form is read off `config.RELEASE_STAMP_FILENAME`: present means an exported/
|
||||
distributed tree (default *off* - an operator never asked for telemetry),
|
||||
absent means the dev checkout this package ships from (default *on* - the
|
||||
traces are this stack's own measuring instrument, see EVALS.md).
|
||||
traces are this stack's own measuring instrument, see
|
||||
docs/explanation/telemetry-and-evaluation.md).
|
||||
|
||||
**Caching.** Only the filesystem-derived half - the release stamp and the
|
||||
config file - is cached, keyed on the resolved root. `WIKI_TRACE` and the two
|
||||
|
||||
@@ -38,7 +38,6 @@ def repo(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
|
||||
"<!-- dist:strip-start -->\n```\n└── commonplace/\n```\n<!-- dist:strip-end -->\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(root / "EVALS.md").write_text("# EVALS\n", encoding="utf-8")
|
||||
(root / "CLAUDE.md").write_text("# CLAUDE\n\n@AGENTS.md\n", encoding="utf-8")
|
||||
(root / ".gitignore").write_text("*.pyc\n", encoding="utf-8")
|
||||
(root / ".gitattributes").write_text("* text=auto eol=lf\n", encoding="utf-8")
|
||||
@@ -191,6 +190,18 @@ def test_plan_never_includes_docs_dev(repo):
|
||||
assert "docs/explanation/why-gates-are-code.md" in plan
|
||||
|
||||
|
||||
def test_plan_ships_no_retired_root_docs(repo):
|
||||
"""`EVALS.md` and `INSTALL-MCP.md` became pages under docs/. A stray copy
|
||||
left at the root of a source tree is not shipped, so an upgraded instance
|
||||
loses them as retired files instead of carrying a stale second copy."""
|
||||
(repo / "EVALS.md").write_text("# EVALS\n", encoding="utf-8")
|
||||
(repo / "INSTALL-MCP.md").write_text("# MCP\n", encoding="utf-8")
|
||||
plan = dist_cmd.build_plan()
|
||||
assert "EVALS.md" not in plan
|
||||
assert "INSTALL-MCP.md" not in plan
|
||||
assert "README.md" in plan
|
||||
|
||||
|
||||
def test_plan_never_includes_instructions_dev(repo):
|
||||
"""instructions/dev/ - flat dev-only instructions and the nested skill
|
||||
that switches a session into tool-development mode - is pruned
|
||||
|
||||
@@ -532,6 +532,7 @@ def test_paths_land_in_the_group_a_reviewer_expects():
|
||||
assert group_of("tools/chemenu/cli.py")[0] == "Tooling"
|
||||
assert group_of(".claude/settings.json")[0] == "Harness config"
|
||||
assert group_of("README.md")[0] == "Human docs"
|
||||
assert group_of("docs/how-to/ingest-a-source.md")[0] == "Human docs"
|
||||
assert group_of("work/run/plan.md")[0] == "Workshop"
|
||||
assert group_of("something-else.txt")[0] == "Other"
|
||||
|
||||
|
||||
@@ -99,7 +99,17 @@ def test_every_exception_is_still_in_use():
|
||||
assert ALLOWED <= used, ALLOWED - used
|
||||
|
||||
|
||||
SHIPPED_DOCS = ("AGENTS.md", "README.md", "INSTALL.md", "EVALS.md")
|
||||
SHIPPED_ROOT_DOCS = ("AGENTS.md", "README.md", "INSTALL.md")
|
||||
|
||||
|
||||
def shipped_docs() -> list[Path]:
|
||||
"""The root documents an operator reads, plus every page `dist export` ships under `docs/` -
|
||||
the how-to guides among them name the preflight call an operator types."""
|
||||
docs = REPO / "docs"
|
||||
pages = sorted(
|
||||
path for path in docs.rglob("*.md") if path.relative_to(docs).parts[0] != "dev"
|
||||
)
|
||||
return [REPO / name for name in SHIPPED_ROOT_DOCS] + pages
|
||||
|
||||
# A line that starts the PowerShell preflight - bare (`.\tools\preflight.ps1`, `& preflight.ps1`)
|
||||
# or through pwsh - as opposed to one that merely names the file (a comment, a download).
|
||||
@@ -109,7 +119,7 @@ BYPASS = "pwsh -NoProfile -ExecutionPolicy Bypass -File "
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"path",
|
||||
[REPO / name for name in SHIPPED_DOCS] + shipped_instructions(),
|
||||
shipped_docs() + shipped_instructions(),
|
||||
ids=lambda p: str(p.relative_to(REPO)),
|
||||
)
|
||||
def test_every_powershell_preflight_call_carries_the_bypass(path):
|
||||
|
||||
@@ -5,7 +5,8 @@ asks whether the commands compose - whether a wiki assembled the documented way
|
||||
comes out structurally clean, and whether the catalog is a fixed point rather
|
||||
than something that keeps changing every time it is rebuilt.
|
||||
|
||||
That is the hard-oracle floor the eval ladder in EVALS.md rests on: before a
|
||||
That is the hard-oracle floor the eval ladder in
|
||||
docs/explanation/telemetry-and-evaluation.md rests on: before a
|
||||
score can say anything about how an agent worked, running the tools correctly has
|
||||
to be known to produce a clean tree.
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ recorded reason at all.
|
||||
calls a page in one of its four areas "Humans and agents ... | By link, or on
|
||||
explicit request" - agent-loaded, at a second hop, which is precisely the preview mechanic
|
||||
`instructions/CONTRACT.md` § "Reference depth" treats as real. The exclusion of
|
||||
the human docs (`README.md`, `CHANGES.md`, `EVALS.md`, `INSTALL.md`,
|
||||
the human docs (`README.md`, `CHANGES.md`, `INSTALL.md`,
|
||||
`tools/README.md`) rests on a sentence that does not stretch to cover it: those
|
||||
are "Never loaded by an agent as instruction," while a `docs/` page is not
|
||||
loaded *as instruction* but is very much loaded.
|
||||
|
||||
Reference in new issue
Block a user