Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 16 additions & 2 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,20 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Verify Pages artifact root
- name: Install Chromium release dependency
run: npx playwright install --with-deps chromium

- name: Run browser and accessibility release checks
run: npm run test:browser

- name: Verify Pages artifact root and identity
run: |
test -s _site/index.html
test -s _site/CNAME
test "$(cat _site/CNAME)" = "interdependentway.org"
test -d _site/pagefind
test -s _site/build.json
node -e "const b=require('./_site/build.json'); if(b.commit!==process.env.GITHUB_SHA) process.exit(1)"

- name: Configure Pages
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6, node24
Expand All @@ -64,7 +72,7 @@ jobs:
path: _site

deploy:
name: Deploy verified site
name: Deploy and verify site
needs: build
runs-on: ubuntu-latest
environment:
Expand All @@ -74,3 +82,9 @@ jobs:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5, node24

- name: Verify Pages deployment identity
run: node scripts/verify-live-deployment.mjs "${{ steps.deployment.outputs.page_url }}" "${{ github.sha }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Check out the repo before verification

In the deploy job, this is the first step that references repository files, but that job never runs actions/checkout (the checkout only happens in the separate build job). Because GitHub Actions jobs run on fresh runners, there will be no scripts/verify-live-deployment.mjs on disk after actions/deploy-pages, so every otherwise-successful Pages deployment will fail here with a module-not-found error before the identity check can run.

Useful? React with 👍 / 👎.


- name: Verify custom-domain deployment identity
run: node scripts/verify-live-deployment.mjs "https://interdependentway.org" "${{ github.sha }}"
58 changes: 6 additions & 52 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,59 +23,13 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Audit workflow action versions
run: npm run audit:workflows

- name: Run clean-checkout tests
run: |
set -o pipefail
npm test 2>&1 | tee clean-test.log

- name: Preserve clean-checkout test failure log
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7, node24
with:
name: clean-test-failure-${{ github.sha }}
path: clean-test.log
retention-days: 3
if-no-files-found: ignore

- name: Refresh canonical and organization data
run: npm run refresh:data
- name: Build, validate, and test
run: npm run check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Verify canon authority
run: node -e "const c=require('./src/_data/generated/canon.json'); if(c.source.repository!=='wayseer00/main'||c.source.path!=='canon/INTERDEPENDENT_WAY.txt') process.exit(1)"

- name: Verify canon unit evidence
run: node -e "const c=require('./src/_data/generated/canon.json'); if(!c.source.contentSha256||c.source.contentSha256.length!==64||(!c.source.fallback&&(!c.source.commit||!c.source.blob))||!c.units.length||c.units.some(u=>!u.id||!u.hash)) process.exit(1)"

- name: Verify repository route coverage
run: node -e "const r=require('./src/_data/generated/repos.json'); if(r.publicRepoCount!==r.generatedRouteCount||new Set(r.repositories.map(x=>x.slug)).size!==r.repositories.length) process.exit(1)"

- name: Verify recovery inputs
run: test -s fallback/index.html && test -s artifacts/four-cuts-1.html

- name: Validate generated content contracts
run: npm run validate

- name: Generate Eleventy site
run: |
set -o pipefail
npx eleventy 2>&1 | tee eleventy-build.log

- name: Preserve Eleventy failure log
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7, node24
with:
name: eleventy-failure-${{ github.sha }}
path: eleventy-build.log
retention-days: 3
if-no-files-found: ignore

- name: Generate Pagefind search index
run: npx pagefind --site _site
- name: Install Chromium release dependency
run: npx playwright install --with-deps chromium

- name: Run generated-site tests
run: npm run test:generated
- name: Run browser and accessibility release checks
run: npm run test:browser
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ yarn-error.log*
# Dependency directories
node_modules/

# Build output (if using bundlers)
# Build output
_dist/
dist/
build/
_site/
.cache/

# Build-time generated data
/src/_data/generated/canon.json

# Python
__pycache__/
*.pyc
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The canonical text lives in `wayseer00/main:canon/INTERDEPENDENT_WAY.txt`, and n
- `.interdependency/project.yml` supplies reviewed project purpose, maturity, relationships, and links.
- `fallback/` is a dependency-free emergency edition.
- `artifacts/four-cuts-1.html` is deliberately published at `/artifacts/four-cuts/` through Eleventy passthrough.
- `_site/build.json` publishes the site commit and canonical source identity for live deployment verification.

## Usage guidance

Expand Down Expand Up @@ -56,4 +57,6 @@ Place that file at `.interdependency/project.yml`. Until it exists, the public p

## Release discipline

