Files
ai-for-dummies/docs/operations-guide.md
T
2026-09-05 01:39:47 +00:00

26 KiB

name, tags
name tags
Guides/AI For Dummies Presentation
guide
ai
skills
agents
worktrees
gitea
pages

AI For Dummies — authoring and operations guide

This guide explains how to maintain the AI For Dummies presentation, how Gitea Pages is updated, and how the skills, subagents, model routing, and Git worktree practices taught by the presentation fit together.

Resource Location
Live presentation https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/
Gitea repository https://git.marcospaulo.dev.br/netcracker/ai-for-dummies
Local checkout /home/marcos/Projects/ai-for-dummies
Source branch main
Published branch pages
Local verification npm run verify
SilverBullet page Guides/AI For Dummies Presentation
Skills-review vote API vote-service/ — separate pod, see vote-service/README.md

How the site is built

The presentation is authored in Astro. main holds source; the Gitea Pages Server still serves a branch directly, so the pages branch holds generated dist/ output and is not a source branch.

File Responsibility
src/ Astro routes, layouts, components, and source styles
public/hands-on/ Verbatim vanilla lab fixtures; Astro does not process them
astro.config.mjs Static build with base: '/ai-for-dummies'
scripts/verify.mjs Content and interaction contract checks
.gitea/workflows/verify.yml Gate, build, and machine-owned publication to pages

Astro ships no JavaScript by default. Interactive islands opt in per component; the bilingual behaviour remains a client-side concern until its dedicated migration task.

Normal edit and publish workflow

flowchart LR
  E[Edit main] --> V[npm run gate]
  V --> C[Commit]
  C --> P[Push main]
  P --> G[Gitea Actions: gate + build]
  G --> B[Force-push dist to pages]
  B --> S[Gitea Pages Server]
  S --> L[Live URL]

1. Start from current main

cd /home/marcos/Projects/ai-for-dummies
git switch main
git pull --ff-only
git status --short --branch

Do not overwrite unrelated local changes. The untracked scripts/inspect.py and scripts/__pycache__/ are local visual-test artifacts and are intentionally not part of the published site.

2. Preview locally

npm run dev

Open http://localhost:4321/ai-for-dummies/. Check English and Portuguese, keyboard focus, the interactive panels, and at least one desktop and one mobile viewport. The production site is under the /ai-for-dummies/ base path, so do not test only root-relative URLs.

3. Verify before committing

npm run gate

The gate runs Astro types and build checks, content contracts, the runtime dependency audit, and the token check. It also refuses a reduced count of verify.mjs assertions.

4. Commit and push the source branch

git add <only-files-for-this-change>
git commit -m "feat: describe the change"
git push origin main

Stage only files that belong to the change. Review git status --short before committing.

5. CI publication and its manual fallback

On a successful main push, Gitea Actions builds dist/ and force-pushes it to pages. This force-push is intentional: pages is machine-owned generated output, and no person or other workflow may write it.

This Gitea's act-runner registration is kept in an emptyDir. A pod restart silently removes the registration; if a site does not update, check and re-register the runner before changing the workflow.

If the runner is unavailable, use the following manual fallback from a clean main checkout. It deliberately replaces the generated branch tree only:

npm install --package-lock=false --prefer-offline
npm run build
git worktree add /tmp/ai-for-dummies-pages --detach pages
git -C /tmp/ai-for-dummies-pages rm -rf .
cp -a dist/. /tmp/ai-for-dummies-pages/
git -C /tmp/ai-for-dummies-pages add --all
git -C /tmp/ai-for-dummies-pages commit -m "chore: publish site"
git -C /tmp/ai-for-dummies-pages push --force origin HEAD:pages
git worktree remove /tmp/ai-for-dummies-pages

6. Verify the deployment

curl -sS -o /dev/null -w '%{http_code}\n' \
  "https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/summary/?v=$(git rev-parse --short HEAD)"

