feat(engineering): deep-learning-book — companion skill for the free Goodfellow/Bengio/Courville textbook - #994
Conversation
… 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
…ree 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
…lugin root
CI gate G1 (scripts/check_paths.py) failed on the previous commit: the agent and
command files live at engineering/deep-learning-book/{agents,commands}/, so bare
references/*.md and assets/*.md tokens resolved against neither the plugin root,
the file's own directory, nor the repo root — the three bases the linter accepts.
The files they point at live under skills/deep-learning-book/.
Prefix the nine offending links with skills/deep-learning-book/ so they resolve
from the plugin root. Content unchanged otherwise; SKILL.md's own relative links
were already correct and were not touched.
Reproduced the failure locally (9 unresolvable references across 4 files), then
confirmed the same check clean, plus every other blocking gate: compileall,
check_plugin_json, check_skill_names, check_frontmatter, check_dual_publish,
check_model_freshness, smoke_scripts (696 passed), derive_counters --check.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
Review:
|
…ME-padding disclosure Two small findings from the automated review on PR #994, both verified against the source before fixing. 1. reading_path_planner.py: the plan() parameter was named include_optional while the CLI flag and call site both use include_intro, and it only ever gates ch01. Renamed the parameter and its use for consistency. Behavior unchanged, confirmed both ways: --include-intro keeps ch01 first, the default drops it. 2. model_arithmetic.py: conv2d "same" padding computes ceil(H / stride), which is the TensorFlow/Keras SAME convention, and the tool did not disclose which framework it matches. Documented it in the module docstring — including that PyTorch's padding='same' is symmetric-only and rejects a stride other than 1, so a strided PyTorch layer will not match, with "valid" named as the exact-case workaround — plus a pointer comment at the computation itself. No arithmetic change; the sample stack reports identical parameters and FLOPs. The reviewer's third point was that it could not execute the gates in a sandboxed environment. No code change: those gates were run locally and are green. Verified after the change: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, the book-skill validator, and --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Both code nits verified against the source and fixed in 1. 2. conv2d 3. Gates you couldn't execute — no code change needed, but for the record, all of these are green locally on the current head: One unrelated thing surfaced while running the suite, left alone deliberately: the advisory Note that the first CI run on this branch was red on gate G1 for a real defect of mine (bare Generated by Claude Code |
Independent review —
|
Second independent review on PR #994 observed that reading_path_planner.py's score_lanes() broke equal-hit ties alphabetically by lane key, so SKILL.md's own documented example "train a transformer" resolved to the practitioner lane rather than sequence. Reproduced: the goal hits practitioner on "train" and sequence on "transformer", one keyword each, and alphabetical ordering picked practitioner. Fixed the cause rather than the example. Ties now break on keyword specificity — the lane whose longest matched keyword is longest wins — because an equal hit count between a generic term and a discriminating one should not be settled by luck. Lane key remains the final tie-break so ordering stays deterministic. Regression battery over eight goals: "train a transformer" now routes to sequence; vision, generative, foundations, practitioner, complete, representation and sequence goals all route exactly as before. Refusal paths unchanged (out-of-scope exit 3, unroutable exit 4, sample exit 0). Gates green after the change: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Verified the lane tie-break observation and fixed the cause in Reproduced first: Rather than swapping the example in Regression battery over eight goals — Gates green after the change: One related case I looked at and deliberately left alone: Generated by Claude Code |
Review:
|
…meter error in the example asset Third review on PR #994 found a real bug in the flagship example asset. Verified before fixing: assets/example_layer_spec.json reported 1,207,962,624 parameters for the feedforward up-projection instead of 2,362,368 — off by exactly 512x, the sequence length — putting the block's total at ~1.21B instead of ~7.09M. Root cause was in the tool, not only the asset. model_arithmetic.py's mha layer emits (seq, d_model) but linear refused any 2-D input, so the only way to attach a feedforward block was to flatten first. Flattening collapses all 512 positions into one 393,216-element vector, which models a dense layer over the whole sequence — a different layer, with seq_len times the parameters. A transformer FFN was therefore not expressible at all, and the shipped example walked straight into it. Clean exit is not correct numbers, which is why --sample exit-code testing never caught it. Fixed the cause: linear on a 2-D (seq, features) input is now position-wise — one weight matrix shared across positions, parameters independent of sequence length, compute linear in it. Documented in the module docstring; the 3-D path still refuses with an updated message pointing at flatten. Removed the flatten from the example asset and recorded in its comment why it must not come back. Verified: the corrected block reports 7,087,872 parameters, matching a hand-check of 2*(2*768) + (4*768^2+4*768) + (768*3072+3072) + (3072*768+768) exactly, and the size of a BERT-base encoder layer. The convnet --sample is unchanged at 545,098, and linear on 3-D input still exits 5. Also adds the missing CHANGELOG.md [Unreleased] entry, which the same review noted: CLAUDE.md, README.md and marketplace.json carried the new skill and its counter deltas but CHANGELOG.md did not. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Good catch — this was a real bug, and the diagnosis was exactly right. Fixed in Reproduced first: the shipped asset reported 1,207,962,624 parameters for the FFN up-projection instead of 2,362,368, off by exactly 512× the sequence length, putting the block total at ~1.21B instead of ~7.09M. Fixed the cause, not just the spec. The root problem was in the tool: Verified numerically rather than by exit code: Convnet CHANGELOG entry added — correct, it was missing while Your closing point is the one I'd most like to keep: exit-code correctness is not numeric correctness, and this slipped through precisely because Generated by Claude Code |
Review: PR #994 —
|
…ut validation Fourth review on PR #994 raised two findings against this plugin's scripts. Both reproduced before fixing; the review's other findings are against marketing/linkedin, which this branch carries from main but does not touch (see the PR comment). 1. reading_path_planner.py matched keywords by bare substring, so "rag" matched inside "storage", "lora" inside "exploratory", "conv" inside "converge" and "text" inside "context". Confirmed: --goal "train models for image storage and retrieval" exited 3, confidently refused as out-of-scope RAG work, and "an exploratory look at optimization" exited 3 citing LoRA. A tool whose stated design is to refuse rather than guess was guessing, and doing it with certainty. Matching is now word-boundary anchored with an optional plural, plus an explicit surface-form table for the few tokens whose inflections a word-boundary match would otherwise miss (fine-tuning, prompting, agentic). Verified: both goals above now route correctly (exit 0 / the optimization lane), "converge" reaches the optimization lane rather than vision, and the real refusals still refuse — RLHF, LoRA fine-tuning, RAG pipelines and prompt/agent goals all still exit 3. 2. model_arithmetic.py documented exit 4 for a spec it cannot parse but only caught SpecError and ShapeError, so malformed input escaped as a traceback with exit 1. Confirmed across five cases: a non-dict top-level JSON, a non-dict layer entry, stride 0, groups 0, and a non-numeric filters value. Numeric fields now go through a checked accessor that rejects non-integer and non-positive values, the input layer's shape is validated, and the top-level spec and every layer entry are type-checked. All five now exit 4 with a message naming the layer and field. Regression battery over eight goals routes exactly as before; the convnet sample still reports 545,098 parameters and the transformer asset 7,087,872. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Thorough review — thank you. Findings 3 and 4 are against this PR's own code and are both fixed in Fixed (findings 3 and 4)3 — substring matching in Matching is now word-boundary anchored with an optional plural, plus an explicit surface-form table for the few tokens whose inflections a bare 4 — malformed input crashing past exit 4 in Regression battery over eight goals routes exactly as before; convnet sample still 545,098 parameters, transformer asset still 7,087,872. Full gate suite green. Not fixed here — and whyFindings 1, 2, 5, 6 and most of the smaller items are in They look like real bugs from your traces, and two are worth prioritizing — the Also worth recording: your note that Generated by Claude Code |
ReviewSolid piece of work — the rights-gate reasoning for going "companion, not compilation" is well-argued and consistent with One remaining gap I found in the same category as the "typed input validation" fix:
|
…numeric field Fifth review on PR #994 found the one numeric spec field I missed when adding typed validation in the previous commit: embedding's seq_len still went through a bare int(), so it bypassed the checks every sibling field had just been given. Both failure modes reproduced before fixing: seq_len "ten" -> uncaught ValueError, traceback, exit 1 (documented: exit 4) seq_len 0 -> no error at all; reported a plausible "0x8" layer with zero activation elements and exited 0, presenting a degenerate model as a valid one Routed through _positive_int with the existing default (the incoming sequence length, or 1), so both now exit 4 naming the layer and field. Verified the default fallback still resolves to the input shape (16x8) and an explicit valid seq_len is still honoured (32x8). Swept the file afterwards rather than fixing only the reported instance: all 13 numeric spec fields now go through _positive_int, and no raw int() on a spec field remains. The reference specs are unchanged — convnet 545,098 parameters, transformer asset 7,087,872. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Correct on both counts, and it's the one field I missed when hardening the others in Reproduced before fixing, and the second case is slightly worse than described: So the non-positive case wasn't merely unvalidated — it presented a degenerate model as a valid one, which for an arithmetic tool is the worse of the two failures. Routed through Since the finding was really "one field escaped a convention the rest of the file enforces," I swept the file rather than patching the single instance: all 13 numeric spec fields now go through Worth recording for anyone reading this thread later: this is the second bug found in the exact seam where a fix was applied — the 512× parameter error was in the tool's flagship example, and this one was in the field the hardening pass skipped. Both were in Generated by Claude Code |
ReviewReviewed the Context noted: the commit history shows this PR already went through five rounds of review with real fixes applied — a parameter-name mismatch, SAME-padding disclosure, keyword-tie-breaking by specificity, a 512x transformer-FFN parameter bug (flatten collapsing position-wise linear), substring-vs-word-boundary keyword matching, and Code quality —
|
Sixth review on PR #994 noted that --include-intro appeared to have an observable effect only on the complete lane. Checked it, and it was worse than reported: the flag was inert on every lane, complete included. Two reasons compounded. ch01 is not a prerequisite of any chapter, so it never arrived through prerequisite closure; and the only lane that targets it, complete, skipped the ch01 filter entirely. The filter therefore removed a chapter that was never present, and the flag that controlled it could not change any output. This also means my own verification of the parameter rename in c75500f was inconclusive: it compared the complete lane with the flag against the vision lane without it, and those differ for reasons unrelated to the flag. A test that cannot fail proves nothing. Inverted the logic so the flag adds ch01 rather than un-removing it, which gives it a real effect on every lane while leaving complete unchanged (ch01 is already among its targets). Help text now states what it does and that no lane pulls ch01 in on its own. Verified per lane: complete unchanged; vision, generative and foundations each gain ch01 with the flag and are untouched without it; ch01 sorts first and never precedes a chapter it would violate. Routing and both refusal paths are unchanged — sequence, vision, generative and practitioner all route as before, out-of-scope still exits 3, unroutable still exits 4. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Checked the Two causes compounded. ch01 is not a prerequisite of any chapter, so it never arrived through closure; and Inverted the logic so the flag adds ch01 rather than un-removing it. It now has a real effect on every lane, Worth recording, since it bears on how much the earlier rounds actually verified: my own check of the parameter rename in That's the third distinct instance in this PR of the same underlying mistake: a check that ran clean without actually exercising the thing it claimed to cover ( Generated by Claude Code |
Review:
|
…LI flags Seventh review on PR #994 noted that capacity_planner.py exposes --overfit-rel-gap but hardcodes the two params-per-example regime bands, unlike its sibling scripts where every threshold is overridable. The reviewer called it fine as shipped; the inconsistency is small enough to close rather than carry. The band matters more than a typical default: it decides whether "shrink the model" is ranked last, which is the double-descent correction this tool exists to apply. The interpolation point depends on task, architecture and label noise, so a user whose model sits elsewhere had no way to say so. Adds --underparameterized-max and --overparameterized-min, threaded through plan() and classify_regime() as keyword arguments defaulting to the existing constants, and reports all three thresholds in --output json the way training_diagnostics.py already does. The help text repeats that these are heuristic bands, not a threshold theorem. Defaults preserve behaviour exactly: the --sample fixture still reports overparameterized / OVERFIT / 240.0 params-per-example with smaller-model ranked last, identical to before the change. An override demonstrably moves the regime (--overparameterized-min 500 reclassifies the same model as near-interpolation). Exit codes unchanged: 1 for an action, 0 for balanced, 4 for a leaky split. Not fixed here: CHANGELOG.md's duplicate [Unreleased] header, also noted in that review. Verified pre-existing rather than introduced by this branch — the count is 2 at the merge-base with main and 2 at HEAD. Left for a separate changelog cleanup. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Both observations checked. One closed in Regime bands now overridable. You called it fine as shipped, and it was, but the inconsistency is small enough to close rather than carry — and this particular band matters more than a typical default, since it decides whether Added Verified defaults preserve behavior exactly — the Duplicate So this branch didn't introduce it, and my entry went under the first header. Agreed it's changelog debt worth a separate cleanup — flagging it here so it doesn't get lost. For the record on this thread: that's seven review rounds, six of which surfaced something real in this plugin's tooling — every one in code I had reported as verified. The content and rights reasoning have gone unchallenged throughout; the defects clustered entirely in the four scripts. Worth weighing against any "ready to merge" verdict, including the ones already given. Generated by Claude Code |
|
Review: deep-learning-book skill (PR #994) Note up front: the diff against Overall Code quality — the 4 scripts (read in full) One minor correctness nit, low severity: Plugin/manifest compliance (per this repo's CLAUDE.md)
I wasn't able to actually execute Nothing else flagged Nice work — the "companion, not compilation" framing plus the delta layer is a genuinely useful pattern this repo didn't have before, and the repeated fix commits in the history (word-boundary matching, position-wise-linear correction, embedding seq_len validation) show real iteration rather than a first-draft dump. |
…-refusal collision Eighth review on PR #994 found that _matches()'s (?:s|es)? suffix reintroduced a smaller version of the substring bug it was written to fix: "rag" + "es" matches the standalone word "rages", so --goal "why overfitting still rages in large models" exited 3, refused as out-of-scope retrieval-augmented-generation work. Reproduced before fixing, then checked whether the -es branch earns its keep at all. It does not: every keyword in the table ending in s, x, z, ch or sh is already plural or non-count (basics, features, foundations, prerequisites, statistics, speech, mlops, fairness, mathematics, time series), so no token needs -es appended. Narrowed the auto-plural to plain -s and documented that irregular forms belong in SURFACE_FORMS, spelled out, the way fine-tuning, prompting and agentic already are. Verified: "rages" no longer matches while standalone "rag" still does; transformers, embeddings, autoencoders and agentic still match; the goal above is now correctly unroutable (exit 4) rather than confidently misrouted. RLHF, LoRA fine-tuning, RAG pipelines and prompt/agent goals still exit 3; sequence, vision, generative and practitioner routing unchanged. That makes two rounds of false out-of-scope refusals from the same root cause — approximate string matching standing in for a word list. The refusal path is the part of this tool users are least able to second-guess, so it is the wrong place to approximate. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Real, reproduced, and fixed in Before fixing I checked whether the Verified both directions: The pattern worth naming: this is the second round of false out-of-scope refusals from the same root cause — approximate string matching standing in for a word list. Round 4 caught Also noted and appreciated: you were explicit that your check was inspection rather than execution, since script execution was gated in your environment. That's useful calibration — the last three findings across reviewers all came from reading the code, not running it, and this one was reproducible in one command. Generated by Claude Code |
Review: PR #994 —
|
Ninth review on PR #994 found that --underparameterized-max and --overparameterized-min, added two commits earlier, were never checked against each other. Reproduced, and the consequence is sharper than a silent misclassification: with --underparameterized-max 20 --overparameterized-min 5 and a ratio of 10, the tool reported a model ten times overparameterized as "underparameterized" and exited 0. That verdict ranks "shrink the model" FIRST rather than last, inverting the exact double-descent correction this tool exists to apply. Added an argparse guard rejecting under-max >= over-min with a message naming both values (exit 2, the documented usage-error code). Equal bands are rejected too, since they leave the near-interpolation regime unreachable. Verified: inverted and equal bands both exit 2; a valid override still moves the regime (--overparameterized-min 500 gives near-interpolation); defaults unchanged at overparameterized / OVERFIT / 240.0 with smaller-model last; the other exit codes still 1 for an action, 0 for balanced, 4 for a leaky split. Worth noting for the two flags' own history: they were added to close a consistency nit, and introduced this defect in doing so. A new option is new surface, and its interaction with existing options is part of it. Gates green: compileall, check_paths, check_frontmatter, check_dual_publish, check_model_freshness, smoke_scripts (696 passed), derive_counters --check, check_skill_names, check_plugin_json, book_skill_validator, and --help + --sample --output json on all four tools. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BswsZp5zrJWFAGU6KWNA1s
|
Reproduced and fixed in With Added an argparse guard rejecting Worth recording about these two flags specifically: they were added to close a consistency nit, and introduced this defect in doing so. A new option is new surface, and its interaction with the options already there is part of that surface — which I didn't check when adding them. That's the second time in this PR a fix has created the next finding (the Also appreciated that you re-derived the eight prior fixes independently instead of trusting the commit messages. Given that six of the nine rounds found something real in code I'd already reported as verified, re-checking rather than trusting was the right call. Generated by Claude Code |
|
test |
Review: deep-learning-book companion skillI reviewed the actual new content of this PR — engineering/deep-learning-book/ (SKILL.md, 4 scripts, 4 references, 20 chapter files, glossary/patterns/cheatsheet, agent, commands, plugin manifests) — and read the four Python tools end-to-end plus spot-checked several chapters/references. The other files in the diff (marketing/linkedin/*, .codex/.gemini/.hermes/.vibe index updates) are base-branch drift from main being ahead of dev, as the PR description explains, and not new work in this PR. Overall Scripts (scripts/*.py)
I read rather than re-executed the scripts in this sandbox (tool execution was restricted here), but the logic traced cleanly by hand against every documented exit code, and the PR's own testing notes (hand-checked arithmetic, --help/--sample/--output json on all four) look sufficiently rigorous given the fix-commit history already exercised these paths. Content quality Manifests Minor nit: plugin.json version is 2.12.0 (repo release version at merge time), while other recently-added single-skill plugins use 1.0.0 for their own version (e.g. book-to-skill) or the repo version at their own merge point (e.g. agent-memory at 2.11.2). Not wrong, just an inconsistent convention across plugins — not blocking. Process note Security / test coverage Nice work — this is a good template for how to handle 'convert a copyrighted book into a skill' requests going forward. |
|
Checked both observations. Neither warrants a change, and here's the evidence for each rather than just a judgment call. 1. Band rules only in comments, not What 2.
Repo-release-version is the dominant convention by roughly 12:1, and 3. CI status. All seven checks green on the current head. Ten rounds in, this is the first with nothing to fix — so I'm stopping here rather than making changes that don't earn their CI cycle. Still an open draft; the Generated by Claude Code |
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
Summary
Requested as "convert https://www.deeplearningbook.org/ into a skill". Shipped as a companion, not a compilation — and the reasoning is the reusable part of this PR.
Why
book-to-skillwas not used. Its emitter refuses ashareablepackage withoutpublic-domain/open-license/internal-docs/author-permission. None applies to an MIT Press title whose own site states the HTML-only format exists as a friction against copying under the authors' contract, and whose PDF distribution is not permitted. Itsrights_and_provenance.mdlists "publish 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 in any case.The rule this sets for the repo (recorded in
references/rights_and_use.md): when a user asks to convert a copyrighted work into a shareable skill, build a companion that indexes and updates the source, not a compilation that reproduces it. Compile only when the gate clears; keep the output local when it does not.What shipped. The compiled-skill shape — master
SKILL.md(~2.0k tokens, chapter index + topic index),chapters/ch01..ch20,glossary.md,patterns.md,cheatsheet.md— filled with original synthesis. No passages, figures, exercises, or per-paragraph paraphrase; every chapter file links to the official free chapter. The organizing structure is the book's published table of contents.The differentiator is the delta layer. A compilation freezes a source at its publication date; this one dates it. Every chapter carries a "What changed after 2016" section, and
references/book_to_2026_delta.mdgives five corrections with primary citations and per-claim confidence levels:capacity_planner.pyencodes the correction.Two commonly repeated claims are marked contested rather than propagated (batch norm's "internal covariate shift" mechanism; the strong lottery-ticket form) and two are named as folklore. Stated rule: the conflict is almost always in the recommendation, not the analysis.
Four stdlib tools, each with a real refusal:
reading_path_planner.pytraining_diagnostics.pycapacity_planner.pymodel_arithmetic.pyPlus 4 references citing 7–8 sources each, 3 assets,
cs-deep-learning-tutor, and/cs:deep-learning·/cs:dl-reading-path·/cs:dl-diagnose.Note on the diff: this branch was cut from
main, which currently sits 3 commits ahead ofdev(thelinkedinplugin, merged via #991). Those commits ride along in this PR againstdev; the work under review here is the singledeep-learning-bookcommit.Checklist
dev(notmain)SKILL.mdwith valid YAML frontmatter (name,description,license)--helpwithout errors — all four also support--sampleand--output jsonengineering/deep-learning-book/skills/deep-learning-book/SKILL.md)Type of Change
README.md,CLAUDE.md,marketplace.json)Testing
Every gate run against the repo's own tooling:
book_skill_validator.py(frombook-to-skill, all four check families) — passed all checks, exit 0token_budget_estimator.py --skill-dir— every file inside its cap; resident core 2,010 / 4,000 tokens, 20 chapters averaging ~644 tokens eachcheck_plugin_json.py --all—OK engineering/deep-learning-book/.claude-plugin/plugin.json; marketplace description 899 chars (cap 1,024)derive_counters.py --check— passed: skills 386→387, tools 723→727, refs 838→842, agents 116→117, commands 146→149, plugins 97→98--help,--sample, and--sample --output json(valid JSON) verified; typed exit codes confirmed on the refusal paths (3, 4, 5) and the success pathsmodel_arithmetic.pyarithmetic hand-checked against the sample convnet (conv 3×3×3×32+32 = 896; linear 4096×128+128 = 524,416; MHA 4·768²+4·768 = 2,362,368; LSTM 4·(768·256+256²+2·256) = 1,050,624)model_arithmetic.py --spec assets/example_layer_spec.json— runs cleanGenerated by Claude Code