Ship a GitHub Actions pipeline that publishes the entire docs/ tree to GitHub Pages, so every developer can browse all 32 HTML plans from one public URL — landing straight on the filterable plans gallery — instead of cloning the repo and opening files by hand.
Read and implement all steps in the plan at docs/plans/publish-plans-to-github-pages.html — Publish all HTML plans to GitHub Pages for one-click browsing
publish-plans-to-github-pages.html
docs/plans/publish-plans-to-github-pages.html
Context
The repo already generates rich, self-contained HTML plans into docs/plans/ (32 of them today), and a PostToolUse hook (rebuild-plans-index.py) keeps docs/plans/index.html — a filterable gallery — current after every plan write. The one missing piece is reach: those files only exist on disk, so a developer has to clone the repo and open them in a local browser to read them.
GitHub Pages closes that gap. The repo (shawn-sandy/agentics) already runs GitHub Actions, so the cleanest fit is a dedicated Pages deploy workflow using the official actions/upload-pages-artifact + actions/deploy-pages pair, publishing the whole docs/ directory on every push to main. Two known footguns shape the approach: GitHub Pages runs Jekyll by default (which can mangle hand-built HTML and ignores _-prefixed paths) — neutralised with a .nojekyll marker; and a project Pages site is served under a base path (/agentics/), so the landing page must use a relative redirect. The gallery's own links are already relative, so they survive the base path unchanged.
Per the decisions taken while drafting: deploy via a GitHub Actions workflow (not branch/folder), and make the existing plans gallery the site's landing page via a root redirect, keeping docs/plans/index.html as the single hook-maintained source of truth.
Files to Modify
- .github/workflows/
deploy-pages.ymlnew Actions workflow that deploys docs/ to Pages- docs/
.nojekyllnew disable Jekyll processing of hand-built HTMLindex.htmlnew root redirect to the plans galleryREADME.mdmodified add a link/badge to the published site
Diagram
push to main (docs/**)upload-pages-artifact (path: docs)deploy-pagesshawn-sandy.github.io/agentics/Steps
docs/.nojekyll marker file
.nojekyll file at the published root tells Pages to serve every byte verbatim.Verify
test -f docs/.nojekyll && echo present prints present. The file is empty (zero bytes is fine).docs/index.html as a relative redirect to the plans gallery
docs/ means the site root resolves to docs/index.html, which does not yet exist — visitors would hit a 404. A tiny redirect page forwards the root to plans/index.html so visitors land directly on the filterable gallery (the chosen landing page), while docs/plans/index.html stays the single hook-maintained source of truth. Use a relative target (plans/index.html, not a leading slash) so it works under the /agentics/ Pages base path, plus a <meta http-equiv="refresh">, a canonical <link>, and a visible fallback anchor for no-JS/no-refresh clients.Verify
docs/index.html in a browser from a local server — it immediately navigates to the plans gallery. grep -q 'plans/index.html' docs/index.html succeeds, and the href does not start with / (no absolute path that would break the base-path)..github/workflows/deploy-pages.yml deploy workflow
push to main filtered to paths: ['docs/**', '.github/workflows/deploy-pages.yml'] (plus workflow_dispatch for manual re-runs), so changes to the workflow itself also trigger a redeploy. It declares the required permissions (pages: write, id-token: write, contents: read) and a concurrency group of pages with cancel-in-progress: false. A build job checks out, asserts docs/.nojekyll exists (fail fast if accidentally deleted), runs actions/configure-pages, and uploads docs via actions/upload-pages-artifact; a deploy job with environment: github-pages runs actions/deploy-pages. Pin every action to a commit SHA with a version comment, matching the convention in auto-version-bump.yml. Look up current SHAs from each action's releases page or the existing pinned versions in auto-version-bump.yml.Verify
python3 -c "import yaml,sys; yaml.safe_load(open('.github/workflows/deploy-pages.yml'))"). It declares both pages: write and id-token: write, a build and a deploy job, uploads artifact path docs, every uses: is pinned to a 40-char SHA, the path filter includes both docs/** and .github/workflows/deploy-pages.yml, and the build job asserts docs/.nojekyll exists before uploading the artifact.workflow (Pages is currently disabled — the API returns 404). This is a one-time repo setting that must be completed before the PR is merged, since the workflow will fail on first trigger if Pages is not enabled. Enable it with gh api -X POST repos/shawn-sandy/agentics/pages -f build_type=workflow, or via Settings → Pages → "Build and deployment" → Source: GitHub Actions. Requires admin on the repo. If admin access is unavailable, coordinate with a repo admin to complete this step before merging.Verify
gh api repos/shawn-sandy/agentics/pages --jq .build_type returns workflow (no longer 404), and the response html_url shows https://shawn-sandy.github.io/agentics/.README.md
README.md pointing at https://shawn-sandy.github.io/agentics/ so the gallery is discoverable from the repo's front door. Keep it one line — this is a pointer, not a section.Verify
grep -q 'shawn-sandy.github.io/agentics' README.md succeeds, and the link renders correctly in the GitHub README preview.tests/pages/
test-pages-smoke.sh, test-root-redirect.sh, test-workflow-config.sh) but no earlier step creates them. Create mkdir -p tests/pages and write all three scripts with the assertions described in the Tests section. The unit and integration tests should be runnable locally as pre-merge validation; the smoke test runs post-deploy against the live URL with a retry loop (up to 5 attempts, 15s apart) to handle Pages propagation delay.Verify
ls tests/pages/test-*.sh | wc -l returns 3. Each script is executable (chmod +x) and exits 0 when run against the expected inputs (local files for unit/integration, live URL for smoke).main, then confirm the first deploy serves the live gallery
main, the docs/** path filter fires the workflow; watch the run complete, then load the public URL and confirm the gallery and a sample plan render. This is the real acceptance gate — a green Actions run plus a reachable site.Verify
gh run list --workflow=deploy-pages.yml --limit 1 shows a completed/success run. curl -sI https://shawn-sandy.github.io/agentics/ returns 200, and curl -s https://shawn-sandy.github.io/agentics/plans/ contains the gallery title Plans Library. A sample plan such as .../plans/add-tests-section-to-plans.html also returns 200.Tests
File: tests/pages/test-pages-smoke.sh
Type: smoke test (run post-deploy, e.g. a final step of deploy-pages.yml or manually against the live URL)
Asserts: the objective is actually met — GET https://shawn-sandy.github.io/agentics/ returns 200 and redirects to the gallery; /agentics/plans/ contains Plans Library; and a loop over every docs/plans/*.html filename confirms each returns 200 at /agentics/plans/<name> (all plans browsable — count derived dynamically from find docs/plans -name '*.html', not hardcoded). Includes a retry loop (up to 5 attempts, 15s apart) per URL to handle GitHub Pages propagation delay.
Run: bash tests/pages/test-pages-smoke.sh https://shawn-sandy.github.io/agentics
File: tests/pages/test-root-redirect.sh
Targets: docs/index.html
Key cases: file exists; contains a refresh/redirect to plans/index.html; the redirect target is relative (does not begin with / or http); a visible fallback anchor to the gallery is present for no-refresh clients.
File: tests/pages/test-workflow-config.sh
Targets: .github/workflows/deploy-pages.yml + docs/.nojekyll
Key cases: YAML parses; triggers on push to main with paths: docs/**; declares pages: write and id-token: write; has a build job uploading artifact path docs and a deploy job using actions/deploy-pages with environment: github-pages; all uses: pinned to SHAs; docs/.nojekyll exists so the artifact disables Jekyll.
Acceptance Criteria
Verification
End-to-end: after the change merges to main, confirm the deploy-pages.yml run completes successfully (gh run list --workflow=deploy-pages.yml shows success). Then load https://shawn-sandy.github.io/agentics/ in a browser — it should redirect to and display the plans gallery with all plan cards and working filter chips. Click into at least two plans (e.g. a normal plan and one ending in -review.html) and confirm they render with full styling, working checkboxes, and the sidebar table of contents. Spot-check that deep links work directly (paste a .../plans/<name>.html URL fresh). Finally, run the smoke test (bash tests/pages/test-pages-smoke.sh https://shawn-sandy.github.io/agentics) and confirm it passes for the root, the gallery, and all plan files; and verify the README link resolves to the live site.
Troubleshooting: If the first deploy fails, check: (1) GitHub Pages is enabled with build_type=workflow (Step 4), (2) the workflow has correct permissions (pages: write, id-token: write), (3) the artifact path is docs, not ./docs. If the site returns 404 after a green deploy, wait 60–90 seconds for Pages propagation. If the smoke test times out, verify the URL base path (/agentics/) matches the repo name.
Completion Checklist
Completion Report
No items to report — all requirements met.
▶ Team Review (2026-06-07 16:09:00 UTC) — 5 core reviewers
Executive Summary
The plan is approved with revisions. All 5 reviewers found the design architecturally sound, well-aligned with project conventions, and appropriately scoped. Three cross-reviewer concerns dominate: (1) the test files described in the Tests section had no corresponding creation step, (2) the Pages enablement ordering was implicit rather than enforced, and (3) there was no pre-deploy CI validation. Additionally, the plan hardcoded “32 plans” in acceptance criteria and used underscore-separated test filenames against the project’s kebab-case convention. All issues have been addressed with inline edits.
Role-by-Role Findings
Architecture Review
Fit: Architecturally sound — a thin static-site deployment layer that correctly avoids touching the existing hook-driven content pipeline.
- Path filter gap (medium): workflow changes to
deploy-pages.ymlitself wouldn’t trigger a redeploy. Fixed: path filter now includes the workflow file. - No .nojekyll guard (low): accidental deletion would silently re-enable Jekyll. Fixed: build job now asserts .nojekyll exists.
- Post-deploy-only smoke test (low): no pre-upload local validation of artifact completeness. Mitigated: new step 6 creates test files runnable pre-merge.
Completeness Review
Completeness: Well-structured with good specificity, but had two notable gaps.
- Missing test file creation step (high): tests were specified but no step created them. Fixed: new Step 6 added.
- Pages enablement ordering implicit (medium): no note that Step 4 must precede merge. Fixed: Step 4 now states “must be completed before the PR is merged.”
- Hardcoded SHA lookups (medium): no guidance on where to find SHAs. Fixed: Step 3 now references action release pages and existing workflow.
- Hardcoded “32” in AC6 (low): stale if plans are added/removed. Fixed: AC6 now says “all plan files present at deploy time.”
Testability Review
Test coverage: Present but thin — tests existed on paper but not as executable files, and there was no pre-merge CI gate.
- No pre-deploy CI validation (high): only post-deploy smoke test. Mitigated: Step 6 creates tests; step 3 adds .nojekyll assertion. Unit/integration tests runnable locally pre-merge.
- Hardcoded plan count in smoke test (low): Fixed: now derived dynamically via find.
- No Jekyll-suppression test (medium): no test verifies .nojekyll is active. Partially addressed: build job .nojekyll assertion catches the most common failure mode.
Risk Review
Risk level: Medium overall.
- Pages enablement prerequisite (high): workflow fails silently if Pages not enabled. Fixed: Step 4 strengthened with ordering requirement and admin access note.
- Stale gallery index (medium): hook-maintained index could be stale if plan committed without hook. Noted: recommend CI-side index regeneration as a follow-up.
- Public content is irreversible once indexed (medium): plans become public immediately. Noted: recommend a content audit before enabling Pages.
- Smoke test propagation delay (low): no retry. Fixed: smoke test now specifies retry loop.
Conventions Review
Fit: Good alignment with project patterns overall.
- Test file naming (medium): used underscores (
test_*) instead of project-standard kebab-case. Fixed: all test files renamed totest-*. - Missing tests/pages/ directory creation (low): no step to mkdir. Fixed: included in new Step 6.
Agreements & Conflicts
Confirmed concerns (flagged by 2+ reviewers):
- Missing test file creation step (Completeness + Testability)
- Pages enablement ordering (Completeness + Risk)
- No pre-deploy CI validation (Architecture + Testability)
- Hardcoded plan count (Completeness + Testability)
- Workflow path filter gap (Architecture + Risk)
No conflicts between reviewers.
Highest-Risk Issues (Priority Order)
- Pages must be enabled before merge — Risk reviewer (high). Fixed in Step 4.
- Test files must be created, not just described — Completeness reviewer (high). Fixed with new Step 6.
- No pre-deploy CI gate — Testability reviewer (high). Mitigated with .nojekyll assertion and local-runnable tests.
- Public content exposure — Risk reviewer (medium). Recommend content audit before enabling.
- Gallery index staleness in CI — Risk reviewer (medium). Recommend CI-side regeneration as follow-up.
Edits Applied
| Target | Action | Change |
|---|---|---|
| AC6 label | edit | Replaced “All 32 plan files” with “All plan files present in docs/plans/ at deploy time” |
| Step 3 why | edit | Added workflow self-trigger path, .nojekyll assertion, SHA lookup guidance |
| Step 3 verify | edit | Added path-filter and .nojekyll assertion checks |
| Step 4 why | edit | Added “must be completed before PR is merged” and admin access note |
| After Step 5 | insert | New Step 6: Create test files in tests/pages/ |
| Old Step 6 | edit | Renumbered to Step 7 |
| All test filenames | edit | Renamed from underscore to kebab-case (test_* → test-*) |
| Objective test | edit | Dynamic plan count + retry loop for propagation delay |
| Verification | edit | Removed hardcoded “32”; added troubleshooting paragraph |
| AC1 label | edit | Added workflow self-trigger and .nojekyll assertion mentions |
| Criteria list | append | New AC8: test scripts exist and pass locally |
| Progress label | edit | Updated from 0/7 to 0/8 |