- #954: strip non-spec source/attribution keys from all 39 plugin.json
manifests so Claude Code's validator accepts them; metadata preserved in
new .claude-plugin/authoring-notes.json sidecars; check_plugin_json.py now
hard-fails manifests carrying those keys and sanity-checks the sidecar;
CLAUDE.md ClawHub schema section updated to the new rule.
- #949: move the c-level-agents plugin out of c-level-advisor/ to a
top-level directory so the two marketplace sources no longer overlap;
updated marketplace.json source, homepage, descriptions, all
cross-references, docs, harness manifest, mirror-tree symlinks/indexes,
and rebased the moved files' relative links; domain counters trued up
(18 -> 19 domains).
- #933: replace dead links to the gitignored maintainer-local megaprompts/
tree with annotated plain-text references (44 files: SKILL.md, READMEs,
agents, commands).
- #931: DynamoDB on-demand pricing updated to post-Nov-2024 rates
($0.625/M writes, $0.125/M strongly consistent reads).
- #969: skill_security_auditor.py and the three dossier scripts reconfigure
stdout/stderr to UTF-8 (errors=replace) so legacy Windows codepages no
longer crash at print time; PYTHONUTF8=1 documented.
- #968: Windows Notes section in INSTALLATION.md + README pointer for the
core.symlinks mirror-tree checkout caveat.
- #924/#885 residuals: hook commands quote "${CLAUDE_PLUGIN_ROOT}" paths in
all plugin hooks.json/settings.json (space-safe roots); removed the stale
pre-rename status/review mirror symlinks and index entries left over from
the memory-status/memory-review rename.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4
Fourth review on PR #947 reported two functional bugs, explicitly noting it had
not run anything. Both reproduced, and the first is severe.
1. F1 -- the blocking gate -- could be bypassed by a typo.
_check_forgetting_rule() failed only when `rule` was literally
"none"/""/"never", and otherwise inferred PASS from what the rule was *not*.
So anything unrecognized fell through to the PASS branch with an empty
mechanism list. Reproduced:
{"rule": "asdf"} -> F1=PASS "Forgetting is designed: ."
{"rule": "ttl"} (no ttl_days)-> F1=PASS "Forgetting is designed: ."
A misspelling silently passed the one check this entire skill is built
around, and the nonsensical detail string was the only hint.
The check is now allowlist-based: PASS is unreachable unless a concrete
mechanism is actually found (ttl_days > 0, max_records/max_bytes > 0, or a
decay setting). Failure messages now distinguish an unrecognized rule from a
declared-but-unconfigured one, so a typo is never mistaken for a deliberate
decision not to forget. Booleans are rejected where a number is expected,
and ttl_days=0 counts as absent.
Verified across 10 cases: all six bypass variants now FAIL at exit 4, all
four legitimate mechanisms still PASS, and the empty-mechanism string can no
longer be emitted.
2. --print-sample-spec was unreachable on all three scripts that offer it.
The flag sat outside a mutually-exclusive group declared required=True, and
argparse enforces that during parse_args() -- before any of our code runs.
So the flag alone exited 2 with a usage error, which broke the first line of
the workflow SKILL.md documents verbatim:
python scripts/memory_cost_profiler.py --print-sample-spec > workload.json
The group is now required=False with explicit post-parse validation, so
no-args still errors helpfully and names all valid entry points. Verified the
full round-trip on all three: --print-sample-spec > f.json, then feed f.json
back in.
This slipped through because the PR's own checklist covered --help, --sample
and --output json, but never ran --print-sample-spec standalone.
Also removed the identity dict in render() flagged as a nit.
Verified: 4/4 scripts help/sample/json; error paths 3/4/4; all six blocking
gates; checklist 6/6 PASS; security auditor PASS (0 critical, 0 high, 0 info).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv
Second automated review on PR #947 found a real bug, verified by execution:
`pick()` looks up `tuple(sorted([winner, runner_up]))`, but two of the four
TIE_BREAKERS keys were authored in the other order, so they could never match:
('flat_rag', 'structured_rag') sorted -> matches
('structured_rag', 'agentic') sorted -> ('agentic', ...) DEAD
('long_context', 'flat_rag') sorted -> ('flat_rag', ...) DEAD
('long_context', 'structured_rag') sorted -> matches
Only 2 of 4 authored questions were reachable. The two dead ones are the
plausible near-ties (structured_rag vs agentic on a high-recall/high-mutability
workload; long_context vs flat_rag under build-budget pressure), so the tool's
most distinctive behaviour — an authored, specific tie-breaking question —
silently degraded to the generic fallback with no error.
Keys are now normalized through sorted() at import, with a collision check that
raises if two entries describe the same pair. Verified by injecting a duplicate
in the reverse order: the guard fires. This repo has no test suite, so the check
runs at import rather than living in a test.
Confirmed by execution, not inspection: all 4 keys reachable, and a constraint
set that ties structured_rag against agentic now returns the authored question
("Does your memory need to correct itself without a human in the loop?")
instead of the fallback.
Also from the review: the SKILL.md workflow block labelled steps 1-4 while the
prose referenced a step 5, so a reader skimming only the code block would not
know it existed. Added a `# 5 - No command.` line and compensated elsewhere to
stay within the checklist's 100-line limit (still 6/6 PASS).
Verified: 4/4 scripts --help/--sample/--output json; all six blocking gates.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv
Automated review on PR #947 flagged find_duplicates() undercounting. Verified
and fixed, though the diagnosis was incomplete in a way that changes the fix.
`seen.add(j)` only ever recorded the second member of a matching pair, so for
a fully-connected cluster of k mutually-duplicate records len(seen) == k-1.
That number is not meaningless -- it is exactly the count of redundant copies
you could delete. The actual defect is that it was reported under the name
`records_with_a_duplicate`, and rendered as "N records have a near-duplicate",
which describes participants (k), not redundant copies (k-1). Two valid
metrics, one reported under the other's name.
So rather than just adding `seen.add(i)`, both are now computed and reported:
participants -- every record with >= 1 near-duplicate; drives duplicate_share
and the DUPLICATE_BLOATED threshold, matching the wording
redundant -- participants minus one survivor per connected cluster
Clusters are resolved with union-find, not by counting pair endpoints: a
3-record cluster emits pairs (i,j), (i,k), (j,k), so endpoint arithmetic gets
the redundant count wrong. Verified k=2/3/4 give participants=k, redundant=k-1,
and that a 3-cluster plus an unrelated record still gives 3/2.
Sample output moves from "1 record (17%)" to "2 records (33%), of which 1
redundant" -- the reviewer's point that this could tip a real store under the
15% threshold was correct.
Also from the same review:
- Dropped the stale `-> list[dict]` hint (the function returns a tuple); the
return shape is documented in the docstring instead.
- Capped the O(n^2) scan at MAX_DUPLICATE_SCAN=2000 eligible records and made
the tool print how many were skipped, per this repo's no-silent-caps rule --
a quiet cap reads as "no duplicates found".
Verified: 4/4 scripts --help/--sample/--output json; all six blocking gates;
skill checklist 6/6 PASS; real-directory run unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv
CI gate G1 (scripts/check_paths.py) failed with 8 unresolvable references.
Both command files referenced `scripts/<tool>.py` and `assets/<file>` as if
they were relative to the command file, but commands/ sits at the plugin root
while the scripts live under skills/memory-engineering/. SKILL.md was correct
already — it sits inside the skill directory, so its bare `scripts/...` paths
resolve — which is why this only showed up in the two command files.
Rewritten to the plugin-root-relative form
(`skills/memory-engineering/scripts/...`), matching how agent-harness writes
its command paths.
check_paths.py --all now reports 0 findings across 586 files. Also re-ran the
other five blocking gates locally: check_plugin_json, check_dual_publish,
smoke_scripts, smoke_json_output, derive_counters --check — all pass, plus
compileall on the plugin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv
Two follow-ups after running the repo's own CI auditors locally:
- Removed `from __future__ import annotations` from all 4 scripts. The repo's
skill_validator.py counts it as an external import (script_tester.py
disagrees and reports the same files as stdlib-only, but the stricter of the
two is what CI surfaces). PEP 585 generics are native on the 3.11 CI runner,
and the single PEP 604 union annotation was the only thing needing the
import — it is now unannotated. Takes this skill from 7 validator errors to
3, matching productivity/weekly-review and better than productivity/fable-goal
(4). The 3 remaining are the legacy v2.0.0 schema checks (min-100-lines, and
Tier/Category/Features/Usage frontmatter+sections) that directly contradict
the Matt Pocock checklist CLAUDE.md declares binding for post-v2.6.0 skills —
every recently-merged skill carries the same ones.
- SKILL.md: steps 4 and 5 used a bold-number style left over from the
compression pass while steps 1-3 had become prose. Reworded to match; still
exactly 100 lines and 6/6 PASS.
Verified after the change: 4/4 scripts pass --help / --sample / --output json;
script_tester 5/5 PASS; security auditor PASS (0 critical, 0 high, 0 info).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv
New engineering/memory-engineering/ plugin. The repo had no skill for
designing, pricing, or auditing an agent memory system: llm-wiki maintains
one vault, skillopt-sleep runs a consolidation loop, agent-harness bounds a
task loop. This bounds a store.
Four stdlib scripts, one per lens:
- memory_cost_profiler.py — construction vs query split, cost per correct
answer, amortization ratio, construction co-location warning
- memory_architecture_picker.py — scores the four paradigm families,
disqualifies on hard constraints, names the cost the choice makes you pay,
and refuses to pick when the top two tie (exit 2 + tie-breaking question)
- memory_density_auditor.py — classifies records FACT/SKILL/LOG/PROSE, finds
near-duplicates, flags staleness and time-relative wording, scores density;
runs on a real --dir or --jsonl
- forgetting_policy_linter.py — the gate. 8 checks; F1 (explicit forgetting
rule) and F4 (contradictions surfaced, never auto-merged) block at exit 4
Evidence discipline: the four-lens framing is synthesized from @N01ennn's
"How to be a Memory Engineer", but every quantitative claim is re-cited to
the primary source, and two of the article's paraphrases are corrected in the
references rather than propagated — the 47x energy figure is the spread across
ten evaluated systems (not an accuracy-matched pair), and the 97%
first-pass-error figure is Rakuten's named vendor testimonial (not a
controlled study). Per-claim confidence levels throughout.
Three classifier defects found and fixed during the build, each of which would
have produced garbage on a real repo: markdown headings inside fenced code
blocks were splitting records (258 phantom records -> 107 on a real directory);
short fragments matched trivially at 1.00 Jaccard (41 false-positive
duplicates); and signal-less prose was labeled LOG, firing LOG_HEAVY at 74% on
a documentation folder — now its own PROSE class.
Also ships 4 references (7 sources each), a seven-question forcing worksheet,
a combined example spec consumed by all three spec-taking scripts, an F1–F8
policy template, cs-memory-engineer, /cs:memory-engineering and
/cs:forgetting-audit.
Verified: all 4 scripts pass --help / --sample / --output json, stdlib-only,
correct exit codes on error paths; SKILL.md 6/6 PASS on the write-a-skill
checklist; check_plugin_json.py --all and derive_counters.py --check both pass.
Counters: skills 362->363, tools 644->648, refs 741->745, agents 102->103,
commands 116->118, plugins 88->89.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv