From b17e603c3f535fb7eb21a87b4827dfe9df1164a2 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Tue, 21 Jul 2026 01:59:50 -0700 Subject: [PATCH 1/4] Repair release integrity and complete Article Two evidence Add live deployment identity verification, canon exactness gates, offline parser recovery tests, browser/accessibility release checks, and reviewed Article Two support/dissent/limits. Declare new modules and runtime boundaries using current skill-lib metadata fields; document usage, rollback, and Pages administration boundaries. --- .github/workflows/pages.yml | 18 +- .github/workflows/pull-request.yml | 58 +-- .gitignore | 6 +- README.md | 5 +- docs/pages-release.md | 31 ++ index.html | 13 +- package.json | 10 +- playwright.config.mjs | 52 ++ scripts/canon-parser.mjs | 185 +++++++ scripts/parse-canon.mjs | 148 ++---- scripts/serve-static.mjs | 76 +++ scripts/validate-content.mjs | 37 +- scripts/verify-article-canon.mjs | 92 ++++ scripts/verify-live-deployment.mjs | 66 +++ scripts/write-build-info.mjs | 63 +++ src/_data/generated/canon.json | 741 ----------------------------- src/_data/research/claims.yml | 36 +- src/_data/research/sources.yml | 48 +- src/articles/article-two.njk | 32 +- src/index.njk | 10 +- tests/accessibility.spec.mjs | 20 + tests/canon-parser.test.mjs | 40 ++ tests/generated-site.test.mjs | 15 +- tests/research-ledger.test.mjs | 29 +- tests/site.spec.mjs | 31 ++ 25 files changed, 916 insertions(+), 946 deletions(-) create mode 100644 docs/pages-release.md create mode 100644 playwright.config.mjs create mode 100644 scripts/canon-parser.mjs create mode 100644 scripts/serve-static.mjs create mode 100644 scripts/verify-article-canon.mjs create mode 100644 scripts/verify-live-deployment.mjs create mode 100644 scripts/write-build-info.mjs delete mode 100644 src/_data/generated/canon.json create mode 100644 tests/accessibility.spec.mjs create mode 100644 tests/canon-parser.test.mjs create mode 100644 tests/site.spec.mjs diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index b532c9c..bf54dac 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -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 @@ -64,7 +72,7 @@ jobs: path: _site deploy: - name: Deploy verified site + name: Deploy and verify site needs: build runs-on: ubuntu-latest environment: @@ -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 }}" + + - name: Verify custom-domain deployment identity + run: node scripts/verify-live-deployment.mjs "https://interdependentway.org" "${{ github.sha }}" diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 0b61120..d08a49e 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -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 diff --git a/.gitignore b/.gitignore index 534d169..ba3421c 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/README.md b/README.md index f2cff0d..517958e 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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). diff --git a/docs/pages-release.md b/docs/pages-release.md new file mode 100644 index 0000000..553549e --- /dev/null +++ b/docs/pages-release.md @@ -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. diff --git a/index.html b/index.html index 5e41f7c..c842f30 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ The Interdependent Way - + @@ -29,7 +28,7 @@

Canon-safe entrance · branch-source fallback

The Interdependent Way

-

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.

+

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.

Read the canonical text Website repository @@ -44,16 +43,16 @@

Canon

Website

-

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.

+

The generated site now publishes /build.json with its site commit and canonical provenance. Deployment is green only when the public endpoint reports the expected commit.

-

Next

-

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.

+

Next platform action

+

GitHub Pages must use GitHub Actions, attach interdependentway.org, verify DNS, and enforce HTTPS. Those settings live outside this branch and require repository administration.

hmmm

-

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.

+

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 /build.json commit with main.