Also check a nested static asset; base-path problems usually appear on assets first:

curl -sS -o /dev/null -w '%{http_code}\n' \
  "https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/hands-on/starter/?v=$(git rev-parse --short HEAD)"

The correct URL pattern is owner subdomain + repository path:

https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/

https://ai-for-dummies.netcracker.pages... is the wrong hostname and can produce ERR_SSL_PROTOCOL_ERROR because it does not match the wildcard TLS certificate.

Skills-review vote service

skills-review/ is served by the same static Pages Server as the rest of this site, so it cannot itself remember votes. vote-service/ is a separate Go API on its own pod for that: one JSON file as the store, one vote per visitor enforced by IP (a MAC address never reaches a server across the internet). It is deployed independently of main/pages — the site can be republished without touching it, and vice versa.

cd vote-service
docker build -t localhost:30892/ai-for-dummies-vote-service:latest .
docker push localhost:30892/ai-for-dummies-vote-service:latest

# kubelet cannot pull that ref (no certs.d/hosts.toml for localhost:30892 →
# `no basic auth credentials`), so side-load into containerd instead and let
# `imagePullPolicy: Never` skip the network pull. Use microk8s's bundled ctr.
docker save localhost:30892/ai-for-dummies-vote-service:latest -o /tmp/vote-service.tar
/snap/microk8s/current/bin/ctr --address /var/snap/microk8s/common/run/containerd.sock \
  --namespace k8s.io image import /tmp/vote-service.tar

microk8s kubectl apply -f deploy/deployment.yaml   # namespace + Deployment + PVC + Service
microk8s kubectl apply -f deploy/ingress.yaml
microk8s kubectl -n ai-for-dummies rollout restart deploy ai-for-dummies-vote

Namespace ai-for-dummies, ingressClassName: public, no per-ingress TLS. The Deployment is pinned to node kubernets with a nodeSelector: the microk8s-hostpath PV carries a nodeAffinity for whichever node first binds it, so scheduling and storage have to agree on one node.

The vote widget's browser-side fetch calls must reach the API over the public internet — a cluster-internal-only Service would be unreachable from a visitor's browser even if the Pages Server happens to run on the same network. Exposure is therefore public, terminated by Caddy on the Oracle VPS over Tailscale (the same path as every other public host here, not the cloudflared tunnel), with ALLOWED_ORIGIN/CORS as the boundary that restricts which site's script may call it. After deploying, keep window.SKILLS_REVIEW_VOTE_API in skills-review/index.html in sync with ALLOWED_ORIGIN on the service.

One cluster-wide gotcha worth knowing before reading the vote code: the ingress controller runs with use-forwarded-headers off, so nginx overwrites X-Forwarded-For/X-Real-IP with the VPS's tailnet address. Caddy stamps the true client address into X-Client-IP instead. Full rationale, the Caddy block, and the anti-abuse design are in vote-service/README.md.

Adding or changing a presentation section

  1. Add semantic HTML and stable data-* hooks in the focused chapter or full-guide/index.html; keep index.html as the short route map.
  2. Put interactive content in a data object inside app.js.
  3. Add one focused render function and bind its controls once.
  4. Add Portuguese static copy to translations.pt and dynamic copy to the relevant interaction data.
  5. Add responsive CSS, visible keyboard focus, and reduced-motion behavior.
  6. Extend scripts/verify.mjs with structural tokens that would disappear if the feature were accidentally removed.
  7. Test English, Portuguese, Full HD, 4K, and mobile layouts.

Keep English as the source HTML. Do not duplicate the whole site into separate language endpoints unless the architecture changes to server-side routing.

The agent workflow taught by the presentation

flowchart TD
  H[Human intent and boundaries] --> O[Strong orchestrator]
  O --> B1[Bounded UI worker]
  O --> B2[Bounded test worker]
  O --> B3[Bounded docs worker]
  B1 --> R[Independent review]
  B2 --> R
  B3 --> R
  R --> E[Evidence and integration]
  E --> H

