Commit Graph

504 Commits

Author SHA1 Message Date
ef27c9751a refactor(gates): source the boundary resolver into skill-size-check
Why: scripts/skill-size-check.sh embedded a byte-identical 1,061-line copy
of the ADR-0020 boundary resolver only because it was also exported
through .pre-commit-hooks.yaml, whose consumers could not reach a file
inside the plugin. 4de5b6b retired that export, so the hook now runs only
in this repo and can source factory-audit's lib-boundary-resolver.sh like
validate.sh does. One copy removes the edit-one-paste-the-other hazard.

Implementation Notes:
- The hook's Python program is assembled from its own preamble, the
  library's resolver and its own checks, read from quoted here-docs. The
  assembled program matches the old one line for line except one comment,
  and the hook's stdout, stderr and exit code are identical over every
  corpus SKILL.md and the 26 differential-suite fixtures.
- The hook fails closed, naming the library, when it is missing or
  defines no resolver.
- test-adr0020-contract.sh assertion 1 now pins the single copy: one
  marker pair in the library, none in the hook, fail-closed on a missing
  or gutted library, and a sentinel planted in a copied library that must
  appear in the hook's output. 1a expects exactly one authority. 27 -> 29
  passes.
- ADR-0020 and ADR-0025 carry dated amendments; gates.md and the
  library, hook and mode-library comments no longer describe two copies.
- factory-audit is new on this branch, so the version-bump gate exempts
  it; kyberforge is already at 2.0.0 against main's 1.6.2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 13:25:16 +00:00
adaa978d20 docs: deploy the ai-constitution with core so the governance pointer resolves
Why: the always-on governance.md told agents to read
docs/ai-constitution.md when a decision is not covered, a path that
exists only in this repo, so the fallback failed in every other project.
(Simplification audit finding 27, second defect.)

Implementation Notes:
- Move docs/ai-constitution.md to core/ai-constitution.md; the existing
  core deploy step now ships it to ~/.claude/core/.
- governance.md line 4 and line 73 name ~/.claude/core/ai-constitution.md;
  the HUMANS.md and CONTROLS.md pointers now say they live in the
  holocron repo.
- Repoint path-qualified citations in AGENTS.md, architecture.md,
  skill-implementation-workflow.md and CONTROLS.md. The vendored
  write-skill example and the audit's historical notes are left as
  records.
- The docs/wiki gitlink is not bumped here; the wiki commit awaits push.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 12:56:49 +00:00
a840f3fe04 docs: close the stale spots left in the simplification audit
Why: a full read after finding 15 closed found notes that still read as
open or predated later outcomes, and the fixed governance.md had never
reached ~/.claude.

Implementation Notes:
- Record that the fixed governance.md is deployed. It was copied alone
  rather than through install.sh, which would have overwritten
  machine-local keys in ~/.claude/settings.json.
- Close finding 2: check-scope-walkup-sync stays now that 14 left its
  ports at four and 15 is refuted.
- Correct the §9 and §10 sentences that still assumed 15 would merge,
  and tick the §8 external-consumers question.
- Mark every closed finding [x] regardless of outcome; only 22, deferred
  with bin, stays unmarked. §7 states the convention.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 12:48:55 +00:00
02d5774a99 docs: refute finding 15 on measurement
Why: finding 15 proposed merging skill-author and agent-author on the
claim that they share most of contract.md and near-identical steps.
Measured, the pair shares about 150-180 distinct non-blank lines,
against the 2,934 the factory-audit merge removed. ADR-0020's exclusion
of the pair holds, so the merge does not proceed.

Implementation Notes: finding 15 is struck through and carries a dated
Refuted note with per-file counts and the command that reproduces them.
The §7 order and status notes and the §8 ADR-0012 bullet now show no
open finding, with 22 deferred with bin. ADR-0020's rejected
alternative records the measurement; ADR-0025 point 7 no longer calls
the finding open and unmeasured.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 12:40:55 +00:00
14248e04b9 docs: fix the review findings on the hook-contract retirement
Why: a review of 4de5b6b and 3c5f6a6 found seven places that still
described the retired external hook contract as current, or that could
pass without checking anything.

Implementation Notes:
- gates.md: drop the "one caveat below" pointer; the caveat is gone.
- SIMPLIFICATION-AUDIT.md: the §7 note now says all but one entry is
  closed and lists 36 (4de5b6b) as struck. Finding 2's count chain gets
  a closing note: pre-push is 8 repo-authored hooks (10 reported).
- .pre-commit-config.yaml: the check-vale-style-sync comment points at
  case 32 (one-plugin narrowing guard), not the deleted case 33.
- ADR-0014: the retirement pointer now covers the ADR-0025 amendment
  above it too, naming case 33 and the exported hook IDs. ADR-0022 gets
  a reciprocal amended-by note on its check-release-needed comparison.
  Historical body text is unchanged.
- test-vale-wrap.sh case 32: property 3 fails when a class's corpus
  regex matches no tracked file, instead of passing vacuously after a
  layout move. The corpus regexes are now globals so a new Part D can
  point them at a missing layout and require that failure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 12:30:42 +00:00
3c5f6a6e37 docs: mark finding 36 done in the simplification audit
Why: 4de5b6b retired the external pre-commit hook contract, so the audit
still listed 36 as open, with a deferred decision.

Implementation Notes: finding 36 is struck through and carries a dated
Done note (measured line counts, the case 33 cost and how its guard was
kept). The §7 status notes, the §8 consumer question and the §10
dispositions now leave 15 as the only open finding, with 22 deferred
with bin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:53:25 +00:00
4de5b6b355 chore(gates): retire the external pre-commit hook contract
Why: .pre-commit-hooks.yaml and its release-tag gate served external
consumers that do not exist. No repo on the Gitea instance pins these
hooks, and the README names apm as the only supported install path. The
mechanism was also already failing: skill-size-check.sh changed after
v2.0.1 with no tag cut, and the gate cannot fire through Gitea's merge
button. (Simplification audit finding 36.)

Implementation Notes:
- Delete .pre-commit-hooks.yaml, scripts/check-release-needed.sh,
  tests/test-check-release-needed.sh and tests/test-vale-hooks-consumer.sh,
  and remove the check-release-needed pre-push hook. The repo: local
  skill-size-check and vale-audit-prefilter-* hooks are unchanged.
- ADR-0014 is amended, not retired: its runtime decision to bundle Vale
  inside factory-audit stands. The amendment keeps the entry[0]-only
  constraint (LESSONS.md:101,105) in case the export returns. ADR-0025
  gets a pointer.
- test-vale-wrap.sh: drop case 33 (the cross-manifest drift check) and
  case 28's hook-scope half, which read the published manifest. Case 32
  now also requires each hook to select every tracked file of its class,
  which keeps case 33's one-plugin-narrowing guard, with a mutation test.