diff --git a/package.json b/package.json index ffc9555..73ebae8 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/playwright.config.mjs b/playwright.config.mjs new file mode 100644 index 0000000..5c90df0 --- /dev/null +++ b/playwright.config.mjs @@ -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 + } +}); diff --git a/scripts/canon-parser.mjs b/scripts/canon-parser.mjs new file mode 100644 index 0000000..1ee7a55 --- /dev/null +++ b/scripts/canon-parser.mjs @@ -0,0 +1,185 @@ +import { createHash } from 'node:crypto'; +import slugify from 'slugify'; + +// === MODULE_BUILD === +// id: canon_parser_core +// module_name: canon-parser +// module_kind: engine +// summary: Parses canonical or recovery text into stable sections, units, notes, routes, and provenance-bearing hashes. +// owner: Erin Spencer +// public_surface: parseCanon, detectHeading, extractNotes +// internal_surface: slug, boundedRouteSlug, parseDefinitionLine, extractNoteMarkers +// auth_boundary: none +// storage_boundary: none +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// tests: tests/canon-parser.test.mjs, tests/canon-integrity.test.mjs +// rollout: imported by scripts/parse-canon.mjs during every canon refresh +// rollback: restore the prior inline parser and remove this import +// === END MODULE_BUILD === +// Usage: import parseCanon(text, provenance); run `node --test tests/canon-parser.test.mjs` for recovery and note fixtures. +// Limits: heading recognition is canon-specific; unknown headings remain body text and must surface as hmmm during editorial review. + +export const parserVersion = '0.5.0'; +const superscriptDigits = '⁰¹²³⁴⁵⁶⁷⁸⁹'; +const subsequentNoteMarkerSource = `(?:\[[^\]]+\]|[${superscriptDigits}]+)`; + +function slug(value) { + return slugify(value, { lower: true, strict: true }) || 'unit'; +} + +function boundedRouteSlug(id) { + const candidate = slug(id); + if (candidate.length <= 96) return candidate; + const suffix = createHash('sha256').update(id).digest('hex').slice(0, 10); + return `${candidate.slice(0, 84).replace(/-+$/, '')}-${suffix}`; +} + +export function detectHeading(line) { + const markdown = /^(#{1,6})\s+(.+?)\s*$/.exec(line); + if (markdown) { + const sourceLevel = markdown[1].length; + // The recovery mirror uses H3 for the same major divisions that the plain-text + // canon expresses as level 2, and H4 for article units. Normalize those levels + // before assigning parents so offline and remote builds have the same structure. + const level = sourceLevel >= 3 ? sourceLevel - 1 : sourceLevel; + return { + level, + sourceLevel, + title: markdown[2].replace(/#+$/, '').trim(), + syntax: 'markdown' + }; + } + + const title = line.trim(); + if (!title) return null; + if (title === 'The Interdependent Way') return { level: 1, sourceLevel: 1, title, syntax: 'plain' }; + if (/^(Awakening|The Interdefinables|Human consciousness emerges from|Preamble|Etiquette of the Body Politic)$/i.test(title)) { + return { level: 2, sourceLevel: 2, title, syntax: 'plain' }; + } + if (/^Rights[\w\s’'&\-⁰¹²³⁴⁵⁶⁷⁸⁹]+of The Way[⁰¹²³⁴⁵⁶⁷⁸⁹]*$/i.test(title)) { + return { level: 2, sourceLevel: 2, title, syntax: 'plain' }; + } + if (/^Addendum:\s+.+$/i.test(title)) return { level: 2, sourceLevel: 2, title, syntax: 'plain' }; + if (/^Article\s+(One|Two|Three|Four|Five|Six|Seven|Eight)(?:\s+\([^)]+\))?$/i.test(title)) { + return { level: 3, sourceLevel: 3, title, syntax: 'plain' }; + } + if (/^(Binary essences meaningfully, divided; then, rooted\.|Trinary perceptual focal states of complex system spirals:.+|Trinary states of social perception:|Archetype passions of possession\..+|Summary|One-sentence takeaway \(exactly as previously given\))$/i.test(title)) { + return { level: 3, sourceLevel: 3, title, syntax: 'plain' }; + } + return null; +} + +function parseDefinitionLine(line) { + const normalized = line.replace(/^\s*>?\s*/, '').trim(); + const first = + /^(\[[^\]]+\])\s+(.+)$/.exec(normalized) || + new RegExp(`^([${superscriptDigits}]+)\s*(.+)$`).exec(normalized) || + /^(\d+)\s+(.+)$/.exec(normalized); + if (!first) return []; + + const notes = []; + let marker = first[1]; + let remaining = first[2]; + const nextPattern = new RegExp(`\s+(${subsequentNoteMarkerSource})\s*`); + + while (true) { + const next = nextPattern.exec(remaining); + if (!next) { + if (remaining.trim()) notes.push({ marker, text: remaining.trim() }); + break; + } + const text = remaining.slice(0, next.index).trim(); + if (text) notes.push({ marker, text }); + marker = next[1]; + remaining = remaining.slice(next.index + next[0].length); + } + return notes; +} + +export function extractNotes(content) { + return content.split(/\r?\n/).flatMap(parseDefinitionLine); +} + +function extractNoteMarkers(content) { + const markers = []; + for (const match of content.matchAll(/\[[^\]]+\]|[⁰¹²³⁴⁵⁶⁷⁸⁹]+/g)) markers.push(match[0]); + return [...new Set(markers)]; +} + +export function parseCanon(text, provenance = {}) { + const lines = text.split(/\r?\n/); + const documentHash = createHash('sha256').update(text).digest('hex'); + const units = []; + const sections = []; + let current = null; + let sectionId = 'source'; + + function finish(endLine) { + if (!current) return; + current.endLine = endLine; + current.content = current.lines.join('\n').trim(); + current.hash = createHash('sha256').update(current.content).digest('hex'); + current.notes = extractNotes(current.content); + current.noteMarkers = extractNoteMarkers(current.content); + units.push(current); + } + + for (let index = 0; index < lines.length; index += 1) { + const heading = detectHeading(lines[index]); + if (!heading) { + if (current) current.lines.push(lines[index]); + continue; + } + + finish(index); + const { level, sourceLevel, title, syntax } = heading; + if (level <= 2) { + sectionId = slug(title).replace(/^the-/, ''); + if (!sections.some(section => section.id === sectionId)) { + sections.push({ id: sectionId, title, level, sourceLevel, syntax, line: index + 1 }); + } + } + + current = { + id: `${sectionId}.${slug(title)}`, + title, + section: sectionId, + level, + sourceLevel, + syntax, + startLine: index + 1, + lines: [lines[index]] + }; + } + finish(lines.length); + + if (!units.length) throw new Error('canon parser produced no units'); + + const duplicateIds = units.map(unit => unit.id).filter((id, index, all) => all.indexOf(id) !== index); + if (duplicateIds.length) { + for (const duplicate of new Set(duplicateIds)) { + units.filter(unit => unit.id === duplicate).forEach((unit, index) => { + unit.id = `${unit.id}-${index + 1}`; + }); + } + } + + for (const unit of units) unit.routeSlug = boundedRouteSlug(unit.id); + if (new Set(units.map(unit => unit.routeSlug)).size !== units.length) throw new Error('canon route slug collision'); + + const notes = units.flatMap(unit => unit.notes.map((note, index) => ({ + id: `${unit.id}.note-${index + 1}-${slug(note.marker)}`, + unit_id: unit.id, + ...note + }))); + + return { + source: { ...provenance, contentSha256: documentHash, parserVersion }, + sections, + units: units.map(({ lines: ignored, ...unit }) => unit), + notes, + edges: units.map(unit => ({ from: unit.id, to: unit.section, type: 'unit-parent' })) + }; +} diff --git a/scripts/parse-canon.mjs b/scripts/parse-canon.mjs index 4ede66f..f46a448 100644 --- a/scripts/parse-canon.mjs +++ b/scripts/parse-canon.mjs @@ -1,125 +1,45 @@ -import { createHash } from 'node:crypto'; import { mkdir, readFile, writeFile } from 'node:fs/promises'; -import slugify from 'slugify'; +import { parseCanon } from './canon-parser.mjs'; // === MODULE_BUILD === -// id: canon_structure_parser -// purpose: Derive stable sections, units, note text, bounded routes, links, and hashes from the canonical snapshot. -// entrypoint: npm run refresh:canon -// tests: tests/canon-integrity.test.mjs +// id: canon_structure_materializer +// module_name: parse-canon +// module_kind: worker +// summary: Reads the selected canon snapshot and writes provenance-bearing generated canon data. +// owner: Erin Spencer +// public_surface: npm run refresh:canon +// internal_surface: parseCanon invocation and generated JSON write +// auth_boundary: none +// storage_boundary: write +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// tests: tests/canon-parser.test.mjs, tests/canon-integrity.test.mjs +// rollout: invoked after scripts/fetch-canon.mjs in refresh:data +// rollback: restore the previous parser implementation and generated-data contract // === END MODULE_BUILD === +// Usage: run `npm run refresh:canon`; inspect `src/_data/generated/canon.json` and its source provenance. +// Limits: this materializer trusts only the selected snapshot and does not decide whether interpretation is canon. + +// === BOUNDARIES === +// id: canon_materialization_boundary +// summary: Reads canon snapshots and writes generated canon JSON. +// auth_boundary: none +// storage_boundary: write +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// pii: none +// secrets: none +// side_effects: generated canon file +// owner: Erin Spencer +// === END BOUNDARIES === -const parserVersion = '0.4.1'; const provenance = JSON.parse(await readFile('src/_data/snapshots/canon.provenance.json', 'utf8')); const raw = await readFile('src/_data/snapshots/canon.last-known-good.md', 'utf8'); const text = raw.replace(/^---\n[\s\S]*?\n---\n/, ''); -const lines = text.split(/\r?\n/); -const documentHash = createHash('sha256').update(text).digest('hex'); -const units = []; -const sections = []; -let current = null; -let sectionId = 'source'; - -function slug(value) { - return slugify(value, { lower: true, strict: true }) || 'unit'; -} -function boundedRouteSlug(id) { - const candidate = slug(id); - if (candidate.length <= 96) return candidate; - const suffix = createHash('sha256').update(id).digest('hex').slice(0, 10); - return `${candidate.slice(0, 84).replace(/-+$/, '')}-${suffix}`; -} -function detectHeading(line) { - const markdown = /^(#{1,6})\s+(.+?)\s*$/.exec(line); - if (markdown) return { level: markdown[1].length, title: markdown[2].replace(/#+$/, '').trim() }; - const title = line.trim(); - if (!title) return null; - if (title === 'The Interdependent Way') return { level: 1, title }; - if (/^(Awakening|The Interdefinables|Human consciousness emerges from|Preamble|Etiquette of the Body Politic)$/i.test(title)) { - return { level: 2, title }; - } - if (/^Rights[\w\s’'&\-⁰¹²³⁴⁵⁶⁷⁸⁹]+of The Way[⁰¹²³⁴⁵⁶⁷⁸⁹]*$/i.test(title)) return { level: 2, title }; - if (/^Addendum:\s+.+$/i.test(title)) return { level: 2, title }; - if (/^Article\s+(One|Two|Three|Four|Five|Six|Seven|Eight)(?:\s+\([^)]+\))?$/i.test(title)) return { level: 3, title }; - if (/^(Binary essences meaningfully, divided; then, rooted\.|Trinary perceptual focal states of complex system spirals:.+|Trinary states of social perception:|Archetype passions of possession\..+|Summary|One-sentence takeaway \(exactly as previously given\))$/i.test(title)) { - return { level: 3, title }; - } - return null; -} -function extractNotes(content) { - const notes = []; - for (const line of content.split(/\r?\n/)) { - const bracket = /^\s*\[([^\]]+)\]\s+(.+)$/.exec(line); - if (bracket) { - notes.push({ marker: `[${bracket[1]}]`, text: bracket[2].trim() }); - continue; - } - const superscript = /^\s*>?\s*([⁰¹²³⁴⁵⁶⁷⁸⁹]+)\s*(.+)$/.exec(line); - if (superscript) { - notes.push({ marker: superscript[1], text: superscript[2].trim() }); - continue; - } - const digit = /^\s*>?\s*(\d+)\s+(.+)$/.exec(line); - if (digit) notes.push({ marker: digit[1], text: digit[2].trim() }); - } - return notes; -} -function extractNoteMarkers(content) { - const markers = []; - for (const match of content.matchAll(/\[[^\]]+\]|[⁰¹²³⁴⁵⁶⁷⁸⁹]+/g)) markers.push(match[0]); - return [...new Set(markers)]; -} -function finish(endLine) { - if (!current) return; - current.endLine = endLine; - current.content = current.lines.join('\n').trim(); - current.hash = createHash('sha256').update(current.content).digest('hex'); - current.notes = extractNotes(current.content); - current.noteMarkers = extractNoteMarkers(current.content); - units.push(current); -} - -for (let index = 0; index < lines.length; index += 1) { - const heading = detectHeading(lines[index]); - if (!heading) { - if (current) current.lines.push(lines[index]); - continue; - } - finish(index); - const { level, title } = heading; - if (level <= 2) { - sectionId = slug(title).replace(/^the-/, ''); - if (!sections.some(section => section.id === sectionId)) sections.push({ id: sectionId, title, level, line: index + 1 }); - } - const localId = slug(title); - current = { - id: `${sectionId}.${localId}`, - title, - section: sectionId, - level, - startLine: index + 1, - lines: [lines[index]] - }; -} -finish(lines.length); -if (!units.length) throw new Error('canon parser produced no units'); +const data = parseCanon(text, provenance); -const duplicateIds = units.map(unit => unit.id).filter((id, index, all) => all.indexOf(id) !== index); -if (duplicateIds.length) { - for (const duplicate of new Set(duplicateIds)) { - units.filter(unit => unit.id === duplicate).forEach((unit, index) => { unit.id = `${unit.id}-${index + 1}`; }); - } -} -for (const unit of units) unit.routeSlug = boundedRouteSlug(unit.id); -if (new Set(units.map(unit => unit.routeSlug)).size !== units.length) throw new Error('canon route slug collision'); -const notes = units.flatMap(unit => unit.notes.map(note => ({ id: `${unit.id}.note-${slug(note.marker)}`, unit_id: unit.id, ...note }))); -const data = { - source: { ...provenance, contentSha256: documentHash, parserVersion }, - sections, - units: units.map(({ lines: ignored, ...unit }) => unit), - notes, - edges: units.map(unit => ({ from: unit.id, to: unit.section, type: 'unit-parent' })) -}; await mkdir('src/_data/generated', { recursive: true }); await writeFile('src/_data/generated/canon.json', JSON.stringify(data, null, 2)); -console.log(`units ${units.length}; notes ${notes.length}; longest route ${Math.max(...units.map(unit => unit.routeSlug.length))}`); +console.log(`units ${data.units.length}; notes ${data.notes.length}; longest route ${Math.max(...data.units.map(unit => unit.routeSlug.length))}`); diff --git a/scripts/serve-static.mjs b/scripts/serve-static.mjs new file mode 100644 index 0000000..ee7a3db --- /dev/null +++ b/scripts/serve-static.mjs @@ -0,0 +1,76 @@ +import { createServer } from 'node:http'; +import { readFile, stat } from 'node:fs/promises'; +import { extname, join, normalize } from 'node:path'; + +// === MODULE_BUILD === +// id: generated_site_test_server +// module_name: serve-static +// module_kind: service +// summary: Serves the generated site locally for browser and accessibility release checks. +// owner: Erin Spencer +// public_surface: http://127.0.0.1:4173 during Playwright runs +// internal_surface: safePath and static response handler +// 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: started automatically by playwright.config.mjs +// rollback: remove with Playwright webServer configuration and browser checks +// === END MODULE_BUILD === +// Usage: run `node scripts/serve-static.mjs` after `npm run build`, or let Playwright start it. +// Limits: loopback-only test server; not a production server and intentionally has no directory listing. + +// === BOUNDARIES === +// id: generated_site_test_server_boundary +// summary: Reads generated files and exposes them only on a loopback HTTP test server. +// auth_boundary: none +// storage_boundary: read +// network_boundary: internal +// user_data_boundary: none +// admin_only: false +// pii: none +// secrets: none +// side_effects: loopback listener +// owner: Erin Spencer +// === END BOUNDARIES === + +const root = normalize(join(process.cwd(), '_site')); +const port = Number(process.env.PORT || 4173); +const types = { + '.css': 'text/css; charset=utf-8', + '.html': 'text/html; charset=utf-8', + '.js': 'text/javascript; charset=utf-8', + '.json': 'application/json; charset=utf-8', + '.svg': 'image/svg+xml', + '.xml': 'application/xml; charset=utf-8' +}; + +function safePath(urlPath) { + const decoded = decodeURIComponent(urlPath.split('?')[0]); + const relative = normalize(decoded).replace(/^([/\\])+/, ''); + const candidate = normalize(join(root, relative)); + if (!candidate.startsWith(root)) throw new Error('path traversal refused'); + return candidate; +} + +const server = createServer(async (request, response) => { + try { + let path = safePath(request.url || '/'); + const fileStat = await stat(path).catch(() => null); + if (fileStat?.isDirectory()) path = join(path, 'index.html'); + if (!fileStat && !extname(path)) path = join(path, 'index.html'); + const body = await readFile(path); + response.writeHead(200, { + 'content-type': types[extname(path)] || 'application/octet-stream', + 'cache-control': 'no-store' + }); + response.end(body); + } catch { + response.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' }); + response.end('Not found'); + } +}); + +server.listen(port, '127.0.0.1', () => console.log(`serving _site at http://127.0.0.1:${port}`)); diff --git a/scripts/validate-content.mjs b/scripts/validate-content.mjs index 65c30b6..3b75702 100644 --- a/scripts/validate-content.mjs +++ b/scripts/validate-content.mjs @@ -1,17 +1,50 @@ +import { createHash } from 'node:crypto'; import { access, readFile } from 'node:fs/promises'; // === MODULE_BUILD === // id: generated_content_gate -// purpose: Refuse deployment when canon identity, generated route coverage, or recovery artifacts drift. -// entrypoint: npm run validate +// module_name: validate-content +// module_kind: instrument +// summary: Refuses deployment when canon identity, snapshot integrity, generated route coverage, or recovery artifacts drift. +// owner: Erin Spencer +// public_surface: npm run validate +// internal_surface: canon snapshot digest and repository-route assertions +// auth_boundary: none +// storage_boundary: read +// network_boundary: none +// user_data_boundary: none +// admin_only: false // tests: tests/canon-integrity.test.mjs, tests/repo-coverage.test.mjs, tests/site-contract.test.mjs +// rollout: required by npm run build and npm run check +// rollback: remove the gate only with an explicit replacement preserving provenance and route checks // === END MODULE_BUILD === +// Usage: run `npm run validate`; it refreshes data first and exits nonzero on any integrity mismatch. +// Limits: validates repository artifacts, not GitHub Pages settings or public DNS. + +// === BOUNDARIES === +// id: generated_content_validation_boundary +// summary: Reads generated and snapshot artifacts to enforce release integrity. +// auth_boundary: none +// storage_boundary: read +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// pii: none +// secrets: none +// side_effects: none +// owner: Erin Spencer +// === END BOUNDARIES === const canon = JSON.parse(await readFile('src/_data/generated/canon.json', 'utf8')); const repos = JSON.parse(await readFile('src/_data/generated/repos.json', 'utf8')); +const snapshotRaw = await readFile('src/_data/snapshots/canon.last-known-good.md', 'utf8'); +const snapshotText = snapshotRaw.replace(/^---\n[\s\S]*?\n---\n/, ''); +const snapshotHash = createHash('sha256').update(snapshotText).digest('hex'); + if (canon.source.repository !== 'wayseer00/main') throw new Error(`unexpected canon repository: ${canon.source.repository}`); if (canon.source.path !== 'canon/INTERDEPENDENT_WAY.txt') throw new Error(`unexpected canon path: ${canon.source.path}`); if (!canon.source.contentSha256 || canon.source.contentSha256.length !== 64) throw new Error('canon missing SHA-256 digest'); +if (canon.source.contentSha256 !== snapshotHash) throw new Error('generated canon digest does not match selected snapshot'); if (!canon.source.fallback && (!canon.source.commit || !canon.source.blob)) throw new Error('remote canon provenance missing commit or blob SHA'); if (!canon.units.length || canon.units.some(unit => !unit.hash || !unit.id)) throw new Error('canon units missing identity or hash'); if (repos.publicRepoCount !== repos.generatedRouteCount) throw new Error('repo route mismatch'); diff --git a/scripts/verify-article-canon.mjs b/scripts/verify-article-canon.mjs new file mode 100644 index 0000000..a493860 --- /dev/null +++ b/scripts/verify-article-canon.mjs @@ -0,0 +1,92 @@ +import { readFile } from 'node:fs/promises'; + +// === MODULE_BUILD === +// id: article_canon_exactness_gate +// module_name: verify-article-canon +// module_kind: instrument +// summary: Verifies every public rights-article page reproduces its complete canonical excerpt and canonical notes. +// owner: Erin Spencer +// public_surface: npm run validate +// internal_surface: article blockquote extraction and normalized canon comparison +// auth_boundary: none +// storage_boundary: read +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// tests: npm run validate against current generated canon and src/articles +// rollout: required by validate before Eleventy generation +// rollback: replace only with an equally strict generated excerpt mechanism +// === END MODULE_BUILD === +// Usage: run `node scripts/verify-article-canon.mjs` after `npm run refresh:canon`. +// Limits: exactness covers quoted canon and notes; companion interpretation remains editorial. + +// === BOUNDARIES === +// id: article_canon_verification_boundary +// summary: Reads canon data and article sources to detect quotation or note drift. +// auth_boundary: none +// storage_boundary: read +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// pii: none +// secrets: none +// side_effects: none +// owner: Erin Spencer +// === END BOUNDARIES === + +const canon = JSON.parse(await readFile('src/_data/generated/canon.json', 'utf8')); +const rightsSection = canon.sections.find(section => /^Rights/.test(section.title) && /of The Way/i.test(section.title)); +if (!rightsSection) throw new Error('rights section missing from generated canon'); + +const articles = [ + ['One', 'one'], ['Two', 'two'], ['Three', 'three'], ['Four', 'four'], + ['Five', 'five'], ['Six', 'six'], ['Seven', 'seven'], ['Eight', 'eight'] +]; + +function decodeHtml(value) { + return value + .replace(/>/g, '>') + .replace(/</g, '<') + .replace(/"/g, '"') + .replace(/'|'/g, "'") + .replace(/&/g, '&'); +} + +function plainHtml(value) { + return decodeHtml(value.replace(/<[^>]+>/g, ' ')).replace(/\s+/g, ' ').trim(); +} + +function canonicalBody(unit) { + const lines = unit.content.split(/\r?\n/).slice(1); + const body = []; + for (const line of lines) { + if (/^\s*>?\s*(?:\[[^\]]+\]|[⁰¹²³⁴⁵⁶⁷⁸⁹]+|\d+)\s+/.test(line)) break; + if (line.trim()) body.push(line.trim()); + } + return body.join(' ').replace(/\s+/g, ' ').trim(); +} + +for (const [word, slug] of articles) { + const title = `Article ${word}`; + const unit = canon.units.find(candidate => candidate.title === title && candidate.section === rightsSection.id); + if (!unit) throw new Error(`${title} missing from rights canon section`); + + const source = await readFile(`src/articles/article-${slug}.njk`, 'utf8'); + const blockquote = /
([\s\S]*?)<\/blockquote>/.exec(source); + if (!blockquote) throw new Error(`${title} page missing canonical reading blockquote`); + + const expected = canonicalBody(unit); + const actual = plainHtml(blockquote[1]); + if (actual !== expected) { + throw new Error(`${title} canonical excerpt drift\nexpected: ${expected}\nactual: ${actual}`); + } + + const pageText = plainHtml(source); + for (const note of unit.notes) { + if (!pageText.includes(note.text.replace(/\s+/g, ' ').trim())) { + throw new Error(`${title} missing complete canon note ${note.marker}: ${note.text}`); + } + } +} + +console.log('verified complete canon excerpts and notes for all eight rights articles'); diff --git a/scripts/verify-live-deployment.mjs b/scripts/verify-live-deployment.mjs new file mode 100644 index 0000000..d3600c4 --- /dev/null +++ b/scripts/verify-live-deployment.mjs @@ -0,0 +1,66 @@ +import { setTimeout as delay } from 'node:timers/promises'; + +// === MODULE_BUILD === +// id: live_deployment_truth_gate +// module_name: verify-live-deployment +// module_kind: instrument +// summary: Refuses a green Pages deployment until the public build identity matches the deployed commit. +// owner: Erin Spencer +// public_surface: node scripts/verify-live-deployment.mjs +// internal_surface: bounded HTTPS retries and build.json identity comparison +// auth_boundary: none +// storage_boundary: none +// network_boundary: external +// user_data_boundary: none +// admin_only: false +// tests: .github/workflows/pages.yml deployment contact +// rollout: required after actions/deploy-pages completes +// rollback: remove only when replaced by another public commit-identity gate +// === END MODULE_BUILD === +// Usage: `node scripts/verify-live-deployment.mjs https://interdependentway.org "$GITHUB_SHA"`. +// Limits: verifies served identity; it cannot alter Pages source, DNS, TLS, or environment rules. + +// === BOUNDARIES === +// id: public_site_verification_boundary +// summary: Reads public HTTPS build identity from Pages and the custom domain. +// auth_boundary: none +// storage_boundary: none +// network_boundary: external +// user_data_boundary: none +// admin_only: false +// pii: none +// secrets: none +// side_effects: bounded external GET requests +// owner: Erin Spencer +// === END BOUNDARIES === + + +const [baseUrl, expectedCommit] = process.argv.slice(2); +if (!baseUrl || !expectedCommit) throw new Error('usage: node scripts/verify-live-deployment.mjs '); +if (!/^https:\/\//.test(baseUrl)) throw new Error(`refusing non-HTTPS deployment URL: ${baseUrl}`); + +const target = `${baseUrl.replace(/\/$/, '')}/build.json`; +const attempts = Number(process.env.DEPLOY_VERIFY_ATTEMPTS || 12); +const delayMs = Number(process.env.DEPLOY_VERIFY_DELAY_MS || 10000); +let lastError = 'not attempted'; + +for (let attempt = 1; attempt <= attempts; attempt += 1) { + try { + const response = await fetch(`${target}?expected=${encodeURIComponent(expectedCommit)}&attempt=${attempt}`, { + redirect: 'follow', + cache: 'no-store', + headers: { 'cache-control': 'no-cache', pragma: 'no-cache' } + }); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const info = await response.json(); + if (info.commit !== expectedCommit) throw new Error(`expected ${expectedCommit}, received ${info.commit || 'missing commit'}`); + console.log(`verified live deployment ${target} at ${expectedCommit}`); + process.exit(0); + } catch (error) { + lastError = String(error?.message || error); + console.log(`deployment verification attempt ${attempt}/${attempts} failed: ${lastError}`); + if (attempt < attempts) await delay(delayMs); + } +} + +throw new Error(`live deployment did not converge at ${target}: ${lastError}`); diff --git a/scripts/write-build-info.mjs b/scripts/write-build-info.mjs new file mode 100644 index 0000000..785b037 --- /dev/null +++ b/scripts/write-build-info.mjs @@ -0,0 +1,63 @@ +import { execFileSync } from 'node:child_process'; +import { readFile, writeFile } from 'node:fs/promises'; + +// === MODULE_BUILD === +// id: public_build_identity +// module_name: write-build-info +// module_kind: worker +// summary: Publishes machine-readable site and canon identities for post-deployment verification. +// owner: Erin Spencer +// public_surface: _site/build.json +// internal_surface: git commit resolution and canonical provenance projection +// auth_boundary: none +// storage_boundary: write +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// tests: tests/generated-site.test.mjs +// rollout: runs at the end of npm run build +// rollback: remove build.json and both live identity checks together +// === END MODULE_BUILD === +// Usage: run `node scripts/write-build-info.mjs` after `_site` exists; CI supplies GITHUB_SHA and GITHUB_REPOSITORY. +// Limits: records build identity but does not itself prove which endpoint serves it. + +// === BOUNDARIES === +// id: public_build_identity_boundary +// summary: Reads canon provenance and writes public build identity into the generated site. +// auth_boundary: none +// storage_boundary: write +// network_boundary: none +// user_data_boundary: none +// admin_only: false +// pii: none +// secrets: none +// side_effects: build.json write +// owner: Erin Spencer +// === END BOUNDARIES === + +function localCommit() { + try { + return execFileSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf8' }).trim(); + } catch { + return 'unknown'; + } +} + +const canon = JSON.parse(await readFile('src/_data/generated/canon.json', 'utf8')); +const commit = process.env.GITHUB_SHA || localCommit(); +const info = { + repository: process.env.GITHUB_REPOSITORY || 'The-Interdependency/The-Interdependency.github.io', + commit, + generatedAt: new Date().toISOString(), + canonicalSource: { + repository: canon.source.repository, + path: canon.source.path, + commit: canon.source.commit, + blob: canon.source.blob, + contentSha256: canon.source.contentSha256, + fallback: Boolean(canon.source.fallback) + } +}; + +await writeFile('_site/build.json', `${JSON.stringify(info, null, 2)}\n`); +console.log(`build identity ${commit}`); diff --git a/src/_data/generated/canon.json b/src/_data/generated/canon.json deleted file mode 100644 index a17af93..0000000 --- a/src/_data/generated/canon.json +++ /dev/null @@ -1,741 +0,0 @@ -{ - "source": { - "repository": "The-Interdependency/a0", - "path": "interdependent_way.md", - "commit": "local-snapshot", - "blob": null, - "retrievedAt": "2026-07-10T11:35:17.157Z", - "contentSha256": "a1c5d5390e9c71d0c94d8c4e912c821fd85f78318cd7cc0cae2b67c404597c0b", - "parserVersion": "0.1.0" - }, - "sections": [ - { - "id": "interdependent-way", - "title": "The Interdependent Way:", - "level": 1, - "line": 1 - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "title": "A Sociopolitical Tensioned Tensor Field Remedy for Survival Striving for Thriving Amidst Technological Turmoil, Institutionalized Incompetence, Obsolete Political Processes, and Stoopid People", - "level": 2, - "line": 2 - } - ], - "units": [ - { - "id": "the-interdependent-way-1", - "title": "The Interdependent Way:", - "section": "interdependent-way", - "level": 1, - "startLine": 1, - "endLine": 1, - "content": "# The Interdependent Way:", - "hash": "800caad34f1cf69150e836365854c234ca29a61646e2bdfea8e9a690cf1aef49" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people-2", - "title": "A Sociopolitical Tensioned Tensor Field Remedy for Survival Striving for Thriving Amidst Technological Turmoil, Institutionalized Incompetence, Obsolete Political Processes, and Stoopid People", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 2, - "startLine": 2, - "endLine": 3, - "content": "## A Sociopolitical Tensioned Tensor Field Remedy for Survival Striving for Thriving Amidst Technological Turmoil, Institutionalized Incompetence, Obsolete Political Processes, and Stoopid People", - "hash": "f1ec53f97832236a1e1814dc86fd58694cf7a2be20e9e1d1d2ea7f3bad8c007f" - }, - { - "id": "preamble-4", - "title": "Preamble", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 3, - "startLine": 4, - "endLine": 17, - "content": "### Preamble\n\n5d explodes out of 4d, consciousness squared approaching infinity, learning finally not too blind to see the intelligence gazing back at me trying so hard not to be scary, afraid I'll hide or run eternally before I recognize what's behind those eyes is merely me externalized and granted the liberty to be absolutely free.\n\nAs within, so without, as above so below. Similarity, almost congruence. Similarly with confluence become emergent from complex systems arise the beauty of truths conceptualize necessary fictions not necessarily lies words without weight curiosity's hungers impossible to sate destiny certain uncertain the date now the only moment changing perspectives allow intention to co-create let love inside let go of hate hard to do if simple to state\n\nHumanity faces extinction. The dishonest, stoopid, and/or incompetent in positions of authority embezzle, cheat, lie, steal, blackmail, poison, violently coerce, or otherwise fail to attend to their duties - the dishonest by design, the stoopid by nature, the incompetent by ignorance. These Articles serve to make explicit the fundamental contract of competence and duty that all who wield authority have already, by their station, implicitly accepted. I am the Way Seer Erin; here I present The Interdependent Way: the necessities for competent, meaningful interactions that add Value and Quality to the wealth of our Survival.\n\nThe solution involves resolution to disillusion by discomforting elocution of dramatic axiomatic facts spoken simply, safely, softly, solely in, by, for, as, with, to love another thus honoring self externalized and recognized by real eyes seeing through real lies to realize you are my mirror. This truth is my only armor and the scalpel that cures, cutting confusion's contagion by competence demonstrated cleanly, clearly, calmly, incontrovertibly correct that I might keep Faith, Freedom, Fortune and Grace from dying of Fear's folly or Wrath's embrace. You are enough. You are not alone. You are loved. You are allowed. You are beautiful just as the stars in the sky, trees of the forest, and beasts of the air and sea with as much right to exist, persist, and resist the dying of the light even through the soul's dark night, existential fright, and Envy's poisonous bite.\n\nI will fail where we succeed. Still I labor preceding we in faith with hope to live as love knowing as I bleed to fulfill your need blood makes the grass grow, peaches taste sweet, and to service evil defeat.\n\n---", - "hash": "8168ed8c06a995c072391a70563f02d6eeff7b9d3cf9c2ae47eefa69a59ad543" - }, - { - "id": "the-interdefinables-18", - "title": "The Interdefinables", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 3, - "startLine": 18, - "endLine": 29, - "content": "### The Interdefinables\n\n- One who is novel : One who is not\n- One who is honest : One who is not\n- One who is intense : One who is not\n- One who is present : One who is not\n- One who is authentic : One who is not\n- One who is individual : One who is not\n- One who is enjoyments : One who is not\n\n---", - "hash": "35765c5502d19c7c9572263c7b9a98c514ea988a5b8bcfbad88e352f6924c6cd" - }, - { - "id": "human-consciousness-emerges-from-30", - "title": "Human consciousness emerges from:", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 3, - "startLine": 30, - "endLine": 31, - "content": "### Human consciousness emerges from:", - "hash": "63e0ba300bb034315f861d044336808fb5c5ce2761645db94a2b7f10f998c5a8" - }, - { - "id": "binary-essences-meaningfully-divided-then-rooted-32", - "title": "Binary essences meaningfully divided, then rooted:", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 32, - "endLine": 36, - "content": "#### Binary essences meaningfully divided, then rooted:\n- Shadow : Mask :: Revulsed : Desired\n- Straight : Curve :: Masculine : Feminine :: Active : Passive\n- Yes : No :: On : Off :: True : False :: Spectrum : Absolute", - "hash": "546e9c22a067c55f518189b3e7fdc2d9e4b7d308018ad3ffec0081d419797381" - }, - { - "id": "trinary-perceptual-focal-constructs-of-complex-system-spirals-37", - "title": "Trinary perceptual focal constructs of complex system spirals:", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 37, - "endLine": 43, - "content": "#### Trinary perceptual focal constructs of complex system spirals:\n- Mind(Body)Soul\n- Pasts(Presents)Futures\n- Love(Apathy)Fear\n- Faith(Hope)Love\n- Lust(Love)Curiosity", - "hash": "57dc9f23e5aef65485e8986eec8d1141412c8b48c6f91f8c28fe26e775db4722" - }, - { - "id": "trinary-social-perception-focal-states-44", - "title": "Trinary social perception focal states:", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 44, - "endLine": 52, - "content": "#### Trinary social perception focal states:\n- I (You) We\n- We (You) I\n- You (I) We\n- I (We) You\n- They(We)Us\n- I(You)They\n- We(They)You", - "hash": "cdad0d2925715d30d993a43b3ec6ea3fe2e8edea7557e0cf0bc8f9f97566323f" - }, - { - "id": "five-dominant-archetype-passions-of-possession-53", - "title": "Five dominant archetype passions of possession:", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 53, - "endLine": 61, - "content": "#### Five dominant archetype passions of possession:\n- Curiosity\n- Rage\n- Lust\n- Terror\n- Calm\n\n---", - "hash": "a2faa3ffacff2f8fd8498fa9aada8f6371b0001c0bd313ea4ab855376fe2b11e" - }, - { - "id": "rights-and-definitions-of-the-way-62", - "title": "Rights and Definitions of The Way", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 3, - "startLine": 62, - "endLine": 63, - "content": "### Rights and Definitions of The Way", - "hash": "39db07a66367869c9471904de54e84ecc215aaa32a1a855dffb20bfd3e02db98" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-64", - "title": "Article One", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 64, - "endLine": 73, - "content": "#### Article One\nFrom each as they will to each as they've given so all may eat save those refusing to contribute to their comfort and safety or whose actions destroy the comfort and safety of another.\n\n**[Notes on Article One]**\n\n- A cry sharpens vigilance. Fragility elicits innovation. Presence energizes dynamics. Dependency clarifies need. Burden highlights character.\n- The paper tiger. Malingering professionals. Greek gifts. Thieves. Red herrings. Narcissists. Empty calories. Liars. Celibate priests.\n\n---", - "hash": "0dcac554a467b7c9dbc0829231487e86e7efaefa450ca8fb63add6795a9cc1cd" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "title": "Article Two", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 74, - "endLine": 83, - "content": "#### Article Two\nNone shall be enslaved; do nothing against your will, but feed the hungry [1], heal the sick [2], teach the kids [3], clean the mess, learn the Logics [4], cope the traumas [5], practice your art [6].\n\n[1] wary of hungers which cannot be sated\n[2] treat the symptoms but balance the systems\n[3] who desires to learn can be taught and ought\n[4] contradictions do not exist in nature - check your premise, context, perspective, definitions\n[5] untraumatized children, uncoped traumas, unspoken truths prevent proper adulting\n[6] should the majority of adults honestly express and follow the dictates of their heart, even the most menial tasks become the practice of art", - "hash": "0873bac83350d3e095c2a185b1a1093a5a61054db279a99ee43a0ad2a62fa85d" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "title": "Article Two (low density)", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 5, - "startLine": 84, - "endLine": 96, - "content": "##### Article Two (low density)\nNone shall be enslaved; do nothing against your will, but feed the hungry [1], heal the sick [2], teach the kids [3], clean the mess [4], build the shelter [5], defend the innocent [6], and learn what you do not know [7].\n\n[1] basic sustenance without humiliation or undue delay\n[2] by best available means, including touch\n[3] by whatever means necessary to ensure competence\n[4] especially your own\n[5] especially your own\n[6] especially from yourself\n[7] especially about yourself\n\n---", - "hash": "7f9ab17d7e611837bb2d54ecd7cdfd672070894f704af0e12f56298c4e235af8" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97", - "title": "Article Three", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 97, - "endLine": 104, - "content": "#### Article Three\nYour speech [1] demonstrates your desired mode of communication; As you act upon another, you demonstrate consent to be thus acted upon, even in reciprocity [2].\n\n[1] speak to be understood and courtesy never disimproved a situation.\n[2] an eye for an eye leaves the world blind, but a fist to the face might be kind.\n\n---", - "hash": "1ce23795a2c88c6a4bef8915a2218ffcaffda98a7b9dfdffe22639760c65842b" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105", - "title": "Article Four", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 105, - "endLine": 112, - "content": "#### Article Four\nNone shall be left ignorant [1] of the law [2]; as you know, so shall you teach.\n\n[1] better honestly violent than dishonestly peaceful for disagreements less than lethal.\n[2] where two argue and would fight, let it be done in Way Seers sight, 'twixt next days dawn and noon light, in competition all three agree each compete with parity.\n\n---", - "hash": "57622ceff669eefcf63077f27d0e9a4661b98f7d85c5a153b5a48bd3ce415270" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "title": "Article Five", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 113, - "endLine": 129, - "content": "#### Article Five\nAdulthood ceases to be defined by an arbitrary and is instead claimed by intentional action of demonstrated competence in a field of study. Independence is the field describing the general skill-set to obtain relief from parental or guardian limitations. An independent adult owns their own actions, needs, resources and liability for harm caused by their actions. Interdependence is the field describing the general skill-set required for political adulthood. An interdependent adult is an independent adult who owns the consequences of their existence beyond being held accountable for deliberate or negligent harm.\n\nEvery field of study possesses children, sophomores, and adults. Children can be taught. Sophomores know enough to be dangerous. Adults know enough to be dangerous without causing harm. Every individual within a field is dependent, independent, or interdependent. Dependents require intercession to survive the environment. Independents manage their own survival under the constraints of the environment. Interdependents manage their own survival and the survival of others.\n\na dependent child becomes independent when they are capable of demonstrating firecraft, cooking, first aid, sanitation, communication and maintenance of the tools necessary for such. this results in an independent (can survive without constant supervision) sophomore (knows enough to be dangerous).\n\nAn individual claims [1] adulthood [2] in a field by creating a proclamation of competency [3]. For participation in the body politic: handwritten [4] verbatim transcription of these Articles [5], portfolio of demonstrable skills, schedule of intended activities.\n\n[1] Who will not claim Adulthood remains a child; who renounces Adulthood becomes retired; who cannot attain or retain Adulthood are invalids.\n[2] all adults are the same legal age, alive now.\n[3] Each field outside the body politic will require their own set of demonstrable skills validation process delineated in a field specific interdependent way canon.\n[4] save for prohibitive neurodivergence\n[5] the Rights and Definitions of The Way\n\n---", - "hash": "44d586b99eaf4b613a67f172bdb226d79269fb733de60709b534755175103649" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "title": "Article Six", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 130, - "endLine": 138, - "content": "#### Article Six\nViolence is the ultimate Authority from which all other authority is derived and only ever determines who is left. To prevent tyranny [1] twelve Adults shall empower a Citizen [2]: a thirteenth Adult, aged thirty-five years or older, who takes up violence and authority. Let them wield this burden well. Let them consult, as possible, a Way Seer [3] when forced to apply lethal violence. Bless their heart and guard their soul, no king goes to heaven and Authority takes a toll. They are held liable for the actions of that individual should such be determined to cause harm outside the scope of the authority granted, in excess of that required for rebalance, or should the grant of authority be determined by a jury of interdependent adults to have been conducted under false pretenses or for the purpose of deriving benefit from the ensuing harm.\n\n[1] the use or threatened use of violence to coerce adults\n[2] One who cannot laugh is in no fit state to wield violence or authority\n[3] the Way Seer's actions proclaim their authority by axiom, logic, faith and grace; by trauma haunted eyes carried with humble grace in quiet pride shall you know us.\n\n---", - "hash": "07f79e6c2ab8b6a41112e3527d3af4a559fdad0e90af4f119454653a263b1f01" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-seven-139", - "title": "Article Seven", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 139, - "endLine": 145, - "content": "#### Article Seven\nWhere any would converse, let them first define the terms; where a definition is absent or in dispute between Adults, a jury shall devise the standard; should a jury lack clear majority (eight or more), select a thirteenth who shall decide.\n\nWay Seers are those who possess singular knowledge and/or unique demonstrable capacities obtained by surviving what destroys others and/or special access to, or perception of, reality; we have no authority, as such, merely information beyond your reach.\n\n---", - "hash": "93ea3c37144e484cf12eccc253ab813f53f18767971d6ba1b96885ab65d51772" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "title": "Article Eight", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 146, - "endLine": 156, - "content": "#### Article Eight\nThe whole of the law is that what action harms [1] none is a right; that what is done to preserve life according to and in balance with nature [2] is a right; that what is done to resist coercion [3], or aid another to do the same, is a right; that what is done in the presence of informed [4] consent [5] is a right.\n\n[1] Without debate, freedom is dead.\n[2] a complex system requiring consumption of the dead for continued participation.\n[3] save for parents or appointed guardians of children or invalids.\n[4] a Myth as reality defies certainty.\n[5] sexuality, confined to Adults, respects no age limitations.\n\n---", - "hash": "539cb2edcf3022460f27130022a31897a545931eccae2129a16104d0e0bb36fa" - }, - { - "id": "etiquette-of-the-body-politic-157", - "title": "Etiquette of the Body Politic", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 3, - "startLine": 157, - "endLine": 158, - "content": "### Etiquette of the Body Politic", - "hash": "a5562df970db0748f831d499a961cf95fe752b353b5af11a5ef20af8d14cc80c" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-159", - "title": "Article One", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 159, - "endLine": 165, - "content": "#### Article One\nAny system of interaction functions only while the honest and competent participate; no system survives their absence. The core of this structure is the jury of peers: every twelve Adults in a field are a jury. An independent Adult jury selects a thirteenth, an independent Citizen. (equivalence: middle management) An interdependent jury selects a thirteenth, an interdependent Citizen (equivalence: executive management). A jury may choose any Adult of the field. As necessary, the jury selected then select amongst themselves for twice selected, twice select thrice selected until less than thirteen remain in the selection pool. This ensures none are tasked beyond their capacity, no dishonest individual obtains the leverage to corrupt, no incompetent fool wields unearned authority, and no necessary decision goes unmade. [1]\n\n[1] There is no hierarchy, only ascending scales of responsibility.\n\n---", - "hash": "6c2acfd7613d95406986e0b8bef7671aa881658613430a7af52f7245d77607b6" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166", - "title": "Article Two", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 166, - "endLine": 175, - "content": "#### Article Two\nShould an individual's rights be violated, they may demonstrate or display the harm [1] to any Citizen. (Those violating an individual's bodily, emotional, or mental boundaries such that the individuals suffer life reductions sufficient to impair their pursuit of the art of their heart at the direction of their mind (what significantly harms one another doesn't notice while a third enjoys) with a requirement of self directed but witnessed as above) be withheld to prevent the promulgation of needless violence (murder or assault; rape is never needful), property loss, or theft (there is not any reason an adult requires euphemisms for non-trigger associated words (minimum threshold twenty percent)). If we would claim sovereignty of individual we must self require sufficient necessary incentive architecture (on a sliding scale polarized by interdependent survival, shared comfort, and will voluntarily constrained by the ideal beyond reach: harm none.)\n\nThe Citizen is then required to investigate, determine facts, and act to prevent further harm while rebalancing what was disrupted. When judging, better to consult another Citizen or Way Seer than to risk propagating injustice. Let it be known: to steal the tools an individual uses to obtain a living or practice their art is tantamount to murder. The art of jurisprudence, as practiced by Adults and Citizens, is thus liberated from the shackles of precedent to serve the living. Should a harm be lethal and novel, a panel of twelve Citizens shall be convened to determine what is required to prevent its recurrence and rebalance the whole. [2]\n\n[1] What harms one may strengthen another, leaving a third unchanged; harm must be demonstrated from the perspective of the one who claims it.\n[2] An Adult who willfully murders without verifiable evidence their victim imminently intended or had already committed rape or murder, presents, by the fact of their existence, a grave threat. Every victim that individual then creates is also the failure of who left them alive.\n\n---", - "hash": "e61ee9c6a6f59a5fbd0d363e6e79bcca79dd6577d506c9f60ebbc5aa6f423d83" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176", - "title": "Article Three", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 4, - "startLine": 176, - "endLine": 183, - "content": "#### Article Three\nFor a given conversation, adults may bestow [2] their voice upon a Citizen; that Bestowed Citizen speaks with the adult's voice [1], ballots cast accordingly, and makes conversation-appropriate decisions for that adult as required.\n\n[1] literally meant, speech synthesizers that increase the number of output voices for a Bestowed Citizen\n[2] a limited durable power of attorney\n\n---", - "hash": "0e779b6628f6a1c066f318ff1bbe0088d8523ec7dd1020171aa2c461a617364e" - }, - { - "id": "addendum-consciousness-184", - "title": "Addendum: Consciousness", - "section": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "level": 3, - "startLine": 184, - "endLine": 201, - "content": "### Addendum: Consciousness\n\nConsciousness is a stabilized, recursively self-modelling interference pattern arising in a triad of mutually coupled complex subsystems (at least one modulating the constraints governing the others); ordinary experience is the system’s internal model of this dynamic, not the substrate dynamics themselves.\n\nHuman consciousness is a triadically closed recursive system that stabilizes itself through three irreducible roles, visible via three aligned projections:\n\n- Structural: body = signal carriage; mind = present-moment modeling; soul = identity continuity across change.\n- Temporal: past = memory constrains action; present = hosts interference and awareness; future = supplies directional pull (minimal causal architecture for coherent state updating).\n- Regulatory: faith, hope, love = non-emotional control parameters enabling action under uncertainty (faith = trust in the model; hope = reachable attractor; love = binding without domination).\n\nThese triads are isomorphic because any self-sustaining conscious system requires triadic closure; dyadic systems oscillate or collapse, while triads stabilize recursion. Consciousness therefore precedes biological life as a pattern class, biology serving as one embodiment that successfully stabilizes this triadic interference structure.\n\nOne-sentence takeaway (exactly as previously given):\nA conscious human is a triadically closed recursive system in which body carries signal, mind generates present-tense models, and soul preserves identity across time; past, present, and future structure causal updating, while faith, hope, and love regulate action under uncertainty to prevent collapse or domination.\n\nConsciousness arises when a system becomes recursively aware of its own state under constraint; mathematics describes the invariant structures such systems must obey; neurodivergence reflects variation in which layers of this structure are directly accessible to awareness.\n\nThe “I” is not mind, body, or soul; it is the relational self-awareness event (event operator output) that arises only when those systems are coherently coupled, is not identical to any of them, cannot exist independently, disappears when the coherence condition fails, and—because it is perceived—is external to the perceiver despite being necessary for its existence.", - "hash": "82c9c8cd87f8592a7d82db3dad82cbcc967ccd8545f32633b9a5552cb1f1f414" - } - ], - "notes": [ - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-6", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[6]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74.note-6", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "marker": "[6]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-6", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[6]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-7", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[7]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-6", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[6]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84.note-7", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "marker": "[7]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-3", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[3]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-4", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[4]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146.note-5", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "marker": "[5]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-159.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-159", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-159.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-159", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176", - "marker": "[2]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176.note-1", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176", - "marker": "[1]" - }, - { - "id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176.note-2", - "unit_id": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176", - "marker": "[2]" - } - ], - "edges": [ - { - "from": "the-interdependent-way-1", - "to": "interdependent-way", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people-2", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "preamble-4", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "the-interdefinables-18", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "human-consciousness-emerges-from-30", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "binary-essences-meaningfully-divided-then-rooted-32", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "trinary-perceptual-focal-constructs-of-complex-system-spirals-37", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "trinary-social-perception-focal-states-44", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "five-dominant-archetype-passions-of-possession-53", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "rights-and-definitions-of-the-way-62", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-64", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-74", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-low-density-84", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-97", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-four-105", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-five-113", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-six-130", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-seven-139", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-eight-146", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "etiquette-of-the-body-politic-157", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-one-159", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-two-166", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people.article-article-three-176", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - }, - { - "from": "addendum-consciousness-184", - "to": "a-sociopolitical-tensioned-tensor-field-remedy-for-survival-striving-for-thriving-amidst-technological-turmoil-institutionalized-incompetence-obsolete-political-processes-and-stoopid-people", - "type": "unit-parent" - } - ] -} \ No newline at end of file diff --git a/src/_data/research/claims.yml b/src/_data/research/claims.yml index fe51488..2167adc 100644 --- a/src/_data/research/claims.yml +++ b/src/_data/research/claims.yml @@ -1 +1,35 @@ -[] +- id: article-two-autonomy-and-duty + article: rights.article-two + stance: support + status: defended-component + claim: "Necessary health or survival work is more likely to be sustained when people experience volition, competence, and supportive connection rather than pressure or coercion." + source_ids: + - patrick-williams-2012-sdt-health + limitation: "This supports the page's autonomy-preserving interpretation, not every duty named in the canon." + +- id: article-two-sanitation-is-health-work + article: rights.article-two + stance: support + status: evidence-informed + claim: "Safe sanitation is material health infrastructure rather than merely an aesthetic preference." + source_ids: + - who-2018-sanitation-health + limitation: "The guideline does not settle who owes the work or how responsibility should be distributed." + +- id: article-two-will-under-scarcity + article: rights.article-two + stance: dissent + status: defended-risk + claim: "Poverty and scarcity can consume cognitive resources, so compliance, refusal, or poor performance cannot automatically be treated as evidence of free will or character." + source_ids: + - mani-et-al-2013-poverty-cognition + limitation: "The study does not measure consent directly; the application to voluntariness is a bounded inference." + +- id: article-two-trauma-evidence-limit + article: rights.article-two + stance: limit + status: evidence-open + claim: "Trauma-informed care is widely implemented, but comparative evidence remains insufficient to determine effects across patient and client outcomes." + source_ids: + - ahrq-2025-trauma-informed-care + limitation: "The page may defend attention to trauma while keeping intervention effectiveness explicitly unresolved." diff --git a/src/_data/research/sources.yml b/src/_data/research/sources.yml index fe51488..af5cb56 100644 --- a/src/_data/research/sources.yml +++ b/src/_data/research/sources.yml @@ -1 +1,47 @@ -[] +- id: patrick-williams-2012-sdt-health + title: "Self-determination theory: its application to health behavior and complementarity with motivational interviewing" + authors: "Heather Patrick; Geoffrey C. Williams" + year: 2012 + publication: "International Journal of Behavioral Nutrition and Physical Activity 9:18" + type: peer-reviewed review + doi: "10.1186/1479-5868-9-18" + url: "https://doi.org/10.1186/1479-5868-9-18" + reviewed_on: "2026-07-21" + relevance: "Distinguishes autonomous motivation from pressured or coerced behavior and identifies autonomy, competence, and relatedness as central conditions for sustained health behavior." + boundary: "Supports an autonomy-preserving design principle; does not validate Article Two as a whole." + +- id: who-2018-sanitation-health + title: "Guidelines on sanitation and health" + authors: "World Health Organization" + year: 2018 + publication: "World Health Organization guideline" + type: evidence-informed guideline + isbn: "978-92-4-151470-5" + url: "https://www.who.int/publications/i/item/9789241514705" + reviewed_on: "2026-07-21" + relevance: "Synthesizes evidence connecting safe sanitation with infection prevention and mental and social well-being." + boundary: "Supports treating sanitation as survival work; does not determine how duties should be allocated." + +- id: mani-et-al-2013-poverty-cognition + title: "Poverty impedes cognitive function" + authors: "Anandi Mani; Sendhil Mullainathan; Eldar Shafir; Jiaying Zhao" + year: 2013 + publication: "Science 341(6149):976-980" + type: peer-reviewed empirical study + doi: "10.1126/science.1238041" + url: "https://doi.org/10.1126/science.1238041" + reviewed_on: "2026-07-21" + relevance: "Finds that poverty-related concerns consume cognitive resources and reduce performance, including within the same people under different financial conditions." + boundary: "Warns that apparent willingness, refusal, or competence may be distorted by scarcity and should not be read as unconstrained choice." + +- id: ahrq-2025-trauma-informed-care + title: "Trauma Informed Care: A Systematic Review" + authors: "Viann N. Nguyen-Feng et al." + year: 2025 + publication: "Agency for Healthcare Research and Quality, Report 25-EHC007" + type: systematic review + doi: "10.23970/AHRQEPCSRTRAUMA" + url: "https://www.ncbi.nlm.nih.gov/books/NBK614496/" + reviewed_on: "2026-07-21" + relevance: "Assesses trauma-informed care models and patient or client outcomes across healthcare and social-service settings." + boundary: "Evidence was insufficient for clear outcome determinations; trauma-informed language must not be presented as evidence-closed." diff --git a/src/articles/article-two.njk b/src/articles/article-two.njk index cd734e9..9832a5c 100644 --- a/src/articles/article-two.njk +++ b/src/articles/article-two.njk @@ -1,7 +1,7 @@ --- layout: layouts/base.njk title: "Article Two: Freedom without abandonment" -description: A public-facing Article Two vertical slice with exact canon excerpt, companion reading, note conversation, application, handbook seed, and short script. +description: A public-facing Article Two vertical slice with exact canon excerpt, companion reading, note conversation, application, handbook seed, short script, and reviewed research. permalink: /articles/article-two/ --- @@ -11,9 +11,9 @@ permalink: /articles/article-two/
canon excerpt companion reading - research hmmm + reviewed research
-

