After the QA pass earlier today, the ACL drill at /acl-practice.html is no longer noindex. Added to sitemap, llms.txt, tools.html (new "SECURITY / ACL" section), and manifest.js. The CCNA Hub's Domain 5 card went from "COMING SOON · 0%" to "PARTIAL · 10% COVERED" with topic 5.6 (Configure and verify ACLs) flipped to COVERED — linked to both the drill and the cheat sheet's ACL section. First Domain 5 win, and the most exam-tested concept in that domain shipped first. Hub status counters: 5 → 7 browser tools, 10 → 11 of 53 topics covered. SITE_VERSION 1.23.0 → 1.24.0.
Built on top of yesterday's manifest. progress-display.js bumped to v5: any page that includes <div class="next-steps" data-slug="X"></div> gets auto-populated with 2 manifest-driven suggestions plus a reference fallback. Logic: if the page is in the CCNA path order, suggest the next uncompleted item; otherwise find pages in shared paths or shared tags; always include the cheat sheet as a reference fallback. Skips items already in the visitor's completed list. Deployed to all 12 articles via bulk patch (one Python pass — verified mf=1 ns=1 on every file). Inserts above the newsletter CTA so the retention prompt comes before the email ask. Labs already had hand-curated next-steps blocks — those stay; the new pattern is opt-in via data-slug. SITE_VERSION 1.22.0 → 1.23.0.
New file at /manifest.js exposes window.TLM_MANIFEST with every article (12), lab (9), tool (6), and path on the site. Each page entry carries: slug (matches LocalStorage completion key), title, url, type, CCNA domain, lab number, paths it belongs to, tags, posted date. The CCNA Hub's DOMAIN_MAP and the homelab path's STAGE_TO_SLUG are now both derived from manifest data — so adding a new article means one edit instead of three. progress-display.js bumped to v4: reads manifest if loaded, falls back to its existing hardcoded values otherwise. Backwards compatible everywhere — pages without manifest.js work exactly as before. Foundation for the no-dead-ends pillar (auto-generated "What's Next") and a future site-wide search. SITE_VERSION 1.21.0 → 1.22.0.
New tool at /cheatsheet.html. VLAN, inter-VLAN, STP, EtherChannel, OSPF (single + multi-area), static routing, ACL, NAT/PAT, DHCP, CDP/LLDP, and IPv6 — each topic gets config templates, show commands, and a classic exam gotcha. Copy button on every code block, hash-deep-linkable (#ospf, #acl etc.), print-friendly CSS that expands all panels and strips chrome for a single-topic paper sheet. Sized for SEO — the meta title and topic headings cover the high-volume "cisco ___ cheat sheet" search variants. Linked from /tools.html under a new REFERENCE section. Sitemap and llms.txt updated. SITE_VERSION 1.20.1 → 1.21.0.
Before opening the drill up for public play I walked the engine code looking for edge cases. Three real bugs found and fixed: (1) the "middle line" targeting branch in pickWeightedTarget was off-by-one — for an N-line ACL it could only target idx 0 to N-2, so the last line could literally never be the correct answer. Now spans 1 to N-1. (2) buildImplicitDenyPacket picked the packet's protocol from [tcp, udp] but always picked its port from TCP_PORTS — a UDP packet could end up shown as "Protocol: UDP, Dest port: 3389" which is incoherent. Port now keyed off the chosen protocol. (3) When the answer was implicit deny, the implicit-deny row didn't get the green match-correct highlight that real lines do. Added data-idx="implicit" to the row and the highlight logic now branches on result type. Engine source-of-truth architecture made these surface easily — generator stayed honest, only the question-distribution layer needed fixes.
First non-CCNA learning path: /paths/homelab/ — five-stage build order (foundation → network edge → compute → self-hosting → operate). Each stage card flips to green when the linked article is marked complete in LocalStorage. Homepage gets a new "★ CHOOSE YOUR PATH" section between the subnet banner and the blog grid: 5 cards (CCNA · Homelab · Fortinet · Self-Hosting · Career), first two clickable, last three marked DRAFTING. The homelab path-card on /start-here.html now leads with a link to the full path. Sitemap + llms.txt updated.
Live but noindex at /acl-practice.html. Randomized ACL + packet generator, top-down evaluation engine, three difficulty modes (standard / extended / mixed default), score persistence in LocalStorage, field-by-field walkthrough on every answer, classic-trap callout when a wrong-but-later-matching line is picked. ~45 KB self-contained HTML+CSS+JS. v1 scope: tcp/udp/ip protocols, eq port operator only, prefix-aligned wildcards, RFC1918 sources. Out of scope for v1: named ACLs, source ports, gt/lt/range, ICMP types, established. Holding on launch until QA pass.
Took a hard look at why the site has traffic but low retention. Diagnosed the real problem: every page renders as an endpoint, not a vertex in a graph. Drafted a phase-based plan to fix it — build-log, completion tracking, "no dead ends" module, learning paths. Phase 1 starts today.
Shipped the foundation of the retention architecture: this build log itself (now visible in the nav and on the homepage), a LocalStorage-backed "Mark Complete" checkbox on every lab and article, and a "What's Next" module replacing the old "previous / next" file-order navigation on Lab 5, Lab 7, and Lab 8. No accounts, no database — pure client-side state, no friction.
Four-device topology demonstrating Cisco Discovery Protocol vs IEEE 802.1AB LLDP, with a security angle (what each protocol leaks, why CDP off on edge interfaces). Domain 2 of the CCNA Hub flipped from 44% → 56% covered. SITE_VERSION 1.17.1 → 1.18.0.
Big monetization day. Added 10 new Amazon products to inventory (OCG Library, Cisco 2960X, console cable, MikroTik, Klein tester, UPS, Pi 5, Beelink Ryzen), wired contextual affiliate-boxes across 20+ pages, deployed a sticky yellow OCG banner on the resources page and CCNA Hub, and bulk-applied rel="sponsored noopener" to every amazon.ca link for Google compliance. Impact tracking pixel verified. Pearson IT Cert (CJ), Pluralsight (Impact), Udemy (Impact) applications submitted.
Got told some of the OSPF content was wrong. Audited articles 9/10/12 and lab-doc-8 against standard OSPF behaviour. Found three real issues: (1) article-9 incorrectly called multi-area a "CCNP topic" — rewrote to clarify it's in scope for CCNA understanding; (2) lab-doc-8 sample show ip ospf neighbor output showed all neighbours as FULL/DR, which is mathematically impossible given the router-IDs — corrected R10 and R20 to FULL/BDR; (3) show ip route ospf sample included a "C" connected route that command never returns. All fixed.
Six routers, five OSPF areas, three ABRs, one router in interface-mode OSPF. Built and shipped alongside Article 12, the LSA types deep-dive (Type 1/2/3/4/5/7, flooding scope, packet types, stub area variants). Domain 3 of the CCNA Hub deepened — multi-area is technically beyond the CCNA blueprint's hands-on config requirement, but the concepts and LSA terminology are squarely in scope. SITE_VERSION 1.17.0.
All three EtherChannel modes in one Packet Tracer topology: a routed PAgP /30 between L3 distribution switches, an LACP active/passive trunk between access switches, and a static "on/on" bundle on the third. End-to-end ping across all three modes proves the whole stack. CCNA Hub Domain 2.4 flipped to COVERED. SITE_VERSION 1.16.0.
Cleared the IPv6 + static-routing backlog in one push: Lab 6 (static + floating static routes), Article 11 (IPv6 for the CCNA — compression, address types, EUI-64), tools.html landing page, and three new interactive tools — IPv6 subnetting drill, IPv6 address types quiz, EUI-64 converter. CCNA Hub Domains 1.8, 1.9, 3.3 all flipped to COVERED.
The CCNA Hub went live — a full exam-blueprint map of the 200-301 with every topic linked to the article, lab, or tool that covers it. Same day, migrated the newsletter from Buttondown to beehiiv (custom domain mail.thelineman.ca, all DNS swapped to Cloudflare). Two structural changes in one push.
Spent a day reviewing every article and lab-doc against Google Search Console data. Rewrote page titles to lead with keywords. Tightened meta descriptions. Rewrote lab-doc H1s to read like search queries ("Configure VLANs in Packet Tracer" rather than "VLAN Lab 1"). The compounding effect of this kind of cleanup is invisible until weeks later.
Newsletter signup wired across the site with a working welcome automation. Resources page populated with Amazon Associates (Fortinet 60F, FortiSwitch 124E, FortiAP 421E) and the first OCG book recommendations. The starting line for treating this as more than a hobby project.
First articles were the Fortinet-on-a-budget piece and the subnetting one — written for past-me, who'd been studying for the CCNA and was stuck on subnetting. The whole "build in public" angle wasn't planned; it just happened to be how I write. Static HTML, Apache2, Cloudflare Tunnel — no CMS, no framework, no analytics beyond self-hosted Umami. Same stack now as on day one.
This log updates every time something ships. Want it in your inbox instead? Subscribe to the newsletter for the weekly recap.