docs/ als ausgelieferter Hintergrund-Ort; Decision-Seiten bleiben in kb/, Decay-Skip fuer concept_type: decision (4.3.0, #38)
CI / verify (push) Successful in 49s
Release / release (push) Successful in 36s

Files changed:
- AGENTS.md
- CHANGES.md
- VERSION
- instructions/kb-profiles.md
- kb/CONVENTIONS.md
- kb/concepts/COLLECTION.md
- tools/CONTRACT.md
- tools/chemenu/commands/confidence_decay.py
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/tests/test_confidence_decay.py
- tools/chemenu/tests/test_dist_cmd.py
This commit is contained in:
2026-09-03 19:01:21 +02:00
parent 9b461421e8
commit 0b8ca746fa
11 changed files with 135 additions and 18 deletions
@@ -11,6 +11,14 @@ Keeping the undecayed anchor in `confidence_base` is what makes repeated runs
idempotent - decaying the stored `confidence` in place (the pre-2026-08-13
behavior) compounded on every run, because the elapsed-months factor kept
growing while the multiplicand had already shrunk.
Pages with `concept_type: decision` are skipped structurally, not as an
interim measure. The formula models staleness - a claim that nobody has
re-checked in a while becomes less trustworthy - and a decision is not a
claim about the world that time can falsify. What retires a decision is a
later decision superseding it, never elapsed months on its own; that is a
category the decay formula does not have a term for, so it does not apply
one.
"""
from __future__ import annotations
@@ -118,6 +126,8 @@ def confidence_decay(
missing_base = []
for title, page in sorted(pages.items()):
if page.frontmatter.get("concept_type") == "decision":
continue
confidence = page.frontmatter.get("confidence")
if confidence is None:
continue
+8 -1
View File
@@ -347,6 +347,12 @@ def build_plan(origin: Optional[Origin] = None) -> dict[str, PlannedFile]:
for hook_dir in HOOK_DIRS:
plan.update(_copy_tree(config.ROOT / hook_dir, hook_dir, frozenset()))
# docs/ is stack background - why the stack is built the way it is - and
# ships verbatim like instructions/ and types/: it carries no page, no
# frontmatter, and (AGENTS.md § File naming) no normative sentence, so
# there is nothing instance-owned in it to split off as a .template.
plan.update(_copy_tree(config.ROOT / "docs", "docs", frozenset()))
# `kb/CONTRACT.md` is stack-owned and ships verbatim; everything beside it
# under `kb/` is the instance's own and ships only as a `.template`. That is
# the personalization split (`USER.md`/`SOUL.md`) one directory down, and
@@ -492,7 +498,8 @@ def export_command(
):
"""Export a contentless, distributable copy of this repo's machinery:
AGENTS.md/README.md (dev-instance-only marker blocks removed),
instructions/ (no instructions/dev/), types/, tools/ (no venv/caches),
instructions/ (no instructions/dev/), types/, docs/ verbatim,
tools/ (no venv/caches),
the .github/hooks/+.vibe session-tracing config plus .claude/settings.json,
kb/CONTRACT.md plus a COLLECTION.md.template per collection and
kb/CONVENTIONS.md.template (no pages, no areas), empty
+20 -1
View File
@@ -5,7 +5,7 @@ import pytest
from chemenu import config
from chemenu.commands import confidence_decay
from chemenu.commands.confidence_decay import FLOOR, compute_decay
from chemenu.frontmatter_io import read_page
from chemenu.frontmatter_io import read_page, write_page
def test_no_decay_at_zero_months():
@@ -68,3 +68,22 @@ def test_decay_skips_pages_without_a_base(decay_wiki):
confidence_decay.confidence_decay(apply=True)
frontmatter, _ = read_page(decay_wiki / "entities/systems/aurora.md")
assert frontmatter["confidence"] == 0.9
def test_decay_skips_decision_pages(decay_wiki):
"""A decision is not falsified by elapsed time, only by a later decision
superseding it - `concept_type: decision` is a categorical skip, not
something an old `modified` date should ever decay (Gitea #38)."""
decision_path = decay_wiki / "concepts" / "some-decision.md"
write_page(
decision_path,
{
"type": "types/concept.md", "concept_type": "decision",
"tags": [], "created": "2015-01-01", "modified": "2015-01-01",
"related": [], "sources": [], "confidence": 0.9, "confidence_base": 0.9,
},
"\n# some-decision\n",
)
confidence_decay.confidence_decay(apply=True)
frontmatter, _ = read_page(decision_path)
assert frontmatter["confidence"] == 0.9
+9
View File
@@ -135,6 +135,10 @@ def repo(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
f"<!-- {config.TEMPLATE_SENTINEL} -->\n# conventions template\n", encoding="utf-8"
)
docs_dir = root / "docs"
docs_dir.mkdir()
(docs_dir / "why-gates-are-code.md").write_text("# Why gates are code\n", encoding="utf-8")
for relative in ("raw/CONTRACT.md", "reports/CONTRACT.md", "work/CONTRACT.md"):
path = root / relative
path.parent.mkdir(parents=True, exist_ok=True)
@@ -156,6 +160,11 @@ def test_plan_never_includes_commonplace(repo):
assert "commonplace" not in combined
def test_plan_ships_docs_verbatim(repo):
plan = dist_cmd.build_plan()
assert plan["docs/why-gates-are-code.md"].content == "# Why gates are code\n"
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