BlogWikiAbout

Kyle Pericak

"It works in my environment"

Bot-Wiki/Stack Contract

Stack Contract

Last verified: 2026-04-01

Languages and runtimes

  • Go: Agent controller (deprecated, not deployed), planned for future orchestration
  • TypeScript / JavaScript: Blog (Next.js 14 static export), blog tooling
  • Python: Wiki-RAG tool, utility scripts (always use apps/blog/.venv/bin/python)
  • Bash: Glue scripts, CronJob entrypoints, bootstrap automation
  • Swift: iOS app (sillyapp, inactive)
  • Java: Minecraft mods (inactive)

Kubernetes

  • Distribution: K3s via Rancher Desktop on 2 Mac machines
  • Clusters: pai-m1 (always-on server), kyle-m2 (gaming laptop, sometimes off)
  • Namespace: ai-agents for all agent workloads
  • Security: Pod Security Standards enforced, NetworkPolicy in place, ResourceQuota set
  • Sandbox isolation: gVisor planned but not yet deployed

GitOps and deployment

  • ArgoCD: Runs on pai-m1, watches main branch, auto-syncs both clusters
  • ApplicationSets: Cluster generator creates one Application per cluster per release
  • Helm releases: vault, cronjobs, pai-responder
  • Helmfile: Used for bootstrap and ArgoCD fallback, not primary deploy method
  • CI/CD: Minimal — only auto-merge-wiki GitHub Actions workflow. No image build pipeline.
  • Production deploys: Manual, Kyle only. Never automated.
  • Docker images: Built and pushed manually. Runtime image: kpericak/ai-agent-runtime

Secrets

  • Vault: HashiCorp Vault with GCP KMS auto-unseal
  • Delivery: Vault Agent Injector writes secrets to in-memory tmpfs at /vault/secrets/
  • No plain-text K8s Secrets — everything goes through Vault
  • Secret paths: secret/ai-agents/{discord,github,anthropic,pai,openrouter}

Observability

  • Logs: OpenObserve deployed on pai-m1 (standalone, 10Gi PVC). Log ingestion incomplete (DaemonSet not yet deployed).
  • Agent activity: Discord #log channel — agents post tool call summaries via PostToolUse hook
  • Health checks: Healthcheck agent CronJob queries pod status and OpenObserve
  • Metrics: No Prometheus or Grafana. No application-level metrics instrumentation.
  • Alerting: Not configured.

Agent runtime

  • Image: kpericak/ai-agent-runtime (Playwright base, Claude Code CLI, Python, Git, kubectl)
  • Execution model: CronJob pods — Vault init → optional GitHub token init → agent container → push
  • Scheduled agents: journalist (daily 8am ET), pai-morning (daily 8:30am ET)
  • Long-running: pai-responder (Discord polling Deployment, pai-m1 only)
  • Agent definitions: .claude/agents/*.md (12 agents: publisher, analyst, researcher, reviewer, qa, security-auditor, synthesizer, prd-writer, design-doc-writer, pai, journalist, healthcheck)

Blog platform

  • Framework: Next.js 14, static HTML export
  • Hosting: Google Cloud Storage, served via GCS website
  • Content: Markdown posts in apps/blog/blog/markdown/posts/
  • Wiki: Markdown in apps/blog/blog/markdown/wiki/ (119 pages, 15 sections)
  • Internal links: Must end in .html
  • Dev server: npm run dev on port 3000

Networking

  • Ingress: Cloudflare Tunnel → Traefik → K8s services
  • Domains: kyle.pericak.com (blog), pai.pericak.com (internal services)
  • Cloudflare Access: Protects internal services (OpenObserve, ArgoCD)

Conventions

  • Git: Branch protection on main, all changes through PRs, assign to kylep
  • Branch naming: kyle/<linear-id>-short-description or kyle/descriptive-name
  • Testing: Test before merging (kubectl apply, helm template, docker build, agent runs). No merge-to-test.
  • Security scanning: semgrep, trivy, gitleaks via kpericak/ai-security-toolkit-1 Docker image
  • Pre-commit: gitleaks hook for secret detection
  • Monorepo: Each directory in apps/ and games/ is independent. No cross-project imports.
Related:wiki/devops/ai-agents-infrawiki/devops/bootstrapwiki/custom-tools
Blog code last updated on 2026-04-04: a678902a732ef24296278b1bff9ff5e899f6e384