2026-05-13 — petrova.codes build plan and stack decision
Status: proposed Author: ops@devarno.cloud Decides for: distribution surface architecture, stack, deployment, build pipeline
Context
Section titled “Context”petrova.codes is a reserved domain (per 2026-05-08 decision) for the artifact distribution surface. PRODUCT.md and DESIGN.md define its purpose and visual dialect. A four-stream synthesis analysis (primary plan + alternative approach + critical review + factual verification) identified the optimal architecture and exposed three blocking implementation issues requiring decision docs before code execution.
Decision
Section titled “Decision”Stack and deployment
Section titled “Stack and deployment”- Framework: Astro 5, fully static (
output: "static"), no SSR - Deploy: Vercel, separate project from
petrova.hostandpetrova.blog - Domain:
petrova.codes(custom domain, manual Vercel project setup by operator) - Environment: Node 20+, npm install with
--no-audit --no-fund, standard Astro build
Rationale: Static sites are cache-friendly, deploy fast, and require no runtime. Astro 5 aligns with existing site/ and dashboard/ (polyrepo-shaped monorepo pattern). Separate Vercel project isolates from dashboard/ SSR requirements and site/ editorial scope.
Content model and versioning
Section titled “Content model and versioning”Versioning is first-class, not inferred. Per critical review finding #4, artifacts (skills, prompts, schemas) have no embedded version field. Semantic versioning is applied via a single source file:
codes/src/data/versions.yaml — canonical version registry:
skills: petrova-act: "0.1.0" petrova-boundary-check: "0.1.0" # ... (11 total, one per skill)prompts: 00-bootstrap: "0.1.0" # ... (11 total, one per prompt)cli: null # null until GitHub Release existspull-content.ts reads this file at prebuild. Every artifact stamped with its version. Updates to versions.yaml are PRed for audit (MR-7 append-only workflow).
Content collections: Three Astro content collections with Zod schemas:
skills(content type)prompts(content type)schemas(data type — JSON Schema rendering)
Each artifact carries: name, version (from versions.yaml), description, updated (git log ISO date), status (enum: published/draft/deprecated), optional source path for attribution.
Build pipeline and artifact generation
Section titled “Build pipeline and artifact generation”codes/scripts/pull-content.ts — prebuild script with three phases:
-
Hard-fail guards. Assert all source directories exist and are non-empty:
../skills/(≥1 subdir),../core/prompts/(≥1.md),../spec/verbs/(≥1.schema.json). Exit with clear error message on failure. Never silently produce empty collections. -
Content transformation and copy:
- Skills: read SKILL.md, extract existing
name/description, stampversion/updated/status, write tosrc/content/skills/<slug>.md - Prompts: extract title from first H1, no existing frontmatter, stamp full frontmatter, write to
src/content/prompts/<slug>.md - Schemas: read JSON Schema, extract
$id/title/description, emit.mdstub with JSON in code block, write tosrc/content/schemas/<slug>.md
- Skills: read SKILL.md, extract existing
-
Machine-consumable indices:
public/manifest.json— flat JSON array of all artifacts (type, slug, name, version, description, updated, status, url) for client-side searchpublic/llms.txt— structured text index per llms.txt spec for agent consumption
Wipes destination directories idempotently before copy. Logs counts per collection.
Git submodule handling for Vercel
Section titled “Git submodule handling for Vercel”Critical blocker resolved: Vercel’s default shallow clone does not fetch git submodules. core/prompts/ is a git submodule. Without explicit config, the prompts collection is silently empty on Vercel builds.
Resolution: Set ENABLE_GIT_SUBMODULES=1 in the Vercel project environment variables (manual step by operator during project setup — cannot be done via code).
CLI distribution
Section titled “CLI distribution”GitHub Releases do not yet exist. Critical review #6 confirmed zero releases. The /cli page is published as “coming soon” stub with npx install instructions only — no broken GitHub Release links.
Once a tagged release exists, update /cli and versions.yaml CLI entry. This decision does not block the codes/ launch.
Deployment ignoreCommand
Section titled “Deployment ignoreCommand”Vercel rebuild is triggered only on changes to codes/, skills/, spec/verbs/, or core/prompts/. Ignores unrelated monorepo changes (registry updates, decision docs, dashboard tweaks):
"ignoreCommand": "git diff HEAD~1 --name-only | grep -qE '^codes/|^skills/|^spec/verbs/|^core/prompts/'"Design dialect
Section titled “Design dialect”Distribution dialect per DESIGN.md: utilitarian, no editorial serif, system-sans body, monospace for labels/code. Single layout (Distribution.astro), one component (ArtifactCard.astro). Iron-oxide accent tokens shared with other surfaces. No nav, no sidebar — task-completion optimized.
Indexing: No noindex meta tag (opposite of blog). Artifacts should be discoverable via search engines.
Search: Client-side filter over pre-rendered manifest.json on the index page. No backend required. No pagination.
Blocking issues resolved
Section titled “Blocking issues resolved”- Content partition (see 2026-05-13-petrova-codes-content-partition.md) — Ensures
blogandcodesdon’t duplicate content. - Submodule support on Vercel — Documented as environment variable
ENABLE_GIT_SUBMODULES=1(operator responsibility). - Versioning mechanism —
versions.yamlis the canonical source. - CLI releases — Deferred;
/clipage is stub.
Alternatives considered
Section titled “Alternatives considered”- Separate repo, not monorepo. Rejected: increases blast radius, breaks polyrepo pattern already established by
site/anddashboard/. - 11ty instead of Astro. Rejected: loses consistency with existing stack, Astro 5 content collections are well-suited.
- MCP API as content source. Rejected: build-time network dependency on
petrova.hostcreates fragility; file copy is more resilient. - Single-page searchable index (pkg.go.dev pattern). Partially accepted: added client-side filter on index page (hybrid approach).
Consequences
Section titled “Consequences”For code:
- New
codes/package:package.json,astro.config.mjs,vercel.json, TypeScript config, 6 pages, 1 layout, 1 component, 1 stylesheet, 1 prebuild script versions.yamlcreated with"0.1.0"baseline for all artifactsskills/petrova-*/SKILL.mdnot edited; sourced as-is by prebuild
For docs:
- Two new decision docs (this and partition doc)
- Vercel project setup instructions (manual, not automated)
For deployment:
- Vercel project
petrova-codescreated manually by operator with:- Root Directory:
codes/ - Environment:
ENABLE_GIT_SUBMODULES=1 - Connected to GitHub repo
petrova-codes/petrovaatmainbranch
- Root Directory:
For in-flight phases:
- No active phases affected; this is new surface
For invariants:
- MR-3 (sibling files):
skills/petrova-*/SKILL.mdis a sibling consumed by bothcodes/andblog/. - MR-4 (absolute dates): This decision is dated
2026-05-13. - MR-7 (append-only): All choices recorded here; no retroactive edits on deployment.
- MR-12 (CLAUDE.md projection): No consumer CLAUDE.md references this; it’s operator-facing.
Verification
Section titled “Verification”codes/builds cleanly:cd codes && npm install && npm run buildwith 0 errors, 0 warnings- Expected page counts: 11 skills, 11 prompts, 13 schemas, 1 index, 1 cli stub, 1 404 page
dist/manifest.jsonis valid JSON with correct artifact countsdist/llms.txtis non-empty with Skills/Prompts/Schemas sections- No
noindexmeta tag in rendered HTML - Detail pages render with
ArtifactCardcomponent and copy-to-clipboard buttons - Submodule is fetched during build (validate via Vercel environment variable set)
References
Section titled “References”PRODUCT.md— distribution surface definitionDESIGN.md— Distribution dialect specdocs/decisions/2026-05-08-petrova-domain-pivot.md— domain acquisitiondocs/decisions/2026-05-13-petrova-codes-content-partition.md— content partitioning (blocks this decision)- Four-stream synthesis analysis (OpenCode planning session)
Sign-off
Section titled “Sign-off”- Subagent: OpenCode planning session (synthesis analysis + critical review)
- Human: awaiting confirmation