- test-skill-size-check.sh and test-adr0020-contract.sh now assert the
  hook contract and verbose: true on .pre-commit-config.yaml only.
- gates.md: pre-push count goes from 9 to 8 authored hooks (11 to 10
  reported), and the Release table, the External consumers section and
  the two-manifest scope table are removed. README and script/test
  comments no longer describe the export as live. The resolver comment
  is edited identically in both copies.
- The v1.0.0/v2.0.0/v2.0.1 tags are left in place; they are inert.

ADR: 0014
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:52:14 +00:00
2119da9700 docs: record the second review round in the simplification audit
Why: the audit carried stale figures and working-tree citations after the
grill commits landed, and this review round's decisions needed recording.

Implementation Notes: line totals pinned to c07ca07, working-tree
citations replaced with commits, version-location count corrected, and a
new section lists this round's dispositions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:24:33 +00:00
807caf22ee fix(kyberforge): give branch-aware advice for the refreshed apm lock
Why: the docs said to discard a refreshed apm.lock.yaml on a feature
branch because the refresh records main's commit, but the branch's own
lock records a (older) main commit too, and the SessionStart notice gave
the same "commit or discard" advice on every branch.

Implementation Notes:
- check-apm-current.sh picks fixed advice by branch: commit or discard
  deliberately on the default branch (origin/HEAD, else main), discard and
  reinstall on a feature branch; the branch name is never interpolated.
- README, AGENTS.md and ADR-0019 give the real reasons (no lock churn in
  the branch diff, deployed tree matches the committed lock), the cost
  (the session runs the older main) and that the next session start
  refreshes again.
- ADR-0019's check-clean and stale-server claims restated to match apm's
  source.

ADR: 0019
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:24:32 +00:00
398515bcad chore: drop the duplicated package descriptions from root apm.yml
Why: for a local-path marketplace entry, apm treats a root description: as
an override of the package's own apm.yml, reported only at verbose level,
so the "two copies stay identical" rule had no enforcement. Same fix as
2def060 made for version:.

Implementation Notes:
- All six root copies matched their package apm.yml before removal; the
  compiled marketplace.json descriptions are unchanged.
- apm-workflow references now scope the "omit it" advice to local-path
  entries: on a remote entry, version: is the semver range that selects
  the tag, and version: or ref: is required.

Impact: ADR-0021 amended; the package apm.yml is the single source.

ADR: 0021
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:24:22 +00:00
c5d43b4d63 chore(release): bump bin, git, gitea, core and lint patch versions
Why: each of these plugins changed shipped .apm/ content on this branch
without a package version bump, which configure.md requires and no gate
catches. No skill, agent or hook was removed, so a patch bump fits.

Implementation Notes: marketplace.json regenerated with apm pack; the diff
is the five version strings only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:24:21 +00:00
1d40544075 fix(gates): hold skill versions above main's tip as well as the merge-base
Why: two branches that both bump a skill 1.0.0 -> 1.0.1 with different
content merge without a conflict, and each passed the gate against its own
merge-base, so main could ship two changes under one version.

Implementation Notes:
- check-skill-version-bump requires the pushed version to exceed both the
  merge-base and the main tip; failures name the baseline they missed.
- Presence is read from the tree, so a blob missing from a partial clone is
  a read failure instead of a silently exempt "new" skill.
- A leading UTF-8 BOM no longer reads as a missing version.
- Version parts reject leading zeros in all three validators
  (check-skill-version-bump, skill-size-check, factory-audit).
- New tests cover equal bumps, moved files, major/minor ordering, bad refs,
  unreadable blobs, mode-only changes, symlinks and tag peeling.

Impact: ADR-0022 amended (reverses "not main's current tip"); gates.md
updated to match, including pre-commit 4.6.1's exact ref selection.

ADR: 0022
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 11:24:08 +00:00
b426460f75 docs: reconcile the audit with the review of the grill commits
Re-measures the figures the new hook and ADR edits moved, re-points
shifted gates.md and config citations, ticks the decided §8 questions,
and aligns §7, §10 and the finding 8/18/28/33 notes with the decisions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:33:36 +00:00
c07ca0767e docs(kyberforge): stop apm-workflow assuming root package versions
The root apm.yml packages[] entries no longer carry version:, and a
version there is a silent override that --check-versions does not
catch. configure.md and marketplace.md now name the package's own
apm.yml as the single source and drop version: from the examples.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:33:35 +00:00
dd0b9233e6 docs: correct the version-bump gate and branch-refresh documentation
ADR-0022 and gates.md now state the merge-base baseline, the fail-closed
cases, the PyYAML requirement and the multi-ref push gap (shared with
check-release-needed); the new hook gets its own gates.md group. Both
ADR additions follow each file's amendment format. README and AGENTS.md
now say to discard a refreshed apm.lock.yaml on a feature branch, and
that an .apm/ edit is live only once it is on the remote's main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:33:34 +00:00
1ce596cdbe fix(gates): close the review findings in check-skill-version-bump
- Read changed paths NUL-delimited so non-ASCII paths are no longer
  silently skipped.
- Fail closed when only local main resolves and the pushed commit is
  the merge-base, instead of passing on an empty diff.
- Accept ASCII-only versions with at most nine digits per part.
- Check for python3/PyYAML up front, and report read failures as such
  rather than as a missing version; name a missing SKILL.md.
- Document that pre-commit gates only the first ref of a multi-ref push.

Tests grow to 29 cases covering each fix plus annotated tags, CRLF
frontmatter, unrelated histories and pushing main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:33:33 +00:00
89b1c6fc85 docs: record the grill and declined-finding decisions in the audit
Findings 11, 17, 23, 25 and 27 are declined. From the grill: 33 and 34
done, 8, 18, 20 and 28 closed, 22 deferred with bin. Open: 15 and 36.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:10:00 +00:00
afcf477ede docs(adr): record the feature-branch refresh hazard in ADR-0019
The session-start refresh resolves against main, so on a branch it
redeploys content the branch removed and rewrites the lock to main's
commit. Documented as a consequence rather than skipped in code, since
a skip would only freeze the session on an older main. Also records the
re-measured refresh time (~24-26 s). Simplification audit finding 34.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:09:59 +00:00
2def06054a chore: drop the duplicated package versions from root apm.yml
The six packages[].version lines restated each plugin's own apm.yml
version and were unpoliced: on drift apm silently shipped the curator
value. apm reads the plugin's apm.yml when the entry is absent, and
apm pack --check-versions --check-clean still passes with the committed
marketplace.json unchanged. Simplification audit finding 33.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:09:58 +00:00
8451169d2b feat(gates): enforce metadata.version bumps on changed skills at pre-push
check-skill-version-bump fails a push when a skill directory changed
against its merge-base with main (tests/ excluded) without a strictly
higher metadata.version than main. New, renamed and deleted skills are
exempt; every plugin is covered. Recorded as a dated section in
ADR-0022 and documented in gates.md.

