Commit graph

142 commits

Author SHA1 Message Date
Alireza Rezvani
8b0fca4a4d
fix(book-to-skill): correct emitter docstring drift and the resident-core figure
Addresses both review findings on #993.

1. skill_plugin_emitter.py's module docstring still described the behaviour this
   PR removed. Its tree diagram called plugin.json the "manifest with
   ./skills/<slug> + attribution", and the rights-gate paragraph said
   cleared_for_distribution is recorded "in the manifest" -- both now the
   sidecar. A docstring asserting the opposite of its own file's point is worse
   than no docstring, and it is what `--help` readers see.

   Also corrects a third instance the review did not name but which shares the
   root cause: the tree diagram never listed authoring-notes.json at all, even
   though this PR's fix is what creates it. Added, with the issue #954 reason
   stated inline so the next reader knows why provenance cannot live in the
   manifest.

2. CLAUDE.md said the resident core is 2,066 tokens while, twelve lines later,
   the same file said 2,101. 2,066 predates the worked invocation block added
   for write-a-skill checklist item 5; token_budget_estimator.py reports 2,101
   on the current tree, matching CHANGELOG.md and the PR body. CLAUDE.md was
   the only stale copy and it contradicted itself.

Docstring-only and prose-only; no behaviour change. Verified the emitter still
emits both plugin.json and authoring-notes.json via --sample after the edit.

Gates: compileall, check_plugin_json --all, check_paths, check_frontmatter,
check_dual_publish, check_model_freshness, smoke_scripts (696/696),
derive_counters --check, book_skill_validator --strict.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UySnyf5upm4y8xhYA3w6yw
2026-08-25 22:57:41 +00:00
Alireza Rezvani
3301348d09
fix(docs): correct the commands delta and a README spacing nit
Addresses both review findings on #993.

1. The changelog/CLAUDE.md counter line said "commands 147 → 150", which
   asserts this plugin adds three commands. It adds exactly one
   (commands/cs-spinning-up-deep-rl.md). 147 was this branch's pre-merge
   baseline; after merging dev the delta had to be restated against dev's
   baseline, and that one figure was carried over unchanged while the others
   were updated. Verified empirically rather than by arithmetic: derive_counters
   on an origin/dev worktree reports 149 commands, and the raw command-file
   count goes 281 → 282 across the merge. Corrected to 149 → 150. The other
   three figures on that line (skills 387 → 388, agents 117 → 118, plugins
   98 → 99) were already right.

2. README POWERFUL-tier row had a stray space before a comma:
   "calculator) , **spinning-up-deep-rl**". Removed.

Neither affected derive_counters --check, which reads the tree rather than the
prose -- which is exactly why a wrong delta in prose can survive a green gate,
and why it was worth fixing in a repo this strict about counters being
trustworthy.

Gates re-run: compileall, check_plugin_json --all, check_paths,
check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts
(696/696), derive_counters --check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UySnyf5upm4y8xhYA3w6yw
2026-08-25 22:53:54 +00:00
Alireza Rezvani
d5635e5a05
Merge branch 'dev' into claude/spinning-up-book-skill-hhbjpy
dev moved: PR #994 landed engineering/deep-learning-book, which collides with
this branch on every headline-counter and registry surface.

Conflicts resolved in four files, keeping both sides' content:

- .claude-plugin/marketplace.json -- both plugin entries kept; the registry now
  carries spinning-up-deep-rl and deep-learning-book. 99 plugins.
- CHANGELOG.md -- both Unreleased sections kept.
- CLAUDE.md, README.md -- dev's prose taken as the newer baseline, then this
  branch's engineering-row entry restored and every counter re-derived rather
  than hand-picked from either side.

Counters re-derived from the merged tree with derive_counters.py, which is the
ground truth, and trued up across all five surfaces: 388 skills, 99 plugins,
727 tools, 842 references, 118 agents, 150 commands.

Both changelog/CLAUDE.md delta lines are restated: each side was written against
its own base and both claimed 386 -> 387, which is no longer true of either now
that they land together. This branch's entry is now stated as the delta on top of
deep-learning-book.

Gates re-run on the resolved merge: no conflict markers left in the tree,
compileall, check_plugin_json --all, check_skill_names, check_paths,
check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts
(696/696), derive_counters --check, book_skill_validator --strict, and a
JSON/YAML parse of every file touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UySnyf5upm4y8xhYA3w6yw
2026-08-25 22:49:14 +00:00
Claude
1a8d782872
feat(engineering): add deep-learning-book — companion skill for the free Goodfellow/Bengio/Courville textbook
Requested as "convert deeplearningbook.org into a skill". Built as a companion
rather than a compilation, because the repo's own rights gate forbids the latter
for a public plugin.

Why not book-to-skill: its emitter refuses a shareable package without
public-domain / open-license / internal-docs / author-permission, none of which
applies to an MIT Press title whose site states its HTML-only format exists as a
friction against copying under the authors' contract. Its rights reference lists
publishing a compiled skill of a copyrighted book to a public marketplace under
"Do not", and its hard rule 1 forbids scraping a book from the web, so the
pipeline could not have run against a URL either.

What shipped instead: the compiled-skill shape (master SKILL.md ~2.0k tokens with
chapter and topic indexes, chapters/ch01..ch20, glossary, patterns, cheatsheet)
filled with original synthesis and linking to the official free chapters. No
passages, figures, or per-paragraph paraphrase. Passes book-to-skill's own
book_skill_validator.py clean, with every file inside token_budget_estimator's caps.

The differentiator is the delta layer. A compilation freezes a source at its
publication date; this one dates it. Every chapter carries "What changed after
2016", and references/book_to_2026_delta.md gives five corrections with primary
citations and per-claim confidence levels: double descent qualifying Ch 5's
U-curve, AdamW splitting weight decay from L2, transformers displacing Ch 10's
recurrence, diffusion growing out of Ch 18's score matching, and self-supervised
learning vindicating Ch 15 while replacing its methods. Two claims are marked
contested rather than propagated, two named as folklore.

Four stdlib-only tools, each with a real refusal:
- reading_path_planner.py — prerequisite closure over the book's actual dependency
  graph; exit 3 for a goal the book does not cover, exit 4 with forcing questions
- training_diagnostics.py — Ch 11's rules in priority order, so a NaN is never
  reported as overfitting; exit 4 rather than diagnosing with no instruments
- capacity_planner.py — regularization ladder in cost order, "shrink the model"
  ranked last in the overparameterized regime; exit 4 on a val-below-train split
- model_arithmetic.py — params/FLOPs/activation memory for conv, linear, MHA and
  LSTM/GRU stacks; exit 5 naming the layer whose shapes do not connect

Also: 4 references citing 7-8 sources each, 3 assets, cs-deep-learning-tutor
agent, /cs:deep-learning + /cs:dl-reading-path + /cs:dl-diagnose.

Counters: skills 386 to 387, tools 723 to 727, refs 838 to 842, agents 116 to 117,
commands 146 to 149, plugins 97 to 98 (verified by derive_counters.py --check).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
2026-08-25 18:56:57 +00:00
Alireza Rezvani
800a0d5672
feat(engineering): compile OpenAI's Spinning Up in Deep RL into a knowledge-base plugin
Runs engineering/book-to-skill end to end on its first real source: OpenAI's
Spinning Up in Deep RL (MIT, (c) 2018 OpenAI; primarily developed by Joshua
Achiam). Cloned openai/spinningup and compiled its docs/ reStructuredText tree
(38 files, ~37k words, ~49K tokens) through the full pipeline -- extract
--mode technical, analysis, 20 chapter files, glossary/patterns/cheatsheet,
master SKILL.md, validator, plugin emitter.

The compiled skill passes book_skill_validator.py in --strict mode with every
file inside budget: a 2,101-token resident core (cap 4,000) plus 20 on-demand
chapters averaging ~1,256 tokens each.

Chapter structure follows the source's own toctree rather than a heading scan:
user documentation (ch01-06), Introduction to RL Parts 1-3 (ch07-09), the
researcher essay / key papers / exercises / benchmarks (ch10-13), one chapter
per algorithm in lineage order (ch14-19: VPG to TRPO to PPO, DDPG to TD3 and
SAC), and the logger/MPI/ExperimentGrid utilities (ch20).

Rights basis is open-license, not fair use -- the emitter's Step-11 gate
refuses a shareable package without one. Upstream's MIT notice is reproduced
in full in the plugin's LICENSE beside this package's own, and README.md names
the source, the author and the source's frozen version; a sidecar JSON is not
a license notice.