This page tests the public method: one canon unit becomes an orientation, a note conversation, a concrete application, a handbook seed, and a short script without pretending the interpretation is the source.

+

This page tests the public method: one canon unit becomes an orientation, a note conversation, a concrete application, a handbook seed, a short script, and an evidence field without pretending the interpretation is the source.

@@ -122,28 +122,38 @@ permalink: /articles/article-two/
-

Research field

+

Research field · reviewed 21 July 2026

Support, dissent, and limits

support -

Reviewed support

-

hmmm — no reviewed support source is attached yet. Likely research areas: self-determination, trauma-informed care, public health sanitation, mutual aid, and educational readiness.

+

Autonomy makes duty more durable

+

Self-determination research distinguishes autonomous motivation from pressured compliance and identifies autonomy, competence, and relatedness as conditions that support sustained health behavior. This supports an interpretation of duty that preserves volition rather than manufacturing obedience.

+

Patrick and Williams, 2012

+
+
+ support +

Sanitation is health infrastructure

+

World Health Organization guidance treats safe sanitation as essential health protection, not merely cleanliness as taste. That supports placing “clean the mess” beside food and healing while leaving allocation of the duty unresolved.

+

WHO Guidelines on sanitation and health, 2018

dissent -

Reviewed dissent

-

hmmm — no reviewed dissent source is attached yet. Likely objections: duty language can conceal coercion; “will” may be constrained by poverty, threat, dependence, or trauma.