Use a strong model where ambiguity dominates: repository inspection, architecture, decomposition, risk analysis, and review. Use faster or cheaper models for bounded implementation only after the brief defines the goal, files, constraints, and checks.

Every worker should return:

  • changed files and a concise diff summary;
  • checks executed and their results;
  • remaining risk, uncertainty, or blocked work;
  • no unrelated edits.

Parallelism helps only when tasks are genuinely independent. More agents add coordination cost, context cost, and integration risk.

Worktree-per-worker model

A Git branch isolates history; a Git worktree also isolates the active files and index. Give each editing agent one task, one branch, and one worktree.

git worktree add ../task-ui -b agent/ui
git worktree add ../task-tests -b agent/tests
git worktree add ../task-docs -b agent/docs
git worktree list

Recommended lifecycle:

  1. Create the task branch and worktree.
  2. Give the worker a bounded brief and acceptance checks.
  3. Let the worker edit and verify only inside its worktree.
  4. Review git diff main...agent/name from fresh context.
  5. Merge, request changes, or discard.
  6. Remove the finished worktree with git worktree remove PATH.

Worktrees prevent agents from changing the same checkout underneath each other. They do not eliminate semantic merge conflicts; task ownership and review still matter.

What a skill is

A skill is a reusable procedure that changes how an agent makes decisions. It is not magical memory and does not replace a task brief or acceptance criteria.

skill-name/
├── SKILL.md              required: name, description, workflow, constraints
├── agents/openai.yaml    optional: UI metadata and invocation policy
├── scripts/              optional: deterministic repeated operations
├── references/           optional: conditional facts and detailed guidance
└── assets/               optional: templates or files copied into output

Progressive disclosure keeps context light:

  1. Name and description are visible during selection.
  2. SKILL.md loads when the skill applies.
  3. References, scripts, and assets load only when the workflow needs them.

Do not create empty resource directories. Every file should have a real consumer and should improve a decision or repeatable operation.

Skill-creation workflow

1. Observe repeated friction

Collect realistic requests. Identify a non-obvious decision that agents keep rediscovering or getting wrong. A one-off project fact usually belongs in project documentation, not a global skill.

2. Define discovery

Choose a lowercase, action-oriented name. Write a concise description stating what the skill does and when it applies. Include a boundary only when it stops likely false activation.

---
name: review-ui
description:
  Review frontend changes for focus, responsive layout, and reduced-motion
  behavior.
---

3. Choose the smallest anatomy

  • Put shared workflow and constraints in SKILL.md.
  • Add scripts/ when deterministic execution prevents repeated reimplementation.
  • Add references/ for details needed only in certain modes.
  • Add assets/ for templates or generated-output inputs.
  • Add agents/openai.yaml only when UI metadata or invocation policy is useful.

4. Write decision-changing guidance

Assume the agent is already capable. Include desired outcome, non-obvious constraints, routing decisions, stopping conditions, and evidence expectations. Remove generic advice, duplicated manuals, and speculative rules.

5. Validate and iterate

python3 /home/marcos/.codex/skills/.system/skill-creator/scripts/quick_validate.py /path/to/skill

Structural validation checks package shape and frontmatter. It does not prove the skill makes good decisions. Also run every new script and test realistic prompts. After real failures, sharpen the narrowest relevant rule instead of accumulating universal instructions.

Common skills and when to use them

