Commit graph

7 commits

Author SHA1 Message Date
Claude
7405298b4b
fix: resolve the actionable reported issues (#954, #949, #933, #931, #969, #968, #924, #885)
- #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
2026-08-21 05:47:37 +00:00
Claude
2c384a9c47
fix(memory-engineering): close an F1 bypass and make --print-sample-spec reachable
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
2026-08-09 05:10:36 +00:00
Claude
5c0e5314b4
fix(memory-engineering): make all four tie-breakers reachable
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
2026-08-09 04:57:43 +00:00
Claude
cb49e3b5e1
fix(memory-engineering): report duplicate participants and redundant copies separately
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
2026-08-09 04:52:19 +00:00
Claude
e716c6ada0
fix(memory-engineering): use plugin-root-relative paths in command files
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
2026-08-09 04:31:15 +00:00
Claude
c6dc69c18a
chore(memory-engineering): drop __future__ imports, unify step numbering
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
2026-08-09 04:28:05 +00:00
Claude
733e897402
feat(engineering): add memory-engineering skill — engineer the forgetting
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
2026-08-09 04:19:43 +00:00