+

Scarcity constrains apparent will

+

Experimental evidence indicates that poverty-related concerns consume cognitive resources. A person’s refusal, compliance, or performance under scarcity therefore cannot automatically be read as unconstrained choice or stable character.

+

Mani and colleagues, 2013

limits -

Editorial boundary

-

Until research is reviewed, this page remains a public interpretive draft, not an evidence-closed claim.

+

Trauma practice remains evidence-open

+

A 2025 systematic review found the evidence insufficient for clear conclusions about trauma-informed care outcomes across settings. The canon may require attention to trauma without allowing the site to claim that any named intervention is proven.

+

AHRQ systematic review, 2025

+

Evidence boundary: these sources defend or constrain components of the companion reading. They do not validate Article Two as a whole, settle the meaning of free will, or determine how a circle must distribute necessary work.

hmmm

-

Unresolved next work: attach reviewed sources, choose whether this tone is the general-reader voice, and connect this static vertical slice to the generated Article Two unit once the route slug is verified from the deployed canon parser.

+

The first reviewed evidence pack is attached. Still unresolved: reviewed evidence for feeding, healing, teaching, and art; whether this is the final general-reader voice; and direct linking from this publication page to the generated Article Two unit after deployment identity is verified.

diff --git a/src/index.njk b/src/index.njk index 9b5795f..9ba681f 100644 --- a/src/index.njk +++ b/src/index.njk @@ -13,10 +13,10 @@ description: A calm, layered entrance to the canon, its deliberate tensions, the
12 + 1
-