Skill Use it for Core rule Avoid when
ponytail-lite Requests inviting unnecessary frameworks or abstractions Stop at the first sufficient solution: reuse, standard library, native platform, existing dependency, then minimum new code Simplification would remove validation, security, accessibility, or real edge cases
caveman Routine status, handoffs, and technical summaries Put signal first and remove filler Security warnings, irreversible actions, or sequences where terse wording can be misread
unlazy Substantial builds, audits, and parallel work Define observable gates and finish against evidence Trivial edits or factual answers
research APIs, standards, current behavior, and architecture facts Trace claims to primary sources and save cited findings The answer is already stable and locally proven
diagnosing-bugs Hard bugs, flakes, and regressions Build a fast red-capable feedback loop before theorizing Simple known fixes with an existing regression test
code-review Branch or PR review Check repository standards and original specification as separate axes No comparison point or review request exists
token-saver Verbose tests, builds, logs, and Git output Preserve signal and retain full failure output for recovery Exact raw wording or full diff context is required
webapp-testing Frontend interaction and responsive verification Drive the real UI and assert on DOM, console, and screenshots Static structure checks are already decisive

Useful compositions:

  • Large feature: unlazyponytail-lite → implementation → code-review.
  • Hard regression: diagnosing-bugs → fix → code-reviewcaveman handoff.
  • Documentation with unstable facts: research → writing → cited verification.
  • Interactive presentation: frontend-designwebapp-testing → responsive evidence.

Model and effort routing

Treat model tier and reasoning effort as separate controls:

Work shape Capability tier Effort baseline
Formatting, lookup, narrow edit Luna / Haiku / Flash-Lite Low or minimal where supported
Normal implementation and tests Terra / Sonnet / Flash Medium
Architecture, orchestration, hard debugging Sol / Opus / Pro High

For Claude Code, /model opus, /model sonnet, and /model haiku switch the model alias; opusplan can use Opus while planning and Sonnet while executing. Claude effort support depends on the active model. For OpenAI GPT-5.6, reasoning.effort supports none, low, medium, high, xhigh, and max. Gemini 3 uses model-specific thinkingLevel values, while Gemini 2.5 uses thinkingBudget. Never assume one provider's control maps exactly to another.

Start with the lightest configuration that passes representative checks. Move one knob at a time and compare quality, latency, and cost. See model-routing.md for official source links and copy-ready provider examples.

The field-kit cards link to commit-pinned public sources. The presentation also includes a copy-ready installation request that tells the coding agent to:

  1. Detect the host's documented skill location.
  2. Inspect downloaded instructions, scripts, hooks, and permissions first.
  3. Show a source-to-destination plan and existing-file diffs.
  4. Ask for approval before copying files.
  5. Verify final paths, hashes, validation, and actual skill discovery.

Important exceptions: ponytail-lite is published as AGENTS.md, not a conventional skill package; token-saver expects a separate RTK binary; and unlazy includes optional hooks. The prompt does not install binaries or enable hooks without separate approval. See skill-sources.md for exact commits, package paths, and confidence notes.

Hands-on lab

The presentation includes a dependency-free starter at hands-on/starter/. It renders a small task board but intentionally omits the All / Open / Done filter.

Run it from the repository root:

python3 -m http.server 4173

Open http://localhost:4173/hands-on/starter/. In a fresh coding-agent session, copy Run A — Good prompt from the presentation. Record changed files, dependencies, checks, and evidence. Restore the starter, then repeat with Run B — Good prompt + skills.

The skill-enabled prompt invokes only two working methods:

  • $ponytail-lite keeps the implementation native and small;
  • $webapp-testing verifies filters, URL state, history navigation, accessibility state, empty state, and mobile layout.

The goal is not to prove that a longer prompt is better. Both prompts define the same task contract. Run B adds reusable operating discipline without repeating those skill instructions inside the prompt.

Compare:

Signal Useful question
Files changed Did the agent stay inside hands-on/starter/?
Dependencies Did it add a library where native APIs were enough?
Verification Did it actually exercise URL reload and browser history?
Evidence Did the final response name checks and results?
Complexity Is the solution proportionate to three tasks and three filters?

Hands-on rules lab

