feat: Zensical documentation site - Material theme, workflow-deployed Pages - #630
Conversation
… Pages (2.5.6) Replace the legacy branch-built Jekyll Pages rendering with a Zensical (Material theme) site built from docs/ and deployed by GitHub Actions: - zensical.toml: site config with an explicit nav grouping the User Guide, Harness Engineer Guide, and Developer Reference into sidebar subsections; light/dark palette toggle; admonitions + Mermaid fences. - pyproject.toml (docs-only) pins zensical; .github/workflows/docs.yml builds on push to v2 touching docs/** and deploys via actions/deploy-pages (all actions SHA-pinned). - Move roadmap.md -> docs/roadmap.md so the roadmap stays a published page (/roadmap/); update the README link. - Committed markdown keeps its relative links to files outside docs/ (dist/ agent sources, core/ knowledge, plugins/, root README) so local clones navigate normally; the deploy workflow rewrites them to GitHub blob URLs at build time via scripts/docs-rewrite-links.ts, which exits 1 on a missing link target so a typo'd path fails the deploy instead of shipping a dead link. Zensical renders docs/ only, unlike Jekyll which rendered the whole branch. - Fix six stale intra-docs anchors surfaced by the zensical build (heading IDs drifted from the linked fragments). - Gitignore the build output (/site/, /.cache/). Activation is a one-time repo-settings flip: Pages source from "Deploy from a branch: v2" to "GitHub Actions". zensical build after rewrite: clean (0 warnings). Tier: smoke+unit 174/174 green; t68/t132/t174/t239 pins green; package.ts --check clean; typecheck clean.
leandrodamascena
left a comment
There was a problem hiding this comment.
Findings
P1: Bootstrap the workflow on main first
.github/workflows/docs.yml:13
GitHub only enables workflow_dispatch when the workflow exists on the default branch, which is currently main. Therefore, gh workflow run docs.yml --ref v2 will not work with this workflow only on v2.
Before merging this PR, open a small prerequisite PR against main adding the same workflow file. Keep this PR targeting v2, where the workflow remains necessary for push-triggered deployments.
P1: Make documentation warnings fail the build
.github/workflows/docs.yml:51
zensical build exits successfully when it finds broken internal links or anchors. I reproduced two reported issues followed by exit code zero, meaning the workflow would deploy a broken site.
Please use:
run: uv run zensical build --strictThe current documentation passes strict mode without warnings.
P2: Validate documentation before merge
.github/workflows/docs.yml:3
The workflow only runs after changes are pushed to v2, so broken configuration or documentation is detected after merge.
Please add a pull_request trigger targeting v2, run the build for PRs, and condition the deploy job so it only runs for pushes or manual dispatches.
P2: Preserve the roadmap during the Pages cutover
README.md:8
The new /roadmap/ URL currently returns 404, while /roadmap.html works. Because Pages still publishes the root of v2 through Jekyll, merging the rename first will move the legacy page to /docs/roadmap.html before the administrator switches Pages to GitHub Actions.
Please preserve a root-level redirect/stub until activation, or coordinate the Pages source change so the README never points to a missing page.
P2: Trigger validation when out-of-tree targets change
.github/workflows/docs.yml:7
The documentation links to files under core/, dist/, and plugins/, but changes to those directories do not trigger this workflow. Renaming or deleting one of those targets can therefore leave published dead links without running the rewriter's validation.
Please include the linked source trees in the path filters, or remove the restrictive path filter.
P2: Commit the Python dependency lock
pyproject.toml:7
.github/workflows/docs.yml:30
Only the direct Zensical dependency is pinned. Without a committed uv.lock, transitive dependencies are resolved again on every deployment. Additionally, setup-uv installs latest, so the build tool itself also floats.
Please commit uv.lock, use uv sync --locked, and pin the uv release.
P2: Do not rewrite links inside fenced examples
scripts/docs-rewrite-links.ts:39
The regular expression processes Markdown code fences as ordinary content. I reproduced a relative link inside a fenced Markdown example being rewritten to a GitHub URL; a missing example target also caused the script to fail.
Please make the rewrite fence-aware or use a Markdown parser rather than replacing across the raw document.
P3: Scope Pages permissions to the deploy job
.github/workflows/docs.yml:15
The workflow-level permissions grant pages: write and id-token: write to the build job, although only the deploy job needs them.
Please leave contents: read on the build job and grant Pages/OIDC permissions only to deploy.
Verification
The current branch passes zensical build --strict, bun scripts/package.ts --check, actionlint, version synchronization, and all 174 smoke/unit test files (4,310 assertions).
…eps, fence-aware rewriter, roadmap redirect Review findings on the docs-site PR: - zensical build --strict: broken links/anchors now fail the build (verified: exit 1 on the unrewritten tree, exit 0 after the rewrite). - pull_request trigger on v2 validates docs changes pre-merge; the Pages artifact upload and deploy job are conditioned to push/dispatch. - Path filters removed: renames under core/, dist/, plugins/ now also run the build, so the rewriter's exists-on-disk check catches doc links going stale. - Workflow-level permissions reduced to contents: read; pages: write + id-token: write granted only to the deploy job. - uv.lock committed, uv sync --locked, setup-uv pinned to 0.11.28 (matching the lockfile's generator) instead of 'latest'. - docs-rewrite-links.ts is fence-aware: lines inside ``` / ~~~ blocks ship verbatim (example links are content, not navigation); missing targets now report file:line. - /roadmap.html keeps working on both renderings: a root redirect stub covers the legacy Jekyll site until activation (README keeps the .html URL), and the workflow emits site/roadmap.html on the Zensical side; the stub documents its own removal condition. - .venv/ gitignored (created by uv sync). Workflow bootstrap on main (workflow_dispatch registration) is a separate prerequisite PR against main. actionlint clean; strict build + rewrite dry-run green; pinned tests t68/t132/t174/t239 green.
|
Thanks @leandrodamascena - all eight findings addressed in e1485fe (kept as a separate commit on top of the reviewed base for an incremental diff): P1 strict build - P1 bootstrap on main - you're right, P2 PR validation - P2 roadmap 404 - fixed for both eras: a root P2 path filters - removed entirely. Every push/PR to P2 lockfile - P2 fenced links - the rewriter is fence-aware (``` and ~~~, CommonMark up-to-3-space indent): lines inside fences ship verbatim. Reproduced your case in a fixture - a fenced fake link is untouched and no longer errors, while a real out-of-tree link on the same page still rewrites. P3 permissions - workflow level reduced to Re-verified at e1485fe: actionlint clean, strict build + rewrite dry run green (redirect emit included), |
leandrodamascena
left a comment
There was a problem hiding this comment.
Thanks for addressing the original review. I verified that the main bootstrap PR #633 is merged with a byte-identical workflow, and that strict builds, PR-only validation, roadmap compatibility, path coverage, locked dependencies, and job-scoped permissions are now in place.
Two issues remain:
P2: Track the opening fence delimiter instead of toggling on every fence-like line
scripts/docs-rewrite-links.ts:46
The new implementation toggles inFence for every line beginning with three or more backticks/tildes. That is not CommonMark fence-closing behavior: a closing fence must use the same marker character and at least as many markers as the opener.
I reproduced this with a valid four-backtick Markdown fence containing a three-backtick example. The inner three-backtick line incorrectly toggles inFence off, and the following example link is processed as navigation:
````markdown
```text
[example](../../missing.md)```
The script reports the fenced link as missing and exits 1. Please retain the opening marker character and length, and only close on a compatible delimiter. A focused test covering ordinary, tilde, longer/nested, and real out-of-tree links would prevent regression.
### P2: Serialize all production Pages deployments in one concurrency group
`.github/workflows/docs.yml:18`
Including `github.event_name` in the workflow concurrency key puts a `push` deployment and a manual deployment for the same branch in different groups. They can run concurrently, so an older manual run can finish after a newer push and replace the site with stale content.
GitHub's Pages starter workflow deliberately uses one `pages` concurrency group for production deployments. Please keep PR builds independently cancellable, but serialize the `deploy` job across push/manual runs, for example with job-level `concurrency: { group: pages, cancel-in-progress: false }`.
Verification performed on `e1485fe9`: GitHub docs build check passed with deploy skipped; #633 is merged and workflow-identical; actionlint passed; locked install and `zensical build --strict` passed; package parity and typecheck passed; 27 targeted documentation/version tests passed. The aggregate lint command still reports the pre-existing `core/tools/aidlc-doctor-bundle.ts:628` warning from the base branch, unrelated to this PR.
|
Why does a documentation framework update causes a version increase for AIDLC? This is just needless churn for customers. |
…ges deploys Round-2 review findings: - docs-rewrite-links.ts tracks the OPENING fence delimiter (marker char + length) instead of toggling on every fence-like line: a fence closes only on the same character, at least as many markers, and no info string - so a three-backtick example inside a four-backtick block is content, a tilde line never closes a backtick fence, and a longer marker carrying an info string is content too. Regression-pinned by tests/unit/t246-docs-rewrite-links-fences.test.ts (runs the real script as a subprocess against fixture markdown: plain/tilde fences, nested-delimiter cases, rewrite-resumes-after-close, missing-target exit 1 with file:line). - Production Pages deployments are serialized in one shared `pages` concurrency group (cancel-in-progress: false) on the deploy job, so a push deploy and a manual dispatch can never interleave and an older run cannot overwrite a newer site; PR validation builds stay independently cancellable per ref (workflow-level group now cancels in-progress only for pull_request events). actionlint clean; t246 7/7; strict build + rewrite dry run green; t68/t132/t174/t239/t246 green; typecheck clean.
|
@leandrodamascena both round-2 findings fixed in 15e77c5: P2 fence delimiters - the rewriter now tracks the opening delimiter (marker character + length) and closes only on the same character, at least as many markers, and no info string. Your four-backtick repro is covered: the inner three-backtick line is content, the example link ships verbatim, exit 0. Regression-pinned by the new P2 deploy serialization - the deploy job now carries its own Verified at 15e77c5: actionlint clean, t246 7/7, rewrite + |
The changelog policy exempts doc-only changes from version bumps, and this PR's own entry said "nothing to re-copy into projects" - a new aidlc-version.ts in every dist tree would wrongly signal installed copies are outdated. Version stays 2.5.5; the CHANGELOG entry, badge bump, and the six version-file diffs are removed. The published-URL migration is recorded in the PR description and served by the /roadmap.html redirects. Also removes this PR from the 2.5.x version-slot contention entirely. package.ts --check clean; t68/t174/t239/t246 green.
What
Replaces the legacy branch-built Jekyll rendering of https://awslabs.github.io/aidlc-workflows/ with a Zensical (Material theme) site built from
docs/and deployed by GitHub Actions: full-text search, light/dark mode, and a sidebar that groups the User Guide, Harness Engineer Guide, and Developer Reference into subsections.Live preview of this build (served from a fork's Pages): https://apackeer.github.io/aidlc-workflows/
Doc/site-only: no version bump, no CHANGELOG entry, nothing for users to re-copy into projects. No framework behavior changes.
How
zensical.toml- site config with an explicit nav (subchapter grouping per doc set, agents ordered by lifecycle position), indigo/cyan palette with dark-mode toggle, admonitions + Mermaid fences. Same stack as sample-collaborative-ai-dlc.pyproject.toml+uv.lock- docs-only dependency group; zensical and all transitives locked,uv sync --locked, uv release pinned in the workflow..github/workflows/docs.yml-zensical build --stricton every push and pull request tov2(broken links/anchors fail the build); deploy runs on push/dispatch only, serialized in a singlepagesconcurrency group (cancel-in-progress: false) so an older run can never overwrite a newer site, with Pages/OIDC permissions scoped to the deploy job. All actions SHA-pinned. Bootstrapped onmainby ci: bootstrap the docs deploy workflow on the default branch #633 soworkflow_dispatchis registered.scripts/docs-rewrite-links.ts- the committed markdown keeps its relative links to files outsidedocs/(so local clones navigate normally); this script rewrites them to GitHub blob URLs on the CI checkout just before the build, and exits 1 withfile:lineif a linked file is missing so a typo'd path fails the deploy instead of shipping a dead link. Fence-aware with CommonMark delimiter rules (opening marker character + length tracked; example links inside code blocks ship verbatim), regression-pinned bytests/unit/t246-docs-rewrite-links-fences.test.ts.roadmap.md->docs/roadmap.md(pure rename) so the roadmap stays a published page at/roadmap/. The old/roadmap.htmlURL keeps working on both renderings: a root redirect stub covers the legacy Jekyll site until activation, and the workflow emitssite/roadmap.htmlon the Zensical side./site/,/.cache/,/.venv/gitignored; the build output is never committed.Activation (post-merge, needs repo admin)
One-time flip: Settings -> Pages -> Source: "Deploy from a branch" -> "GitHub Actions", then dispatch the workflow (registered via #633) or re-run the last push run. Until the flip, merging is inert: the deploy job fails with a 400 (expected) and the legacy Jekyll site keeps serving unchanged, including the roadmap via the redirect stub.
Breaking (bookmarks/links only)
Published URLs change shape:
/docs/guide/00-introduction.html->/guide/00-introduction/./roadmap.htmlredirects to/roadmap/. Repository files outsidedocs/are no longer rendered as pages (most already 404'd under Jekyll, which skips dot-directories likedist/claude/.claude/).Testing
zensical build --strictclean after the rewrite step; exit 1 verified on the unrewritten tree (14 issues), so the strict gate is realbun scripts/package.ts --checkclean; typecheck clean; actionlint clean