Establish Eleventy static-first scaffold with canonical parser, project map, and Lab scaffolding - #2
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2d565af09
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| push: | ||
| branches: [main] |
There was a problem hiding this comment.
Disable the stale root Pages deploy
On pushes to main, this workflow runs alongside the pre-existing .github/workflows/deploy.yml, which also triggers on push to main but uploads path: './' and deploys it without running the Eleventy build. If the new npm ci/npm run check path fails, or if the older workflow finishes after this one, GitHub Pages can publish the repository root/old site instead of the generated _site, bypassing the validation added here. Remove or retarget the old deploy workflow, or put both workflows under one deployment path/concurrency group.
Useful? React with 👍 / 👎.
| push(lines.length); | ||
| if(!units.length){ units.push({id:'source.full-text',title:'The Interdependent Way',section:'source',level:1,startLine:1,endLine:lines.length,content:text,hash:contentSha256}); sections.push({id:'source',title:'Source',level:1,line:1});} | ||
| for (const u of units){ const matches=[...u.content.matchAll(/\[(\d+|[a-z])\]/gi)]; for (const match of matches) notes.push({id:`${u.id}.note-${match[1]}`,unit_id:u.id,marker:match[0]}); } | ||
| const data={source:{repository:'The-Interdependency/a0',path:'interdependent_way.md',commit:process.env.CANON_COMMIT || 'local-snapshot',blob:null,retrievedAt:new Date().toISOString(),contentSha256,parserVersion},sections,units:units.map(({lines,...u})=>u),notes,edges:units.map(u=>({from:u.id,to:u.section,type:'unit-parent'}))}; |
There was a problem hiding this comment.
Preserve the snapshot commit in generated provenance
npm run refresh:canon never sets CANON_COMMIT, while fetch-canon.mjs writes the fetched commit into the snapshot front matter. This line discards that metadata and emits commit: 'local-snapshot', and the Source template displays generated.canon.source.commit, so every rebuilt /source/... page loses the exact source commit users need for provenance. Parse the snapshot front matter or pass the fetched commit through before writing canon.json.
Useful? React with 👍 / 👎.
| } | ||
| let fallback=false, repos=[]; | ||
| try { repos=await fetchAll(); } catch(e){ fallback=true; try{repos=JSON.parse(await readFile('src/_data/snapshots/repos.last-known-good.json','utf8')).repositories;}catch{repos=[];} } | ||
| const mapped=repos.map(r=>({name:r.name,slug:r.name.toLowerCase().replace(/[^a-z0-9]+/g,'-'),html_url:r.html_url,description:r.description,archived:r.archived,fork:r.fork,default_branch:r.default_branch,topics:r.topics||[],license:r.license?.spdx_id||null,language:r.language,homepage:r.homepage,pushed_at:r.pushed_at,visibility:r.visibility||'public',hmmm:['Editorial project map missing until .interdependency/project.yml is reviewed.']})); |
There was a problem hiding this comment.
Preserve snapshot licenses when offline
When GitHub API access fails or OFFLINE=1 is used as documented in the runbook, repos is populated from src/_data/snapshots/repos.last-known-good.json, where license is already a string such as MPL-2.0. This raw-API mapping then reads r.license?.spdx_id, turning every license into null, and the next line writes that corrupted data back over the last-known-good snapshot. Handle normalized snapshot records separately or preserve string licenses before remapping.
Useful? React with 👍 / 👎.
| size: 1 | ||
| alias: repo | ||
| permalink: "/projects/{{ repo.slug }}/" | ||
| title: "Project: {{ repo.name }}" |
There was a problem hiding this comment.
Compute generated page titles with eleventyComputed
Eleventy only evaluates template variables in permalink and eleventyComputed front matter; this title value remains the literal string Project: {{ repo.name }}. As a result, every generated project page gets the same broken browser/Pagefind title, and the same pattern is used in the generated unit templates. Move these dynamic titles under eleventyComputed so metadata reflects the current paginated item.
Useful? React with 👍 / 👎.
| function push(end){ if(current){ current.endLine=end; current.content=current.lines.join('\n').trim(); current.hash=createHash('sha256').update(current.content).digest('hex'); units.push(current); }} | ||
| for (let i=0;i<lines.length;i++){ | ||
| const m=/^(#{1,6})\s+(.+?)\s*$/.exec(lines[i]); | ||
| if(m){ push(i); const level=m[1].length; const title=m[2].replace(/#+$/,'').trim(); if(level<=2){top=slug(title).replace(/^the-/, ''); sections.push({id:top,title,level,line:i+1}); article=0;} if(/article\s+[ivxlcdm0-9]+/i.test(title)) article++; const id=/article/i.test(title)?`${top}.article-${article||slug(title)}`:slug(title); current={id:`${id}-${i+1}`,title,section:top,level,startLine:i+1,lines:[lines[i]]}; } |
There was a problem hiding this comment.
Stop deriving canonical IDs from line numbers
The docs added in this commit describe canon units as having stable IDs, but this line appends i + 1 to every ID and all unit permalinks are built from unit.id. Inserting a paragraph or heading anywhere above an existing article changes the line suffix and breaks existing /way/, /lab/, and /source/ links even when the article title/content did not change. Use a stable heading/article key plus a duplicate counter or hash instead of the source line number.
Useful? React with 👍 / 👎.
| } | ||
| push(lines.length); | ||
| if(!units.length){ units.push({id:'source.full-text',title:'The Interdependent Way',section:'source',level:1,startLine:1,endLine:lines.length,content:text,hash:contentSha256}); sections.push({id:'source',title:'Source',level:1,line:1});} | ||
| for (const u of units){ const matches=[...u.content.matchAll(/\[(\d+|[a-z])\]/gi)]; for (const match of matches) notes.push({id:`${u.id}.note-${match[1]}`,unit_id:u.id,marker:match[0]}); } |
There was a problem hiding this comment.
Deduplicate footnote markers per unit
For articles that contain both an inline marker and its definition, such as feed the hungry [1] followed by [1] wary..., this loop records both occurrences with the same note ID. The Lab template renders one Speaker B turn for every entry in generated.canon.notes, so affected units show each footnote twice and downstream consumers cannot treat note IDs as unique. Track markers already seen within a unit or parse definitions separately before emitting notes.
Useful? React with 👍 / 👎.
Motivation
hmmmrather than inventing balance or placeholder research.Description
.eleventy.js,src/_includes/layouts/base.njk,src/assets/css/site.css).src/_data/generated/canon.json(scripts/fetch-canon.mjs,scripts/parse-canon.mjs) and to fetch the public org repository snapshot intosrc/_data/generated/repos.json(scripts/fetch-github-org.mjs)./way/), Article Lab (/lab/), exact Source (/source/), and Projects (/projects/), including per-unit and per-repository pages and provenance displays (src/way/*,src/lab/*,src/source/*,src/projects/*).scripts/validate-content.mjs,scripts/verify-generated-routes.mjs,tests/*.test.mjs), documentation and runbooks (docs/*.md), and CI workflows for Pages and PR checks (.github/workflows/*.yml).Testing
npm install,npm run build, and the fullnpm run checksequence which executes build, validation, and tests, and the run completed successfully.node --test tests/*.test.mjs) all passed with the repository-local scaffold, includingcanon-integrity.test.mjs,repo-coverage.test.mjs,research-ledger.test.mjs, and a basic site existence check.24canonical units discovered and rendered,21public repositories discovered and project pages generated, and Pagefind indexed the generated site pages.Codex Task