Minimal bilingual blog built with a custom Python static site generator.
The site is published as generated static HTML under en/, pt/, index.html, and sitemap.xml. Source content lives under _source/. Translation is handled by the translation_v2 runtime during the build.
blog/
├── _source/
│ ├── posts/ # Markdown source posts
│ ├── build.py # Build orchestrator / CLI entrypoint
│ ├── content_loader.py # Markdown parsing + post metadata sidecar
│ ├── renderer.py # HTML rendering for all page types
│ ├── seo.py # Sitemap + structured data
│ ├── translation_common.py # Build-side translation validation helpers
│ ├── translation_revision.yaml # Revision requests for specific artifacts
│ └── translation_v2/ # OpenCode translation runtime
│ ├── prompts/v2/ # Active prompt pack
│ ├── references/ # Locale briefs and localization references
│ └── ... # Orchestrator, contracts, cache adapter, etc.
├── _cache/ # Build-time state (git-ignored)
│ ├── post-metadata.json # Source change detection manifest
│ ├── translation-cache.json # Accepted translation cache
│ └── translation-runs/ # Per-run artifacts and debug traces
├── docs/
│ ├── adr/ # Architecture decision records
│ └── translation_v2_opencode_runbook.md
├── static/ # Shared CSS, JS, images
├── en/ # Generated English site
├── pt/ # Generated Portuguese site
├── cv_data.yaml # Structured CV source of truth
├── index.html # Generated landing page
└── sitemap.xml # Generated sitemap
uv sync --all-extras
uv run python _source/build.py
uv run python -m http.server 8000The current build is source-first.
- Parse all source posts.
- Render source-language outputs first.
- Render source indexes and sitemap.
- Initialize the translation runtime.
- Translate static artifacts (
about,cv) and commit accepted outputs immediately. - Translate posts and commit accepted outputs immediately.
“Commit” means:
- persist accepted translation state to
_cache/translation-cache.json - persist per-run artifacts under
_cache/translation-runs/<run_id>/ - render and write the corresponding HTML output immediately
This means accepted work is durable even if a later artifact fails.
uv run python _source/build.py- Builds source outputs
- Runs
translation_v2 - Logs quality issues but continues on build-side validation errors
uv run python _source/build.py --strict- Same runtime, but build-side error-level translation validation fails the build
- Uses staged/atomic output promotion
uv run python _source/build.py --post _source/posts/<post-file>.mduv run python _source/build.py --post _source/posts/<post-file>.md --skip-about-cv-translationBuild-time translation is OpenCode-only and lives under _source/translation_v2/.
The active stage graph is:
source_analysisterminology_policytranslatecritiquerevisefinal_review
Current model split:
- translation:
GPT-5.4with high reasoning - revision:
GPT-5.4with high reasoning - critique:
GPT-5.2 - final review:
GPT-5.2
The runtime also loads:
- WRITING_STYLE.md
- locale briefs under
_source/translation_v2/references/
There are three distinct persistence layers:
_cache/post-metadata.json- source-side content hash and timestamp tracking
_cache/translation-cache.json- accepted translation cache
_cache/translation-runs/<run_id>/- per-run prompts, structured responses, stage events, runner logs
Use _source/translation_revision.yaml to force reassessment of a specific artifact/locale pair:
posts:
some-post-slug:
pt-br:
reason: revisit locale naturalness
notes: preserve connective tissue and dry humorOperational triage details live in docs/translation_v2_opencode_runbook.md.
The build runs two different quality layers:
-
Translation-stage review inside
translation_v2- critique
- revision
- final review
-
Build-side deterministic validation in
_source/translation_common.py- untranslated overlap checks
- repeated identical sentence detection
- malformed code fence / HTML tag checks
- suspicious length warnings
Default mode logs these issues and continues. Strict mode fails on error-level build-side validation issues.
Additional validation commands:
uv run python _source/link_checker.py
uv run --extra dev python _source/html_validator.pyFocused translation/runtime suites:
UV_CACHE_DIR=/tmp/uv-cache uv run --extra dev pytest \
tests/test_build_translation_v2_integration.py \
tests/test_build_translation_routing_integration.py \
tests/test_translation_v2_boundaries.py \
tests/test_translation_prompt_versions.py \
tests/test_translation_locale_rules.py -qOne-file lane regression:
UV_CACHE_DIR=/tmp/uv-cache uv run --extra dev pytest \
tests/test_translation_v2_onefile_lane.py -qGenerated HTML is committed to git and served directly by GitHub Pages.
Recommended release flow:
uv run python _source/build.py --strict
git add en pt index.html sitemap.xml
git commit -m "publish: update generated site"
git pushThe repo’s major architecture and translation-policy decisions are tracked under docs/adr/.