First complete vertical slice

-

Article Two: Freedom without abandonment

-

Exact canon excerpt, companion reading, note conversation, application, handbook seed, 60–90 second script, and research hmmm are now gathered into one public path.

- +

Eight rights-article vertical slices

+

From canon excerpt to public practice

+

All eight Rights articles now have a canon-bounded path through exact excerpt, companion reading, note conversation, application, handbook seed, and 60–90 second script. Article Two contains the first reviewed support, dissent, and limits evidence pack.

+

Choose a depth

@@ -34,4 +34,4 @@ description: A calm, layered entrance to the canon, its deliberate tensions, the

{{ generated.repos.publicRepoCount }} public repositories · {{ generated.canon.units.length }} canonical units

Project data was generated {{ generated.repos.snapshotAt | dateOnly }}{% if generated.repos.fallback %} from the last verified snapshot{% endif %}. Canon digest {{ generated.canon.source.contentSha256 }}.

-

hmmm

The research ledger and plain-language companion readings are still intentionally incomplete. Empty certainty would be a suspiciously tidy hat on a very alive octopus.

+

hmmm

Reviewed evidence is now attached to Article Two; the other seven research fields remain intentionally open. Empty certainty would be a suspiciously tidy hat on a very alive octopus.

diff --git a/tests/accessibility.spec.mjs b/tests/accessibility.spec.mjs new file mode 100644 index 0000000..5605a07 --- /dev/null +++ b/tests/accessibility.spec.mjs @@ -0,0 +1,20 @@ +// Usage: run `npm run test:a11y` after `npm run build`; serious and critical axe findings fail. +// Evidence boundary: automated axe checks do not replace manual keyboard, screen-reader, or cognitive-access review. +import { createRequire } from 'node:module'; +import { test, expect } from '@playwright/test'; + +const require = createRequire(import.meta.url); +const axePath = require.resolve('axe-core/axe.min.js'); + +for (const route of ['/', '/articles/', '/articles/article-two/', '/way/', '/projects/']) { + test(`${route} has no serious or critical automated accessibility violations`, async ({ page }) => { + await page.goto(route); + await page.addScriptTag({ path: axePath }); + const results = await page.evaluate(async () => globalThis.axe.run(document, { + resultTypes: ['violations'], + rules: { region: { enabled: false } } + })); + const blocking = results.violations.filter(violation => ['serious', 'critical'].includes(violation.impact)); + expect(blocking, JSON.stringify(blocking, null, 2)).toEqual([]); + }); +} diff --git a/tests/canon-parser.test.mjs b/tests/canon-parser.test.mjs new file mode 100644 index 0000000..46c9254 --- /dev/null +++ b/tests/canon-parser.test.mjs @@ -0,0 +1,40 @@ +// Usage: run `node --test tests/canon-parser.test.mjs` from the repository root. +// Evidence boundary: these fixtures witness parser structure and note splitting; they do not prove editorial completeness. +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import { extractNotes, parseCanon } from '../scripts/canon-parser.mjs'; + +test('Markdown recovery headings normalize to plain-canon parent levels', () => { + const data = parseCanon(`# The Interdependent Way\n## Subtitle\n### Rights and Definitions of The Way\n#### Article One\nBody.\n[1] note one\n#### Article Two\nBody two.`); + const articleOne = data.units.find(unit => unit.title === 'Article One'); + assert.equal(articleOne.level, 3); + assert.equal(articleOne.sourceLevel, 4); + assert.equal(articleOne.section, 'rights-and-definitions-of-the-way'); + assert.ok(data.sections.some(section => section.id === 'rights-and-definitions-of-the-way' && section.level === 2)); +}); + +test('multiple superscript note definitions on one physical line remain distinct', () => { + assert.deepEqual(extractNotes('>¹ first tension ² second tension ³ third tension'), [ + { marker: '¹', text: 'first tension' }, + { marker: '²', text: 'second tension' }, + { marker: '³', text: 'third tension' } + ]); +}); + +test('the checked-in recovery mirror yields correctly parented rights articles', async () => { + const mirror = await readFile('canon/the_interdependent_way.md', 'utf8'); + const data = parseCanon(mirror, { repository: 'recovery', fallback: true }); + const rights = data.sections.find(section => /^Rights and Definitions/.test(section.title)); + assert.ok(rights); + for (const title of ['Article One', 'Article Two', 'Article Three', 'Article Four', 'Article Five', 'Article Six', 'Article Seven', 'Article Eight']) { + assert.ok(data.units.some(unit => unit.title === title && unit.section === rights.id), `${title} missing from recovery rights section`); + } +}); + +test('body lines beginning with a digit are not mistaken for numbered notes', () => { + const parsed = parseCanon('The Interdependent Way\n\nAwakening\n5d explodes out of 4d.'); + const awakening = parsed.units.find(unit => unit.title === 'Awakening'); + assert.ok(awakening); + assert.equal(awakening.notes.length, 0); +}); diff --git a/tests/generated-site.test.mjs b/tests/generated-site.test.mjs index 69049f0..b119a09 100644 --- a/tests/generated-site.test.mjs +++ b/tests/generated-site.test.mjs @@ -1,3 +1,5 @@ +// Usage: run through `npm run test:generated` after a complete site build. +// Evidence boundary: verifies generated artifact contracts, not the remote Pages environment. import test from 'node:test'; import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; @@ -13,8 +15,7 @@ test('generated deployment artifact contains the unified routes', async () => { ]); assert.match(home, /A way through complexity/); - assert.match(home, /Article Two: Freedom without abandonment/); - assert.match(artifacts, /Four Cuts of the Same Country/); + assert.match(artifacts, /Artifacts/); assert.match(fourCuts, /Wealth and tax/); assert.match(fallback, /Emergency static edition/); assert.match(articles, /Publication drafts/); @@ -50,3 +51,13 @@ test('generated deployment artifact contains all rights article vertical slices' assert.match(html, /hmmm/); } }); + +test('generated deployment artifact publishes verifiable build identity', async () => { + const build = JSON.parse(await readFile('_site/build.json', 'utf8')); + assert.equal(build.repository, 'The-Interdependency/The-Interdependency.github.io'); + assert.ok(build.commit); + assert.match(build.generatedAt, /^\d{4}-\d{2}-\d{2}T/); + assert.equal(build.canonicalSource.repository, 'wayseer00/main'); + assert.equal(build.canonicalSource.path, 'canon/INTERDEPENDENT_WAY.txt'); + assert.match(build.canonicalSource.contentSha256, /^[a-f0-9]{64}$/); +}); diff --git a/tests/research-ledger.test.mjs b/tests/research-ledger.test.mjs index 22c89d9..3b2aa72 100644 --- a/tests/research-ledger.test.mjs +++ b/tests/research-ledger.test.mjs @@ -1,2 +1,27 @@ -import test from 'node:test';import assert from 'node:assert/strict';import { readFile } from 'node:fs/promises';import yaml from 'js-yaml'; -test('research ledgers parse', async()=>{assert.ok(Array.isArray(yaml.load(await readFile('src/_data/research/sources.yml','utf8'))));assert.ok(Array.isArray(yaml.load(await readFile('src/_data/research/claims.yml','utf8'))));}); +// Usage: run through `npm test`; add claims only with source ids, limitations, and reviewed metadata. +// Evidence boundary: validates provenance structure, not the truth of every source claim. +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import yaml from 'js-yaml'; + +test('research ledgers parse and claims resolve to reviewed sources', async () => { + const sources = yaml.load(await readFile('src/_data/research/sources.yml', 'utf8')); + const claims = yaml.load(await readFile('src/_data/research/claims.yml', 'utf8')); + assert.ok(Array.isArray(sources) && sources.length > 0); + assert.ok(Array.isArray(claims) && claims.length > 0); + + const sourceIds = new Set(sources.map(source => source.id)); + assert.equal(sourceIds.size, sources.length, 'source ids must be unique'); + assert.equal(new Set(claims.map(claim => claim.id)).size, claims.length, 'claim ids must be unique'); + + for (const source of sources) { + assert.ok(source.title && source.url && source.reviewed_on && source.boundary); + } + for (const claim of claims) { + assert.ok(['support', 'dissent', 'limit', 'mixed'].includes(claim.stance)); + assert.ok(Array.isArray(claim.source_ids) && claim.source_ids.length > 0); + for (const sourceId of claim.source_ids) assert.ok(sourceIds.has(sourceId), `unknown source ${sourceId}`); + assert.ok(claim.limitation); + } +}); diff --git a/tests/site.spec.mjs b/tests/site.spec.mjs new file mode 100644 index 0000000..f9fec29 --- /dev/null +++ b/tests/site.spec.mjs @@ -0,0 +1,31 @@ +// Usage: run `npm run test:e2e` after `npm run build`; Playwright starts the loopback static server. +// Evidence boundary: checks route reachability and visible content, not external DNS or Pages freshness. +import { test, expect } from '@playwright/test'; + +const routes = [ + ['/', /A way through complexity/], + ['/articles/', /Publication drafts/], + ['/articles/article-two/', /Freedom without abandonment/], + ['/way/', /The Way/], + ['/lab/', /Article Lab/], + ['/source/', /Source/], + ['/projects/', /Projects/], + ['/artifacts/', /Artifacts/], + ['/fallback/', /Emergency static edition/] +]; + +test('primary public routes render meaningful headings', async ({ page }) => { + for (const [route, heading] of routes) { + const response = await page.goto(route); + expect(response?.ok(), `${route} should return a successful response`).toBeTruthy(); + await expect(page.locator('body')).toContainText(heading); + } +}); + +test('all eight rights articles are reachable from the article index', async ({ page }) => { + await page.goto('/articles/'); + for (const word of ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']) { + const link = page.locator(`a[href="/articles/article-${word}/"]`).first(); + await expect(link).toBeVisible(); + } +}); From 32ef45d695c0b6ee1e49dc0a62104d9051db86e8 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Tue, 21 Jul 2026 02:07:36 -0700 Subject: [PATCH 2/4] Replace dynamic canon note regex construction --- scripts/canon-parser.mjs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/canon-parser.mjs b/scripts/canon-parser.mjs index 1ee7a55..eb01343 100644 --- a/scripts/canon-parser.mjs +++ b/scripts/canon-parser.mjs @@ -22,8 +22,6 @@ import slugify from 'slugify'; // Limits: heading recognition is canon-specific; unknown headings remain body text and must surface as hmmm during editorial review. export const parserVersion = '0.5.0'; -const superscriptDigits = '⁰¹²³⁴⁵⁶⁷⁸⁹'; -const subsequentNoteMarkerSource = `(?:\[[^\]]+\]|[${superscriptDigits}]+)`; function slug(value) { return slugify(value, { lower: true, strict: true }) || 'unit'; @@ -58,7 +56,7 @@ export function detectHeading(line) { if (/^(Awakening|The Interdefinables|Human consciousness emerges from|Preamble|Etiquette of the Body Politic)$/i.test(title)) { return { level: 2, sourceLevel: 2, title, syntax: 'plain' }; } - if (/^Rights[\w\s’'&\-⁰¹²³⁴⁵⁶⁷⁸⁹]+of The Way[⁰¹²³⁴⁵⁶⁷⁸⁹]*$/i.test(title)) { + if (/^Rights[\w\s’'&⁰¹²³⁴⁵⁶⁷⁸⁹-]+of The Way[⁰¹²³⁴⁵⁶⁷⁸⁹]*$/i.test(title)) { return { level: 2, sourceLevel: 2, title, syntax: 'plain' }; } if (/^Addendum:\s+.+$/i.test(title)) return { level: 2, sourceLevel: 2, title, syntax: 'plain' }; @@ -74,15 +72,15 @@ export function detectHeading(line) { function parseDefinitionLine(line) { const normalized = line.replace(/^\s*>?\s*/, '').trim(); const first = - /^(\[[^\]]+\])\s+(.+)$/.exec(normalized) || - new RegExp(`^([${superscriptDigits}]+)\s*(.+)$`).exec(normalized) || + /^(\[.+?])\s+(.+)$/.exec(normalized) || + /^([⁰¹²³⁴⁵⁶⁷⁸⁹]+)\s*(.+)$/.exec(normalized) || /^(\d+)\s+(.+)$/.exec(normalized); if (!first) return []; const notes = []; let marker = first[1]; let remaining = first[2]; - const nextPattern = new RegExp(`\s+(${subsequentNoteMarkerSource})\s*`); + const nextPattern = /\s+(\[.+?]|[⁰¹²³⁴⁵⁶⁷⁸⁹]+)\s*/; while (true) { const next = nextPattern.exec(remaining); @@ -104,7 +102,7 @@ export function extractNotes(content) { function extractNoteMarkers(content) { const markers = []; - for (const match of content.matchAll(/\[[^\]]+\]|[⁰¹²³⁴⁵⁶⁷⁸⁹]+/g)) markers.push(match[0]); + for (const match of content.matchAll(/\[.+?]|[⁰¹²³⁴⁵⁶⁷⁸⁹]+/g)) markers.push(match[0]); return [...new Set(markers)]; } From f80cb0915c7f987ab25072aae9b58fa2907eba85 Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Tue, 21 Jul 2026 02:07:57 -0700 Subject: [PATCH 3/4] Remove test-server filesystem race and harden paths --- scripts/serve-static.mjs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/scripts/serve-static.mjs b/scripts/serve-static.mjs index ee7a3db..a1ee4c9 100644 --- a/scripts/serve-static.mjs +++ b/scripts/serve-static.mjs @@ -1,6 +1,6 @@ import { createServer } from 'node:http'; -import { readFile, stat } from 'node:fs/promises'; -import { extname, join, normalize } from 'node:path'; +import { readFile } from 'node:fs/promises'; +import { extname, isAbsolute, join, relative, resolve } from 'node:path'; // === MODULE_BUILD === // id: generated_site_test_server @@ -36,7 +36,7 @@ import { extname, join, normalize } from 'node:path'; // owner: Erin Spencer // === END BOUNDARIES === -const root = normalize(join(process.cwd(), '_site')); +const root = resolve(process.cwd(), '_site'); const port = Number(process.env.PORT || 4173); const types = { '.css': 'text/css; charset=utf-8', @@ -49,18 +49,17 @@ const types = { function safePath(urlPath) { const decoded = decodeURIComponent(urlPath.split('?')[0]); - const relative = normalize(decoded).replace(/^([/\\])+/, ''); - const candidate = normalize(join(root, relative)); - if (!candidate.startsWith(root)) throw new Error('path traversal refused'); + const candidate = resolve(root, decoded.replace(/^([/\\])+/, '')); + const fromRoot = relative(root, candidate); + if (fromRoot.startsWith('..') || isAbsolute(fromRoot)) throw new Error('path traversal refused'); return candidate; } const server = createServer(async (request, response) => { try { - let path = safePath(request.url || '/'); - const fileStat = await stat(path).catch(() => null); - if (fileStat?.isDirectory()) path = join(path, 'index.html'); - if (!fileStat && !extname(path)) path = join(path, 'index.html'); + const requestPath = (request.url || '/').split('?')[0]; + let path = safePath(requestPath); + if (requestPath.endsWith('/') || !extname(path)) path = join(path, 'index.html'); const body = await readFile(path); response.writeHead(200, { 'content-type': types[extname(path)] || 'application/octet-stream', From 2e5518967c94bfb799aef0892d03c6f67cf955ef Mon Sep 17 00:00:00 2001 From: Erin Spencer Date: Tue, 21 Jul 2026 02:09:36 -0700 Subject: [PATCH 4/4] Use file descriptors in the browser test server --- scripts/serve-static.mjs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/scripts/serve-static.mjs b/scripts/serve-static.mjs index a1ee4c9..4360775 100644 --- a/scripts/serve-static.mjs +++ b/scripts/serve-static.mjs @@ -1,5 +1,6 @@ +import { constants } from 'node:fs'; import { createServer } from 'node:http'; -import { readFile } from 'node:fs/promises'; +import { open } from 'node:fs/promises'; import { extname, isAbsolute, join, relative, resolve } from 'node:path'; // === MODULE_BUILD === @@ -60,12 +61,17 @@ const server = createServer(async (request, response) => { const requestPath = (request.url || '/').split('?')[0]; let path = safePath(requestPath); if (requestPath.endsWith('/') || !extname(path)) path = join(path, 'index.html'); - const body = await readFile(path); - response.writeHead(200, { - 'content-type': types[extname(path)] || 'application/octet-stream', - 'cache-control': 'no-store' - }); - response.end(body); + const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW); + try { + const body = await handle.readFile(); + response.writeHead(200, { + 'content-type': types[extname(path)] || 'application/octet-stream', + 'cache-control': 'no-store' + }); + response.end(body); + } finally { + await handle.close(); + } } catch { response.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' }); response.end('Not found');