Patch-bumps the 17 skills that changed on this branch without a bump,
so the branch passes its own gate. Simplification audit finding 33.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:09:56 +00:00
69119f4754 docs: reconcile the ADRs, gates and audit log with the shipped behaviour
Why

A six-agent review of the two preceding commits found their code sound -- the
differential claim holds, the published hook contract is byte-unchanged -- but
their prose drifted from it in three ways: statements of fact the code
contradicts, markers in a convention this repo does not use, and figures that
went stale when the merge changed what they counted.

Implementation Notes

ADR-0025's edge-path table is rewritten around one stated doctrine: exit 0 is
audited and clean, exit 1 is audited with findings or a target present but
unreadable, exit 2 is that nothing was audited. Its old row 1 promised "one
generic matches-neither message" for three different inputs; there are three
distinct messages, and the missing-path case exited 1 until the preceding commit
fixed it. Rows are added for the preflight and CDPATH changes, because a table
claiming to enumerate every entry-point behaviour change reproduces its own
"an earlier revision of this ADR said they were behaviour-neutral" failure if it
omits any.

ADR-0025 also gains a Consequences supersession record in ADR-0016's form:
partially-superseded entries for 0008, 0014, 0020 and 0021, and explicit
"is not superseded" entries with reasoning for the rest. Twelve ADRs are amended
and it previously listed none.

ADR-0008 moves from an amendment note to partially superseded. Its contract
genuinely narrowed -- an agent .md outside an agents/ directory was audited
before the merge and is refused now -- and ADR-0020 already recorded that the
merge "reopens ADR-0008". Its detector description said "a path under
.apm/agents/", the phrasing ADR-0025 rejects as wider than the script and
circular; the shipped rule is a .md whose immediate parent is named agents/, at
any scope.

ADR-0020's amendment claimed the boundary resolver is sourced by
validate-provenance.sh. It is not, and never was; only validate.sh sources it,
once per mode branch. Three Home-column entries pointed at reference filenames
the merge renamed, one of which now resolves to two files because its row covers
skills and agents.

Five ADRs opened with "Skill renamed per ADR-0025", a form this repo does not
use, in the same commit that used the conventional "Amended by ADR-0025" twice.
They are normalized. "Renamed" was also wrong: the BREAKING-CHANGE trailer says
the skills were removed and their flows merged.

SIMPLIFICATION-AUDIT.md had 2026-09-15 notes attached to headlines that were
never updated, against its own convention of correcting in place with
strikethrough. Every figure here was re-derived at HEAD by command, and several
differed from the review's own numbers, so the notes record the basis rather
than the result alone.

LESSONS.md asserted the two review-time suite failures were the SIGPIPE race.
The commit that fixed that race explicitly declined to claim it -- the suite was
running while agents edited live config files -- so the hedge is restored.

Impact

No code, test or configuration change; documentation only. Suites stay 20/20
strict with 0 skipped and 374/374 bats. No gate parses ADR or gates.md content,
so nothing here is load-bearing for a hook.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-16 09:14:01 +00:00
ffcbed6c41 fix(tests): replace pipefail-racy echo | grep -q with here-strings
Why

Two suites failed intermittently — tests/test-vale-wrap.sh case 21 and
tests/test-check-release-needed.sh cases 4 and 15 — on correct output, and never
when run alone. The cause is the `echo "$OUT" | grep -q P` idiom under
`set -o pipefail`: grep -q exits as soon as it has an answer, bash's echo can
hand a multi-line value to the pipe one line at a time, and a write after the
reader is gone kills echo with SIGPIPE. pipefail then reports the writer's
death, so output that DID match reads as "no match". Every observed failure had
lines after its match; case 15's match is on line 1 of 6, the widest window in
that file.

Forced with a pause before the writer's last line, the pipe form failed 50 of 50
runs; a here-string, a match on the last line, and the same pipe without
pipefail each passed 50 of 50. Unforced the rate is about 1 per 670 suite runs,
which is why it read as a flaky gate rather than a bug.

The failures at review time are consistent with this, but were not proven to be
it: the suite was running while agents edited live config files in place, and a
brief change to .vale.ini or .pre-commit-hooks.yaml would produce the same two
failures. The race is real and fixed either way.

Implementation Notes

`grep -q P <<< "$VAR"` has no separate writer process, so there is nothing to
race. It is not a retry or a sleep. 121 sites converted across 9 files, three of
them scripts rather than tests: new-agent.sh, new-skill.sh and
check-executables-allow-sync.sh. None ships via .pre-commit-hooks.yaml, so no
external consumer pins them, and all three are single-pipeline checks whose
verdict cannot change.

Left alone deliberately: 14 sites whose writer is a command, not a shell
builtin — they either absorb the writer's status with `|| true` or are python3
and awk, which write once at exit — and one file with no pipefail. `printf '%s'`
sites differ from a here-string only by a trailing newline, which no -q verdict
on a non-empty pattern depends on.

tests/test-no-pipefail-early-exit-grep.sh is a static guard against new
occurrences, discovered automatically by run-tests.sh. It only scans files that
set pipefail, joins continuation lines, skips comments, and flags only
echo/printf writers. Its first case proves the scanner can fail before its
second trusts a clean verdict on the tree.

A guard covers exactly the spellings its regex models, so the miss surface was
measured rather than assumed. Four were found and closed: pipefail declared as
`set -o errexit -o pipefail` (where the old pattern required pipefail to follow
the FIRST -o, and a file-level miss skips every site in that file); a writer
separated from grep by an intermediate stage; a pipeline wrapped on a trailing
`|` rather than a backslash; and readers spelled egrep, fgrep, /bin/grep,
`command grep` or with an env-var prefix. Segment characters exclude a bare `&`
so `echo ok && other | grep -q x`, whose writer is `other`, does not false-fire.
Widening surfaced 5 live sites invisible to the original scanner, all in
tests/test-apm-current-hook.sh, all `echo "$out" | json_field ... | grep -q`;
they are safe today only because json_field is python3, which reads to EOF and
writes once. Fixtures go 4 to 12 vulnerable spellings plus near-miss negatives.

Two `grep ... | head -1` sites (test-vale-wrap.sh) are the same race with a
different early-exiting reader, and are fixed by absorbing the writer. The
scanner deliberately does not model `head`, `sed -n 1p` or a bare `read`: most
legitimate uses in this tree are already absorbed with `|| true` and the scanner
cannot see absorption from pipeline text, so a high false-positive rate would be
how this guard gets weakened. Heredoc bodies are scanned as code; none in the
tree trips it today.

