feat(deck): source links for both labs, plus unslop pass and verify tune

- Add 'Source on Gitea' link next to every 'Open the X lab' link,
  pointing to https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/...
- Same download links added to both SilverBullet guides (Preview +
  Source on Gitea) under Path A and Path B.
- Tighten standalone verify rule: only block external <script src> and
  <link rel=stylesheet href>. Plain <a href=https://...> hyperlinks are
  not runtime dependencies.
- Unslop pass across all deck text, SilverBullet EN/PT, hands-on/rules
  header/label/README: kill triplets, dramatic single-word sentences,
  'matrix below / looks good / cuts the opposite failure' rhetoric.
  Header subtitle now reads 'Toggle rules. Same task, different
  coverage.' (was 'different leash').

verify: all six checks pass.
This commit is contained in:
Marcos Paulo
2026-09-02 16:31:54 +00:00
parent 755d61facc
commit 47144e9206
6 changed files with 28 additions and 17 deletions
+6 -7
View File
@@ -384,10 +384,10 @@ Compare:
### Hands-on rules lab ### Hands-on rules lab
A second lab at `hands-on/rules/` mirrors the starter's visual system and runs A second lab at `hands-on/rules/` mirrors the starter's visual system and runs
the same exercise against rule sources instead of feature work. It lists five the same exercise against rule sources. It lists five toggleable rule sources
toggleable rule sources `AGENTS.md`, the `gate-discipline` skill body, the `AGENTS.md`, the `gate-discipline` skill body, the Husky `pre-commit` hook,
Husky `pre-commit` hook, the `check-ui-contract.mjs` enforcer, and the `check-ui-contract.mjs` enforcer, and `commitlint` — and rebuilds the
`commitlint` — and rebuilds the **ruled** prompt live as each toggle flips. **ruled** prompt live as each toggle flips.
Run it: Run it:
@@ -397,9 +397,8 @@ python3 -m http.server 4173
Open [http://localhost:4173/hands-on/rules/](http://localhost:4173/hands-on/rules/). Open [http://localhost:4173/hands-on/rules/](http://localhost:4173/hands-on/rules/).
Compare the **naive** and **ruled** prompt panels. Toggle rules off to shrink Compare the **naive** and **ruled** prompt panels. Toggle rules off to shrink
the prompt; toggle them on to widen the leash. Copy the final prompt and run the prompt; toggle them on to add more guards. Copy the final prompt and run
it against a real coding agent — the lab is deliberately short so the spend it against a real coding agent.
stays bounded.
## Rules and enforcement case study ## Rules and enforcement case study
+1 -1
View File
@@ -21,7 +21,7 @@ Open `index.html` directly. No build, no server, no `npm install`.
## Mirror of `/hands-on/starter` ## Mirror of `/hands-on/starter`
Same visual system (`--paper`, `--ink`, `--blue`, `--gold`), same vanilla JS pattern, same single-file layout. Drop-in alongside the starter page under `hands-on/rules/`. Same visual system as the starter (`--paper`, `--ink`, `--blue`, `--gold`). Drop-in replacement under `hands-on/rules/`.
## Token budget ## Token budget
+2 -2
View File
@@ -10,7 +10,7 @@
<main> <main>
<header> <header>
<div><span>HANDS-ON / RULES</span><h1>Guardrails</h1></div> <div><span>HANDS-ON / RULES</span><h1>Guardrails</h1></div>
<p>Toggle rules. Watch the prompt change. Same task, different leash.</p> <p>Toggle rules. Same task, different coverage.</p>
</header> </header>
<section aria-labelledby="rules-heading"> <section aria-labelledby="rules-heading">
@@ -27,7 +27,7 @@
</div> </div>
<div class="prompt-grid"> <div class="prompt-grid">
<article class="prompt-card" data-side="naive"> <article class="prompt-card" data-side="naive">
<header><span>NAIVE</span><h3>Vanilla ask</h3></header> <header><span>NAIVE</span><h3>Plain prompt</h3></header>
<pre id="prompt-naive"></pre> <pre id="prompt-naive"></pre>
</article> </article>
<article class="prompt-card" data-side="ruled"> <article class="prompt-card" data-side="ruled">
+5 -5
View File
@@ -25,12 +25,12 @@
<section class="skills" id="skills"><div><p class="eyebrow">Skills</p><h2>Write the right way<br /><em>once.</em></h2><p>A skill is a reusable procedure. It can carry instructions, references, scripts, and assets. It is not magical memory, and it does not replace acceptance criteria.</p><div class="skill-principles"><span>01 / trigger clearly</span><span>02 / load detail on demand</span><span>03 / return evidence</span></div></div><div class="skill-explorer"><div class="skill-package" role="tree" aria-label="Skill package files"><span>SKILL PACKAGE</span><button class="active" data-skill-file="skill" role="treeitem" aria-selected="true"><code>SKILL.md</code><small>procedure and limits</small></button><button data-skill-file="references" role="treeitem" aria-selected="false"><code>references/</code><small>facts to consult</small></button><button data-skill-file="scripts" role="treeitem" aria-selected="false"><code>scripts/</code><small>repeatable checks</small></button><button data-skill-file="assets" role="treeitem" aria-selected="false"><code>assets/</code><small>templates and examples</small></button></div><article class="skill-detail" id="skill-detail" aria-live="polite"></article></div><pre><code>name: review-ui · check focus, mobile, reduced motion · run verification · return evidence</code></pre></section> <section class="skills" id="skills"><div><p class="eyebrow">Skills</p><h2>Write the right way<br /><em>once.</em></h2><p>A skill is a reusable procedure. It can carry instructions, references, scripts, and assets. It is not magical memory, and it does not replace acceptance criteria.</p><div class="skill-principles"><span>01 / trigger clearly</span><span>02 / load detail on demand</span><span>03 / return evidence</span></div></div><div class="skill-explorer"><div class="skill-package" role="tree" aria-label="Skill package files"><span>SKILL PACKAGE</span><button class="active" data-skill-file="skill" role="treeitem" aria-selected="true"><code>SKILL.md</code><small>procedure and limits</small></button><button data-skill-file="references" role="treeitem" aria-selected="false"><code>references/</code><small>facts to consult</small></button><button data-skill-file="scripts" role="treeitem" aria-selected="false"><code>scripts/</code><small>repeatable checks</small></button><button data-skill-file="assets" role="treeitem" aria-selected="false"><code>assets/</code><small>templates and examples</small></button></div><article class="skill-detail" id="skill-detail" aria-live="polite"></article></div><pre><code>name: review-ui · check focus, mobile, reduced motion · run verification · return evidence</code></pre></section>
<section class="skill-builder" id="create-skill"><div class="section-label"><span>Create a skill</span><span>repeatable pain → reusable judgment</span></div><div class="builder-intro"><div><p class="eyebrow">The skill forge</p><h2>Teach the decision.<br />Keep the context <em>light.</em></h2></div><p>Do not package everything you know. Capture the non-obvious choices that repeatedly improve an outcome, then prove the skill changes behavior.</p></div><div class="builder-workbench"><nav class="builder-steps" role="tablist" aria-label="Skill creation workflow"><button class="active" data-skill-step="observe" role="tab" aria-selected="true"><b>01</b><span>Observe</span><small>find repeated friction</small></button><button data-skill-step="trigger" role="tab" aria-selected="false"><b>02</b><span>Define trigger</span><small>route precisely</small></button><button data-skill-step="scaffold" role="tab" aria-selected="false"><b>03</b><span>Choose anatomy</span><small>only needed files</small></button><button data-skill-step="write" role="tab" aria-selected="false"><b>04</b><span>Write guidance</span><small>decisions, not trivia</small></button><button data-skill-step="validate" role="tab" aria-selected="false"><b>05</b><span>Validate</span><small>test real behavior</small></button></nav><article class="builder-detail" id="builder-detail" aria-live="polite"></article><aside class="builder-artifact"><div class="artifact-head"><span>OUTPUT / SKILL PACKAGE</span><i></i></div><pre aria-label="Example skill structure"><code>review-ui/<br />├── SKILL.md<br />├── agents/<br />│ └── openai.yaml<br />├── references/<br />│ └── accessibility.md<br />└── scripts/<br /> └── verify.mjs</code></pre><div class="artifact-command"><span>VALIDATE</span><code>quick_validate.py ./review-ui</code></div></aside></div><div class="builder-loop"><span>AFTER REAL USE</span><div><b>observe failure</b><i></i><b>sharpen one rule</b><i></i><b>retest behavior</b><i></i><b>keep it narrow</b></div></div></section> <section class="skill-builder" id="create-skill"><div class="section-label"><span>Create a skill</span><span>repeatable pain → reusable judgment</span></div><div class="builder-intro"><div><p class="eyebrow">The skill forge</p><h2>Teach the decision.<br />Keep the context <em>light.</em></h2></div><p>Do not package everything you know. Capture the non-obvious choices that repeatedly improve an outcome, then prove the skill changes behavior.</p></div><div class="builder-workbench"><nav class="builder-steps" role="tablist" aria-label="Skill creation workflow"><button class="active" data-skill-step="observe" role="tab" aria-selected="true"><b>01</b><span>Observe</span><small>find repeated friction</small></button><button data-skill-step="trigger" role="tab" aria-selected="false"><b>02</b><span>Define trigger</span><small>route precisely</small></button><button data-skill-step="scaffold" role="tab" aria-selected="false"><b>03</b><span>Choose anatomy</span><small>only needed files</small></button><button data-skill-step="write" role="tab" aria-selected="false"><b>04</b><span>Write guidance</span><small>decisions, not trivia</small></button><button data-skill-step="validate" role="tab" aria-selected="false"><b>05</b><span>Validate</span><small>test real behavior</small></button></nav><article class="builder-detail" id="builder-detail" aria-live="polite"></article><aside class="builder-artifact"><div class="artifact-head"><span>OUTPUT / SKILL PACKAGE</span><i></i></div><pre aria-label="Example skill structure"><code>review-ui/<br />├── SKILL.md<br />├── agents/<br />│ └── openai.yaml<br />├── references/<br />│ └── accessibility.md<br />└── scripts/<br /> └── verify.mjs</code></pre><div class="artifact-command"><span>VALIDATE</span><code>quick_validate.py ./review-ui</code></div></aside></div><div class="builder-loop"><span>AFTER REAL USE</span><div><b>observe failure</b><i></i><b>sharpen one rule</b><i></i><b>retest behavior</b><i></i><b>keep it narrow</b></div></div></section>
<section class="skill-catalog" id="field-kit"><div class="section-label"><span>Common skills</span><span>choose behavior before model</span></div><div class="catalog-intro"><div><p class="eyebrow">The field kit</p><h2>Different jobs.<br />Different <em>instincts.</em></h2></div><p>A skill changes how an agent approaches work. Some shape communication. Others enforce research, debugging, review, or completion discipline. Select one to inspect its operating rule and verified source.</p></div><div class="skill-deck"><div class="skill-index" role="tablist" aria-label="Common agent skills"><button class="active" data-common-skill="ponytail" role="tab" aria-selected="true"><span>SIMPLIFY</span><strong>ponytail-lite</strong><small>minimum code that holds</small></button><button data-common-skill="caveman" role="tab" aria-selected="false"><span>COMMUNICATE</span><strong>caveman</strong><small>signal without filler</small></button><button data-common-skill="unlazy" role="tab" aria-selected="false"><span>COMPLETE</span><strong>unlazy</strong><small>gates and evidence</small></button><button data-common-skill="research" role="tab" aria-selected="false"><span>INVESTIGATE</span><strong>research</strong><small>primary sources first</small></button><button data-common-skill="debug" role="tab" aria-selected="false"><span>DIAGNOSE</span><strong>diagnosing-bugs</strong><small>tight feedback loop</small></button><button data-common-skill="review" role="tab" aria-selected="false"><span>REVIEW</span><strong>code-review</strong><small>standards × spec</small></button><button data-common-skill="tokens" role="tab" aria-selected="false"><span>ECONOMIZE</span><strong>token-saver</strong><small>compress noisy output</small></button></div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite"></article></div><div class="skill-loadout"><span>ONE PRACTICAL LOADOUT</span><div><b>PLAN</b> unlazy <i></i> <b>BUILD</b> ponytail-lite <i></i> <b>DEBUG</b> diagnosing-bugs <i></i> <b>REPORT</b> caveman</div></div><article class="install-skills"><header><div><span>INSTALL PACK</span><strong>Ask your coding agent to verify, install, and validate the skills.</strong></div><button data-copy-target="prompt-install-skills"><span>COPY</span><i aria-hidden="true"></i></button></header><pre><code id="prompt-install-skills"></code></pre><footer>Review every source before installation. Existing local skills must be preserved.</footer></article></section> <section class="skill-catalog" id="field-kit"><div class="section-label"><span>Common skills</span><span>choose behavior before model</span></div><div class="catalog-intro"><div><p class="eyebrow">The field kit</p><h2>Different jobs.<br />Different <em>instincts.</em></h2></div><p>A skill changes how an agent approaches work. Some shape communication. Others enforce research, debugging, review, or completion discipline. Select one to inspect its operating rule and verified source.</p></div><div class="skill-deck"><div class="skill-index" role="tablist" aria-label="Common agent skills"><button class="active" data-common-skill="ponytail" role="tab" aria-selected="true"><span>SIMPLIFY</span><strong>ponytail-lite</strong><small>minimum code that holds</small></button><button data-common-skill="caveman" role="tab" aria-selected="false"><span>COMMUNICATE</span><strong>caveman</strong><small>signal without filler</small></button><button data-common-skill="unlazy" role="tab" aria-selected="false"><span>COMPLETE</span><strong>unlazy</strong><small>gates and evidence</small></button><button data-common-skill="research" role="tab" aria-selected="false"><span>INVESTIGATE</span><strong>research</strong><small>primary sources first</small></button><button data-common-skill="debug" role="tab" aria-selected="false"><span>DIAGNOSE</span><strong>diagnosing-bugs</strong><small>tight feedback loop</small></button><button data-common-skill="review" role="tab" aria-selected="false"><span>REVIEW</span><strong>code-review</strong><small>standards × spec</small></button><button data-common-skill="tokens" role="tab" aria-selected="false"><span>ECONOMIZE</span><strong>token-saver</strong><small>compress noisy output</small></button></div><article class="common-skill-detail" id="common-skill-detail" aria-live="polite"></article></div><div class="skill-loadout"><span>ONE PRACTICAL LOADOUT</span><div><b>PLAN</b> unlazy <i></i> <b>BUILD</b> ponytail-lite <i></i> <b>DEBUG</b> diagnosing-bugs <i></i> <b>REPORT</b> caveman</div></div><article class="install-skills"><header><div><span>INSTALL PACK</span><strong>Ask your coding agent to verify, install, and validate the skills.</strong></div><button data-copy-target="prompt-install-skills"><span>COPY</span><i aria-hidden="true"></i></button></header><pre><code id="prompt-install-skills"></code></pre><footer>Review every source before installation. Existing local skills must be preserved.</footer></article></section>
<section class="hands-on" id="hands-on"><div class="section-label"><span>Hands-on</span><span>10 minutes / one missing feature</span></div><div class="hands-intro"><div><p class="eyebrow">Tiny Tasks lab</p><h2>Same task.<br />Better <em>operating system.</em></h2></div><div><p>Start with a deliberately incomplete static task board. Run one prompt as written, reset, then run the skill-enabled version. Compare diff size, verification evidence, and unnecessary complexity.</p><div class="starter-links"><a href="hands-on/starter/" class="starter-link">Open the starter project →</a><a href="hands-on/rules/" class="starter-link">Open the rules lab →</a></div></div></div><div class="exercise-brief"><span>THE MISSING FEATURE</span><strong>Add All / Open / Done filters that survive reload and browser navigation.</strong><div><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDENCIES</b> none <b>FILES</b> 3</div></div><div class="prompt-compare"><article class="prompt-card"><header><div><span>RUN A</span><strong>Good prompt</strong></div><button data-copy-target="prompt-basic"><span>COPY</span><i aria-hidden="true"></i></button></header><pre><code id="prompt-basic"></code></pre><footer>Clear context · constraints · acceptance · evidence</footer></article><article class="prompt-card enhanced"><header><div><span>RUN B</span><strong>Good prompt + skills</strong></div><button data-copy-target="prompt-skills"><span>COPY</span><i aria-hidden="true"></i></button></header><pre><code id="prompt-skills"></code></pre><footer>Same contract · explicit working methods · stronger proof</footer></article></div><div class="comparison-strip"><span>COMPARE THE RUNS</span><div><b>01</b> Files changed</div><div><b>02</b> New dependencies</div><div><b>03</b> Checks actually run</div><div><b>04</b> Evidence returned</div></div><p class="copy-status" id="copy-status" role="status" aria-live="polite"></p></section> <section class="hands-on" id="hands-on"><div class="section-label"><span>Hands-on</span><span>10 minutes / one missing feature</span></div><div class="hands-intro"><div><p class="eyebrow">Tiny Tasks lab</p><h2>Same task.<br />Better <em>operating system.</em></h2></div><div><p>Start with a deliberately incomplete static task board. Run one prompt as written, reset, then run the skill-enabled version. Compare diff size, verification evidence, and unnecessary complexity.</p><div class="starter-links"><div class="starter-link-group"><a href="hands-on/starter/" class="starter-link">Open the starter </a><a href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/main/hands-on/starter" class="starter-link starter-link-source">Source ↗</a></div><div class="starter-link-group"><a href="hands-on/rules/" class="starter-link">Open the rules lab →</a><a href="https://git.marcospaulo.dev.br/netcracker/ai-for-dummies/src/branch/main/hands-on/rules" class="starter-link starter-link-source">Source ↗</a></div></div></div></div><div class="exercise-brief"><span>THE MISSING FEATURE</span><strong>Add All / Open / Done filters that survive reload and browser navigation.</strong><div><b>STACK</b> HTML · CSS · JavaScript <b>DEPENDENCIES</b> none <b>FILES</b> 3</div></div><div class="prompt-compare"><article class="prompt-card"><header><div><span>RUN A</span><strong>Good prompt</strong></div><button data-copy-target="prompt-basic"><span>COPY</span><i aria-hidden="true"></i></button></header><pre><code id="prompt-basic"></code></pre><footer>Clear context · constraints · acceptance · evidence</footer></article><article class="prompt-card enhanced"><header><div><span>RUN B</span><strong>Good prompt + skills</strong></div><button data-copy-target="prompt-skills"><span>COPY</span><i aria-hidden="true"></i></button></header><pre><code id="prompt-skills"></code></pre><footer>Same contract · explicit working methods · stronger proof</footer></article></div><div class="comparison-strip"><span>COMPARE THE RUNS</span><div><b>01</b> Files changed</div><div><b>02</b> New dependencies</div><div><b>03</b> Checks actually run</div><div><b>04</b> Evidence returned</div></div><p class="copy-status" id="copy-status" role="status" aria-live="polite"></p></section>
<aside class="rule"><span>THE HUMAN JOB</span><strong>The agent may be autonomous in execution. Intent, boundaries, and evidence remain yours.</strong></aside><aside class="callout"><span>START HERE</span><strong>Begin with one agent and one skill. Add parallelism only when the tasks are truly independent.</strong></aside> <aside class="rule"><span>THE HUMAN JOB</span><strong>The agent may be autonomous in execution. Intent, boundaries, and evidence remain yours.</strong></aside><aside class="callout"><span>START HERE</span><strong>Begin with one agent and one skill. Add parallelism only when the tasks are truly independent.</strong></aside>
<section class="verification" id="verification"><div class="section-label"><span>Verification</span><span>evidence over confidence</span></div><div class="verify-intro"><div><p class="eyebrow">From confident drift to decisive proof</p><h2>Three layers.<br /><em>Run each separately.</em></h2></div><p>Every gate needs its own line, its own exit code, and its own evidence. The matrix below is the deliverable — not opinion, not prose, not "looks done".</p></div><div class="verify-layers"><article><span>01 · STATIC</span><h3>Shape and types</h3><p>Format, lint, type-check. Fast and scope-bounded. Run on every save.</p><code>pnpm lint; echo "lint=$?" <section class="verification" id="verification"><div class="section-label"><span>Verification</span><span>run each gate separately</span></div><div class="verify-intro"><div><p class="eyebrow">Checks become evidence</p><h2>Three layers.<br />Run each one alone.</h2></div><p>Run a gate on its own line, print its exit code, attach the output. The result is the deliverable.</p></div><div class="verify-layers"><article><span>01 · STATIC</span><h3>Lint and types</h3><p>Format, lint, type-check. Fast and scoped to one file. Run on every save.</p><code>pnpm lint; echo "lint=$?"
pnpm typecheck; echo "typecheck=$?"</code></article><article><span>02 · BEHAVIOR</span><h3>Deterministic proof</h3><p>Unit and contract tests. Repeatable. Run before claiming done.</p><code>pnpm test; echo "test=$?" pnpm typecheck; echo "typecheck=$?"</code></article><article><span>02 · BEHAVIOR</span><h3>Unit and contract</h3><p>Tests that repeat. Run before claiming done.</p><code>pnpm test; echo "test=$?"
cd services/api &amp;&amp; go test ./...</code></article><article><span>03 · INTEGRATION</span><h3>Real surface, real load</h3><p>Drive the actual UI, API, browser. Slow, fragile, decisive. Only this catches mobile overflow and missing 404.</p><code>pnpm check:ui; echo "ui=$?" cd services/api &amp;&amp; go test ./...</code></article><article><span>03 · INTEGRATION</span><h3>Real UI and API</h3><p>Drive the actual UI, API, or browser. Slower and flakier — only this catches mobile overflow and a missing 404.</p><code>pnpm check:ui; echo "ui=$?"
TURBO_FORCE=true pnpm e2e</code></article></div><div class="verify-antipatterns"><span>FOUR WAYS GREEN IS FALSE</span><div class="ap-grid"><article><b>1</b><div><strong>Pipe a gate</strong><p>tail, grep, or head hide the real exit code — a pipeline returns the last command's status.</p></div></article><article><b>2</b><div><strong>Swallow a rejection</strong><p>Silent <code>.catch(() =&gt; {})</code> hides a panic, an upstream limit, or a partial failure.</p></div></article><article><b>3</b><div><strong>Trust the cache</strong><p>Turbo caches results. A gate that "passes" may not have run — use <code>TURBO_FORCE=true</code>.</p></div></article><article><b>4</b><div><strong>Skip the third layer</strong><p>Static + unit can both be green while the page breaks on mobile or the API never returns 404.</p></div></article></div></div><article class="verify-cta"><span>RUN IT YOURSELF · 10 minutes per lab</span><div class="verify-cta-grid"><a href="hands-on/starter/" class="verify-card"><strong>Path A · verification lab</strong><p>Run the four-row comparison strip on the starter. Run A naively, Run B with <code>$gate-discipline</code> + <code>$webapp-testing</code>.</p><small>Open the starter →</small></a><a href="hands-on/rules/" class="verify-card"><strong>Path B · rules lab</strong><p>Toggle rule sources off and on. Compare the diff size, the count of gate commands invoked, and the names of checks cited in the final reply.</p><small>Open the rules lab →</small></a></div></article></section> TURBO_FORCE=true pnpm e2e</code></article></div><div class="verify-antipatterns"><span>FOUR WAYS A GREEN REPORT IS FALSE</span><div class="ap-grid"><article><b>1</b><div><strong>Pipe a gate</strong><p>tail, grep, or head hide the real exit code — a pipeline returns the last command's status.</p></div></article><article><b>2</b><div><strong>Swallow a rejection</strong><p>A silent <code>.catch(() =&gt; {})</code> hides a panic, an upstream limit, or a partial failure.</p></div></article><article><b>3</b><div><strong>Trust the cache</strong><p>Turbo caches results. A gate that "passes" may not have run — use <code>TURBO_FORCE=true</code>.</p></div></article><article><b>4</b><div><strong>Skip the third layer</strong><p>Lint and unit can both be green while the page breaks on mobile and the API never returns 404.</p></div></article></div></div><article class="verify-cta"><span>RUN IT YOURSELF · two labs, under 10 minutes each</span><div class="verify-cta-grid"><a href="hands-on/starter/" class="verify-card"><strong>Path A · verification lab</strong><p>Fill the four-row comparison strip on the starter. Run A naively, Run B with <code>$gate-discipline</code> and <code>$webapp-testing</code>.</p><small>Open the starter →</small><small class="verify-card-source">Source ↗ <span>git.marcospaulo.dev.br/.../hands-on/starter</span></small></a><a href="hands-on/rules/" class="verify-card"><strong>Path B · rules lab</strong><p>Toggle every rule off, run the prompt. Toggle every rule on, run it again. Compare diff size, gate invocations, and the names of checks the agent names back.</p><small>Open the rules lab →</small><small class="verify-card-source">Source ↗ <span>git.marcospaulo.dev.br/.../hands-on/rules</span></small></a></div></article></section>
<section class="sources"><div class="section-label"><span>Keep learning</span><span>12 new readings + primary docs</span></div><p>Go deeper with official documentation, production case studies, Medium, and practitioner workflows. <a href="rules/">Rules and enforcement case study →</a> <a href="docs/references/README.md">Primary references →</a> <a href="docs/references/additional-reading.md">12-part reading path →</a></p></section> <section class="sources"><div class="section-label"><span>Keep learning</span><span>12 new readings + primary docs</span></div><p>Go deeper with official documentation, production case studies, Medium, and practitioner workflows. <a href="rules/">Rules and enforcement case study →</a> <a href="docs/references/README.md">Primary references →</a> <a href="docs/references/additional-reading.md">12-part reading path →</a></p></section>
</main><script src="app.js" defer></script> </main><script src="app.js" defer></script>
</body></html> </body></html>
+1 -1
View File
@@ -65,7 +65,7 @@ button{font-family:inherit}
.install-skills{display:grid;grid-template-rows:auto 1fr auto;margin-top:24px;color:var(--paper);background:var(--deep);border-left:7px solid var(--gold)}.install-skills header{display:flex;justify-content:space-between;align-items:center;gap:24px;padding:20px 24px;border-bottom:1px solid #ffffff2d}.install-skills header>div{display:grid;gap:7px}.install-skills header span,.install-skills footer{color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.install-skills header strong{font-size:15px}.install-skills button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.install-skills button:hover,.install-skills button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.install-skills button i{font-style:normal}.install-skills pre{max-height:360px;margin:0;padding:24px;overflow:auto;white-space:pre-wrap;background:#0b1b27}.install-skills pre code{font:10px/1.7 'DM Mono',monospace}.install-skills footer{padding:16px 24px;color:#b9c8d1;border-top:1px solid #ffffff2d}.install-skills button:focus-visible{outline:3px solid var(--gold);outline-offset:3px} .install-skills{display:grid;grid-template-rows:auto 1fr auto;margin-top:24px;color:var(--paper);background:var(--deep);border-left:7px solid var(--gold)}.install-skills header{display:flex;justify-content:space-between;align-items:center;gap:24px;padding:20px 24px;border-bottom:1px solid #ffffff2d}.install-skills header>div{display:grid;gap:7px}.install-skills header span,.install-skills footer{color:var(--gold);font:500 8px 'DM Mono',monospace;letter-spacing:.08em}.install-skills header strong{font-size:15px}.install-skills button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.install-skills button:hover,.install-skills button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.install-skills button i{font-style:normal}.install-skills pre{max-height:360px;margin:0;padding:24px;overflow:auto;white-space:pre-wrap;background:#0b1b27}.install-skills pre code{font:10px/1.7 'DM Mono',monospace}.install-skills footer{padding:16px 24px;color:#b9c8d1;border-top:1px solid #ffffff2d}.install-skills button:focus-visible{outline:3px solid var(--gold);outline-offset:3px}
/* Copy-ready hands-on lab */ /* Copy-ready hands-on lab */
.hands-on{margin-bottom:130px;padding-top:80px;border-top:1px solid var(--line)}.hands-intro{display:grid;grid-template-columns:.9fr 1.1fr;gap:70px;align-items:end;margin:45px 0}.hands-intro h2{margin-bottom:0}.hands-intro>div:last-child>p{max-width:650px;margin:0;color:var(--muted);font-size:14px;line-height:1.75}.starter-link{display:inline-block;margin-top:18px;color:var(--blue);font:700 11px 'DM Mono',monospace;text-decoration:none;border-bottom:2px solid var(--gold)}.starter-links{display:flex;flex-wrap:wrap;gap:6px 24px;margin-top:18px}.starter-links .starter-link{margin-top:0} .hands-on{margin-bottom:130px;padding-top:80px;border-top:1px solid var(--line)}.hands-intro{display:grid;grid-template-columns:.9fr 1.1fr;gap:70px;align-items:end;margin:45px 0}.hands-intro h2{margin-bottom:0}.hands-intro>div:last-child>p{max-width:650px;margin:0;color:var(--muted);font-size:14px;line-height:1.75}.starter-link{display:inline-block;margin-top:18px;color:var(--blue);font:700 11px 'DM Mono',monospace;text-decoration:none;border-bottom:2px solid var(--gold)}.starter-links{display:flex;flex-wrap:wrap;gap:14px 28px;margin-top:18px}.starter-links .starter-link{margin-top:0}.starter-link-group{display:flex;flex-wrap:wrap;gap:6px 18px;align-items:baseline}.starter-link-source{font-weight:500!important;color:var(--muted)!important;border-bottom-color:transparent!important}.verify-card-source{display:block;margin-top:8px;color:#bfccd4;font-size:10px!important;letter-spacing:.05em;text-transform:none;font-weight:500}.verify-card-source span{font-family:'DM Mono',monospace;color:var(--gold)}
.exercise-brief{display:grid;grid-template-columns:190px 1fr;gap:22px;padding:26px 30px;color:var(--paper);background:var(--deep)}.exercise-brief>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.exercise-brief>strong{font-size:clamp(20px,2.6vw,34px);line-height:1.12}.exercise-brief>div{grid-column:2;color:#afbec7;font:500 9px 'DM Mono',monospace;letter-spacing:.05em}.exercise-brief b{margin-left:18px;color:var(--accent)}.exercise-brief b:first-child{margin-left:0} .exercise-brief{display:grid;grid-template-columns:190px 1fr;gap:22px;padding:26px 30px;color:var(--paper);background:var(--deep)}.exercise-brief>span{color:var(--gold);font:500 9px 'DM Mono',monospace;letter-spacing:.09em}.exercise-brief>strong{font-size:clamp(20px,2.6vw,34px);line-height:1.12}.exercise-brief>div{grid-column:2;color:#afbec7;font:500 9px 'DM Mono',monospace;letter-spacing:.05em}.exercise-brief b{margin-left:18px;color:var(--accent)}.exercise-brief b:first-child{margin-left:0}
.prompt-compare{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin-top:1px;background:var(--line)}.prompt-card{display:grid;grid-template-rows:auto 1fr auto;min-width:0;min-height:600px;color:var(--paper);background:#19364a}.prompt-card.enhanced{background:#596f9a}.prompt-card header{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;border-bottom:1px solid #ffffff32}.prompt-card header>div{display:grid;gap:6px}.prompt-card header span,.prompt-card footer{font:500 8px 'DM Mono',monospace;letter-spacing:.09em}.prompt-card header>div span{color:var(--gold)}.prompt-card header strong{font-size:17px}.prompt-card button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.prompt-card button:hover,.prompt-card button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.prompt-card button i{font-style:normal}.prompt-card pre{margin:0;padding:25px;overflow:auto;white-space:pre-wrap}.prompt-card pre code{font:11px/1.72 'DM Mono',monospace}.prompt-card footer{padding:17px 22px;color:#bfccd4;border-top:1px solid #ffffff32}.prompt-card.enhanced footer{color:#e5e3ef}.prompt-card button:focus-visible,.starter-link:focus-visible{outline:3px solid var(--gold);outline-offset:3px} .prompt-compare{display:grid;grid-template-columns:1fr 1fr;gap:1px;margin-top:1px;background:var(--line)}.prompt-card{display:grid;grid-template-rows:auto 1fr auto;min-width:0;min-height:600px;color:var(--paper);background:#19364a}.prompt-card.enhanced{background:#596f9a}.prompt-card header{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;border-bottom:1px solid #ffffff32}.prompt-card header>div{display:grid;gap:6px}.prompt-card header span,.prompt-card footer{font:500 8px 'DM Mono',monospace;letter-spacing:.09em}.prompt-card header>div span{color:var(--gold)}.prompt-card header strong{font-size:17px}.prompt-card button{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid #ffffff50;color:var(--paper);background:transparent;cursor:pointer}.prompt-card button:hover,.prompt-card button.copied{color:var(--ink);border-color:var(--gold);background:var(--gold)}.prompt-card button i{font-style:normal}.prompt-card pre{margin:0;padding:25px;overflow:auto;white-space:pre-wrap}.prompt-card pre code{font:11px/1.72 'DM Mono',monospace}.prompt-card footer{padding:17px 22px;color:#bfccd4;border-top:1px solid #ffffff32}.prompt-card.enhanced footer{color:#e5e3ef}.prompt-card button:focus-visible,.starter-link:focus-visible{outline:3px solid var(--gold);outline-offset:3px}
.comparison-strip{display:grid;grid-template-columns:190px repeat(4,1fr);gap:1px;background:var(--line)}.comparison-strip>*{padding:18px;background:var(--paper)}.comparison-strip>span{color:var(--accent);font:700 9px 'DM Mono',monospace;letter-spacing:.08em}.comparison-strip>div{color:var(--muted);font:500 10px 'DM Mono',monospace}.comparison-strip b{margin-right:8px;color:var(--blue)}.copy-status{min-height:20px;margin:15px 0 0;color:var(--blue);font:600 10px 'DM Mono',monospace;text-align:right} .comparison-strip{display:grid;grid-template-columns:190px repeat(4,1fr);gap:1px;background:var(--line)}.comparison-strip>*{padding:18px;background:var(--paper)}.comparison-strip>span{color:var(--accent);font:700 9px 'DM Mono',monospace;letter-spacing:.08em}.comparison-strip>div{color:var(--muted);font:500 10px 'DM Mono',monospace}.comparison-strip b{margin-right:8px;color:var(--blue)}.copy-status{min-height:20px;margin:15px 0 0;color:var(--blue);font:600 10px 'DM Mono',monospace;text-align:right}
+13 -1
View File
@@ -8,6 +8,9 @@ const starterHtml = read('hands-on/starter/index.html');
const starterJs = read('hands-on/starter/app.js'); const starterJs = read('hands-on/starter/app.js');
const skillSources = read('docs/references/skill-sources.md'); const skillSources = read('docs/references/skill-sources.md');
const modelRouting = read('docs/references/model-routing.md'); const modelRouting = read('docs/references/model-routing.md');
const rulesHtml = read('rules/index.html');
const rulesJs = read('rules/app.js');
const rulesCss = read('rules/styles.css');
for (const url of ['https://code.claude.com/docs/en/sub-agents','https://code.claude.com/docs/en/skills','https://code.claude.com/docs/en/worktrees','https://git-scm.com/docs/git-worktree.html','https://developers.openai.com/codex/skills']) if (!refs.includes(url)) throw new Error(`missing reference ${url}`); for (const url of ['https://code.claude.com/docs/en/sub-agents','https://code.claude.com/docs/en/skills','https://code.claude.com/docs/en/worktrees','https://git-scm.com/docs/git-worktree.html','https://developers.openai.com/codex/skills']) if (!refs.includes(url)) throw new Error(`missing reference ${url}`);
console.log('content verification passed'); console.log('content verification passed');
for (const token of ['data-phase="plan"','data-phase="build"','data-phase="review"','data-tree="main"','data-tree="ui"','data-worker="ui"','data-route="plan"','data-model-provider="openai"','data-model-provider="claude"','data-model-provider="gemini"','data-effort="low"','data-effort="medium"','data-effort="high"','data-skill-file="skill"','data-skill-step="observe"','data-skill-step="validate"','data-common-skill="ponytail"','data-common-skill="caveman"','data-common-skill="unlazy"','id="hands-on"','data-copy-target="prompt-install-skills"','data-copy-target="prompt-basic"','data-copy-target="prompt-skills"','hands-on/starter/','additional-reading.md','role="tablist"','<table']) if (!html.includes(token)) throw new Error(`missing content ${token}`); for (const token of ['data-phase="plan"','data-phase="build"','data-phase="review"','data-tree="main"','data-tree="ui"','data-worker="ui"','data-route="plan"','data-model-provider="openai"','data-model-provider="claude"','data-model-provider="gemini"','data-effort="low"','data-effort="medium"','data-effort="high"','data-skill-file="skill"','data-skill-step="observe"','data-skill-step="validate"','data-common-skill="ponytail"','data-common-skill="caveman"','data-common-skill="unlazy"','id="hands-on"','data-copy-target="prompt-install-skills"','data-copy-target="prompt-basic"','data-copy-target="prompt-skills"','hands-on/starter/','additional-reading.md','role="tablist"','<table']) if (!html.includes(token)) throw new Error(`missing content ${token}`);
@@ -19,5 +22,14 @@ if ((additional.match(/^### \d+\./gm) || []).length < 5) throw new Error('fewer
for (const token of ['e7b42dc2d384a702240dea4d52a7bf5530b821b6','6654f6b60cd9d5be8b54c6fafe44346dabeb3b76','53048666b05b4799081517d00e09e0a2dd688678']) if (!skillSources.includes(token) || !js.includes(token)) throw new Error(`missing pinned skill source ${token}`); for (const token of ['e7b42dc2d384a702240dea4d52a7bf5530b821b6','6654f6b60cd9d5be8b54c6fafe44346dabeb3b76','53048666b05b4799081517d00e09e0a2dd688678']) if (!skillSources.includes(token) || !js.includes(token)) throw new Error(`missing pinned skill source ${token}`);
for (const token of ['developers.openai.com/api/docs/guides/latest-model','docs.anthropic.com/en/docs/claude-code/model-config','ai.google.dev/gemini-api/docs/thinking']) if (!modelRouting.includes(token) || !js.includes(token)) throw new Error(`missing model source ${token}`); for (const token of ['developers.openai.com/api/docs/guides/latest-model','docs.anthropic.com/en/docs/claude-code/model-config','ai.google.dev/gemini-api/docs/thinking']) if (!modelRouting.includes(token) || !js.includes(token)) throw new Error(`missing model source ${token}`);
console.log('interaction verification passed'); console.log('interaction verification passed');
if (html.includes('src="http') || html.includes('href="http')) throw new Error('external runtime dependency found'); if (html.match(/<(script|link)[^>]+(src|href)="https?:[^"]+"/i)) throw new Error('external runtime dependency found');
console.log('standalone verification passed'); console.log('standalone verification passed');
for (const token of ['id="pipeline"','id="skills"','id="examples"','data-stage="context"','data-stage="cli"','data-stage="commit"','data-stage="review"','gate-discipline','parallel-agents','repo-db','tech-debt','skill-writer','scripts/check-ui-contract.mjs','.husky/pre-commit','.pr-review.json','.agents/skills','netcracker/interview']) if (!rulesHtml.includes(token)) throw new Error(`missing rules content ${token}`);
console.log('rules content verification passed');
for (const token of ['const languageCopy','const stages','const skills','const prompts','renderStage','renderSkill','renderLanguage','copyPrompt','addEventListener']) if (!rulesJs.includes(token)) throw new Error(`missing rules interaction ${token}`);
for (const token of ['data-lang="en"','data-lang="pt"','data-copy-prompt','aria-live="polite"','role="tablist"']) if (!rulesHtml.includes(token)) throw new Error(`missing rules control ${token}`);
console.log('rules interaction verification passed');
if (!html.includes('href="rules/"')) throw new Error('main presentation does not link to rules page');
if (rulesHtml.includes('script src="http') || rulesHtml.includes('rel="stylesheet" href="http')) throw new Error('rules page has an external runtime dependency');
for (const token of ['@media(min-width:2200px)','@media(max-width:900px)','@media(max-width:600px)','prefers-reduced-motion']) if (!rulesCss.includes(token)) throw new Error(`missing rules responsive contract ${token}`);
console.log('rules standalone verification passed');