Also fixes a defect the emitter only reveals at its final step:
skill_plugin_emitter.py wrote its whole `source` provenance block into
plugin.json, on a stale inline claim that `source`/`attribution` were approved
extension fields. Claude Code rejects an entire manifest on any unrecognized
key (issue #954) and scripts/check_plugin_json.py hard-fails such a manifest,
so every package the emitter produced failed the blocking CI gate on commit.
_plugin_manifest() now emits spec fields only and a new _authoring_notes()
writes .claude-plugin/authoring-notes.json. Recorded as deviation 26 in
engineering/book-to-skill/README.md; the printed marketplace.json snippet is
unchanged, since `source` is a valid key there.

Counters: skills 386 -> 387, agents 116 -> 117, commands 146 -> 147, plugins
97 -> 98. Tools and references unchanged -- a compiled knowledge base ships
notes, not scripts.

All blocking CI gates verified locally: compileall, check_plugin_json --all,
check_skill_names, check_paths, check_frontmatter, check_dual_publish,
check_model_freshness, smoke_scripts (692/692), derive_counters --check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UySnyf5upm4y8xhYA3w6yw
2026-08-25 18:49:30 +00:00
Claude
645c523be1
feat(marketing): add linkedin plugin — organic presence with platform rules in code
Answers discussion #934, which asked for a strategic assistant for growing a
LinkedIn presence organically rather than a post generator.

Six skills under marketing/linkedin/: an orchestrator (context: fork) plus
profile, strategy, content, engagement, and analytics lanes. 17 stdlib-only
tools, 15 references, 2 agents, 8 /cs:* commands.

The design constraint is the differentiator: no LinkedIn credentials, no API
calls, no scraping, nothing auto-sent. Automated posting, connecting, and
commenting are prohibited by LinkedIn's User Agreement 8.2, and a restricted
account ends a compounding asset. linkedin_policy_gate.py runs before any
drafting and refuses seven request classes — automation, scraping, engagement
pods, bulk messaging, fake identity, fabricated proof, named third-party
automation platforms — each carrying the policy anchor and a compliant
substitute, so the gate never just says no.

Refusals are real rather than advisory. A cadence under 90 minutes a week
returns a comment-only plan instead of a schedule that dies in week five. A
newsletter whose six-month cost exceeds the budget is refused before the promise
is made. An experiment needing more posts than a quarter allows is reported
infeasible rather than quietly re-sized. The pattern miner refuses to test
anything below 10 posts and reports NOTHING_SURVIVED as a finding.

Evidence discipline: two widely repeated claims are corrected rather than
propagated. The "personalised note triples acceptance" claim is not supported by
the largest samples (acceptance is near-identical either way, ~26.4%); what a
note moves is the post-accept reply rate (~5.4% to ~9.4%), which is why the
message builder refuses an ask in a first-touch note. The ~19% in-body link
reach reduction has never been confirmed by LinkedIn as a penalty and has a
plausible dwell-time explanation, so it is a warning rather than a block. Every
reference carries per-claim confidence levels.

Accessibility is a blocking lint finding: Unicode pseudo-bold is announced by
screen readers as mathematical symbols and is not indexed by search.

All six SKILL.md files are 6/6 PASS on the write-a-skill checklist. Every tool
supports --help, --sample, and --output json with typed exit codes.

Counters: skills 380 -> 386; plugins 96 -> 97; tools 706 -> 723; refs 823 -> 838;
agents 114 -> 116; commands 138 -> 146 (derive_counters.py --check).

Also syncs three previously-merged skills (agent-memory, hivemind, skill-doctor)
into the .hermes/ and .vibe/ mirror trees, which had drifted behind .codex/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JSPxUHU6utqme7qC6EwHEh
2026-08-25 07:32:30 +00:00
Claude
4e93f8f66e
fix(docs): true two stale skill counts to 380 and bring them under the counter gate
Caught by review on the v2.12.0 promotion PR #985: README's Skills Overview
heading still said 370 and CLAUDE.md's footer Status line said 379 while the
banner/badges/scope line say the derived 380. Both wordings ('370 skills
across', '379 skills deployed across') were invisible to derive_counters.py's
claim patterns, which is why they could drift — reworded both into the
standardized '<N> production-ready skills across <D> domains' phrasing, made
extract_claims() validate every occurrence of a claim pattern instead of only
the first, and run_check() now reads CLAUDE.md's Status footer line alongside
Current Scope. Verified: planting 999/998 in the two lines fails the gate
naming both; restored values pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4
2026-08-24 21:06:20 +00:00
Claude
817b29c61f
fix(docs): sync agent/command counters in CLAUDE.md + marketplace.json to derived 114/138
PR #984's counter true-up bumped README badges and CHANGELOG to the derived
114 agents / 138 commands but left the CLAUDE.md Current Scope line and
marketplace.json metadata.description at the stale 111/131 (caught by review
on #984). derive_counters.py --check passed because CLAIM_PATTERNS had no
agents/commands patterns — added both (agents anchored on the "(cs-" suffix
so prose like "9 more coding agents" can't false-match), verified the new
gate fails on the pre-fix docs and passes post-fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4
2026-08-24 20:42:50 +00:00
Claude
d928ec95d5
release: v2.12.0 — consolidated release notes, version bump, docs-site regeneration
- CHANGELOG.md gains the [2.12.0] entry (first tagged release since v2.9.0):
  consolidates the previously documented but untagged v2.10.0-v2.11.2 work,
  all post-2.11.2 merges, and the full 17-issue triage sweep; the ten stacked
  [Unreleased] sections are demoted into the 2.12.0 body so the Release
  workflow tags and publishes the whole span. Verified parseable with
  scripts/extract_release_notes.py (version 2.12.0, 554-line body).
- Version markers bumped to 2.12.0: marketplace.json metadata,
  CLAUDE.md current-version header + footer.
- Counters trued to the derived values (380 skills / 96 plugins / 20 domains /
  706 tools / 823 refs / 114 agents / 138 commands) in README badges + prose,
  CLAUDE.md, marketplace.json, and the long-stale mkdocs.yml/docs/index.md
  site description (was still claiming 345/78/17).
- Docs site regenerated via scripts/generate-docs.py (568 generated pages;
  new pages for the recently merged plugins); codex/gemini mirrors resynced;
  mkdocs build verified locally with the same plugin set static.yml uses
  (670 HTML pages, no errors).
- Fix: the three hivemind worker personas (assets/agents/{coder,scout,tester}.md,
  merged via #979 while Actions was not triggering) lacked the frontmatter
  `name:` field and hard-failed the blocking G10 gate — named
  hive-coder/hive-scout/hive-tester; 645 files now scan with 0 errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4
2026-08-24 20:35:06 +00:00
Claude
d12e2586d0
fix(skill-doctor): address automated review — repo-match transparency, exact-id error dedup
- collect_sessions.py: name-only repo matches (worktree/basename fallback,
  which can match an unrelated same-named repo) are now recorded per session
  (repo_match), counted in inventory.json, called out in the summary, and
  excludable via a new --strict-repo flag
- score_aggregator.py: never-scored detection tracks session ids in a set
  instead of substring-matching error text, so a prefix-style id can no
  longer suppress another session's never-scored error
- redact_secrets(): broader patterns no longer stack markers on top of an
  already-redacted value
- session files read through the MAX_FILE_BYTES cap instead of slurped whole
- README deviations 21-22 recorded; count trued to 22 in CLAUDE.md and
  authoring-notes; prefix-id regression + single-marker redaction verified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017yFdbrdBnFL8Gw7DLrdg19
2026-08-24 20:03:06 +00:00
Claude
813740767c
merge dev (agent-memory) into skill-doctor branch: counters trued to 379/706/823/111/131/96
Resolved the three counter conflicts by taking dev's versions and re-applying
the skill-doctor additions: marketplace entry re-inserted, CLAUDE.md unreleased
section + scope/trailer lines, README badges + engineering row (90, now
mentioning skill-doctor). derive_counters --check passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017yFdbrdBnFL8Gw7DLrdg19
2026-08-24 18:57:27 +00:00
Claude
40f7025250
feat(engineering): rebuild warpdotdev skill-doctor as evidence-gated grading plugin
Rebuild of warpdotdev/common-skills' skill-doctor (MIT, pinned f3b58c81) as a
full engineering/ plugin: harvest local Claude Code + Codex sessions scoped to
one repo, judge condensed transcripts against the two verbatim-preserved
rubrics (labels only), then run a deterministic aggregation gate and render a
self-contained zero-JS HTML report. 20 numbered deviations recorded in the
plugin README (authoritative list).

- new score_aggregator.py gate: derives every number from the rubric label
  tables, rejects scores for unsampled sessions, length-checks reasons,
  refuses suggestions that cite no scored session or carry no diff (exit 4)
- collector hardening: always-on 12-pattern secret redaction with per-label
  counts, chmod 0700/0600 artifacts, plugin-layout skill discovery,
  slash-command usage detection; Warp sqlite/protobuf path dropped
- renderer replaced: pure-CSS diffs + native <details> collapse instead of a
  1,531-line prebuilt JS bundle; dark-mode, print-to-PDF; vendor CTA removed
- cs-skill-doctor agent, /cs:skill-doctor command, 3 references citing 7
  sources each, 3 handoff-shape assets; SKILL.md 6/6 PASS on write-a-skill
- counters trued: skills 378, tools 698, refs 820, agents 110, commands 130,
  plugins 95 (derive_counters --check passing)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017yFdbrdBnFL8Gw7DLrdg19
2026-08-24 18:54:08 +00:00
Claude
2e59fe9873
Merge remote-tracking branch 'origin/dev' into claude/tencent-agent-memory-diy7p7
# Conflicts:
#	.gitignore
#	CLAUDE.md
2026-08-24 18:23:59 +00:00
Claude
a3b6a195cb
feat(agent-memory): implement the four-tier memory ladder
Turns DESIGN.md from a spec into a working plugin. Five stdlib scripts, three
hooks, agent, command, three references, plugin manifests.

The gates are the design:
  L1 -> L2  >= 3 distinct sessions spanning >= 2 distinct calendar days
            (`stated` = 2 sessions, day rule still applies; `verified` = 1
            observation and is the only day-exempt path)
  L2 -> L3  >= 2 distinct projects, >= 30 days, uncontested

Two gates refuse rather than guess. `redacted: true` blocks promotion on any
volume of evidence -- a durability-independent barrier, since a secret restated
across five sessions passes every recurrence gate; the flag firing means the
text was altered, a lexical filter finding one secret is not proof it found all
of them, and L2/L3 are committed to git. An open contradiction freezes both
claims, found by reverse join because the newer atom carries no flag.

All three hooks fail open: a broken memory system costs memory, never a session.
SessionEnd stages promotions to .memory/staged/ and never touches a CLAUDE.md;
only an explicit human adopt does, after backing both files up.

Verified, not asserted:
  - all three pinned atom ids from DESIGN.md reproduce exactly
  - both blocking gates demonstrated on sample input, named in the output
  - end-to-end: two transcripts across two calendar days -> merged L1 atom ->
    staged L2 promotion with the path prefix stripped
  - reverse join blocks the unflagged newer atom
  - cross-tier L2/L3 collision marked at injection time
  - recall p50 29ms / p95 31ms / max 35ms spawn-to-exit, scoring itself 2-3ms
    over 500 atoms -- interpreter cold start is the entire cost
  - validate_examples.py 69 checks 0 failures; SKILL.md 6/6 PASS
  - derive_counters --check, check_plugin_json --all, check_paths all clean

DESIGN.md 10.1's "+6" tool estimate corrected to +8 -- the delivered surface is
5 scripts + 3 hooks. README.md's deviations list is authoritative for that and
five other divergences from the pre-implementation spec.

Concept from TencentCloud/TencentDB-Agent-Memory (MIT). No upstream code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EM5xmJ7AmTMg31rq68BCym
2026-08-24 18:23:01 +00:00
Claude
debda44029
docs: address PR #980 review — wire agent-launcher into root CLAUDE.md, fix dangling report pointer, align version strings
- root CLAUDE.md: Navigation Map row, Repository Structure tree line, and an
  'Unreleased (post-v2.11.2, PR #961 merged)' narrative for the agent-launcher
  domain (grep previously returned zero mentions)
- CHANGELOG: the verification sentence no longer points at
  agent-launcher/DELIVERY-REPORT.md — per the maintainer finish-plan
  (audit/pr-stream-2026-08) that report moved to gitignored documentation/;
  SPEC.md remains the public build target
- sync scripts: v2.12 comment/description strings -> 'unreleased, post-v2.11.2'
  to match the normalized plugin version; codex index regenerated

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012FwXG6TqCXKZQvF4iD69cv
2026-08-24 17:37:51 +00:00
Claude
3e29c960fa
merge dev into agent-launcher branch: counters trued to 377/695/817/94, D1 sidecar move, models pinned to claude-opus-5, references topped up
- Conflict resolution takes dev's counter surfaces and re-applies the
  agent-launcher marketplace entry (description trimmed to 950 chars for the
  new <=1024 guard) and README domain row
- plugin.json source/attribution moved verbatim to authoring-notes.json per
  the post-#954 schema dev now enforces; version aligned to 2.11.2
- claude-opus-4-8 (retired, G7-blocking since #938) pinned to claude-opus-5
  across 5 scripts + example build sheet; all touched scripts re-smoke-tested
- 4 references topped up with external sources (7-8 each)
- DELIVERY-REPORT.md removed from the public tree (sprint artifact; content
  preserved in PR #961 body and git history) — SPEC.md stays as build target
- Gates green: derive_counters --check pass, plugin-json 94 OK + marketplace
  guard OK, frontmatter 0 errors, model freshness 0 findings, smoke 0 failed,
  hooks exit 0 with and without AGENT_LAUNCHER_SESSION

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Bzm6Pafyxja6g4jUDPcei
2026-08-21 09:11:08 +00:00
Claude
fbc3cdc3f7
merge dev into human-gate branch: resolve counter surfaces, move attribution to authoring-notes.json sidecar (issue #954 policy), true up counters to 371/675/812/93
Conflict resolution takes dev's counter surfaces and re-applies the
human-gate additions on top (marketplace entry, README engineering-row
highlight). plugin.json extension keys (source/attribution) relocated
verbatim to .claude-plugin/authoring-notes.json per the post-#954 schema
that dev's check_plugin_json.py now enforces. All gates re-run green:
derive_counters --check pass, plugin-json 0 FAIL, frontmatter 0 errors;
human-gate scripts re-verified (--help x3, --sample, base-void-tag
regression fixture, G1 close-refusal exit 2, no network imports).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Bzm6Pafyxja6g4jUDPcei
2026-08-21 09:04:37 +00:00
Claude
08740d4ec2
fix(stream): post-merge required changes for PRs #895/#926/#942/#943/#944/#965 + counter true-up + #964 guard + #954 doc drift
Applies every pre-merge required change from audit/pr-stream-2026-08/ that
could not land on contributor forks, plus the stream's cross-cutting fixes:

- stock-analysis (#944): description trimmed 1463 -> 1001 chars; Anti-Patterns
  + Cross-References sections added; security-auditor false positive at
  holdco-assetmgr.md:58 suppressed inline (auditor:ignore-line) -> strict PASS
- deepread (#965): renamed research/dsh-deepread -> research/deepread; H1 and
  name updated; research-summarizer cross-ref path-qualified; 12 cited sources
  added across both references; plugin.json + marketplace entry; routed in the
  research orchestrator (SKILL.md registry + SIGNALS + classifier.py in
  lockstep, verified: 'deeply read this pdf' -> deepread, 3 signals)
- business-name-fit (#926): 'Use whenever' -> 'Use when' (validator trigger
  regex); +2 cited sources (USPTO TMEP §1209, Usunier & Shaner 2002) -> 5
- embedded-iot-mentor (#942): references/hardware-selection.md (7 sources,
  datasheet-anchored) + worked mini-example; validator length gate now passes
- swedish-mentor (#943): references/swedish-resources.md (6 sources, stable
  official URLs only); session recipes, milestones, learner situations,
  worked example; mandated opener softened to guidance; plugin.json +
  marketplace entry; validator length gate now passes
- Related Projects (#895): LinkedIn Skills row trued up (10 -> 11 skills,
  hardcoded star count dropped)
- check_plugin_json.py: marketplace description <= 1024 guard added to --all
  (the #964 regression guard; commercial-skills sits at 1021/1024)
- #954 doc drift: quality_gates_for_skills.md, cs-skill-author.md,
  security-guidance SKILL.md now point attribution at authoring-notes.json
- Counter true-up after the 6-skill merge batch: 370 skills / 672 tools /
  809 refs / 92 plugins across README.md badge+table, CLAUDE.md, marketplace
  metadata (derive_counters.py --check passes)

All gates green locally: frontmatter 0 errors, model freshness 0 findings,
dual-publish 0 drifted, paths 0, smoke 0 failed, plugin-json 0 FAIL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Bzm6Pafyxja6g4jUDPcei
2026-08-21 09:01:24 +00:00
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
d1f2396c6f
feat(agent-launcher): new domain plugin for building Claude Managed Agents
Adds the agent-launcher/ top-level domain — a plugin re-implementation of
Anthropic's launch-your-agent reference skill (Apache-2.0; independent, not a
fork) for building Claude Managed Agents (CMA) in the user's own account.

Every session starts with a goal (./my-agent/goal.json, surfaced by an opt-in
AGENT_LAUNCHER_SESSION=1 SessionStart hook + /cs:goal); loop_compiler.py
compiles that goal into a bounded grade->iterate loop (CMA user.define_outcome
self-grading, max_iterations 1..20), a recurring POSIX-cron scheduled-deployment
loop, or a single-pass interview->stage->launch workflow.

- 6 skills: agent-launcher-orchestrator (context: fork goal router) + interview
  + stage-launch + grade-iterate + run-without-you + wrap-up
- 18 stdlib-only deterministic scaffolder tools (NO network/API calls; live
  launches emitted as BYOK curl that never prints the key); all pass --help/--sample
- 4 agents (orchestrator + interviewer + grader + deployer), 8 /cs:* commands
- opt-in SessionStart/SessionEnd hooks (exit 0 on any error), 5 shared
  references, 4 assets (build-sheet schema + overview/next-directions templates
  + example)
- validators enforce CMA limits (<=20 skills/session, <=8 memory stores,
  depth-1 multiagent, max_iterations <=20, <=1000 deployments/org)
- registered in marketplace.json; headline counters trued up via
  derive_counters.py --check (skills 362->368, domains 18->19, tools 644->664,
  refs 741->746, agents 102->106, commands 116->124, plugins 88->89)

Distinct from engineering/agent-harness (generic bounded loop over any domain)
and engineering/write-a-skill (authors Claude Code skills, not CMAs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012FwXG6TqCXKZQvF4iD69cv
2026-08-17 02:39:34 +00:00
Claude
a21206ea33
Merge branch 'dev' into claude/humanizer-skill-audit-plugin-hocj85
book-to-skill landed in dev while this branch was open. All four conflicts were
counter/registry collisions in the shared headline files — resolved by taking
dev's side, then re-deriving from the tree so both plugins are counted:

  skills 363 -> 364 · tools 663 -> 666 · refs 746 -> 749
  agents 103 -> 104 · commands 118 -> 119 · plugins 89 -> 90
  README engineering row 85 -> 86

Also fixed two merge artifacts: the README engineering row lost its human-gate
mention (dev edited the same row for book-to-skill), and the both-sides CHANGELOG
resolution left an orphaned duplicate fable-goal header at the seam — dev had
retitled the real entry "(previous PR)".

Verified after merge: derive_counters --check passes, check_plugin_json --all 90/90
OK, human-gate 6/6 on the write-a-skill checklist, all three scripts --sample green,
no conflict markers left in the tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01233Eggb2cjSYf96X6C3pCm
2026-08-09 05:21:20 +00:00
Claude
d4d83338c1
feat(engineering): add human-gate — batched human review as a verification artifact
Audits petergyang/human-review and ships a conceptual derivation that fits this
repo's stdlib-only conventions.

Audit (audit/human-review-2026-08/AUDIT.md): upstream is a well-engineered ~5,200
LOC Node app — its own test suite passes 90/90, and its security model (loopback
bind, DNS-rebinding Host check, constant-time token compare, realpath traversal
guard, inert Markdown renderer, 45-min idle shutdown) is better than most
local-server tools. It still does not fit: Node 20 + an npm runtime dependency
fails the same stdlib-only test that kept the heavier skillopt package out in
v2.11.2. Seven findings, three material — F1 (HIGH) unpinned `npx -y` executes a
newly published version on every run; F2 (MED) "do not end your turn" plus
re-poll on timeout with no headless guard or retry cap; F3 (MED) only /api/* is
token-gated.

Also: despite the name it is not a humanizer. This is human approval, not human
voice — no overlap with behuman or content-humanizer.

New plugin engineering/human-gate, three stdlib scripts, no server or socket:

- review_page_builder.py — Markdown/HTML to a single-file anchored review page
  with zero network requests (~11 KB, opens over file://). Escapes before
  applying inline markup, scheme-allowlists hrefs, drops script/style on HTML
  input.
- feedback_parser.py — sidecar to batch.v1 JSON. BLOCKER/MAJOR/MINOR/NIT
  (matching md-review) plus EDIT/NOTE/APPROVE. Verifies quotes against the real
  file; strips HTML comments so a documented example cannot parse as a real
  sign-off.
- human_gate.py — open/status/collect/close/reset with atomic writes and
  0700/0600 state. Rules G1-G6 refuse to close on: no collected round, an open
  BLOCKER/MAJOR, an unnamed reviewer, a sidecar changed after collection, an
  exhausted round cap (exit 5 = escalate), or an undocumented waiver.

Loop discipline deliberately inverts upstream: no blocking poll, a headless
guard, a round cap that escalates. The sidecar is hand-writable Markdown, so the
loop closes over SSH and in CI. The optional bridge to upstream is opt-in and
always version-pinned.

Adds 3 references (7-8 sources each), a batch.v1 schema, a worked example,
cs-human-gate agent, /cs:human-gate command. SKILL.md passes the write-a-skill
6-item checklist 6/6; description validator PASS.

Counters: skills 362->363, tools 644->647, refs 741->744, agents 102->103,
commands 116->117, plugins 88->89.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01233Eggb2cjSYf96X6C3pCm
2026-08-09 05:12:33 +00:00
Claude
83f53eec15
merge: resolve dev conflicts after book-to-skill landed
dev moved 8 commits ahead (engineering/book-to-skill), and both branches
touched the same three headline-counter files, so marketplace.json, CLAUDE.md
and README.md all conflicted.

Resolved by taking dev's version of each file wholesale, then re-applying this
branch's additions on top — rather than hand-merging the counter arithmetic,
which is exactly the kind of edit that silently drifts:

- marketplace.json: re-inserted the memory-engineering entry next to
  agent-harness (dev's 89 plugins -> 90)
- CLAUDE.md: re-applied the memory-engineering release note above the
  fable-goal note
- README.md: engineering-POWERFUL row 85 -> 86 plus the plugin mention

Then re-derived every headline number from the merged tree instead of
assuming my original deltas still held — they did not, since book-to-skill
had already consumed them. True values are now skills 364, tools 667, refs
750, agents 104, commands 120, plugins 90. The release note's own delta line
was rewritten to sit on top of book-to-skill rather than claiming the stale
362->363 range.

Verified on the merged tree: all six blocking gates pass (check_plugin_json,
check_paths, check_dual_publish, smoke_scripts, smoke_json_output,
derive_counters --check), compileall clean, skill checklist still 6/6 PASS,
no conflict markers remain.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt1sqt5kQmopyfXu2Hhjnv
2026-08-09 04:45:49 +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
Claude
3fa59a566f
fix(book-to-skill): close the workdir race with fd pinning
Addresses the residual TOCTOU raised in the fourth review. The reviewer called
it non-blocking; it verified as slightly worse than described, and the fix is
small, so it is closed rather than deferred.

The claim checks out: `mkdir(parents=True, exist_ok=True)` does NOT raise on a
symlink-to-directory, because its exists-branch tests `is_dir()`, which follows
symlinks. Demonstrated directly — mkdir succeeded silently on a planted link and
a subsequent write landed in the attacker's directory.

What the review did not note is why the second layer failed to catch it: a file
inside a swapped directory is an ordinary file, not a symlink, so
`_write_private`'s `is_symlink()` check could never see a directory swap. The
artifact-level guard did not back up the directory-level one at all.

Three changes:

- `resolve_workdir()` attempts `mkdir` FIRST and only inspects a path that
  already existed, via `os.lstat` — which does not follow the final component.
  That removes the check-then-create ordering.
- `open_workdir()` pins the directory with `O_NOFOLLOW|O_DIRECTORY`, and both
  artifacts are written through that descriptor. An fd names an inode, so a
  rename or symlink swap of the path afterwards cannot redirect the write.
- `_write_private()` creates with `O_CREAT|O_EXCL|O_NOFOLLOW` at mode 0600 —
  no check-then-act window at all. An artifact from a previous run into the same
  --workdir is unlinked first; unlink removes the link, never its target.

Verified against a live race: pin the directory, rename it away, plant a symlink
to an attacker directory, then write — data lands in the pinned inode, attacker
directory stays empty. Also verified a pre-planted `full_text.txt -> victim`
symlink leaves the victim's content intact and is replaced by a 0600 file we own,
and that re-running into the same --workdir still succeeds.

Degrades to the previous path-based checks where `dir_fd`/`O_NOFOLLOW` are
unavailable (Windows).

Recorded as deviation 25. Full regression re-run: EPUB bomb, EPUB entity,
extensionless sniff bomb, DOCX bomb, emitter symlink, rights gate and the
estimator path check all still refuse; a clean EPUB still extracts. All gates
green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 08:17:16 +00:00
Claude
b6a1687ce3
fix(book-to-skill): skill-quality audit — runnable docs, honest gates
Read the skill as a skill rather than as code, which the previous three review
rounds had not done. Four findings, all now fixed and verified.

1. The documented quick-start did not run. SKILL.md's copy-paste block referenced
   $WORKDIR and $SKILLS_HOME without ever assigning them, so following it
   literally produced a FileNotFoundError traceback at step 2. Both are now real
   assignments, and all five steps were executed verbatim end to end as a check.
   The plugin README's block had the same defect and is fixed the same way. A
   quick-start that does not run is the worst kind of doc bug: it is the part a
   reader trusts most.

2. A gate tool reported success for a path that was not there.
   `token_budget_estimator.py --skill-dir <typo>` produced a complete,
   plausible-looking budget audit — every row "missing", every cap satisfied,
   exit 0 — which reads as a pass. It now refuses a missing directory, a
   non-directory, and a directory with no SKILL.md (exit 2). `--full-text
   <missing>` raised a bare traceback and now refuses cleanly. The other three
   tools already validated their inputs; this one was the outlier.

3. Three upstream artifacts cleaned, one of them load-bearing. epub.py's
   `except (KeyError, Exception)` is simply `except Exception` — it swallowed
   everything including the size refusal `safe_read()` now raises, quietly
   disarming deviation 17 at that call site. Narrowed so ExtractionError
   propagates and only genuine parse failures fall through to the .opf glob.
   utils.py emitted a dynamic {pages_label: pages} key beside a literal "pages",
   colliding whenever the label was "pages"; the alias is now conditional. A
   stray artifact word removed from a pdf.py comment.

4. `tool | head` no longer tracebacks. Observed once on the emitter (racy on
   flush timing, 0/20 on retry) — all four CLIs now exit 141 quietly, the
   standard SIGPIPE convention.

Token cost re-measured: SKILL.md 2,256 tokens resident (229 lines), references
10,216 on demand. Healthy against the ~5k practical ceiling for a resident body.

Full security regression re-run after the changes: EPUB bomb, EPUB entity,
extensionless sniff bomb, DOCX bomb, planted workdir symlink, emitter symlink
and the rights gate all still refuse; a clean EPUB still extracts.

Recorded as deviations 21-24; count synced across plugin.json, CLAUDE.md and
CHANGELOG. All gates green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 08:07:42 +00:00
Claude
058447e4a6
fix(book-to-skill): route the sniff path through the zip budget; emitter fixes
Addresses the third automated review on PR #941.

[High] The magic-byte sniffing path bypassed the zip-bomb budget it was built
to enforce. extract_single_file() reads a `mimetype` member with a bare
zf.read() when the extension is unrecognized — the earliest attacker-controlled
point in the pipeline, running before a format is chosen and before any check in
zip_safety.py. zip_safety.py's own docstring claims "every read goes through
safe_read()"; this one did not, which makes it a documentation defect as much as
a security one. Now routed through safe_read(). Its ExtractionError sits outside
the surrounding except tuple on purpose, so a bomb reports as a bomb rather than
as a generic unsupported format.
Verified: a 200 MB / 1029x fixture with no file extension is refused at ~15 MB
peak RSS instead of being decompressed.

[Medium] --author / --author-url never reached the printed marketplace entry.
_plugin_manifest() threaded them correctly into the emitted plugin.json, but
_marketplace_entry() took no author parameter and hardcoded one name — so the
snippet whose entire purpose is preventing hand-edit mistakes contradicted the
manifest sitting next to it for anyone but the default author. Threaded through.
Verified: --author "Jane Doe" now appears in both.

[Low] Narrow TOCTOU between _assert_no_symlinks() and copytree. copytree already
runs with symlinks=True, so a link planted in that window is copied as a link
rather than dereferenced — no content leak. Now fully closed: the emitted tree
is re-walked after the copy, and the package is deleted rather than shipped if
any link appeared.
Verified with a monkeypatched guard that plants a symlink immediately after the
check passes: refused, package removed, secret content absent.

[Nit] plugin.json asserted "license": "MIT" unconditionally, with the "MIT
covers the converter, not the compiled content" caveat living only in README
prose. Added source.license_scope stating it in the manifest, so a tool reading
only the manifest sees the distinction, plus a code comment at the assignment.

Recorded as deviations 19 and 20; count synced across plugin.json, CLAUDE.md
and CHANGELOG.

All gates green: compileall, check_paths --all, check_dual_publish,
smoke_scripts (0 failed), derive_counters --check, check_plugin_json --all
(0 FAIL). All four CLIs pass --help / --sample.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 07:45:03 +00:00
Claude
9ed709aef3
fix(book-to-skill): guard EPUB XML, cap zip expansion, refuse symlinked trees
Addresses the second automated review on PR #941. All three code findings
verified against the actual behaviour, not just patched.

[Medium] shutil.copytree dereferenced symlinks the validator never saw. The
validator checks SKILL.md, the three supporting files and chapters/*.md; the
copy then followed a link anywhere else in the tree (assets/, any subdirectory)
and baked the target's real content into a package that can go out as
--distribution shareable. _assert_no_symlinks() now walks the whole tree and
refuses, and runs BEFORE the validation branch so --skip-validation cannot
bypass it. copytree also passes symlinks=True so loosening that check later
cannot silently reintroduce dereferencing.
Verified: a symlink in assets/ pointing at a secret file is refused both with
and without --skip-validation, the secret never lands in a package, and a clean
tree still emits.

[Medium] The DOCX XXE/entity guard did not extend to EPUB's ebooklib path.
Upstream hardened DOCX only. EPUB is the same zip-of-XML shape and ebooklib —
one of the packages this skill recommends installing — parsed container.xml,
the OPF and content docs with no equivalent pre-check. The guard moved to a new
book_to_skill/zip_safety.py and now runs for both formats.
Verified: an EPUB whose OPF declares an entity is refused; a clean EPUB still
extracts and detects its chapter.

[Low] No size cap before decompressing zip members. Every archive read now goes
through safe_read(), which checks the declared uncompressed size and the
compression ratio against the central directory before decompressing, and
charges actual bytes against a per-archive budget so a lying directory cannot
get past it either.
Verified: a 200 MB / 1029x bomb is refused at ~14 MB peak RSS instead of being
materialized.

[Low] The PR body's "12 numbered items" was stale against README's list. Fixed
in the PR description; the in-repo count is synced to 18 across plugin.json,
CLAUDE.md and CHANGELOG.

Recorded as deviations 17 and 18. Counters: tools 662 -> 663 (zip_safety.py);
that module is allowlisted in smoke_exceptions.txt like its siblings.

All gates green: compileall, check_paths --all, check_dual_publish,
smoke_scripts (0 failed), derive_counters --check, check_plugin_json --all
(0 FAIL). Security auditor unchanged at 0 critical / 4 high.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 07:31:04 +00:00
Claude
b5031e976e
fix(book-to-skill): private per-invocation workdir; share budget constants
Addresses the automated review on PR #941.

Security (the one item flagged as wanted-before-merge): upstream defaults the
extraction workdir to a fixed `<tempdir>/book_skill_work`. On a shared host that
is CWE-377/CWE-59 — any local user can pre-create the directory in a
world-writable /tmp (the sticky bit prevents deletion, not creation) and plant a
symlink named full_text.txt or metadata.json pointing at a file the victim can
write, because Path.write_text follows symlinks. Two concurrent runs also
silently clobber each other.

- Default workdir is now a fresh `tempfile.mkdtemp(prefix="book_skill_work_")`:
  unpredictable name, 0700 by construction, never shared with a concurrent run.
  The path is printed and carried in metadata.json's `output_text`.
- Artifacts are written 0600, and each write refuses a symlink at the target.
- An explicit --workdir / BOOK_SKILL_WORKDIR is still honoured, but is
  symlink-refused, created 0700, and chmod-tightened if it already exists.
- parsers/calibre.py no longer writes its ebook-convert scratch file to the
  shared directory. That also fixes a real bug the review did not name: it read
  a module-level OUTPUT_DIR constant, so the scratch file ignored --workdir
  entirely and escaped the directory the caller asked for.

Verified: default workdir 0700 with 0600 artifacts and a per-invocation name;
two runs get distinct directories; a 777 --workdir is tightened to 700; a
symlinked workdir is refused; and a planted `full_text.txt -> victim` symlink is
refused with the victim file left untouched.

Also from the review:
- book_skill_validator.py and token_budget_estimator.py restated the same
  BUDGETS dict. Both now import SKILL_FILE_BUDGETS / CHAPTER_TOKEN_CEILING from
  book_to_skill/config.py so the two gating tools cannot drift.
- Corrected the smoke_exceptions.txt rationale: the list is "modules the G8
  probe trips on", not "modules that aren't CLIs". config.py, exceptions.py,
  sanitize.py, parsers/__init__.py, parsers/pdf.py and parsers/text.py are
  equally not CLIs and pass only because they have no argv handling.

Recorded as deviations 15 and 16; count synced in plugin.json, CLAUDE.md and
CHANGELOG. Docs updated: the workdir path is now read from the tool's output
rather than hardcoded.

All gates green: compileall, check_paths --all, check_dual_publish,
smoke_scripts (0 failed), derive_counters --check, check_plugin_json --all
(0 FAIL). Security auditor unchanged at 0 critical / 4 high (documented).
End-to-end pipeline re-run clean: extract -> verdict -> validate -> emit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 07:14:57 +00:00
Claude
4f5a6825f2
fix(book-to-skill): satisfy CI path, smoke, and stdlib-shadowing gates
CI gate G1 (check_paths.py) failed: the agent's tool table referenced
`scripts/<tool>.py`, which resolves relative to the agent's own folder, not the
skill's. Now uses `../skills/book-to-skill/scripts/...` like cs-skill-author.

Two more issues found running the full gate set locally:

- Renamed `parsers/html.py` -> `parsers/html_text.py`. A module named `html.py`
  shadows the stdlib `html` package whenever its own directory lands on
  sys.path[0], and `import html.parser` then fails with "'html' is not a
  package". Renaming removes the hazard rather than documenting it; two import
  lines changed. Verified: HTML extraction still detects chapters, emits block
  boundaries, and tab-joins table cells.
- Registered the eight vendored library modules in scripts/smoke_exceptions.txt.
  They are imported as `book_to_skill.*`, never run as CLIs, so gate G8's
  `--help` probe can only ever fail on them. The four real entry points are
  smoke-tested normally and pass.

Recorded as deviations 13 and 14 in the plugin README; count synced in
plugin.json, CLAUDE.md and CHANGELOG.

All blocking gates green locally: compileall, check_plugin_json --all (89 OK),
check_paths --all (0 findings), check_dual_publish (0 drift), smoke_scripts
(0 failed), derive_counters --check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 07:05:54 +00:00
Claude
b19c40cf95
feat(engineering): add book-to-skill — compile documents into knowledge-base skills
Derived from virgiliojr94/book-to-skill (MIT). Compiles a book, docs folder, or
spec collection (PDF, EPUB, DOCX, HTML, Markdown, RST, AsciiDoc, RTF, MOBI/AZW)
into an agent skill: a resident master SKILL.md (core frameworks + chapter index
+ topic index, capped at 4k tokens) plus on-demand chapter files, a glossary, a
patterns file, and a decision cheatsheet.

The extraction library (scripts/book_to_skill/, 12 modules incl. 7 per-format
parsers) is vendored close to verbatim and keeps upstream's format chains,
chapter detection across Latin/Roman/Chinese/Thai/Korean heading styles,
invisible-Unicode (Trojan Source) sanitization, and the DOCX entity guard.

12 numbered deviations recorded in the plugin README (authoritative list):

- No implicit installs: --install-missing defaults to `report`, printing the pip
  command and using the stdlib fallback, where upstream prompts on a TTY and
  installs into the caller's environment.
- Rights gate: emitting a shareable package refuses without --rights from
  public-domain|open-license|internal-docs|author-permission. `fair-use` is
  deliberately excluded — a defence, not a licence.
- Validator merged and extended: upstream's two validators become one four-family
  gate, adding budget (token caps) and index (dead chapter links, unindexed
  chapters, dangling topic refs) — the failure that silently breaks navigation
  while the skill still looks complete.
- Folded YAML scalars now parse, so a wrapped description no longer under-reports
  its length past the 1024-char cap.
- token_budget_estimator replaces discovery_tax: tiktoken path dropped for one
  deterministic estimator, post-flight budget audit added, plus an explicit
  worth-converting verdict that says "just read it" below ~3x the compiled size.
- Two PRIV-ESC criticals fixed: upstream install hints contained a literal
  `sudo apt install`; they now name the package manager without escalating.

Repo-native addition with no upstream counterpart — Step 11 / /cs:book-to-plugin:
upstream stops at a bare ~/.claude/skills folder this library cannot route to.
skill_plugin_emitter.py wraps a compiled skill as a full plugin package (manifest
+ cs-<slug> agent + /cs:<slug> command + README) and prints the marketplace entry
without editing marketplace.json. Its --force path is guarded against symlinks,
paths outside the destination root, and non-package directories.

Ships 4 stdlib-only tools (all --help/--sample/--output json), 5 references citing
7-8 sources each, 3 asset templates, cs-book-to-skill agent, 2 commands.
Cross-linked into write-a-skill ("author first, compile second").

Regenerated the engineering harness manifest: picked up book-to-skill plus three
skills that had drifted out (minimalist, skillopt-sleep, strict-api), 81 -> 85.

Counters: skills 362 -> 363, tools 644 -> 662, refs 741 -> 746, agents 102 -> 103,
commands 116 -> 118, plugins 88 -> 89 (derive_counters.py --check passes).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017zu9Gmm9S78c2t3kDLnpPX
2026-08-05 07:01:23 +00:00
Claude
7a1c351281
feat(marketplace): register weekly-review, deep-work, meetings plugins + counter true-up
- 3 new marketplace entries (85 -> 88 plugins)
- Headline counters trued up via derive_counters.py: 362 skills, 644
  Python tools, 741 references, 102 agents, 116 commands (also clears
  the counter drift inherited from the branch base)
- Productivity harness manifest regenerated (11 skills)
- CLAUDE.md unreleased-changes note + footer refresh

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQLKzYb1bR2LYqwYUupm5f
2026-07-17 06:16:15 +00:00
Claude
eddbb03451
Merge origin/dev into skillopt-sleep branch, reconcile counters
Resolves conflicts in CLAUDE.md, README.md, and marketplace.json between
this branch's v2.11.2 skillopt-sleep vendoring and dev's productivity/fable-goal
addition — both narratives are kept, ordered by landing time. Headline
counters (skills/tools/refs/agents/commands/plugins) re-derived from the
merged tree via scripts/derive_counters.py and brought back into agreement
across all three files (--check now passes).
2026-07-17 06:04:03 +00:00
Claude
e3a6940902
docs: fable-goal CLAUDE.md changelog entry + destination-regex tighten
- CLAUDE.md gains an 'Unreleased (post-v2.11.1)' narrative block for
  fable-goal so the changelog-of-record covers the addition without
  inventing a release version (review round 5 ask; counters in arrow
  form to stay clear of derive_counters claim regexes — check passes)
- goal_prompt_self_check.py destination pattern now matches 'the N
  links' phrasing ('the \d*\s*links?'); --sample still 6/6, verified
  'the 3 links' now matches standalone

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYh4KrhicuBaS5nRtBeLXK
2026-07-16 06:48:46 +00:00
Claude
e84a53e824
feat(productivity): fable-goal — add goal_prompt_self_check.py per review
Two independent reviews flagged the missing scripts/ folder against the
productivity-domain convention and the repo's 'Algorithm over AI'
principle. Adds one stdlib tool, goal_prompt_self_check.py, which
mechanically verifies the checkable subset of the SKILL.md step-5
self-check on a drafted /goal prompt: word count in the 150-350 band,
goal line, autonomy directive, verification-loop language,
creative-freedom grant, and delivery destination. Exit 0/1/2; --sample
and --output json supported; judgment calls (deliverable concreteness,
resource verification) explicitly stay with the author.

Smoke-verified: --help OK, --sample passes 6/6, degenerate prompt fails
0/6 with exit 1. SKILL.md references the runner in step 5 (79 lines,
checklist still full PASS). agents/ and assets/ remain intentionally
omitted: a single reasoning pass has nothing to orchestrate and no
templates to ship. Counters: python_tools 602 -> 603.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYh4KrhicuBaS5nRtBeLXK
2026-07-16 06:38:25 +00:00
Claude
fc6177d063
feat(productivity): add fable-goal skill — ramble to autonomous /goal prompt
Improved port of duncan-buildroom/freeskills fable-goal ('free to use and
modify'). Converts a rambling description of a desired outcome into one
polished, copy-paste /goal prompt for a fresh autonomous session.

Improvements over upstream:
- Wrong-tool check (build-now vs write-the-prompt) promoted into the body
- Observable-done principle: every deliverable gets a self-checkable
  completion condition
- Six-slot extraction (deliverable/quantity/stakes/tools/quality/destination)
- Per-medium verification defaults (web, CLI, video, written, data, design)
- Six-point pre-delivery self-check
- Anti-pattern list + failure-mode catalog reference with rationale per
  anatomy part
- Second worked example in a non-web medium (CLI with dry-run verification)
- /cs:fable-goal command; attribution block in plugin.json

SKILL.md passes the write-a-skill 6-item checklist (full PASS, 77 lines).
Counters trued up via scripts/derive_counters.py (includes pre-existing
engineering drift 81→83): skills 355→358, refs 731→732, commands 109→110,
plugins 83→84.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YYh4KrhicuBaS5nRtBeLXK
2026-07-16 06:21:15 +00:00
Claude
7eb198ff42
fix(engineering): require --yes for schedule + close mkdir/chmod race (round-10)
A tenth review pass, after confirming all nine prior rounds of fixes
hold up under independent re-reading, found two more low-severity
gaps and offered to accept a follow-up -- fixed both now for
consistency with how every prior round's findings were handled:

1. schedule had no confirmation gate at the CLI layer. The "confirm
   with the user before schedule" safeguard (deviation #15) lived only
   in commands/skillopt-sleep.md's agent-facing instructions --
   cmd_schedule() called scheduler.schedule() directly and installed a
   real crontab entry immediately. Fine for the documented Claude Code
   agent workflow (which confirms in chat first), but anyone invoking
   `python -m skillopt_sleep schedule` directly bypassed it entirely.
   Fixed: schedule now requires --yes; an interactive terminal without
   it gets a [y/N] prompt, a non-interactive one refuses outright
   (exit 2) pointing at --yes. commands/skillopt-sleep.md updated so
   the driving agent passes --yes once it has confirmed with the user
   in chat -- that's what --yes records, not a redundant re-prompt
   that would hang forever with no TTY inside a non-interactive Bash
   tool call.

2. mkdir-then-chmod wasn't atomic in write_staging()/SleepState.save(),
   leaving a brief window where a freshly-created sensitive directory
   sat at the process's default umask. Fixed: the os.makedirs() calls
   creating the state dir, staging leaf dir, and backup dir now pass
   mode=0o700 directly, on top of (not instead of) the existing
   post-creation chmod calls, which still matter for intermediate
   parent dirs and pre-existing directories that mode= doesn't cover.
   The equivalent race for individual files was judged a larger
   rewrite (every open() call site would need os.open() with an
   explicit mode) than this specific low-severity finding warranted --
   documented as a known, narrower residual gap rather than silently
   claimed as fully closed.

Verified: non-interactive schedule without --yes refuses with exit 2,
with --yes it proceeds to the same scheduler.schedule() call as
before; a synthetic run confirms state dir/state.json/staging leaf
still land at 0700/0600/0700 after the mode= change.

Added as README deviations #22-23 and reconciled the count across all
three documents to 23 (6 cosmetic, 17 safety/hardening) across ten
review rounds -- cross-checked with grep.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 19:43:30 +00:00
Claude
a227b06e6f
fix(engineering): anchor scheduler.py's project marker match (round-9 bug)
A ninth review pass found scheduler.py's schedule()/unschedule() both
located "this project's" managed cron line via marker not in ln, a
bare substring test, not an exact-match or delimiter-anchored check.

Failure scenario: two projects scheduled where one path is a literal
prefix of the other (e.g. /home/user/app and /home/user/app-v2) --
"# project=/home/user/app" is itself a substring of
"# project=/home/user/app-v2"'s line. Running schedule() or
unschedule() for /home/user/app would silently drop app-v2's cron
entry too, with no error or warning.

harvest.py's _project_matches() (added in this same PR) already gets
this right via delimiter-anchored comparison; scheduler.py's marker
matching didn't follow the same discipline.

Fixed: added _line_matches_project(), anchored on
ln.rstrip().endswith(marker) since the marker is always the last token
of a generated line -- used at both call sites.

Also fixed the related minor nit: install-cron.sh's printed --backend
value was unquoted next to otherwise-quoted ${RUNNER}/${PROJECT} in
its heredoc (low risk since that script only prints a line for the
user to copy, never executes anything itself, but inconsistent with
the quoting discipline everywhere else).

Verified two ways: a standalone reproduction confirmed the bug before
the fix and its absence after, and a full schedule()/unschedule()
round-trip through the actual public API (crontab -l/crontab - swapped
for an in-memory fake) confirmed scheduling both /home/user/app and
/home/user/app-v2, then unscheduling only app, correctly leaves
app-v2's line intact.

Added as README deviations #20-21 and reconciled the count across all
three documents to 21 (6 cosmetic, 15 safety/hardening) across nine
review rounds -- cross-checked with grep.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 19:32:33 +00:00
Claude
4d68c542f2
fix(engineering): close CLI-output redaction gap (round-8 HIGH finding)
An eighth review pass found that seven rounds of redaction fixes were
all file-level (write_staging(), diagnostics.json, state.json's
archive) but __main__.py's cmd_run() reads the same in-memory Report
object and prints EditRecord.content directly to the console, and
_report_payload() serializes it unredacted for --json --
write_staging()'s redaction runs on a copy (report.to_dict()) used
only for the on-disk JSON, it never touches report.edits itself.

Concretely: scheduler.py's cron entry redirects run's stdout/stderr
straight into <project>/.skillopt-sleep/cron.log -- a secret that
leaked into a proposed edit's content would land there in plaintext on
every scheduled night, in a file that (unlike state.json/staged files)
also had no chmod protection.

Fixed:
- _report_payload() and cmd_run()'s plain-text edit printing now run
  through redact_secrets(), gated on the same redact_secrets config
  flag as everywhere else.
- cmd_harvest()'s debug output (--json, --output <file>, and the
  plain-text loop) gets the same treatment -- it prints raw mined
  TaskRecord.intent text so a human can review it before setting
  "reviewed": true on a --tasks-file, and redaction only strips
  secret-shaped substrings, so it doesn't reduce what's reviewable
  while closing the same leak path.
- scheduler.py's generated cron line now chmod 700s the .skillopt-sleep
  log dir and chmod 600s cron.log itself (best-effort, 2>/dev/null)
  before each run appends to it -- that file was never covered by the
  state/staging chmod pass in an earlier round.

Verified: a synthetic secret seeded into a task's intent no longer
appears in cmd_run's --json payload, plain-text edit output, or
cmd_harvest's redacted payload; executing the actual generated cron
line end-to-end (not just inspecting the string) produces a 0700 log
dir and 0600 log file on disk.

Added as README deviation #19 and reconciled the count across all
three documents to 19 (5 cosmetic, 14 safety/hardening) across eight
review rounds -- cross-checked with grep.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 19:24:29 +00:00
Claude
19fd75a2d6
fix(engineering): correct stale upstream-layout paths in shell launchers
A sixth review pass found sleep.sh and run-sleep.sh still described and
partially resolved against upstream's <repo>/plugins/claude-code/ and
<repo>/plugins/run-sleep.sh layout, not this vendored copy's actual
layout (scripts/ and skillopt_sleep/ as siblings directly under the
plugin root, engineering/skillopt-sleep/). The primary co-located and
repo-relative resolution branches happen to still succeed regardless
(so this was unreachable in normal operation), but the documented
SKILLOPT_SLEEP_REPO and CLAUDE_PLUGIN_ROOT escape hatches would have
silently failed for anyone actually relying on them -- e.g. after a
future re-vendor that missed copying run-sleep.sh into scripts/.

Fixed: sleep.sh's SKILLOPT_SLEEP_REPO branch now checks
$SKILLOPT_SLEEP_REPO/scripts/run-sleep.sh; run-sleep.sh's
CLAUDE_PLUGIN_ROOT branch now checks $CLAUDE_PLUGIN_ROOT/skillopt_sleep
(this repo's actual layout) ahead of the upstream two-levels-up check
(kept for portability if this script is ever reused in that shape
again). Header comments in both files corrected to describe the real
layout instead of upstream's.

Verified both previously-broken fallback branches resolve correctly
when isolated from the co-located script (copied each launcher to a
scratch dir and ran it standalone with only the relevant env var set).

Added as README deviation #18 (cosmetic/hardening) and reconciled the
count across all three documents to 18 (5 cosmetic, 13 safety/
hardening) across six review rounds -- cross-checked with grep.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 19:01:56 +00:00
Claude
e64c1cdd44
fix(engineering): relabel misleading redaction placeholder (round-5 review)
A fifth review pass found staging.py's sk-[A-Za-z0-9_-]{10,} secret
pattern -- which matches OpenAI, Anthropic (sk-ant-...), and other
vendors sharing the sk- prefix convention -- was labeled
[REDACTED_OPENAI_KEY] regardless of which vendor's key shape it
actually matched. Redaction itself was unaffected (the text was
scrubbed either way), just a misleading placeholder if a user reads it
literally. Relabeled to [REDACTED_API_KEY].

Added as README deviation #17 (cosmetic) and reconciled the count
across all three documents (README.md's numbered list, plugin.json,
CLAUDE.md) to 17 (4 cosmetic, 13 safety/hardening) across five review
rounds -- cross-checked with grep, not just eyeballed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 18:48:21 +00:00
Claude
e729f157ee
fix(engineering): close round-4 review findings on vendored skillopt-sleep
A fourth automated review pass on PR #907 found the deviation count had
drifted out of sync across the three places that document it, plus two
more real gaps in the vendored plugin:

1. Deviation count inconsistency: plugin.json and README.md both said
   13 (after round 3), but CLAUDE.md's v2.11.2 section said "8
   deviations" with an itemized list that didn't map onto the real
   13-item README list -- it named a "dead cross-reference to a
   non-vendored design doc" as a cosmetic item that was never actually
   added as a numbered README deviation (it was fixed in round 3's
   commit but never itemized). Fixed: added it as README deviation
   #14, updated plugin.json's derivation_note with a note that
   README.md's numbered list is the single source of truth if any
   summary disagrees again, and rewrote CLAUDE.md's bullet to match.

2. commands/skillopt-sleep.md's action table listed `schedule` as an
   ordinary action alongside safe previews (`status`/`dry-run`/`run`),
   while its own "Safety reminders" section separately said to point
   users at the print-only install-cron.sh instead -- two
   uncoordinated stories about the same action. scheduler.schedule()
   writes directly to the user's real crontab the moment it runs, with
   no confirmation step. Fixed (README deviation #15): "Steps to
   follow" now has an explicit step 1 telling the agent to confirm
   with the user before running `schedule`; "Safety reminders" no
   longer contradicts the action table.

3. state.json (the cross-night task archive) and
   .skillopt-sleep/staging/<ts>/'s proposal/report/diagnostics files
   contain real harvested session content in plaintext, created via
   plain os.makedirs/open(...,"w") -- world-readable-by-default on a
   typical multi-user box. Fixed (README deviation #16): state.py and
   staging.py now chmod every directory they create to 0700 and every
   file they write to 0600 (best-effort). Live CLAUDE.md/SKILL.md
   files are intentionally left alone -- those are the user's own,
   often-committed files, not new output this plugin introduces.

All three documents (README.md's numbered list, plugin.json's
derivation_note, CLAUDE.md's v2.11.2 section) now agree on 16
deviations (3 cosmetic, 13 safety/hardening) -- verified by grep.

Verified: py_compile clean, mock-backend dry-run still exits 0, a
synthetic test confirms state dir/state.json/staging dir/staging files
land at 0700/0600/0700/0600 respectively after this fix (previously
default umask permissions), all 4 repo CI gates pass locally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 13:47:56 +00:00
Claude
32446887e6
fix(engineering): close round-3 review findings on vendored skillopt-sleep
A third automated review pass on PR #907 found 2 HIGH and 5 further
gaps in the vendored skillopt-sleep plugin, all in the same family as
rounds 1-2 (a safety claim in the docs the code didn't fully back up):

HIGH:
1. state.py's add_to_archive() persisted raw TaskRecord content
   (intent/context_excerpt/attempted_solution -- real harvested
   prompt/response text) to ~/.skillopt-sleep/state.json indefinitely,
   entirely outside the staging dir a user is ever told to review.
   Fixed: cycle.py now redacts each task dict before archiving, using
   the same redact_enabled flag as everything else.
2. report.md / report.json were never redacted, despite being the two
   files a human is told to read FIRST (the SKILL.md's own workflow:
   "show the user the exact proposed edits"). EditRecord.content/
   .rationale come from the optimizer's reflect() output over real
   failing task responses. Fixed: write_staging() now redacts the
   rendered report_md string and report.to_dict() before writing.

MEDIUM/LOW:
3. replay_mode: "fresh" (worktree replay) was declared in config but
   never implemented anywhere -- only fed a cosmetic report label.
   Implementing real worktree isolation was judged too invasive for a
   vendored copy; instead cycle.py now warns loudly when it's set to
   anything but "mock" rather than silently implying isolation that
   isn't happening.
4. backend.py shipped an AzureOpenAIBackend/AzureResponsesBackend pair
   with 5 internal-looking Azure endpoint hostnames and a hardcoded
   Managed Identity client ID, commented as sourced from "the intern's
   avail_api.md" -- reads like leaked internal Microsoft dev infra.
   Already unreachable from this plugin's documented mock/claude/
   codex/copilot --backend choices and requires deps this repo doesn't
   vendor. Removed entirely (classes, constants, get_backend()/
   build_backend() dispatch branches, the now-unused azure_endpoint
   param); get_backend("azure") now safely falls back to MockBackend.
5. attempt_with_tools() (all three CLI backends) used a task's tool
   name both as a shim filename and interpolated unescaped into the
   shim's generated shell body. Tool names originate from a
   hand-authored --tasks-file's judge.checks[].arg, never validated --
   not reachable via harvest/mine today, but a documented user-facing
   input. Fixed: a shared _sanitize_tool_names() helper filters to a
   safe-identifier allowlist before any name is used as a filename or
   shell text.
6. SKILL.md pointed to a design doc path (docs/superpowers/specs/...)
   that was deliberately not vendored. Fixed: points to the real
   upstream guide URL instead, with a note on why the local path is
   absent.
7. CLAUDE.md's "Current Scope" line claimed v2.11.2 but no dated
   version section existed for it. Added one matching the repo's
   established per-release convention.

All 13 deviations (2 cosmetic, 11 safety/hardening) cross-documented
in plugin.json's derivation_note and README.md's "Deviations from
upstream" + "Safety model" + "What was and wasn't vendored" sections.

Verified: py_compile clean, mock-backend dry-run still exits 0, all 4
repo CI gates pass, and a synthetic test with a real API-key-shaped
secret confirms it appears in NONE of state.json's task archive,
report.md, or report.json after this fix (all three fired positive
signal for the leak before it).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-11 13:36:00 +00:00
Claude
186c0f6d11
fix(engineering): close 3 safety gaps found by PR review in vendored skillopt-sleep
Automated review on PR #907 read the actual module code (not just the
surface docs) and found the vendored plugin's own safety claims didn't
fully match its behavior. Patches applied directly to our vendored copy
(documented as deviations in the plugin README for re-vendor):

1. staging.py: redact_secrets() was applied to diagnostics.json but not
   to proposed_SKILL.md/proposed_CLAUDE.md -- the exact files adopt()
   copies over the live CLAUDE.md/SKILL.md (with --auto-adopt, with no
   human in the loop). A secret pasted into a real debugging session
   could have landed in live memory unredacted. Now redacted before
   write_staging() persists either file.

2. scheduler.py: the generated crontab line interpolated an arbitrary
   project path via unescaped f-string into a command cron runs through
   sh -c on every fire. A path containing shell metacharacters could
   break out of the quoting. Now shlex.quote()-d.

3. cycle.py: max_tokens_per_night was declared in config.py's DEFAULTS
   and budget.py already had a Budget/plan_depth heuristic built for
   it, but nothing in the production run_sleep_cycle() path ever read
   it -- a real-backend night had no actual token ceiling. Now a
   Budget starts right after backend construction (harvest/mine spend
   counts too), sizes dream_rollouts down via plan_depth() when
   remaining budget is tight, and the report notes when it caps
   rollouts or the budget is exhausted -- no silent truncation. This
   caps rollout depth per task, not a hard mid-call abort; documented
   as a residual limitation in the README.

Also dropped a leftover hardcoded nvm path in backend.py's
resolve_codex_path() (the generic scan a few lines below already
covers it) and added a one-line acknowledgment to CLAUDE.md's
Anti-Patterns list that this plugin's non-mock backends are a
documented, opt-in exception to "no LLM calls in scripts" -- not
precedent for adding LLM calls to analysis/reference skills.

Verified: py_compile clean, mock-backend dry-run still exits 0,
synthetic test confirms dream_rollouts capping actually engages under
a tight budget and is a no-op under the default budget, all repo CI
gates (smoke_scripts, check_plugin_json, check_paths, derive_counters)
still pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-08 06:41:32 +00:00
Claude
cf6ca763ec
feat(engineering): vendor SkillOpt-Sleep from microsoft/SkillOpt
Verbatim copy of the stdlib-only skillopt_sleep engine + Claude Code
plugin surface (skills/hooks/commands/scripts) into
engineering/skillopt-sleep/. Gives a local agent a nightly gated
self-improvement cycle: read-only harvest of past Claude Code session
transcripts -> mine recurring tasks -> offline replay -> held-out-gated
CLAUDE.md/SKILL.md edits -> staged for explicit /skillopt-sleep adopt.
Nothing live changes without that explicit step.

The heavier skillopt training package (needs numpy/openai/azure-* +
hand-labeled benchmarks per task) was deliberately not vendored, since
it optimizes one narrow scoreable task at a time and doesn't fit this
repo's broad domain-expertise skills or no-ML-in-scripts convention.

Attribution preserved in plugin.json + LICENSE + README.md (MIT,
Microsoft Corporation / Yifan Yang), following the same verbatim-vendor
pattern already used for loop-library/. Registered as its own
marketplace plugin; headline counters in README.md/CLAUDE.md/
marketplace.json trued up via scripts/derive_counters.py --check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TX374i2YGrjNV4Yi3AmaKS
2026-07-08 05:42:44 +00:00
Alireza Rezvani
58cde08506
Merge pull request #898 from alirezarezvani/claude/claude-md-self-improvement-06a4xm 2026-07-06 07:47:15 +02:00
Claude
1aaada1cca
docs(claude-md): add Self-learning and Lessons sections for mistake-driven rule capture
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQoPnWU7BeEJpHkBDwV9nK
2026-07-06 05:44:18 +00:00
Claude
5c811661c9
fix(pm-product): address review findings — version relabel to v2.11.1, MC zero-week sampling, as-of guard, manifest truncation
- Relabel this release v2.10.4 -> v2.11.1 (dev already carries v2.11.0 from the
  engineering agent-harness PR); add a proper Current Version changelog entry and
  sync marketplace metadata.version + both plugin manifests + SKILL.md frontmatter.
- jira_snapshot_bridge.py: Monte Carlo forecast now samples zero-filled weekly
  throughput over the full observed span (Vacanti: dead weeks are observations),
  and the 4-week refusal gate counts observed calendar weeks; regenerated the
  pinned fixture. normalize() skips non-dict records instead of crashing.
- discovery_cadence_tracker.py: --as-of earlier than the interview history now
  refuses cleanly with exit 5 instead of raising.
- harness_manifest_builder.py: descriptions truncate on word boundaries with an
  ellipsis instead of mid-word; regenerated all 18 domain manifests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Uzm8dKoeXPayJVMojpSbw
2026-07-03 13:19:53 +00:00
Claude
46bb258a94
feat(pm-product): agent-harness upgrade for product-team + project-management + agentic audit
Deep audit of both domains against the AR v1 agentic-readiness rubric
(audit/pm-product-agentic-2026-07/: master + per-domain reports + research-backed
improvement fields + research digest), plus the harness layer the audit motivated:

- pm-skills rebuilt as a context:fork orchestrator with an agentic delivery loop:
  pm_goal_router.py (8 lanes, exit-code route/ask/refuse), jira_snapshot_bridge.py
  (searchJiraIssuesUsingJql output -> Kanban Guide 2025 flow metrics with SLE +
  aging-WIP alerts + seeded Monte Carlo forecasts, or scrum-master sprint schema —
  verified end-to-end into velocity_analyzer.py), delivery_loop_gate.py (G1-G6
  delegation governance: human owner, reviewer for agent tasks, machine-checkable
  acceptance, evidence-before-done, close refusal, exhausted-budget-is-escalation).
- product-skills rebuilt as a context:fork orchestrator with the continuous-discovery
  loop: product_goal_router.py (16 lanes incl. standalone plugins),
  discovery_cadence_tracker.py (Torres weekly-habit health 0-100 with named gaps),
  ost_linter.py (O1-O5 Opportunity Solution Tree structural gates).
- 6 new references citing 6-7 sources each (flow/forecasting canon, agentic delivery
  governance, PM loop playbook, continuous discovery, product operating model,
  AI product evals); pinned fixtures (expected_flow_metrics.json, sample OST/log).
- cs-pm-orchestrator + cs-product-orchestrator agents; /cs:pm, /cs:grill-pm,
  /cs:pm-loop, /cs:product, /cs:grill-product, /cs:product-loop commands.
- Fixed the two CLI-noncompliant product tools (user_story_generator.py,
  persona_generator.py): real argparse --help, seeded determinism, backward-compatible
  positionals.
- Regenerated agent-harness manifests for both domains (orchestrators now score all
  five agentic_signals); updated domain CLAUDE.mds, plugin manifests (2.10.4),
  marketplace entries, and headline counters (602 tools / 731 references / 99 agents /
  109 commands; derive_counters --check passes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Uzm8dKoeXPayJVMojpSbw
2026-07-03 06:41:46 +00:00
Claude
0a5d18ceba
feat(engineering): agent-harness skill + agentic-readiness audit of both engineering domains
Deep-audit both engineering folders (engineering/ + engineering-team/) against the
June 2026 baseline and score every skill on a new 6-dimension agentic-readiness rubric
(goal intake, decomposition, deterministic execution, verification, loop discipline,
close-out). Combined: 26 HARNESS-READY, 39 LOOP-CAPABLE, 43 TOOL-ONLY, 7 PROSE-ONLY.
Headline finding: loop discipline (AR5) is the repo-wide gap.

Ship engineering/agent-harness — the thin unifying layer that turns any of the repo's
18 domains into a bounded, self-verifying agent loop:
- harness_manifest_builder.py: scan a domain -> manifest.v1 (skills, tools, checks, signals)
- goal_compiler.py: goal + manifest -> plan.v1; refuses vague goals (exit 3) / no-match (4)
- loop_controller.py: init/next/record/verify/close state machine; runs checks itself via
  subprocess (no verification theater), caps attempts+iterations with escalation, refuses
  to close while any task is unverified; atomic state writes
- 18 committed per-domain manifests, JSON schema, harness-runner agent, /cs:harness command,
  3 references citing the 2024-2026 harness canon
- reuses agenthub / autoresearch locked-evaluator / tc-tracker / loop-library primitives

Audit record under audit/engineering-agentic-2026-07/ (master + 2 domain reports +
improvement-fields rollup + research digest + rubric).

Counters: 82->83 plugins, 354->355 skills, 593->596 tools, 722->725 refs (derive_counters
--check passes). All CI gates green: plugin.json, smoke --help/--sample, JSON output,
path linter, dual-publish, counters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4JerbGv6vqitUMhqHPA9g
2026-07-03 06:01:43 +00:00