From 1f3d4f9962954fb736a76885d33dc004f4fe5b4d Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Wed, 16 Sep 2026 15:27:29 +0000 Subject: [PATCH] docs: correct stale resolver, status and duplication claims ADR-0014 gains a dated correction: skill-size-check now sources the boundary resolver from kyberforge (ef27c97), so restoring the external hook contract needs it made self-contained first. ADR-0017's status reflects its supersession, architecture.md and gates.md carry the current duplication counts and reason, gates.md defines vacuous green inline, and the gitleaks lesson is marked historical. Co-Authored-By: Claude Opus 5 (1M context) --- LESSONS.md | 4 ++-- docs/adr/0014-vale-prefilter-ships-from-the-plugin.md | 10 ++++++++++ ...gin-content-mirror-bridges-apm-to-host-discovery.md | 2 +- docs/spec/architecture.md | 4 ++-- docs/spec/gates.md | 7 ++++--- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/LESSONS.md b/LESSONS.md index 5abe08b..db12749 100644 --- a/LESSONS.md +++ b/LESSONS.md @@ -40,9 +40,9 @@ A research sub-agent reported "Process goes in SKILL.md, context in reference fi `claude plugin validate --strict` was left out of the standard plugin audit sweep and only discovered when the user flagged the gap. It catches warnings (missing `version` fields, stray non-agent `.md` files) that will fail CI once strict mode is enforced. Fix: run it on every plugin path and marketplace manifest as a named audit step. -## 2026-06-21 — Source and deployed gitleaks configs can silently diverge +## 2026-06-21 — Source and deployed gitleaks configs can silently diverge (historical) -`scripts/gitleaks.toml` (source) and `.gitleaks.toml` (deployed, hook-read) drifted after someone edited the deployed copy directly; rerunning `setup-gitleaks.sh` would have overwritten it, silently deleting the allowlist. Fix: treat the source as sole truth, never hand-edit the deployed copy, and update both together in the same commit. +Superseded — `5b8b6f5` removed `scripts/gitleaks.toml` and `setup-gitleaks.sh`, so `.gitleaks.toml` is now the only copy and there is nothing to diverge from. Kept for the general pattern, which applies to any source/deployed pair: `scripts/gitleaks.toml` (source) and `.gitleaks.toml` (deployed, hook-read) drifted after someone edited the deployed copy directly; rerunning `setup-gitleaks.sh` would have overwritten it, silently deleting the allowlist. Fix: treat the source as sole truth, never hand-edit the deployed copy, and update both together in the same commit. ## 2026-06-21 — `shellcheck` without `-x` blocks pre-commit on scripts using `source` (historical) diff --git a/docs/adr/0014-vale-prefilter-ships-from-the-plugin.md b/docs/adr/0014-vale-prefilter-ships-from-the-plugin.md index 70a4fbb..fe85904 100644 --- a/docs/adr/0014-vale-prefilter-ships-from-the-plugin.md +++ b/docs/adr/0014-vale-prefilter-ships-from-the-plugin.md @@ -273,6 +273,16 @@ restore the manifest under that constraint, and restore `test-vale-hooks-consume was the only test that exercised the entry-resolution path that once shipped broken. Restore a release gate only once a server-side job can run it on merge. +**Correction (2026-09-16, later the same day).** The paragraph above is wrong about +`skill-size-check.sh`. `ef27c97` removed its embedded resolver copy: the hook now sources +`plugins/kyberforge/.apm/skills/factory-audit/scripts/lib-boundary-resolver.sh` by path and fails +closed without it (ADR-0020's 2026-09-16 amendment; `docs/spec/gates.md`, "Duplicated constants"). +An external consumer's checkout has no such file, so restoring the manifest as described would ship +a hook that fails for every consumer — the defect recorded at `LESSONS.md:101`. Only `vale-wrap.sh` +still meets the `entry[0]`-only constraint. A return must first make `skill-size-check.sh` +self-contained again, by re-embedding the resolver or shipping the library beside the hook, and +restore a consumer test that proves it. + **Superseded statements elsewhere.** ADR-0022's notes that the version-bump gate "is not exported through `.pre-commit-hooks.yaml`" and that it shares its gaps with `check-release-needed`, and ADR-0025's point 5 ("Both exported Vale hook IDs survive unchanged") and its case-33 port, describe diff --git a/docs/adr/0017-plugin-content-mirror-bridges-apm-to-host-discovery.md b/docs/adr/0017-plugin-content-mirror-bridges-apm-to-host-discovery.md index 2c16a85..13fe08b 100644 --- a/docs/adr/0017-plugin-content-mirror-bridges-apm-to-host-discovery.md +++ b/docs/adr/0017-plugin-content-mirror-bridges-apm-to-host-discovery.md @@ -19,7 +19,7 @@ for the parent decision. It resolves the one question ADR-0015's own execution f did not block on: whether Claude Code's installer can actually load content out of `.apm/`. It could not. -**Status: executed (2026-08-13, issue #90).** `scripts/sync-plugin-content.sh` has been run +**Status: superseded by ADR-0024** (originally executed 2026-08-13, issue #90; the text below is the record of that execution). `scripts/sync-plugin-content.sh` has been run against all 6 plugins; flat `agents/`, `skills/`, `commands/` (etc., wherever `.apm/` populates them), and a merged hooks file now exist at each plugin root as tracked, generated files. The merged hooks file lands at `hooks/hooks.json`, not at the plugin root itself — see the second diff --git a/docs/spec/architecture.md b/docs/spec/architecture.md index b1afff4..0d7c7b5 100644 --- a/docs/spec/architecture.md +++ b/docs/spec/architecture.md @@ -27,7 +27,7 @@ Skills are **not** deployed by `install.sh`. They are distributed as plugins and Skills, agents, MCP servers, and hooks are distributed as self-contained plugin units under `plugins/`, installed independently via `apm install`, here and in any consuming repo (ADR-0018). Each unit is an **apm package**: `plugins//apm.yml` plus a hand-authored `plugins//.apm/{skills,agents,hooks,commands,instructions,extensions}/` tree (ADR-0015). There is no per-plugin `plugin.json` at all — apm reads `apm.yml`, and the repo's one generated manifest, `.claude-plugin/marketplace.json`, is compiled from that source. -Self-contained is a hard constraint, not a description: a file reference inside `.apm/skills//` may not reach outside that skill's own directory, and there is no cross-skill sharing mechanism to reach for instead. That is why the Vale styles are duplicated across two skills rather than shared (ADR-0014), and why ADR-0020's constants are copied into three validators rather than sourced from one. The constraint used to be explained by Claude Code's plugin cache-install copying a plugin to a cache; that is no longer the reason and never was the only one. It is stated independently for APM package mode by the agentskills.io spec (`plugins/kyberforge/.apm/skills/skill-author/references/deployment-modes.md`), which is why ADR-0024 consequence 6 pins it as a negative result: ending native install did not relax it, and it is not to be re-litigated on the assumption that it did. +Self-contained is a hard constraint, not a description: a file reference inside `.apm/skills//` may not reach outside that skill's own directory, and there is no cross-skill sharing mechanism to reach for instead. That is why the Vale styles ship inside the one skill that uses them, `factory-audit/assets/vale/` (ADR-0014, ADR-0025), and why ADR-0020's constants are copied into two validators — the plugin's `validate.sh` and the repo's `scripts/skill-size-check.sh` — rather than sourced from one. The constraint used to be explained by Claude Code's plugin cache-install copying a plugin to a cache; that is no longer the reason and never was the only one. It is stated independently for APM package mode by the agentskills.io spec (`plugins/kyberforge/.apm/skills/skill-author/references/deployment-modes.md`), which is why ADR-0024 consequence 6 pins it as a negative result: ending native install did not relax it, and it is not to be re-litigated on the assumption that it did. Which apm package a new skill belongs in follows from what each one is scoped to. The boundary that matters most in practice is `core` vs `kyberforge`: `core` is the home for cross-cutting, repo-agnostic utility skills that a consumer would want against *their* repo, while `kyberforge` is meta-tooling for the holocron marketplace itself. A skill that authors a target repo's `AGENTS.md` is `core`; a skill that audits a `SKILL.md` against this marketplace's contract is `kyberforge`. @@ -61,7 +61,7 @@ Plugin-root documentation belongs in `docs/`. That convention is older than the Those on-demand files are plain markdown — no frontmatter, no schema. The agent decides when to read each one from task context and the content index label alone. Frontmatter is deferred until there is evidence that agents are loading the wrong files in practice; it is a deliberate deferral, not an oversight to close. The governance layer has two phases: -- **Phase 1** (complete): instruction and documentation layer — `governance.md` loaded via `@import`; `core/ai-constitution.md` and `docs/wiki/HUMANS.md` as human-facing reference; `CONTEXT.md` extended with governance domain language. +- **Phase 1** (complete): instruction and documentation layer — `governance.md` loaded via `@import`; `core/ai-constitution.md` and `docs/wiki/HUMANS.md` as human-facing reference; `CONTEXT.md` glossing the one governance term used unglossed elsewhere (HITL); the rest of the governance vocabulary is defined in `core/ai-constitution.md`. - **Phase 2** (planned): deterministic enforcement layer — pre-commit hooks, CI gates, secret scanning, licence scanning. Specified in `docs/research/governance_principles/CONTROLS.md`. ## AGENTS.md pattern diff --git a/docs/spec/gates.md b/docs/spec/gates.md index 0327c2d..5664e8e 100644 --- a/docs/spec/gates.md +++ b/docs/spec/gates.md @@ -406,8 +406,9 @@ findings. `factory-audit`'s `validate.sh` holds a second copy of the four ADR-0020 constants (`DESC_SUGGEST_CHARS` / `DESC_MAX_CHARS` / `BODY_SUGGEST_WORDS` / `BODY_MAX_WORDS`) — the two description constants apply to both artifact types it handles, the two body constants only to -skills. They are copied rather than imported because a cache-installed plugin's scripts cannot read -files outside their own plugin directory. `tests/test-skill-size-check.sh` asserts the copies agree, +skills. They are copied rather than imported because a skill's files may not reach outside that skill's own +directory (the self-contained constraint in `docs/spec/architecture.md`, "Plugin model"), and +`scripts/skill-size-check.sh` does not ship with the plugin. `tests/test-skill-size-check.sh` asserts the copies agree, so drift fails CI rather than silently letting an audit bless a skill the commit hook then rejects. **The shared boundary resolver is one copy** (ADR-0025, then 2026-09-16). It lives between the @@ -438,7 +439,7 @@ Both, and neither is a best-effort accelerator. `python3` because the script measures the **folded** `description` value. Most descriptions here are `>`-block scalars, so a regex over the raw lines measures indentation and newlines instead of the value. Missing it fails the hook with an install pointer rather than skipping the ADR-0020 checks, -which would be a vacuous green. In practice it is already present — pre-commit is itself a Python +which would be a vacuous green — a gate that reports success without having checked anything. In practice it is already present — pre-commit is itself a Python application. **PyYAML** because the hand-rolled fallback frontmatter reader has been **removed deliberately**. It