Impact

The bug predates the factory-audit merge: every converted site in
check-release-needed and case 21 dates to 4d018af and aa8cc22 (2026-08-09).

Test suites go 19 to 20. `run-tests.sh --strict` passes 20/20 with 0 skipped,
four consecutive runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-16 09:14:01 +00:00
620f20b0fd refactor(kyberforge)!: merge skill-audit and agent-audit into factory-audit
Why

The two audit skills carried 1,724 lines of byte-identical duplication: the ADR-0020 boundary
resolver (1,061), vale-wrap.sh (526), the Vale style rules (44) and the Contributing-files parser
(93). Nothing shared them — they were held in sync by a 413-line pre-push gate and its 797-line
test suite. Sync-by-gate had already failed once: at 484357a the two parser copies drifted into
different spellings of the bullet loop while a docstring asserted they were identical. That drift
was behaviour-neutral and was re-unified by hand at 598a7c3, so the copies were identical at merge
time — but nothing had caught it, and the next drift need not be neutral.

Implementation Notes

Self-containment binds BETWEEN skills, not within one. The agentskills.io spec forbids reaching
across skill directories, which is why two separate skills needed embedded copies; two files inside
ONE skill may source a third. That is the whole reason the merge removes duplication rather than
relocating it.

The union of both bodies measured 1,532 words against BODY_MAX_WORDS=900, and only 211 of those
words were shared, so SKILL.md is a dispatch body. Step 0 resolves the flow from the target path
before any validation, and its table mirrors validate.sh's detection exactly: a directory holding
SKILL.md or a SKILL.md file (skill); a *.agent.md, or a .md directly under an agents/ directory
(agent); anything else stops without running a validator. Steps 1-3 live in
references/skill-flow.md and references/agent-flow.md, and gotchas that apply to one flow live in
that flow's file, since it is loaded on every invocation anyway. If validate.sh reports on the
other artifact type, the body restarts at Step 0.

Named factory-audit rather than forge-audit because forge is a live skill, and a family prefix that
matches a live sibling reads as ownership rather than membership.