A second lab at hands-on/rules/ mirrors the starter's visual system and runs the same exercise against rule sources. It lists five toggleable rule sources — AGENTS.md, the gate-discipline skill body, the Husky pre-commit hook, the check-ui-contract.mjs enforcer, and commitlint — and rebuilds the ruled prompt live as each toggle flips.

Run it:

python3 -m http.server 4173

Open http://localhost:4173/hands-on/rules/. Compare the naive and ruled prompt panels. Toggle rules off to shrink the prompt; toggle them on to add more guards. Copy the final prompt and run it against a real coding agent.

Rules and enforcement case study

The separate /rules/ page uses netcracker/interview as a concrete example of repository-level control. Its interactive pipeline shows five layers:

  1. AGENTS.md gives every agent the same product and toolchain context.
  2. .agents/skills/ loads narrow procedures for frontend, Go API, gates, parallel work, repository ledgers, issues, skill writing, and technical debt.
  3. pnpm check:ui compares violations with a baseline that may only decrease.
  4. Husky runs lint-staged and the UI ratchet before commit; commitlint enforces Conventional Commit messages.
  5. .pr-review.json supplies repository-specific policy to the AI reviewer, while the verifier agent reruns gates independently before merge.

The page links directly to each implementation in Gitea and includes a copy-ready, read-only prompt for mapping the same enforcement layers in another repository. Update rules/index.html, rules/app.js, and rules/styles.css together when the underlying interview workflow changes.

Troubleshooting

Symptom Check Fix
Live page is old Compare main, pages, and remote SHAs Fast-forward and push pages; retry with ?v=COMMIT
ERR_SSL_PROTOCOL_ERROR Confirm the hostname Use netcracker.pages.marcospaulo.dev.br/ai-for-dummies/
Portuguese copy is missing Inspect translations.pt and dynamic interaction data Add both static and dynamic translations; reload after clearing saved language if needed
New control does nothing Check data-* hook, event binding, and render function Add the hook to scripts/verify.mjs; run node --check app.js
Desktop works, mobile breaks Inspect the section below 800 px and 600 px Add an explicit stacking rule and preserve focus visibility
Worktree creation says branch is checked out Run git worktree list Reuse or remove the existing worktree; do not force it
Pages push is rejected Fetch and inspect remote branch state Reconcile normally; never force-push without an explicit recovery decision

Safe rollback

Prefer a normal revert so history and the pages branch remain fast-forwardable:

git switch main
git revert BAD_COMMIT
git push origin main
git worktree add /tmp/ai-for-dummies-pages pages
git -C /tmp/ai-for-dummies-pages merge --ff-only origin/pages   # local pages is often stale
git -C /tmp/ai-for-dummies-pages merge --no-edit main
git -C /tmp/ai-for-dummies-pages push origin pages
git worktree remove /tmp/ai-for-dummies-pages

Verify the live URL after rollback. Do not use reset --hard or force-push for ordinary content recovery.

Completion checklist

  • English content is complete without JavaScript.
  • Portuguese static and dynamic copy is complete.
  • Mouse and keyboard interactions work.
  • Full HD, 4K, and mobile layouts remain readable.
  • npm run verify, node --check app.js, and git diff --check pass.
  • main is pushed.
  • pages fast-forwards to the same commit.
  • Live endpoint returns HTTP 200 and contains the new section.
  • Research links and this SilverBullet guide are updated when the workflow changes.

Resumo rápido em português

Edite sempre em main, rode as verificações, faça commit e push, depois avance pages por fast-forward usando um worktree temporário. O servidor externo do Gitea Pages publica diretamente essa branch. Use o endereço com netcracker.pages.../ai-for-dummies/; o formato inverso quebra o TLS.

Para agentes: modelo forte planeja e revisa; workers delimitados implementam em worktrees separados; evidências voltam ao orquestrador. Para skills: capture uma decisão repetida, defina um gatilho preciso, crie apenas os recursos úteis, escreva orientação que muda decisões e valide estrutura e comportamento.