Live at https://alexrajcoomar.github.io
This folder is the website. Adding or changing anything is done from the editor page, not by editing files here.
https://alexrajcoomar.github.io/admin.html
Bookmark that. It is where every routine change happens:
| What you want to do | Where |
|---|---|
| Add a new piece | Pieces → Add a piece → drop the HTML file |
| Change a title, description or tags | Pieces → click the row → edit on the right |
| Reorder anything | Pieces → drag a row, or use the ▲ ▼ buttons |
| Feature something on the home page | Pieces → click the row → Feature it on the home page |
| Replace a file with a newer version | Pieces → click the row → Replace the file |
| Upload images or a PDF | Files → drop them |
| Take something off the site | Pieces → click the row → Remove from the site |
| Change the headline, your email, the About text | Site text |
Nothing is saved until you press Publish. The page tells you what is waiting to be published before you do. After you press it, GitHub rebuilds the site itself; the change is usually live within a minute or two.
The editor needs a token so it can write to the repository. You make it once:
That token is a password. The editor holds it for the current browser tab only and forgets it when the tab closes, so expect to paste it again each time you sit down to publish; that is deliberate, because it keeps a key that can write to the repository out of long-term storage on the same address that serves the site. It is sent only to GitHub. Forget the token clears it immediately. When it expires the editor will say so, and you repeat the six steps above.
admin.html itself is a public page, but it holds no secret and can do nothing
without a token.
This is the part worth understanding, because it is what keeps the site from breaking.
content/pieces.json is the content. One entry per piece: its title, its
description, its tags, where it belongs, whether it is featured, what it was
built from (one line in the owner's words, rendered at the top of the piece),
and which file it opens. The order of the entries is the order on the site. The editor writes
this file and nothing else.
build/build_site.py is the design. It reads content/pieces.json and
writes the generated pages: index.html, research.html, coursework.html,
tools.html, library.html, atlas.html, about.html, colophon.html,
controls.html, 404.html. Those files are output. Editing them by hand is
pointless: the next publish overwrites them.
site.css is the look. One stylesheet for the whole site. It is not
generated, and nothing in the editor touches it.
So: content changes in the editor, design changes in build_site.py and
site.css, and the two cannot collide.
content/pieces.json and any uploaded files in one commit..github/workflows/build.yml.build/build_site.py, which regenerates the listing pages, writes
the head metadata on every piece, refreshes sitemap.xml and the offline
cache, and then checks its own work: thirty-odd checks, from every
link resolving to every number on a generated page being one the build
computed. Every claim the site makes about itself is a row on
controls.html, beside the check that tests it and its last result.build/negatives.py): for each check, a
copy of the site is edited so the claim is false, and the build must
refuse, naming that check. A claim prints held only while a falsification
its check caught is on record for the current code; otherwise untested.
This runs only when the checks' code changed.build/audit.js): nothing requested
from another origin, nothing moving while idle, focus visible, printing,
fitting a phone, the offline copy surviving a publish. Then it makes each
of those claims false on a copy of a page and checks that the measurement
fails it.You can watch step 2 onwards at
https://github.com/alexrajcoomar/alexrajcoomar.github.io/actions. A red mark
there means the rebuild failed; the site keeps serving the last good version
until it is fixed.
| Path | What it is |
|---|---|
admin.html | The editor. Hand-maintained: the build never writes it (check 33 holds it whole and unchanged, the worker never stores it, the audit opens it and works its controls) |
content/pieces.json | The content. Every piece, in order |
content/metrics.json | Word, figure and table counts. Written by the rebuild, not by you |
content/fingerprints.json | Lets the rebuild skip pieces that did not change |
build/build_site.py | Generates the listing pages and runs the checks |
build/claims.py | The register of claims, the glyph walls on controls.html, the run record |
build/negatives.py | The tests of controls: a falsification per check, and what caught it |
build/audit.js | Measures the runtime claims in a browser; --falsify makes each false on a copy |
build/atlas.py | Places every section of every piece on the sphere: each document a disc of two thirds of its share of the area, settled clear of the others inside its origin's zone, its sections on a spiral inside |
build/invariance.py, build/ledger.py | Hold every piece to its record; write the change ledger |
build/emdash.py | The rule that took the em dashes out of the prose |
content/audit.json, content/negatives.json | What the browser measured; what each falsification did. Written by the rebuild |
content/declared.json | The named exceptions: the six records kept as written, the pages allowed past 320px |
content/invariants.json, content/ledger.json | The record every piece is held to, and the change ledger |
build/measure.js | Counts what is on each page, in a real browser |
build/measure_plan.py | Works out which pieces need recounting |
build/cards.js | Draws the link-preview card for each piece |
build/figures.json, specimens.json, refit.json | The figures lifted out of pieces and shown on the site's own pages |
content/cards.json | Lets the rebuild skip cards whose text did not change |
cards/, og-card.png | The link-preview images. Written by the rebuild |
sitemap.xml, robots.txt, sw.js | Generated. Do not edit: the next rebuild overwrites them |
.github/workflows/build.yml | The instruction that runs all of the above after every change |
site.css | The look of every listing page |
site.js | The search box, the filters, the theme switch |
.nojekyll | Tells GitHub to publish the files exactly as they are |
everything else .html | A piece. Self-contained, carries its own styling |
Each piece is one self-contained file named after its address:
skill-forge.html is live at https://alexrajcoomar.github.io/skill-forge.html.
Pieces do not use site.css, so changing the site's look can never break a
piece, and a broken piece can never break the site.
Lowercase, hyphens instead of spaces, ending in .html:
deferred-tax-ladder.html. The editor cleans up names it is given, but a name
chosen well stays in the address bar forever, so it is worth a second's thought.
A file's name is its web address. Renaming a published piece breaks every link anyone has to it, which is why the editor replaces files in place rather than uploading a second copy under a new name.
The editor says the token was refused. It expired, or a space was copied with it. Make a new one; the six steps are above.
A piece was published but shows no reading time. Anything under 1,200 words is treated as an instrument rather than a document and carries no reading time by design. The colophon explains the rule.
The rebuild went red and names a check. That is the check doing its job:
the message opens with check N: and names the page and what is wrong (a link
to a file that is not there, a numeral typed where nothing computed it, a
spelling, an em dash in prose). Fix it and publish again; the deploy waits for
the checks, so the site was never published broken. controls.html lists
every check with the falsification that proved it can catch what it claims.
The site did not update. Check the Actions tab (link above). If the rebuild failed, the message there says why. Nothing is lost: every version is in the repository's history and can be restored.
Something was removed by mistake. Remove from the site only unlists a piece; the file is still there and the link still works. Add it back from Pieces → Add a piece → Add an entry for it.
92 commits
54 commits
24 commits
7 commits
HTML
94.4%
Python
3.6%
JavaScript
1.1%
Live at https://alexrajcoomar.github.io
This folder is the website. Adding or changing anything is done from the editor page, not by editing files here.
https://alexrajcoomar.github.io/admin.html
Bookmark that. It is where every routine change happens:
| What you want to do | Where |
|---|---|
| Add a new piece | Pieces → Add a piece → drop the HTML file |
| Change a title, description or tags | Pieces → click the row → edit on the right |
| Reorder anything | Pieces → drag a row, or use the ▲ ▼ buttons |
| Feature something on the home page | Pieces → click the row → Feature it on the home page |
| Replace a file with a newer version | Pieces → click the row → Replace the file |
| Upload images or a PDF | Files → drop them |
| Take something off the site | Pieces → click the row → Remove from the site |
| Change the headline, your email, the About text | Site text |
Nothing is saved until you press Publish. The page tells you what is waiting to be published before you do. After you press it, GitHub rebuilds the site itself; the change is usually live within a minute or two.
The editor needs a token so it can write to the repository. You make it once:
That token is a password. The editor holds it for the current browser tab only and forgets it when the tab closes, so expect to paste it again each time you sit down to publish; that is deliberate, because it keeps a key that can write to the repository out of long-term storage on the same address that serves the site. It is sent only to GitHub. Forget the token clears it immediately. When it expires the editor will say so, and you repeat the six steps above.
admin.html itself is a public page, but it holds no secret and can do nothing
without a token.
This is the part worth understanding, because it is what keeps the site from breaking.
content/pieces.json is the content. One entry per piece: its title, its
description, its tags, where it belongs, whether it is featured, what it was
built from (one line in the owner's words, rendered at the top of the piece),
and which file it opens. The order of the entries is the order on the site. The editor writes
this file and nothing else.
build/build_site.py is the design. It reads content/pieces.json and
writes the generated pages: index.html, research.html, coursework.html,
tools.html, library.html, atlas.html, about.html, colophon.html,
controls.html, 404.html. Those files are output. Editing them by hand is
pointless: the next publish overwrites them.
site.css is the look. One stylesheet for the whole site. It is not
generated, and nothing in the editor touches it.
So: content changes in the editor, design changes in build_site.py and
site.css, and the two cannot collide.
content/pieces.json and any uploaded files in one commit..github/workflows/build.yml.build/build_site.py, which regenerates the listing pages, writes
the head metadata on every piece, refreshes sitemap.xml and the offline
cache, and then checks its own work: thirty-odd checks, from every
link resolving to every number on a generated page being one the build
computed. Every claim the site makes about itself is a row on
controls.html, beside the check that tests it and its last result.build/negatives.py): for each check, a
copy of the site is edited so the claim is false, and the build must
refuse, naming that check. A claim prints held only while a falsification
its check caught is on record for the current code; otherwise untested.
This runs only when the checks' code changed.build/audit.js): nothing requested
from another origin, nothing moving while idle, focus visible, printing,
fitting a phone, the offline copy surviving a publish. Then it makes each
of those claims false on a copy of a page and checks that the measurement
fails it.You can watch step 2 onwards at
https://github.com/alexrajcoomar/alexrajcoomar.github.io/actions. A red mark
there means the rebuild failed; the site keeps serving the last good version
until it is fixed.
| Path | What it is |
|---|---|
admin.html | The editor. Hand-maintained: the build never writes it (check 33 holds it whole and unchanged, the worker never stores it, the audit opens it and works its controls) |
content/pieces.json | The content. Every piece, in order |
content/metrics.json | Word, figure and table counts. Written by the rebuild, not by you |
content/fingerprints.json | Lets the rebuild skip pieces that did not change |
build/build_site.py | Generates the listing pages and runs the checks |
build/claims.py | The register of claims, the glyph walls on controls.html, the run record |
build/negatives.py | The tests of controls: a falsification per check, and what caught it |
build/audit.js | Measures the runtime claims in a browser; --falsify makes each false on a copy |
build/atlas.py | Places every section of every piece on the sphere: each document a disc of two thirds of its share of the area, settled clear of the others inside its origin's zone, its sections on a spiral inside |
build/invariance.py, build/ledger.py | Hold every piece to its record; write the change ledger |
build/emdash.py | The rule that took the em dashes out of the prose |
content/audit.json, content/negatives.json | What the browser measured; what each falsification did. Written by the rebuild |
content/declared.json | The named exceptions: the six records kept as written, the pages allowed past 320px |
content/invariants.json, content/ledger.json | The record every piece is held to, and the change ledger |
build/measure.js | Counts what is on each page, in a real browser |
build/measure_plan.py | Works out which pieces need recounting |
build/cards.js | Draws the link-preview card for each piece |
build/figures.json, specimens.json, refit.json | The figures lifted out of pieces and shown on the site's own pages |
content/cards.json | Lets the rebuild skip cards whose text did not change |
cards/, og-card.png | The link-preview images. Written by the rebuild |
sitemap.xml, robots.txt, sw.js | Generated. Do not edit: the next rebuild overwrites them |
.github/workflows/build.yml | The instruction that runs all of the above after every change |
site.css | The look of every listing page |
site.js | The search box, the filters, the theme switch |
.nojekyll | Tells GitHub to publish the files exactly as they are |
everything else .html | A piece. Self-contained, carries its own styling |
Each piece is one self-contained file named after its address:
skill-forge.html is live at https://alexrajcoomar.github.io/skill-forge.html.
Pieces do not use site.css, so changing the site's look can never break a
piece, and a broken piece can never break the site.
Lowercase, hyphens instead of spaces, ending in .html:
deferred-tax-ladder.html. The editor cleans up names it is given, but a name
chosen well stays in the address bar forever, so it is worth a second's thought.
A file's name is its web address. Renaming a published piece breaks every link anyone has to it, which is why the editor replaces files in place rather than uploading a second copy under a new name.
The editor says the token was refused. It expired, or a space was copied with it. Make a new one; the six steps are above.
A piece was published but shows no reading time. Anything under 1,200 words is treated as an instrument rather than a document and carries no reading time by design. The colophon explains the rule.
The rebuild went red and names a check. That is the check doing its job:
the message opens with check N: and names the page and what is wrong (a link
to a file that is not there, a numeral typed where nothing computed it, a
spelling, an em dash in prose). Fix it and publish again; the deploy waits for
the checks, so the site was never published broken. controls.html lists
every check with the falsification that proved it can catch what it claims.
The site did not update. Check the Actions tab (link above). If the rebuild failed, the message there says why. Nothing is lost: every version is in the repository's history and can be restored.
Something was removed by mistake. Remove from the site only unlists a piece; the file is still there and the link still works. Add it back from Pieces → Add a piece → Add an entry for it.
92 commits
54 commits
24 commits
7 commits
HTML
94.4%
Python
3.6%
JavaScript
1.1%