The description carries one arrow per boundary target, because ADR-0020 resolves only the first
target after an arrow. It drops the quoted "audit this skill"-style phrases, which restated
"audited" in a second register (ADR-0020's duplicate-register rule). 241 characters, Gotchas 16%
of the body: no size SUGGESTIONs.

The boundary resolver stays embedded in two files rather than imported: a cache-installed plugin
cannot read outside its own directory, and the repo-root hook resolves via .pre-commit-hooks.yaml
where entry[0] is the only token pre-commit rewrites, so no single file is reachable by both.
tests/test-adr0020-contract.sh hashes both copies for byte-identity, and asserts validate.sh sources
the resolver and that no third copy exists.

The entry scripts classify the target from its resolved parent directory, so a bare agent filename
typed inside agents/ works; resolve SCRIPT_DIR CDPATH-safely; and exit 2 when a lib-*.sh is
missing, rather than dying with exit 1, the tier the flows relay as real findings.

The provenance run functions stash their findings code in KYBERFORGE_PROV_RC and
return 0, so validate-provenance.sh calls them UNTESTED. Testing a function's
status (`f || RC=$?`) disables errexit for its entire body, and no subshell or
`set -e` inside can re-arm it once the call sits in a condition context
(measured, both spellings). Their error paths use `exit`, which is unaffected
either way; this keeps errexit armed for anything added later.

Case 0's readability guard reads the file instead of asking `[[ -r ]]`. `-r` is
access(2), which answers yes for uid 0 even on a mode-000 file, and this repo's
dev environment is root -- so the guard could never fire where it exists to fire.
A read attempt is also the stricter question, catching EIO. This is the reasoning
scripts/check-vale-style-sync.sh carried before this commit deleted it; the
hazard did not go with it.

All three entry scripts are CDPATH-safe, vale-wrap.sh included: both of its cd sites are cleared,
the --config resolution and the directory-mirror walk, where an exported CDPATH would otherwise
print a decoy path into the -print0 stream and build the mirror from the decoy's files. The two
remaining bare cd calls take absolute paths, which CDPATH is never consulted for.

Impact

BREAKING: skill-audit and agent-audit no longer exist as invocable skills. kyberforge goes to
2.0.0 (catalog 0.4.7).

Check logic is unchanged: differential runs of the old and new validators across every skill and
agent produced byte-identical stdout, stderr and exit codes, and the reconstructed Python payloads
differ only in comments and the references/field-inventory.md -> agent-field-inventory.md rename.
One doctrine governs the tiers: exit 0 is audited and clean, exit 1 is audited with findings OR a
target present but unreadable, exit 2 is that nothing was audited at all. Edge paths DID change,
deliberately (full table in ADR-0025):
- a missing target exits 2 (never ran), not 1, under its own "does not exist" message; detection is
  by path shape, so a shape-matching path that is simply absent used to reach the validator and come
  back as a FAIL against a file that never existed;
- an unshaped target exits 2 under the generic "matches neither" message, and a directory with no
  SKILL.md under a third, distinct one -- three exit-2 messages, not one;
- a dangling symlink or a symlink loop stays exit 1: it is present but broken, which is a finding
  about the artifact rather than a usage error;
- a SKILL.md file path is audited as its skill directory instead of refused;
- a .md agent outside an agents/ directory is refused rather than audited;
- a missing script library, a missing python3, a missing PyYAML, and no argument at all each exit 2.
  validate-provenance.sh already exited 2 for the last two; validate.sh now matches it.

.pre-commit-hooks.yaml is a published contract consumed by external repos. Both hook IDs and both
files: regexes are unchanged; only entry: and description: moved.

scripts/check-vale-style-sync.sh (413), scripts/sync-vale-styles.sh (21),
tests/test-check-vale-style-sync.sh (797) and agent-audit/scripts/README.md (47) are deleted. The
checker made 17 assertions: 6 compared the two Vale copies and are moot; 10 are rehomed into
tests/test-vale-wrap.sh (case 0, cases 28-31, and the suite's Vale-absent skip); and the
cross-manifest files: agreement check, which selected hooks by entry: and so could not survive both
hooks sharing one, is ported as case 33 pairing hooks by id:. Cases 28, 30 and 33 carry mutation
self-tests; narrowing the local skill prefilter to 6 of 38 SKILL.md files now fails the suite.

Skills go 39 to 38. Pre-push goes 9 repo-authored hooks to 8.

ADR: 0025
BREAKING-CHANGE: the skill-audit and agent-audit skills are removed. Both flows are served by
  factory-audit, which auto-detects whether it was handed a skill directory or an agent file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-16 09:13:57 +00:00
a5962ba773 fix: point the HUMANS.md counterpart references at the file that exists
Why: three governance documents cited `docs/HUMANS.md`, which has never existed -- the human
practitioner rules live at `docs/wiki/HUMANS.md`. One of the three is
`core/instructions/governance.md`, which is `@`-imported into every session in every project,
so an agent following its "read it when making decisions not covered here" pointer hit a dead
path. That file was self-inconsistent: line 73 already cited the correct path while line 82 did
not.

Implementation notes: five occurrences corrected across three files --
`core/instructions/governance.md:82`, `docs/research/governance_principles/CONTROLS.md:5,101,106`,
and `docs/ai-constitution.md:238`. Text is otherwise untouched; this is a path correction only,
not a change to any governance rule. Marked the defect fixed in SIMPLIFICATION-AUDIT.md, which
recorded it in two places as outstanding.

Impact: no rule, gate or behaviour changes. The deployed copy at
`~/.claude/core/instructions/governance.md` no longer matches the repo and stays stale until
`scripts/install.sh` re-runs; it was byte-identical before this commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-15 06:55:00 +00:00
64d3fd8427 docs: record findings 5, 18, 32 and the ten-finding verification wave
Why: this audit was written read-only and its scope estimates proved systematically optimistic.
Ten open findings with claimed yield were re-verified against the files by independent agents.
One premise of ten survived, and the headline figure was wrong in at most eight of the ten.

Implementation notes: per-finding verification notes on 11, 16, 20, 22, 24, 27, 28, 33, 34 and
36. Finding 5 marked not proceeding, on the same grounds as finding 3 -- its six suites are
split by failure class, not ADR section, and five of the six headers name the incident they
guard. Finding 18 re-scoped and folded into finding 22 under three exemptions (audit criteria,
assets/templates and sourced spec restatement, the last now carrying a decidable test rather
than resting on the presence of source_keys). Finding 32 closed with its premise corrected.
Section 8 questions updated where measurement answered them: ADR-0012 is moot, git/gitea
granularity fails an enforced gate at 4.9x, and the external-consumer question has its evidence
but awaits a decision. New section 10 records the wave, the recurring failure mode behind six
wrong findings, and where the remaining opportunity actually sits.

The wave's own notes were then re-verified by a second independent round, and this commit
carries those corrections. The notes had an error rate comparable to the findings they
corrected. Four errors changed a verdict. Finding 11's note anchored its search at column 0 and
so missed every source_keys carrier nested under metadata:, producing "172 carriers" (196),
"zero of 40 SKILL.md files carry source_keys" (28 of 39) and "check 2 is dead code" (live, with
bats coverage); its double-counting accusation was a misreading of the word "plus" and is
withdrawn. Finding 28's note claimed 2,740 lines "has never matched any commit" -- it is exact
at a3e721e, the unique commit of the 67 touching docs/adr/ that yields it, and where all of the
finding's headline figures reproduce simultaneously; the finding went stale, it was not
fabricated. Finding 20's note argued the gitea split was blocked a fortiori by ADR-0011, which
inverts that ADR's reasoning (its objection is to a boundary being crossed, not to bundle size)
-- withdrawn and replaced with the same objection aimed at the correct seam, in the note and in
section 8. Finding 18's "sourced spec restatement" exemption collided with finding 20's own
salvage recommendation in the same commit and now carries a test that separates them.

Bookkeeping corrected throughout: the dangling docs/HUMANS.md path is five occurrences across
three files, not four (the sentence enumerated five while stating four); finding 16's c8a7c9e
chronology was inverted, and its resolver core is 549 executable lines, not 357, making it 2.7x
the proposed budget rather than 1.8x; finding 24's Q1-Q5 coverage is 20 tests and ~67%, not 24
and ~76%; finding 22's estimate is ~150-180 lines with its components summing, and its
RED/GREEN rebuttal no longer depends on ignoring the two diagrams the finding most plausibly
named; finding 27's preamble is 43 words; finding 28's proposal is a wash (+5 to -1) rather
than a firm +5; finding 32's citation is architecture.md:22 and its net is 6 lines. Section 10's
table reconciled against every corrected note.

Impact: no code, gate or behaviour changes. Two defects are flagged for independent fixing -- the
deployed core/instructions/governance.md cites docs/HUMANS.md, which does not exist, in five
places across three files; and apm update on this branch resolves against main and would restore
the obsidian MCP server removed in c96ca9c, via the regenerated repo-root .mcp.json, which is
gitignored and so would not appear in git status.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 21:22:35 +00:00
f91babcacd docs: dedupe structure and stack descriptions (finding 32)
Why: AGENTS.md's Structure bullet restated apm-install mechanics already owned by
docs/spec/architecture.md:24 and README.md:55, and docs/VISION.md carried stack, framework and
deployment choices for a product that lives in a separate repo.

Implementation notes: AGENTS.md keeps two actionable one-liners plus pointers to the README
layout table and architecture.md, preserving the session rule that .claude/skills/ and
.claude/agents/ are install output and must not be edited. VISION.md's Phase 1 Architecture
block becomes a one-line scope statement; the "Mobile/desktop (Phase 3)" line is dropped as an
intra-file duplicate of the Phase 3 section.

Impact: no behaviour change. README.md and docs/spec/architecture.md are untouched -- the
finding's premise was inflated, and architecture.md had already been differentiated in a way it
documents in the file itself.

Refs: SIMPLIFICATION-AUDIT.md finding 32
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 20:31:40 +00:00
062ca47a18 docs: correct claims left stale by today's apm-only commits
A five-agent review of today's seven commits found no executable
regressions and no dangling references, but a set of documents still
asserting, in present tense, machinery that ADR-0024 and its commits
removed. This corrects them in place, keeping the original text as the
historical record wherever the repo's amendment convention applies.

LESSONS.md: the 2026-06-21 entry prescribed a `claude plugin validate`
sweep that now fails on every plugin, so it is marked superseded with
the surviving gates named. The 2026-08-09 entry gained a recurrence
note: today's manifest deletion broke apm's MCP propagation exactly as
that lesson describes, and its prescribed repo-local grep could not
have caught it, because `plugin_parser.py` ships in the apm toolchain
installed outside this repository.

ADR-0019, ADR-0011 and ADR-0021: amendments extended to passages the
earlier correction passes stepped over -- a dead native-consumer guard,
Consequences bullets still calling for a `plugins/gitea/.mcp.json` that
must not be recreated, and a drift-gate list naming a deleted script.
ADR-0021's list is down to one gate, not two: `apm audit --ci` never
read `description` and was never a drift gate.

architecture.md and enrichments.md: the self-containment constraint is
restated on its live source, the agentskills.io APM package-mode spec,
rather than on Claude Code's plugin cache-install, which ADR-0024
consequence 6 pins as a superseded rationale. releasing.md's pointer to
the deleted sync script is rewritten as history.

tests/run-bats.sh and scripts/lib/batch-run.sh: comment-only. The
`.claude/skills/` exclusion comment claimed a duplication that is not
live yet; apm does not strip `tests/`, and the deployed tree is empty
of them only because the lockfile still resolves the six dependencies
to a pre-ADR-0024 commit carrying the flat mirror. The exclusion is
correct but forward-looking, and now says so.

SIMPLIFICATION-AUDIT.md: reconciled against what the commits actually
did. Two closed findings recorded conclusions that ADR-0024 reversed
hours later; findings 1, 3, 31 and 35 carried prescriptions voided the
same day; finding 28 is now recorded as having moved backwards, with
docs/adr/ measured at +336 lines over the day. The section 1 headline
table is re-measured at a6434e0 and labelled with its basis. The
ADR-0012 contradiction between finding 2b and section 8 is resolved in
2b's favour after reading the ADR: only finding 24 is governed by it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 19:50:23 +00:00
a6434e0cdb docs: amend ADR-0021 and close the loose ends ADR-0024 left behind
A six-agent review of today's commits found three documentation defects
that the apm-only change left behind. All three are records that describe
deleted machinery in the present tense; no code or gate is affected.

ADR-0021 was the one ADR that ADR-0024 invalidates without carrying an
amendment note -- 0001, 0006, 0011, 0013, 0014, 0015, 0017, 0018 and 0019
all got one. Its Context section still compiles a plugin description into
four generated files and its Consequences section still names eight, but
718c79a deleted the per-plugin manifest pairs and 0dffff3 deleted the
.github/plugin/marketplace.json mirror. One target survives. The decision
itself is untouched: the note marks the counts historical rather than
rewriting them, since the staleness hazard that motivated the ADR is
exactly what shrinking the blast radius does not fix.

That note also lands the one ADR-0021 has promised since it was written:
its Context section said "see the note below" about the codex profile's
removal and no such note has ever existed in the file.

SIMPLIFICATION-AUDIT.md's section 8 still asked whether Copilot reads the
legacy mirror path. Finding 2c answered that at 11:35 and 0dffff3 acted on
it; two later passes over section 8 (d2480b8, 061bb3d) each checked off a
different question and stepped over this one. Closed with the answer that
already shipped: Copilot's discovery falls through to .claude-plugin/,
so what the deletion cost is discovery-order preference, not consumability.

ADR-0020 cited plugins/bin/skills/zoom-out/SKILL.md:4 as end-to-end
verification evidence. That path is mirror, deleted by ADR-0024. The .apm/
source and the deployed copy both still carry the flag and the pass-through
still holds, so the citation is narrowed to the two live paths rather than
the finding being withdrawn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 18:38:49 +00:00
c96ca9ca0d fix: remove the obsidian MCP server and the unreadable .mcp.json files
718c79a deleted every per-plugin .claude-plugin/plugin.json, which
reclassified each package from a marketplace plugin to a plain apm
package. That silently broke MCP propagation: apm_cli/deps/plugin_parser.py
maps a plugin-root .mcp.json into .apm/.mcp.json, and that code path runs
only for marketplace plugins. With no manifest, apm never reads the file.

Reproduced on ref-pinned consumer clones: at the parent commit a consumer
receives the obsidian server, at HEAD it receives none, and on upgrade apm
prints "Removed stale MCP server 'obsidian' from .mcp.json". This repo
consumes its own plugins through apm (ADR-0018), so the tracked root
.mcp.json would have been rewritten to an empty server map on the next
lock re-resolve -- silent tool loss plus unexplained working-tree drift.

The server is removed entirely rather than relocated to .apm/. It was
already a standing question (SIMPLIFICATION-AUDIT finding 37, deferred on
2026-09-13 pending confirmation, now confirmed), and plugins/bin/apm.yml
declares dependencies.mcp: [] -- apm's supported mechanism was never used.
All seven .mcp.json files go; the root one is apm-generated output and is
now gitignored alongside the other install artifacts.

ADR-0011's deferred ".mcp.json wiring gap" is moot twice over -- the
install route it blocked no longer exists and neither does the file --
and ADR-0018 records why it lost its only worked example of MCP
propagation. apm.lock.yaml still carries the server; it clears on the
first apm update after this reaches the default branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 18:09:17 +00:00
061bb3d5b4 docs: correct the apm-only change after a five-agent review
A five-agent review of 718c79a and d2480b8 found no skill, agent or hook
regressions (39 skills before and after) and confirmed both hook removals
are genuinely moot -- verified against the tree, not taken on the commit's
word. It did find one functional regression (fixed separately) and this
documentation drift.

Counting errors, all from a git pathspec `*` crossing `/`:
  - 17 .bats files shipped to consumers is really 10; 17 counted tracked
    paths merely containing /tests/, one of them a template asset
  - "roughly 88s off every push" is ~92.4s; 88 omitted validate-plugins
  - "roughly 70% of each plugin remains live" holds only for kyberforge;
    the real spread is 44.3% (bin) to 70.6%, now a table
  - the pre-push enforcement row was half-corrected: 33 entries stood
    unstruck (now 27) and 14 -> 11 switched counting basis mid-sentence
  - the root .claude-plugin/plugin.json was described as "kept"; it has
    never been tracked

gates.md said "Ten hooks" above a nine-row table (11 was decremented for
one removal, not two), and "both need the claude CLI" for one remaining
validator. Its pretty-format-json exclude rationale claimed six
alternations expanding to sixteen files in a passage headed "Mind which
number you are quoting" -- four alternations, two live files; the two
dead ones are dropped from the pattern. check-useless-excludes could not
catch this: it only flags an exclude matching nothing at all.

ADR-0024 cited ADR-0006 for a patch-bump rule it does not contain and
which ADR-0015 explicitly retired; stated apm's marketplace probe order
backwards (.claude-plugin/ is the last candidate, not the first, so the
earlier .github/plugin/ deletion only demoted resolution); undercounted
apm's skill-deploying targets as seven when there are fifteen; and never
recorded that validate-plugins was removed. The symlink hedge is resolved:
apm_cli/security/gate.py's ignore_non_content() drops symlinks silently on
deploy while apm_modules/ materialization dereferences them, so content
survives that far and vanishes at install. Accepted with no replacement
guard, per decision -- kyberforge/docs/hooks.md previously asserted a
guard that had been deleted with its script.

Four plugin READMEs still advertised `claude plugin install`; ADRs 0001,
0006, 0013, 0014, 0015 and 0019 described deleted machinery in the present
tense, 0019 most consequentially as the live justification for the
SessionStart hook's .apm/ path. CONTEXT.md's "apm package" entry forbade
"plugin" while using it in its own body, and "Output profile" lost the
antecedent for "one catalogue serves both".

run-tests.sh gains the .claude/skills/ exclusion run-bats.sh already had.
Latent today -- no test-*.sh lives under any .apm/skills/*/tests/ -- but
apm now deploys those directories, so one would be discovered twice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 18:09:03 +00:00
d2480b8191 docs: record the apm-only decision and its carried-forward consequences
Marks §8's install-path question answered and finding 7 superseded-then-done
(deleted rather than shrunk, since the mirror it guarded is gone). Corrects
two stale figures: the mirror was 213 files / 20,061 lines, not 263 / ~22,000,
and the pre-push stage now reports 11 hooks, not 14.

Adds §9 for what the decision carries forward rather than resolves: the two
accepted residuals, the self-containment negative result (findings 14/15 still
need skill merges, not file sharing), and the now-unreported symlink drop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 17:02:35 +00:00
718c79af70 chore: drop the flat content mirror and native install support (ADR-0024)
apm becomes the only supported install path. The flat mirror at each plugin
root existed solely so Claude Code's native `claude plugin install` could
convention-scan plugin content (ADR-0017). With no native consumers, it cost
~20,000 tracked lines plus ~2,100 lines of sync tooling and ~88s of every
push to guard content apm never reads — and its only automated gate,
`claude plugin validate --strict`, passes on a plugin with zero content, so
it could not detect the defect ADR-0017 was created to fix.

Removes the mirror (213 files), the six per-plugin manifest pairs,
sync-plugin-content.sh, its 1,289-line test, the orphaned
marketplace-plugins.sh, and the check-plugin-content-sync and
validate-plugins pre-push hooks. The root `marketplace:` block and
.claude-plugin/ catalogue stay: apm's own marketplace consumers read that
same file, so `<name>@holocron` short names keep working.

tests/run-bats.sh now excludes .claude/skills/. apm installs from .apm/,
which carries the tests/ dirs the mirror stripped, so deployed .bats files
would otherwise be discovered and double-run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 16:59:42 +00:00
0dffff3c21 chore: drop redundant apm-marketplace-check and Copilot marketplace mirror (findings 1, 2)
apm-marketplace-check checked network reachability of remote marketplace
refs, but finding 35 already removed the only remote package entry, so
every marketplace.packages[] source is local and the hook is pure
overlap with apm-pack-check-clean. apm-audit-ci was re-examined and kept
as-is -- its pre-commit-config.yaml comment already carries a dated,
verified justification the audit had missed.

check-marketplace-mirror-sync guarded .github/plugin/marketplace.json
against drift from .claude-plugin/marketplace.json. Verified against
current GitHub Copilot CLI docs: Copilot's marketplace discovery already
falls back through .github/plugin/marketplace.json to
.claude-plugin/marketplace.json, which this repo generates anyway -- the
dedicated mirror bought a discovery-order preference, not a capability.
Deleted the mirror file, its sync script, its test, and the hook.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 11:35:44 +00:00
afa7187d33 docs: dedupe .apm/-mirror and apm.lock/SessionStart restatements (finding 29)
README and AGENTS.md each fully restated the "edit .apm/, never the
mirror" rule and the apm.lock/SessionStart mechanism instead of linking
to their canonical sources (architecture.md, ADR-0019).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-14 07:15:19 +00:00
e2e957efdd docs: record subagent outcomes for findings 2, 31, 38
Three findings from the simplification audit were independently
re-verified before execution, corrected, then implemented by
subagents:

- Finding 2 (check-executables-allow-sync): the audit's "drop it"
  option was found unsafe (ADR-0019 calls this failure mode silent,
  not "visible and recoverable" as claimed); shrunk instead of
  deleted, 231 -> 222 lines.
- Finding 31 (CONTEXT.md): "most terms unused by skills" was found
  overstated (13 of 28 are model-facing must-keeps); cut only the
  9 confirmed true orphans, 28 -> 19 terms. Also de-referenced one
  dangling pointer to a deleted term in the Flagged-ambiguities
  section.
- Finding 38 (pc-author/pc-run): line count was found overstated
  (598 actual vs. 689 claimed); trimmed the two generic reference
  files by 60 lines while preserving house-specific content.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 21:03:58 +00:00
124ce6eaa9 docs(context): remove unreferenced glossary terms (finding 31)
Corrected scope for audit finding 31: the audit's claim that most of
CONTEXT.md's 28 terms are unused was overstated (13 are must-keep,
referenced in model-facing skill references/*.md files). This cuts only
the 9 confirmed true orphans, independently re-verified by grep across
plugins/*/.apm/, docs/, scripts/, and tests/ with zero hits outside
CONTEXT.md (two had a single incidental ADR mention that doesn't
constitute a dependency): Content mirror, apm-consumed install, Vale
audit prefilter, Vacuous green, Management Application, Sycophancy,
HOTL, Preload tax, Skill context contract.

Term count: 28 -> 19. Also removed two Relationships bullets that
existed solely to relate now-deleted terms (Preload tax/Skill context
contract, and HITL/HOTL/Sycophancy), leaving HITL's own entry to stand
alone. The Preload tax entry's self-contradiction (quoting two dated
character counts immediately after saying not to quote either) is
moot since the whole entry is removed. Example dialogue and flagged
ambiguities sections left untouched per scope, including one now-stale
bold reference to "Preload tax" in flagged ambiguities.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 21:02:41 +00:00
1b01e25f3b refactor(hooks): shrink check-executables-allow-sync (finding 2)
Trim the two comment blocks that re-derived ADR-0019's argument in full
(apm's exact-dict-lookup key matching, and why the PyYAML fallback is not
a hard requirement) down to a short summary plus a pointer at ADR-0019,
which already carries that reasoning verbatim. 231 -> 222 lines.

The hook is kept, not deleted, per the audit's own corrected scope: the
"or drop it" option in SIMPLIFICATION-AUDIT.md finding #2 is off the
table because ADR-0019's Consequences section and the script's own
header both call this failure mode silent, and the ADR says a
silent-staleness failure here is strictly worse than the duplication
this repo's other gates catch.

The dual-reader design (PyYAML preferred, hand-rolled shape-scan
fallback) is also kept as-is: it exists specifically so a missing
python3/PyYAML can't silently skip the check or block every push, which
is exactly the loud-failure guarantee this finding must not weaken. No
genuine redundancy was found in the parsing logic, the per-branch
Why/Fix error messages (each tied to a specific test), or the test
matrix (which verifies the two readers agree across every failure mode)
without cutting something load-bearing -- so those are untouched, and
tests/test-check-executables-allow-sync.sh needed no changes since
script behavior and output are byte-identical.

All 23 tests in tests/test-check-executables-allow-sync.sh pass, and
`pre-commit run check-executables-allow-sync --all-files --hook-stage
pre-push` passes against the real repo state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 20:58:41 +00:00
a622200868 docs(pc-skills): trim generic pre-commit boilerplate (finding 38)
Collapse the per-language hook tables in pc-author's hooks-by-language.md
into one shared-repo table plus an "other repos" table, dropping the
repeated repo/rev/rationale text that just restated what each hook does.
128 -> 92 lines. Kept both "Unverified — not in research corpus" flags
and the rev-freshness caveat.

Remove the generic SSH/proxy CI failure sections, the shellcheck SC-code
listing, and compress the generic validate-config schema-error bullets
in pc-run's failure-patterns.md, all of which just restated
pre-commit.com's own docs. 133 -> 109 lines. Kept the rtk-prefixed
re-stage/recommit fix (ADR-0023), the "do NOT reach for
`pre-commit install -f`" warning, and both gitleaks/shellcheck
not-sourced-from-corpus notes.

Combined cut: 60 lines. Flat mirrors regenerated via
scripts/sync-plugin-content.sh and verified byte-identical
(--check exits 0); no plugin.json drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 20:54:17 +00:00
af80d27b9b docs(adr): flag stale codex-profile mention in ADR-0021 context
The Context section still described .agents/plugins/marketplace.json
(apm's codex profile) as an existing, unaffected generated file. It
was removed today in 568ca74; point to the removal instead of leaving
the text describing a file that no longer exists.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 20:30:30 +00:00
14f327409e docs: record subagent outcomes for findings 3, 8, 19, 35, 37
Two landed (8 partial, 35 in full); three declined after investigation
found the audit's premise didn't hold on inspection of current code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 10:18:01 +00:00
e21a5fb24c chore: merge dead-distribution-surface cleanup (finding 35)
Removes the codex marketplace output profile and the mattpocock-skills
remote package entry per SIMPLIFICATION-AUDIT.md finding 35.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 10:17:03 +00:00
568ca749f0 chore: remove codex output profile and mattpocock-skills remote entry
Neither has a real consumer: Codex is not a supported target, and
mattpocock-skills was the sole remote marketplace.packages[] entry
forcing apm-marketplace-check and apm-pack-check-clean to git
ls-remote on every push. Removing both drops .agents/plugins/marketplace.json
(the codex output artifact) and makes every pre-push hook resolve
fully offline. Updates README, AGENTS.md, gates.md, architecture.md,
and ADR-0015/ADR-0021 to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 10:16:02 +00:00
a35f5e889e docs(gates): trim two stale post-mortem passages from gates.md
Cut the "Verified fixed" reproduction paragraph carrying explicitly
stale pre-retrofit figures, and condensed the "Current retrofit
status" section's issue-#99 process narrative to the current-state
facts and the commands to check them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-13 10:13:57 +00:00
cc2553d5f6 docs: fix two more stale commit hashes in simplification audit
Findings 13 and 21 cited b4c3d5e and 4bbd8a5, both dangling (not
reachable from HEAD) -- an amend after ace2d66 changed the hashes of
the underlying commits to 6cfc357 and f5e4d0d without updating the
self-reference. Corrected both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 22:58:07 +00:00
60d3005e67 docs(git): remove stale check-manifests/skill-frontmatter examples
f11b645 and bde9f7f swept check-manifests and skill-frontmatter
references left over from e647f14 and c8a7c9e, but missed two worked
examples in this vendored pre-commit research doc: a "Validate a
generated file" hook naming the deleted scripts/check-manifests.sh,
and a "SKILL.md frontmatter validation (inline bash, as used in this
repo)" example for the skill-frontmatter hook, folded into
skill-size-check.sh in c8a7c9e.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 22:56:43 +00:00
bde9f7fdd8 chore: fix stale skill-frontmatter and check-manifests references
c8a7c9e folded the skill-frontmatter hook into skill-size-check but
left validate.sh's FAIL messages, skill-author's create.md, and the
skill template's frontmatter comment naming the deleted hook as the
enforcer -- misleading for anyone tracing a FAIL back to the gate that
raises it.

f11b645 swept check-manifests references but missed a hand-authored
"Local hooks in this repo" table in the git plugin's vendored
pre-commit research doc, which still listed both check-manifests and
skill-frontmatter as active hooks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 22:13:10 +00:00
f11b6455ce chore: remove stale check-manifests references left by e647f14
e647f14 deleted scripts/check-manifests.sh but missed three live files
that still named it: the apm-marketplace-check hook description in
.pre-commit-config.yaml, and comments in sync-plugin-content.sh and
lib/marketplace-plugins.sh explaining design decisions by pointing at
a script that no longer exists.

Also deletes list_marketplace_remote_plugin_names from
marketplace-plugins.sh — its only caller was check-manifests.sh, so
it's been dead code since that commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 21:50:46 +00:00
ace2d66343 docs: fix stale commit hashes in simplification audit
The Done blockquotes for findings 1, 4, and 6 cited a pre-amend hash
of their own commit (a commit can't know its final hash before it's
made). Point them at the actual final hashes: e647f14, c8a7c9e,
5f9f2b3.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 20:39:04 +00:00
5f9f2b33b0 chore: delete prose-grep governance/instructions tests
test-governance-layer.sh and test-instructions-and-docs.sh (583 lines
combined) grep markdown files for expected phrases, including a
one-shot "issue 0015 refactor incomplete" assertion made permanent and
an assertion that docs/notes/ exists. Neither is referenced by any
other script or doc.

check-apm-agents-valid.sh is left untouched — it is tied to the
separate, out-of-scope skill-merge finding 14.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 20:01:18 +00:00
c8a7c9ea87 chore: fold skill-frontmatter into skill-size-check
skill-frontmatter was a 62-line bash script inlined in
.pre-commit-config.yaml, re-parsing SKILL.md frontmatter with grep and
awk to check for name/description/metadata.version fields.
skill-size-check.sh already parses the same frontmatter block with
PyYAML for its ADR-0020 checks, so the two checks belonged in one
script.

Adds a ~20-line required-frontmatter check (name, description,
metadata.version as three-part semver) to scripts/skill-size-check.sh.
Removes the inline skill-frontmatter hook from .pre-commit-config.yaml
and deletes tests/test-skill-frontmatter.sh (366 lines). Removes the
79-line "the other hook on that scope" discussion from
docs/spec/gates.md and its now-dangling cross-reference, replacing
both with a one-line note of the fold, and updates the pre-push hook
counts there.

Updates fixture builders in test-skill-size-check.sh,
test-adr0020-body-checks.sh, test-adr0020-targets.sh,
test-adr0020-differential.sh, and test-vale-hooks-consumer.sh to carry
valid metadata.version so the new check doesn't spuriously fail
existing fixtures that predate it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 20:00:43 +00:00