GitHub Actions runs the workflow action audit, build, validation, tests, static search generation, and deployment. The workflow audit requires full-length commit SHA pins and rejects tag refs, short SHAs, stale SHAs, or unapproved pins for the GitHub-owned actions used by this site. Failed builds do not replace the last successful Pages artifact. Emergency fallback deployment is explicit rather than automatic.
GitHub Actions runs the workflow action audit, provenance refresh, article-to-canon exactness gate, build, validation, tests, static search generation, browser checks, accessibility checks, deployment, and live build-identity verification. The workflow audit requires full-length commit SHA pins and rejects tag refs, short SHAs, stale SHAs, or unapproved pins for the GitHub-owned actions used by this site. Failed builds do not replace the last successful Pages artifact. Emergency fallback deployment is explicit rather than automatic.

Repository source cannot configure the Pages source, custom domain, DNS, HTTPS, or branch protection. The required administrative settings and the release-truth contract are documented in [`docs/pages-release.md`](docs/pages-release.md).
31 changes: 31 additions & 0 deletions docs/pages-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# GitHub Pages release truth

The production artifact is `_site`. A release is not complete merely because source exists on `main` or a Pages job reports that an artifact was uploaded.

## Repository contract

1. `npm run check` refreshes canon and organization data, verifies provenance, validates all routes, compares every rights-article excerpt and note with the selected canon, generates the Eleventy site and Pagefind index, and runs generated-site tests.
2. Browser and accessibility checks run against the generated artifact before upload.
3. `_site/build.json` records the exact site commit and canonical source identity.
4. After deployment, both the GitHub Pages URL and `https://interdependentway.org/build.json` must report the expected commit. A stale or missing identity fails the workflow.

## Required GitHub configuration

These settings are outside repository source control and require repository administration:

- **Settings → Pages → Build and deployment → Source:** GitHub Actions.
- **Custom domain:** `interdependentway.org`.
- **DNS:** the apex and any intended `www` record must resolve according to GitHub Pages guidance and pass GitHub's domain check.
- **Enforce HTTPS:** enabled after the certificate is available.
- **Environment:** `github-pages` must allow the Pages workflow to deploy.
- **Branch protection:** require the `Verify generated site` pull-request check before merging to `main`.

## Incident reading

- Branch-root `index.html` is a recovery floor, not the preferred publication.
- The generated site is current only when `/build.json` matches the expected deployment SHA.
- Canon freshness is separately shown by the canonical repository, commit, blob, content digest, and fallback flag in the same file.

## hmmm

