Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
d93e3f7
Handbook POC: custom Astro + Cloudflare D1, hand-written Google OAuth
VibratingKoala Jun 30, 2026
1d6db1d
Add collapsible sidebar/TOC, on-page edit button, nested [[TOC]] indent
VibratingKoala Jun 30, 2026
1e83907
Add Back link and Delete button to the page editor
VibratingKoala Jun 30, 2026
b7c363f
Rework editor layout: top bar, collapsible settings, right-aligned ac…
VibratingKoala Jun 30, 2026
9086801
Style editor heading and add a delete confirmation modal
VibratingKoala Jun 30, 2026
4f83b98
Make the body/preview row a single collapsible "Content" section
VibratingKoala Jun 30, 2026
4dddf48
Remove the Leadership access group from the POC
VibratingKoala Jun 30, 2026
734fe02
Make the editor Save/Publish bar sticky to the viewport bottom
VibratingKoala Jun 30, 2026
a32b349
Make editor Back return to the previous page
VibratingKoala Jun 30, 2026
59fd830
Group admin Pages list by collapsible section; style its heading
VibratingKoala Jun 30, 2026
53af30f
Promote "New page" to a top-right button on the Pages list
VibratingKoala Jun 30, 2026
8f95f6e
Align Pages-list columns and add per-row Delete
VibratingKoala Jun 30, 2026
116f69b
Remove Home link from the top navbar (logo already links home)
VibratingKoala Jun 30, 2026
8450504
Sidebar: reset section open-state on reload, keep it across navigation
VibratingKoala Jun 30, 2026
904908a
Unify all buttons onto one .btn base with brand/alt/danger variants
VibratingKoala Jun 30, 2026
dd14d1e
Add "Back to handbook" link on the Pages list
VibratingKoala Jun 30, 2026
ce23ff2
Move "Back to handbook" link below the Pages list
VibratingKoala Jun 30, 2026
dc16806
Add visitor-scoped handbook search (titles + content)
VibratingKoala Jun 30, 2026
10102c0
Rename the editor route /admin -> /edit-pages
VibratingKoala Jun 30, 2026
f93870e
Edit by slug, and rename /edit-pages/new -> /edit-pages/create
VibratingKoala Jun 30, 2026
b3071fb
Move "Back to handbook" link directly under the Pages header
VibratingKoala Jun 30, 2026
4f4e93c
Replace native datalist with a themed Section combobox
VibratingKoala Jun 30, 2026
c44d3c3
Clean up leftovers from iterative UI changes
VibratingKoala Jul 1, 2026
83ff216
Rename editor "Slug" field to "Page URL" for non-technical staff
VibratingKoala Jul 1, 2026
a7ee2ab
Editor sections collapsed by default, restored on back-navigation
VibratingKoala Jul 1, 2026
518f2d7
Extract duplicated back-link logic into a shared helper
VibratingKoala Jul 1, 2026
1a792de
Extract duplicated collapse-persistence into a shared component
VibratingKoala Jul 1, 2026
a00f1a1
Phase 0: add git-backed content collection + frontmatter files
VibratingKoala Jul 1, 2026
d8b6e64
Phase 1: DB-free content read layer + canRead ACL
VibratingKoala Jul 1, 2026
a35cdef
Phase 2: serve readers from the content collection
VibratingKoala Jul 1, 2026
f50aaed
Phase 3: editor reads from git content; writes deferred (workerd)
VibratingKoala Jul 1, 2026
d509fcc
Phase 4: remove D1 content tables + code; D1 is identity-only now
VibratingKoala Jul 1, 2026
956e176
Update POC.md for the git-backed architecture
VibratingKoala Jul 1, 2026
200c087
Enable in-browser editor locally via a Node content agent
VibratingKoala Jul 1, 2026
ee470ac
Remove the database entirely — identity moves to a git config
VibratingKoala Jul 1, 2026
445011c
Validate rename oldSlug before writing (content agent)
VibratingKoala Jul 1, 2026
21cec9b
Purge stale D1/database references from comments + config
VibratingKoala Jul 1, 2026
4d84450
Fix dev:edit runner for the daemonizing astro dev
VibratingKoala Jul 1, 2026
bf23b82
Mark required editor fields (Title, Section) with red asterisks
VibratingKoala Jul 1, 2026
fe66da3
Document migration/cutover from GitHub Pages (VitePress) to Cloudflar…
VibratingKoala Jul 1, 2026
30e9a39
Harden markdown render: drop raw-HTML pass (stored-XSS fix)
VibratingKoala Jul 1, 2026
9db0628
Add DEV_USERS local override; harden identity resolution
VibratingKoala Jul 1, 2026
11c1127
Cleanup: remove stale D1 comments, format (biome)
VibratingKoala Jul 1, 2026
8258880
CI: run-tests.yml targets the Astro app, not the removed VitePress build
VibratingKoala Jul 1, 2026
10bafa2
Add tests: serializer round-trip, directory/DEV_USERS, origin/open-re…
VibratingKoala Jul 1, 2026
29ccac3
Fix post-login open redirect + validate rename source slug
VibratingKoala Jul 1, 2026
9382125
Robustness fixes from code review (render fail-closed, agent commits)
VibratingKoala Jul 1, 2026
c2a0076
Document review decisions: sidebar transparency + preview CSRF exemption
VibratingKoala Jul 1, 2026
a113d52
Rearchitect auth: GitHub OAuth + repo permissions ARE the access control
VibratingKoala Jul 2, 2026
9de4046
Editor saves commit AS THE SIGNED-IN PERSON via the GitHub API (no bot)
VibratingKoala Jul 2, 2026
efddfa2
Editor saves become submit-for-review pull requests (main is PR-prote…
VibratingKoala Jul 2, 2026
e9bddb4
Admin review dashboard: approve & publish handbook edits in-app
VibratingKoala Jul 2, 2026
514c23e
Guard: no personal emails in this public repo; pin pnpm
VibratingKoala Jul 2, 2026
3b89133
One button system: variants + sizes + states, no one-off button CSS
VibratingKoala Jul 2, 2026
ebd96bf
Fix all 8 findings from the PR-wide code review
VibratingKoala Jul 2, 2026
7ee1d6f
Pre-staging: CI trigger for review PRs, staging env, headers, 404 page
VibratingKoala Jul 2, 2026
5471a13
POC.md: production credentials must be org-owned, never personal
VibratingKoala Jul 2, 2026
6f93e64
Editor UX: live controls everywhere, styled popups, env ribbon
VibratingKoala Jul 2, 2026
014305a
Overhaul: 2-tier ACL + git-native draft/publish workflow
VibratingKoala Jul 2, 2026
effdbe5
Resume-from-draft + edit-state chips: unmerged work is never lost or …
VibratingKoala Jul 2, 2026
43d84ca
POC.md: DNS cutover plan updated for the Route 53 reality
VibratingKoala Jul 3, 2026
38512c7
Roles collapse to editor/reader; explicit write gate; POC branch targ…
VibratingKoala Jul 3, 2026
8ba4024
Editing auto-enables when sign-in switches to the GitHub App
VibratingKoala Jul 3, 2026
71fb20f
chore: trigger staging build from POC branch
VibratingKoala Jul 3, 2026
891030a
Fix review findings: parallelize edit-page reads, correct stale ACL c…
VibratingKoala Jul 3, 2026
a6f7059
Role checks self-serve with GitHub App tokens; GITHUB_TOKEN demoted t…
VibratingKoala Jul 6, 2026
8691f0a
Mobile-responsive UI + profile menu; deploy-safe config; docs match d…
VibratingKoala Jul 6, 2026
a03a86f
Pin SESSION KV namespace id so deploys don't rebind it (avoids loggin…
VibratingKoala Jul 6, 2026
d5b3ac3
Fix save/submit POSTing to a garbage URL (form.action clobbered by na…
VibratingKoala Jul 8, 2026
5bb358f
Manage pages: sections collapsed by default everywhere; unify naming
VibratingKoala Jul 8, 2026
c410a31
Editor polish: drafts section stands out; one resume banner; drop req…
VibratingKoala Jul 8, 2026
2f8e74e
Dedupe delete-confirm wiring into wireConfirmDelete; drop dead CSS
VibratingKoala Jul 8, 2026
d161c27
Delete on a never-published page discards its draft branch
VibratingKoala Jul 8, 2026
d199526
Save/Submit UX: busy-state buttons; land back on the edit page
VibratingKoala Jul 8, 2026
225cb81
Dedupe PR-link building; busy-state for Approve/Reject; bfcache reset
VibratingKoala Jul 9, 2026
f698a47
Internal review page: read & approve a pending change without leaving…
VibratingKoala Jul 9, 2026
3248667
Environment ribbon: STAGING -> POC (honest label for the evaluation p…
VibratingKoala Jul 9, 2026
9c8bb4b
Reviews: table -> flex-wrap list (mobile was scrolling sideways)
VibratingKoala Jul 9, 2026
55bdca2
Add CLAUDE.md: standing code-quality + public-repo rules for AI sessions
VibratingKoala Jul 9, 2026
278837a
Reviews polish: card rows; human titles instead of commit-speak
VibratingKoala Jul 9, 2026
3ad8ce4
Deploy-on-push workflow (inert until CLOUDFLARE_API_TOKEN secret exists)
VibratingKoala Jul 9, 2026
77935ce
POC.md: deploy-on-push CI now exists (inert until repo secret added)
VibratingKoala Jul 9, 2026
6d85cd8
Port the five style guides from PR #73 into handbook content
VibratingKoala Jul 10, 2026
434092d
Sidebar nesting via parent frontmatter (matches the original handbook…
VibratingKoala Jul 10, 2026
70e6d73
Sidebar: parents with children are collapsible (chevron, active trail…
VibratingKoala Jul 10, 2026
bf596c3
Cap + center the doc shell at 1440px (ultrawide was scattering the co…
VibratingKoala Jul 10, 2026
0d57bea
POC.md: catch docs up — App live since 07-09, internal review page, p…
VibratingKoala Jul 10, 2026
c592fe8
Merge remote-tracking branch 'origin/main' into i68-handbook-poc
VibratingKoala Jul 13, 2026
c615f3f
Fix astro-check 1002: '<=' in a template expression parses as a fragment
VibratingKoala Jul 13, 2026
9009f0c
Single source: the app reads doc/*.md directly — ported copies deleted
VibratingKoala Jul 13, 2026
8ed029c
ACL-aware llms.txt / llms-full.txt / per-page .md endpoints
VibratingKoala Jul 13, 2026
73a64e0
Deploy on doc/** pushes too — content moved out of app/ in the single…
VibratingKoala Jul 15, 2026
a8e9c3d
POC.md: document the llms.txt agent surface + cutover visibility prer…
VibratingKoala Jul 15, 2026
57c351a
Cleanup pass: consolidate duplicated rules; fix security-policy's set…
VibratingKoala Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/deploy-worker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Deploy Worker
# Deploys the handbook Worker whenever app code or content lands on the
# deployed branch — this is what makes an approved "Submit for approval" merge
# actually appear on the site. During the POC that branch is i68-handbook-poc;
# after the POC merges, pushes to main take over (same worker, same workflow).
#
# INERT UNTIL CONFIGURED: requires the CLOUDFLARE_API_TOKEN repo secret
# (repo admin: Settings → Secrets and variables → Actions; token needs
# Workers Scripts:Edit + Workers KV Storage:Edit). Until it exists, runs
# skip with a notice instead of failing every merge.
#
# Deploy safety: wrangler.toml sets keep_vars=true and pins the SESSION KV id,
# so CI deploys never wipe dashboard vars/secrets or rebind the session store.
on:
push:
branches:
- i68-handbook-poc
- main
paths:
- "app/**"
# content is doc/*.md (single source since the doc/ refactor) — an
# approved editor merge touches ONLY doc/, and it must redeploy too
- "doc/**"
workflow_dispatch:

permissions:
contents: read

# One deploy at a time, never cancelled mid-upload; queued runs collapse to
# the latest.
concurrency:
group: deploy-worker
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Check for Cloudflare credentials
id: creds
env:
TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
if [ -n "$TOKEN" ]; then
echo "ok=true" >> "$GITHUB_OUTPUT"
else
echo "ok=false" >> "$GITHUB_OUTPUT"
echo "::notice::CLOUDFLARE_API_TOKEN secret not set — skipping deploy (a repo admin must add it; see workflow header)."
fi
- uses: actions/checkout@v4
if: steps.creds.outputs.ok == 'true'
- name: Set up pnpm
if: steps.creds.outputs.ok == 'true'
uses: pnpm/action-setup@v4
with:
version: 10
- name: Set up Node.js
if: steps.creds.outputs.ok == 'true'
uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
cache-dependency-path: app/pnpm-lock.yaml
- name: Install dependencies
if: steps.creds.outputs.ok == 'true'
run: pnpm install --frozen-lockfile
working-directory: app
- name: Test & build
if: steps.creds.outputs.ok == 'true'
run: pnpm test && pnpm build
working-directory: app
- name: Deploy
if: steps.creds.outputs.ok == 'true'
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
workingDirectory: app
command: deploy
44 changes: 42 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Run Tests
on:
pull_request:
types: [review_requested, synchronize, labeled]
types: [opened, review_requested, synchronize, labeled]
push:
branches:
- "main"
Expand All @@ -11,13 +11,24 @@ permissions:
pull-requests: write

jobs:
run-tests:
# ONE copy of the trigger condition; both build jobs hang off it via `needs`
# (a skipped gate skips them too). handbook/* head branches are editor
# "submit for review" PRs (opened by the handbook app, never
# review_requested/labeled) — run-tests is a REQUIRED check on main, so
# without that clause those PRs could never merge.
gate:
if: |
(github.event.action == 'review_requested' ||
(github.event.action == 'labeled' && github.event.label.name == 'ci-testing') ||
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'ci-testing'))) ||
(github.event_name == 'pull_request' && startsWith(github.event.pull_request.head.ref, 'handbook/')) ||
(github.event_name == 'push')
runs-on: ubuntu-latest
steps:
- run: "true"

run-tests:
needs: gate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand All @@ -35,6 +46,35 @@ jobs:
repo: context.repo.repo,
labels: ["ci-testing"]
})
- name: Set up pnpm
# app/ is a standalone pnpm project (not in the root workspace);
# pin its pnpm from app/package.json, not the root's.
uses: pnpm/action-setup@v6
with:
package_json_file: app/package.json
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24 # >=22.18 for node --test importing .ts (type stripping)
cache: pnpm
cache-dependency-path: app/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: app
- name: Typecheck, test, guard, build
run: pnpm check && pnpm test && pnpm guard && pnpm build
working-directory: app

# The legacy VitePress site still ships from doc/ until the cutover
# (POC.md "Migration & production cutover") — keep its build green too.
docs-build:
needs: gate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.sha }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Set up pnpm
uses: pnpm/action-setup@v6
- name: Set up Node.js
Expand Down
33 changes: 33 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Claude instructions — osbrjp/handbook

App code lives in `app/` (Astro SSR on Cloudflare Workers). `doc/` is the
legacy VitePress site. `POC.md` records architecture decisions, deploy
mechanics, and the cutover plan — read it before changing auth, deploy
config, or the content workflow.

## Code quality (apply to every change)

- **No duplicates.** Before finishing any change, sweep for copy-pasted
logic/markup/CSS it introduced or touched. Extract a helper or shared
component when the same rule lives in two places (see
`app/src/lib/ui/editorForms.ts`, `app/src/components/Icon.astro` for the
established pattern). Don't extract when call sites merely look similar
but encode different behavior.
- **Comments: short, but enough context for the next session.** Explain WHY
(the constraint, the trap, the verified fact) — never what the next line
does. Delete comments that describe old iterations.
- **CSS**: source order matters in `global.css` — same-specificity overrides
must come AFTER the base rules they override (this has silently broken
before; grep "admin-list mobile" for the documented example).

## Hard rules (public repo)

- **Scan every diff before commit/push** for secrets, tokens, personal
emails, account ids, and live non-production URLs. Encrypted values and
credentials live in Cloudflare/GitHub settings, never in the repo.
- No allow-lists, no databases: GitHub repo access IS the access control.
- Use **pnpm** in `app/` (never npm).

## Gates before any commit

Run in `app/`: `pnpm test` and `pnpm build` — both must pass.
Loading
Loading