paulca / paulca.com Public

Clone
git clone https://amadan.net/paulca/paulca.com

Plain git — no account needed to clone.

1# Instructions for AI agents working on paulca.com
2
3This is Paul Campbell's personal site: a deliberately plain, default-browser-styles
4static site served by GitHub Pages. You (the agent) make changes on Paul's behalf.
5Follow the recipes below exactly.
6
7## How the repo works
8
9- The code lives on amadan: `origin` →
10 [amadan.net/paulca/paulca.com](https://amadan.net/paulca/paulca.com). GitHub
11 is kept as a second remote named `github`, purely as a deploy target for
12 GitHub Pages. See "Recipe: commit and push" — you push to both.
13- `src/` — the source. All edits happen here.
14- `docs/` — the built site, generated by Eleventy and **committed to git**.
15 GitHub Pages serves the `docs/` directory of `main` as-is. There is no build
16 on push: if you don't build locally and commit `docs/`, nothing changes on
17 the live site.
18- `src/blog/*.md` — blog posts, one Markdown file each. The filename is the
19 URL slug: `src/blog/my-post.md` → `https://paulca.com/blog/my-post/`.
20- `src/ledger/*.md` — the prompt & carbon ledger at `/ai.html`, one small
21 Markdown file per entry. `src/_data/ledger.json` holds only the prose
22 equivalent for the running total.
23- `src/_includes/base.njk` and `src/_includes/post.njk` — the only two HTML
24 templates. `post.njk` wraps every blog post.
25- `src/index.njk` — homepage. The Writing list fills itself from `src/blog/`;
26 you never need to edit the homepage when adding a post.
27- `src/blog-text.njk` and the RSS plugin (configured in `eleventy.config.js`)
28 generate a plain-Markdown `/blog/<slug>.text` twin for every post and the
29 feed at `/feed.xml`. Both are automatic — adding a post needs no extra
30 work, and you never edit these.
31- `src/ai.njk` — the ledger page template. The table and running total are
32 generated from the files in `src/ledger/`; you never edit this file to add
33 an entry.
34- `src/faq/*.md` — the FAQ at `/faq/`, one Markdown file per question.
35 `src/faq.njk` is the page template that assembles them in filename order;
36 you never edit it to add a question.
37- `src/posts/`, `src/microblog/`, `src/assets/`, `src/activity_pub/` — frozen
38 archives of the old site, copied into `docs/` unchanged. Never edit these.
39
40## Rules
41
421. **No styling.** No CSS files, no `<style>` blocks, no new inline styles, no
43 classes, no JavaScript. Semantic HTML and Markdown only. The single
44 `max-width:80ch` inline style on `<article>` in `post.njk` (a line-length
45 cap for readability) is the only styling on the site; leave it alone.
462. **Never edit anything in `docs/` by hand.** Change `src/`, then rebuild.
473. **Post Paul's words verbatim.** When Paul gives you text for a blog post,
48 do not rewrite, correct, or embellish it.
494. **The ledger is append-only.** Add a new file under `src/ledger/`; never
50 edit or delete the existing entry files.
515. **Every session that changes the site also adds a ledger entry**, in the
52 same push as the change. This applies to every change you make, with any
53 tool: a model editing files with its own edit tool is AI work, full stop.
54 There is no "hand-edit" exemption for your own actions — the only changes
55 that skip the ledger are ones Paul makes himself, in his own editor,
56 without prompting any model.
576. **Always rebuild before committing**, and commit `src/` and `docs/`
58 together.
59
60## Recipe: add a blog post
61
621. Start up to date, on `main`:
63
64 git checkout main
65 git pull
66
67 Pick a `<slug>` from the post title: lowercase, words separated by
68 hyphens, no punctuation (e.g. "My Great Post!" → `my-great-post`).
69
702. Create `src/blog/<slug>.md`:
71
72 ---
73 title: The post title exactly as Paul gave it
74 date: 2026-07-25
75 ---
76 The body of the post, in Markdown, verbatim.
77
78 The `date` is today's date in `YYYY-MM-DD` format. Links are written as
79 `[text](https://example.com)`.
80
813. Build and check (first time on a machine, run `npm install` once):
82
83 npm run build
84 grep "<h1>" docs/blog/<slug>/index.html
85
86 The grep must print the post title. To preview in a browser:
87 `npm run serve`, then open http://localhost:8080/.
88
894. Add the ledger entry (see recipe below) and rebuild.
90
915. Commit and push (see recipe below).
92
93## Recipe: make a tweak
94
95Same flow as a post, with an edit instead of a new file: pull `main`, edit
96the relevant file under `src/`, run `npm run build`, add a ledger entry,
97then commit and push.
98
99## Recipe: update the prompt & carbon ledger
100
101Each entry is one small Markdown file in `src/ledger/`. Create a new file —
102never edit an existing one — named `YYYY-MM-DD-NN-slug.md`: today's date,
103then `NN`, a two-digit number one higher than the highest already used for
104that date (run `ls src/ledger/` to check; use `01` if the date is new), then
105two or three words about the change. Example: `2026-07-25-08-model-column.md`.
106Get today's date by running `date +%F` — never guess it from memory; models
107frequently don't know what day it is.
108
109 ---
110 model: GPT-OSS (RTX 3090)
111 wh: 4
112 co2_g: 1.6
113 comparison: A few minutes of a smartphone charging
114 prompt: >-
115 “The instruction Paul gave, quoted verbatim.”
116 ---
117 One or two sentences describing what you did, in Markdown.
118
119- `model`: the model doing the work — that is, you, the model reading this
120 file right now. If the latest entries name a different model, do **not**
121 copy them: write your own name and where you run, e.g.
122 `Qwen3-Coder 30B (Ollama)` or `GPT-OSS (RTX 3090)`.
123- The arithmetic, for a local open-source model on the home GPU:
124 `wh = (number of prompts Paul sent this session) × 2`, and
125 `co2_g = wh × 0.4`. Round to one decimal at most.
126- `comparison` is a fresh everyday-energy equivalent for that amount of
127 energy. Vary it; don't reuse a comparison from an existing entry.
128- The `prompt` text must stay indented under `prompt: >-` exactly as in the
129 example. Quotes inside it need no escaping.
130- The running total on the page computes itself. The `totals_comparison`
131 string in `src/_data/ledger.json` is the prose equivalent for the *total*;
132 update it when the total has drifted well past what it describes.
133
134Then rebuild and confirm your entry made it into the page:
135
136 npm run build
137 grep "the comparison text from your new entry" docs/ai.html
138
139## Recipe: add an FAQ entry
140
141Each question is one Markdown file in `src/faq/`, and the page at `/faq/`
142assembles them in filename order. Create a new file — never renumber or edit
143existing ones unless Paul asks — named `NN-slug.md`: `NN` is a two-digit
144number one higher than the highest already in `src/faq/` (run `ls src/faq/`
145to check), and the slug is two or three words from the question. Example:
146`06-what-model-runs-this.md`.
147
148 ---
149 question: >-
150 The question, phrased the way a reader would ask it?
151 ---
152 The answer, in Markdown. Keep it short and factual, write about Paul in
153 the third person, and only state things that are true of this site.
154
155The `question` text must stay indented under `question: >-` exactly as in
156the example. Then rebuild and confirm the question shows up:
157
158 npm run build
159 grep "the question text" docs/faq/index.html
160
161An FAQ change is a site change like any other: add a ledger entry, then
162commit and push as usual.
163
164## Recipe: commit and push
165
166Work directly on `main` — no branches, no pull requests. Paul is the only
167human in the repo and reviews the live site.
168
169 git add -A
170 git commit -m "Add blog post: <title>" # or a one-line description of the tweak
171 git push origin main
172 git push github main
173
174**Push to both remotes, every time.** `origin` is amadan
175(`amadan.net/paulca/paulca.com`) — the home of the code. `github` is a mirror
176that exists only because GitHub Pages serves the live site from it. If you
177push to `origin` alone, your change is safely stored and the live site does
178not move. Both pushes, or the deploy didn't happen.
179
180Use `git add -A` exactly as written — never stage individual files. If your
181commit doesn't include the changed files under `docs/`, the live site will
182not change, no matter what you changed under `src/`. After committing, run
183`git show --stat HEAD` and check that `docs/` files are in it.
184
185Then verify the live site (GitHub Pages takes a minute or two to deploy):
186
187 curl -sL https://paulca.com/blog/<slug>/ | grep "<h1>"
188
189If the push is rejected because the remote has newer commits, run
190`git pull --rebase`, run `npm run build` again, and push again (to both
191remotes).
192
193## Checklist before pushing
194
195- [ ] `npm run build` ran without errors after the last edit to `src/`
196- [ ] The change shows up in `docs/`
197- [ ] No new CSS, classes, or JavaScript anywhere
198- [ ] `src/ledger/` has a new entry file for this session, and its row shows
199 up in `docs/ai.html`
200- [ ] Nothing under `docs/` was edited by hand; nothing under the archive
201 directories was touched
202- [ ] Pushed to **both** `origin` (amadan) and `github` (Pages deploy)
203