The workflow can prove what was built and what the public endpoints serve. It cannot change DNS, attach the custom domain, enable HTTPS, or alter Pages source settings from repository code; those remain explicit administrative boundaries.
13 changes: 6 additions & 7 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The Interdependent Way</title>
<meta name="description" content="Canon-safe public entrance for The Interdependent Way while the full generated site deployment is repaired.">
<meta name="description" content="Canon-safe public entrance for The Interdependent Way when the verified generated site is unavailable.">
<style>
:root { color-scheme: dark; --bg:#07090d; --panel:#111827; --ink:#edf2ff; --muted:#b8c2d6; --line:#2c3446; --accent:#8fd3ff; --warn:#ffd479; }
* { box-sizing: border-box; }
Expand All @@ -21,15 +21,14 @@
.actions { display: flex; flex-wrap: wrap; gap: .75rem; margin: 1.5rem 0; }
.button { border: 1px solid var(--accent); border-radius: 999px; padding: .75rem 1rem; text-decoration: none; font-weight: 700; }
code { background: #05070a; border: 1px solid var(--line); border-radius: .4rem; padding: .1rem .35rem; }
ul { padding-left: 1.2rem; }
footer { color: var(--muted); border-top: 1px solid var(--line); }
</style>
</head>
<body>
<header>
<p class="eyebrow">Canon-safe entrance · branch-source fallback</p>
<h1>The Interdependent Way</h1>
<p class="lede">This page replaces the stale raw-text homepage while the full generated Eleventy / Article Lab deployment is being repaired. It does not replace the canon.</p>
<p class="lede">This is the recovery floor. The preferred public experience is the verified Eleventy artifact, whose machine-readable build identity must match the repository commit that deployed it.</p>
<div class="actions" aria-label="Primary links">
<a class="button" href="https://github.com/wayseer00/main/blob/main/canon/INTERDEPENDENT_WAY.txt">Read the canonical text</a>
<a class="button" href="https://github.com/The-Interdependency/The-Interdependency.github.io">Website repository</a>
Expand All @@ -44,16 +43,16 @@ <h2>Canon</h2>
</article>
<article class="card">
<h2>Website</h2>
<p>The generated static site has a passing build-and-validation path. This root page exists because the public domain is still serving branch-root content rather than the verified generated artifact.</p>
<p>The generated site now publishes <code>/build.json</code> with its site commit and canonical provenance. Deployment is green only when the public endpoint reports the expected commit.</p>
</article>
<article class="card">
<h2>Next</h2>
<p>Repair the GitHub Pages source/deployment setting, then publish the Article Two vertical slice: orientation, exact source, companion reading, Lab conversation, research field, and script/handbook derivatives.</p>
<h2>Next platform action</h2>
<p>GitHub Pages must use GitHub Actions, attach <code>interdependentway.org</code>, verify DNS, and enforce HTTPS. Those settings live outside this branch and require repository administration.</p>
</article>
</section>
<section class="hmmm" style="margin-top:1rem">
<h2>hmmm</h2>
<p>This is a recovery floor, not the preferred public experience. If you are seeing this page, the old raw-text homepage has been displaced, but the full layered site still needs the Pages deployment path corrected.</p>
<p>If you are seeing this page, the recovery floor is doing its job but the generated deployment is not yet proven current. Check the Pages environment and compare the live <code>/build.json</code> commit with <code>main</code>.</p>
</section>
</main>
<footer>
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
"refresh:github": "node scripts/fetch-github-org.mjs",
"research:enrich": "node scripts/enrich-citations.mjs",
"audit:workflows": "node scripts/audit-workflows.mjs",
"validate": "node scripts/validate-content.mjs && node scripts/verify-generated-routes.mjs",
"build": "npm run refresh:data && npm run validate && eleventy && pagefind --site _site",
"prevalidate": "npm run refresh:data",
"validate": "node scripts/validate-content.mjs && node scripts/verify-generated-routes.mjs && node scripts/verify-article-canon.mjs",
"build": "npm run validate && eleventy && pagefind --site _site && node scripts/write-build-info.mjs",
"pretest": "node scripts/prepare-tests.mjs",
"test": "node --test tests/canon-integrity.test.mjs tests/offline-project-snapshot.test.mjs tests/repo-coverage.test.mjs tests/research-ledger.test.mjs tests/site-contract.test.mjs",
"test": "node --test tests/canon-parser.test.mjs tests/canon-integrity.test.mjs tests/offline-project-snapshot.test.mjs tests/repo-coverage.test.mjs tests/research-ledger.test.mjs tests/site-contract.test.mjs",
"test:generated": "node --test tests/generated-site.test.mjs && node tests/links.test.mjs",
"test:e2e": "playwright test tests/*.spec.mjs",
"test:browser": "playwright test",
"test:e2e": "playwright test tests/site.spec.mjs",
"test:a11y": "playwright test tests/accessibility.spec.mjs",
"test:links": "node tests/links.test.mjs",
"test:performance": "node scripts/performance-placeholder.mjs",
Expand Down
52 changes: 52 additions & 0 deletions playwright.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Usage: run `npm run test:browser` after `npm run build`; CI installs Chromium before execution.
// Limits: tests the generated artifact on loopback and does not replace live deployment identity verification.
// === MODULE_BUILD ===
// id: generated_site_browser_harness
// module_name: playwright-config
// module_kind: instrument
// summary: Configures browser, route, and automated accessibility checks against the generated site.
// owner: Erin Spencer
// public_surface: npm run test:browser, npm run test:e2e, npm run test:a11y
// internal_surface: Playwright webServer and Chromium test configuration
// auth_boundary: none
// storage_boundary: read
// network_boundary: internal
// user_data_boundary: none
// admin_only: false
// tests: tests/site.spec.mjs, tests/accessibility.spec.mjs
// rollout: required by pull-request and Pages workflows
// rollback: remove browser scripts, workflow steps, and static test server together
// === END MODULE_BUILD ===
// === BOUNDARIES ===
// id: generated_site_browser_harness_boundary
// summary: Launches Chromium and a loopback-only static server against generated public files.
// auth_boundary: none
// storage_boundary: read
// network_boundary: internal
// user_data_boundary: none
// admin_only: false
// pii: none
// secrets: none
// side_effects: browser processes, loopback listener
// owner: Erin Spencer
// === END BOUNDARIES ===
import { defineConfig } from '@playwright/test';

export default defineConfig({
testDir: './tests',
testMatch: ['**/*.spec.mjs'],
fullyParallel: false,
retries: process.env.CI ? 1 : 0,
reporter: process.env.CI ? 'github' : 'list',
use: {
baseURL: 'http://127.0.0.1:4173',
browserName: 'chromium',
trace: 'retain-on-failure'
},
webServer: {
command: 'node scripts/serve-static.mjs',
port: 4173,
reuseExistingServer: !process.env.CI,
timeout: 30000
}
});
Loading
Loading