13 Commits

Author SHA1 Message Date
Marcos Paulo 054393f7af feat(15d): complete localization of full-guide page to PT 2026-09-05 22:30:50 +00:00
Marcos Paulo f241c5581a docs: verify the base path on the real host
verify-and-publish / gate (push) Successful in 6m21s
verify-and-publish / publish (push) Has been skipped
The real-host smoke test was the migration's #1 production-only failure mode and
had never run. It has now run, without taking the site down: the Astro dist was
published to `pages` additively under two previously-unused paths (`_astro/` and
`_verify/summary/`), so all ten live pages stayed up, then force-pushed away.

Astro's base-prefixed absolute asset URLs resolve on the Pages Server — that was
the actual risk, and it is now proven rather than assumed. Trailing-slash
redirects match `trailingSlash: 'always'`.

Also corrects two things the guide got wrong:

- a `?v=$(git rev-parse --short HEAD)` cache-busting idiom. The Pages Server
  caches for ten minutes keyed on path, so a query string never busted it; the
  guide was telling operators to trust a check that could not work. A file you
  just deleted keeps serving 200 until the cache expires.
- the claim that a push to `main` publishes. It no longer does, and must not
  until cutover.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 05:57:01 +00:00
Marcos Paulo 48c31dc1b3 build: migrate from npm to pnpm
Ten git worktrees each carried their own 225 MB node_modules (1.1 GB across
five) and paid 11s per `npm ci`. pnpm hardlinks from a shared store: the same
five worktrees cost ~250 MB total, and a fresh install is 4s.

What changed beyond the mechanical rename:

- `overrides` moved to `pnpm-workspace.yaml`. pnpm 11 does not read the `pnpm`
  field in package.json *or* npm's top-level `overrides`, and it fails silently
  — the vite/defu/language-server pins would have quietly stopped applying.
- Build scripts are blocked by default in pnpm; esbuild and sharp are allowed
  explicitly via `allowBuilds` (renamed from `onlyBuiltDependencies` in 11).
- `packageManager` + `engines` pin the toolchain.
- gate.sh rejects a package-lock.json/yarn.lock/bun.lock outright, so an agent
  running `npm install` out of habit fails loudly instead of building a second,
  divergent dependency tree.
- CI bootstraps pnpm with `npm install --global pnpm@11.25.0` rather than
  corepack (unbundled as of Node 25) or pnpm/action-setup (this self-hosted
  act-runner has never run a job; fetching a third-party action is not
  something to discover on the first one).

Two pre-existing CI bugs fixed while in the file:

- the gate installed with `npm install --package-lock=false`, which discarded
  the lockfile the previous session had just fixed.
- the visual-regression step imported `playwright`, which is not a dependency,
  and `visual-regression.mjs` has no compare mode anyway — in CI it overwrote
  its own baselines and passed unconditionally. Removed with a comment; it
  comes back when it can diff.

The `publish` job is now manual (`workflow_dispatch`). During the migration
dist/ holds three HTML files against the live pages branch's ten, so publishing
on every push to main would take the site down to a stub. Restore at task 20.

HANDOVER.md's incident log still says npm where it describes what happened at
the time; that is history, not a missed rename.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 04:29:42 +00:00
Marcos Paulo 33df09f541 feat: scaffold astro publishing pipeline 2026-09-05 01:39:47 +00:00
Marcos Paulo aa85c1d0b7 docs: correct the pages publish procedure
`merge --ff-only main` cannot work: the histories diverged some time ago, so
the step fails with `Not possible to fast-forward` and the publish stalls.
Document the normal merge the branch's own history already uses, the stale
local `pages` fast-forward that has to happen first, the take-main-wholesale
conflict resolution, and the tree-equality check that is the real invariant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 00:00:58 +00:00
Marcos Paulo e2bcfff5ab feat: add reader vote widget and vote-service
The skills-review desk is static, so "which draft would you ship?" needs a
stateful counterpart. vote-service is a small Go API on its own pod backed by
a JSON file on a ReadWriteOnce PVC, with one active vote per skill per source
IP as the anti-abuse rule and CORS (ALLOWED_ORIGIN) as the caller boundary.

Deployment notes that differ from the obvious path, all confirmed against the
live cluster: the image is side-loaded with `ctr image import` plus
`imagePullPolicy: Never` because kubelet has no credentials for the Nexus ref;
the pod is pinned to `kubernets` because the hostpath PV takes a nodeAffinity
for whichever node first binds it; and public exposure is Caddy on the VPS,
not the cloudflared tunnel.

The ingress controller runs with `use-forwarded-headers` off, so nginx
overwrites X-Forwarded-For with its own peer — every visitor would collapse
into one voter and each skill would cap at one vote overall. Caddy stamps the
true remote address into X-Client-IP, which nginx forwards untouched, and
clientIP() reads that first. Scoped to this app rather than flipping the
global flag, which would change client-IP handling for every other ingress.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:49:55 +00:00
Marcos Paulo aa85864868 feat: make route map the interactive landing page 2026-09-04 04:18:15 +00:00
Marcos Paulo 47144e9206 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.
2026-09-02 16:31:54 +00:00
Marcos Paulo f526a42ddd feat(hands-on): add guardrails rules lab and wire into docs
- New hands-on/rules/ interactive page: five toggleable rule sources
  (AGENTS.md, gate-discipline skill, Husky pre-commit, check-ui-contract
  enforcer, commitlint) rebuild a ruled prompt live against a naive prompt.
- Visual system mirrors hands-on/starter (same palette, vanilla JS).
- index.html hands-on section now links both labs.
- docs/operations-guide.md gains a 'Hands-on rules lab' subsection.
- README project structure lists the new lab.
- verify.mjs passes content, interaction, and standalone checks for both labs.
2026-09-02 15:30:45 +00:00
Marcos Paulo 9f879ed276 feat: add model routing and hands-on lab 2026-09-02 14:35:27 +00:00
Marcos Paulo ada9b3aa19 docs: add presentation operations guide 2026-09-02 13:51:08 +00:00
Marcos Paulo 273ea5e259 feat: add interactive agent workflow diagrams 2026-09-02 01:30:12 +00:00
Marcos Paulo 9557cae6b6 feat: add AI For Dummies presentation 2026-09-02 00:33:49 +00:00