[{"content":"Session brief — 29 June 2026 Covers connecting Hermes to Slack, the design of the first expert-trained domain agent (neutrality studies, for Prof. Pascal Lottaz), switching the default model to GLM 5.2, wiring Claude Code to GLM via Coding Helper, and a still-open GLM authentication bug. Written to be re-read cold: each section states what was done, why, and what it means.\nStarting point Hermes was already running on the Hetzner VPS (91.99.141.162), reachable via Telegram, with the dashboard accessible over an SSH tunnel, voice transcription working, and the four-project MEMORY.md in place. Today\u0026rsquo;s goals: add Slack as a second front door, design the first expert-training agent, and move the default model to GLM 5.2 for cost.\nPhase 1 — Slack connection What was set up Hermes connected to a new Slack workspace (\u0026ldquo;AI Res\u0026rdquo; app) as a bot via Socket Mode, running alongside Telegram from the same gateway, same memory, same projects.\nWhat Socket Mode is Socket Mode connects the bot to Slack over a WebSocket instead of a public HTTP endpoint. This means the Hetzner server doesn\u0026rsquo;t need to expose any public URL — the bot works from behind the firewall. One less attack surface.\nThe manifest shortcut Instead of manually configuring scopes, events, and slash commands (the error-prone part), hermes slack manifest --write generated a manifest file that declares all of them at once. This was pasted into api.slack.com/apps → Create New App → From an app manifest. The manifest handled the four most-commonly-missed setup steps automatically.\nTokens obtained App-level token (xapp-) — from Socket Mode settings, with connections:write scope Bot token (xoxb-) — from Install App, after installing to workspace Member ID (U...) — for the allowlist, so only authorised users can use the bot These went into the gateway via hermes gateway setup → Slack.\nThe shared-session decision group_sessions_per_user: false was set in config.yaml. This is the key choice for the expert-training use case: the whole channel shares ONE conversation rather than each user getting an isolated silo. When expert A teaches the agent and expert B builds on it, they\u0026rsquo;re in the same context.\nThe tradeoff: users share context growth and token cost, and one person\u0026rsquo;s /reset wipes the session for everyone. Managed by house rules rather than isolation, because isolation would defeat the collaborative-training purpose.\nResult Bot responds in Slack, knows Niall from USER.md, personality intact. Hermes now reachable from Telegram + Slack + terminal, all the same agent.\nPhase 2 — The expert-agent model (design) The purpose Hermes will sit in a shared Slack workspace where domain experts collaborate to train a field-specific AI agent. The expert brings the knowledge; the agent extends their reach. First expert: Prof. Pascal Lottaz (Kyoto University, neutrality studies), who has been asking Niall to build exactly this since March 2025.\nThe five-layer model (why expert agents work) A complete expert agent is NOT \u0026ldquo;an AI that read some PDFs.\u0026rdquo; It has five layers:\nIdentity \u0026amp; epistemic stance — who the agent is, how it\u0026rsquo;s allowed to reason (the channel prompt) Structured domain knowledge — the scaffold of the field: concepts, distinctions, cases, debates (the seed skill) Source corpus — the actual PDFs/books/treaties, structured for accurate retrieval and citation (a real build step, not drag-and-drop) Reasoning conventions — citation, confidence-flagging, distinguishing consensus from contested interpretation The correction loop — how the expert improves it over time, with an auditable, attributed provenance trail The provenance trail is the value: it turns \u0026ldquo;an AI that read PDFs\u0026rdquo; into \u0026ldquo;the agent trained by Professor Lottaz,\u0026rdquo; which is the authority no generic model has.\nWhy experts will enjoy it It\u0026rsquo;s leverage on a life\u0026rsquo;s work — scholarship that reaches hundreds through papers becomes available to anyone, any time. It doesn\u0026rsquo;t replace the expert, it extends their reach. And it offers first-mover authorship of the canonical agent in their field. For someone who\u0026rsquo;s spent fifteen years on a niche subject, that\u0026rsquo;s a gift, not a chore.\nWhat was built A three-file package for the #neutrality-agent channel:\nChannel prompt — defines the agent as a neutrality scholar, with Lottaz\u0026rsquo;s own \u0026ldquo;I study neutrality, I am not neutral\u0026rdquo; distinction baked in as the foundational rule Seed skill — broad scaffold of the field (concepts, legal foundations, canonical cases, periodisation, live debates, key works), every section marked [SEED] to show it awaits expert depth Training protocol — house rules + the correction-log mechanism Saved to outputs. Not yet deployed to the server.\nPhase 3 — GLM 5.2 as default model What was done The default model was switched from openrouter/owl-alpha to glm-5.2 via Z.ai, using hermes model. Base URL https://api.z.ai/api/paas/v4. Reason: GLM 5.2 is strong and cheap on Niall\u0026rsquo;s coding plan, suitable as an everyday default while keeping Claude for high-stakes work (the neutrality agent, An Ceisteoir) via /model switching.\nCoding Helper — Claude Code on GLM Separately, @z_ai/coding-helper was used to point Claude Code (the CLI coding tool) at GLM\u0026rsquo;s Anthropic-compatible endpoint. \u0026ldquo;Configuration synchronized\u0026rdquo; confirmed.\nWhat this means: Claude Code is just a client that speaks the Anthropic API format. Coding Helper repointed its base URL and key to GLM. So the tool is branded \u0026ldquo;Claude Code\u0026rdquo; but the model answering is GLM 5.2. For the honesty standard: the accurate description of the stack is \u0026ldquo;Claude Code as the harness, GLM 5.2 as the model\u0026rdquo; — not \u0026ldquo;using Claude.\u0026rdquo;\nProblems encountered (and what they taught) 1. The GLM API key was set to literal text \u0026ldquo;hermes model\u0026rdquo; grep -i glm ~/.hermes/.env revealed GLM_API_KEY=hermes model — the words \u0026ldquo;hermes model\u0026rdquo; had been captured as the key instead of the real key, during the setup wizard. This caused every GLM call to fail with HTTP 401 (\u0026ldquo;token expired or incorrect\u0026rdquo;).\nThe lesson: a 401 is an authentication failure (key rejected), distinct from a 404 (model not found). When debugging, the error code tells you which layer is broken. The key was the problem, not the model name.\n2. sed kept failing on the key fix Attempts to fix the key with sed threw \u0026ldquo;unterminated s command\u0026rdquo; repeatedly, because the GLM key contains a . and other characters that clash with sed\u0026rsquo;s pattern syntax unless heavily escaped.\nThe lesson: for replacing a value containing dots/special characters, don\u0026rsquo;t use sed. Either use nano (literal typing, no escaping) or the grep-filter-and-append method:\ngrep -v \u0026#34;^GLM_API_KEY=\u0026#34; ~/.hermes/.env \u0026gt; ~/.hermes/.env.tmp \u0026amp;\u0026amp; \\ echo \u0026#34;GLM_API_KEY=THEFULLKEY\u0026#34; \u0026gt;\u0026gt; ~/.hermes/.env.tmp \u0026amp;\u0026amp; \\ mv ~/.hermes/.env.tmp ~/.hermes/.env 3. nano edit didn\u0026rsquo;t save A nano attempt to fix the key didn\u0026rsquo;t write — grep still showed the broken value afterwards. Likely exited without saving (Ctrl+X → Y → Enter sequence not completed).\nCurrent state at end of session ✅ Slack connected, bot responding, shared-session mode set ✅ Default model switched to GLM 5.2 in config ✅ Claude Code wired to GLM via Coding Helper (\u0026ldquo;synchronized\u0026rdquo;) ✅ Neutrality agent design complete (3-file package, saved, not yet deployed) ✅ GLM authentication fixed — the GLM_API_KEY in ~/.hermes/.env was corrected (it had been holding the literal text \u0026ldquo;hermes model\u0026rdquo; instead of the real key). Hermes now authenticates against GLM 5.2 and responds. Outstanding — to do next session Confirm the GLM model string. GLM auth now works. If a 404 ever appears, the model name may need to be glm-5 or glm-4.6 rather than glm-5.2 — check which strings the Z.ai plan exposes. (Keep the model-switching habit: GLM as the cheap default, Claude via /model for deep research, strategising, the neutrality agent, and An Ceisteoir.) Deploy the neutrality agent. Create the #neutrality-agent channel, add the channel prompt to config.yaml under slack.channel_prompts, save the seed skill to ~/expert-agents/neutrality-agent/skill.md, bind it via channel_skill_bindings, restart, invite the bot, self-test with the five verification questions (esp. \u0026ldquo;Are you neutral?\u0026rdquo; — must say it STUDIES neutrality). Draft the follow-up email to Lottaz once the agent is live and self-tested — \u0026ldquo;it\u0026rsquo;s already running, come and try it\u0026rdquo; is far stronger than \u0026ldquo;I\u0026rsquo;d like to build this.\u0026rdquo; Glossary of terms used today Socket Mode — Slack connection method using WebSockets instead of a public URL; works behind a firewall. App manifest — a JSON file declaring a Slack app\u0026rsquo;s scopes, events, and commands all at once; avoids manual configuration. Bot token (xoxb-) / App token (xapp-) — the two credentials a Socket Mode Slack bot needs. Member ID (U...) — Slack\u0026rsquo;s internal user identifier, used for the allowlist. Shared session (group_sessions_per_user: false) — the whole channel shares one conversation context rather than per-user silos. Channel prompt — an ephemeral system prompt injected on every turn in a specific Slack channel; sets the agent\u0026rsquo;s persona for that channel. Channel skill binding — a skill auto-loaded at session start in a specific channel; becomes part of the conversation history. Five-layer model — the framework for a complete expert agent: identity, structured knowledge, corpus, reasoning conventions, correction loop. Correction log — an append-only, attributed record of expert corrections; provides the agent\u0026rsquo;s provenance and authority. Coding Helper — Z.ai\u0026rsquo;s utility (@z_ai/coding-helper) that repoints Claude Code at GLM\u0026rsquo;s Anthropic-compatible endpoint. HTTP 401 vs 404 — 401 is an authentication failure (key rejected); 404 is resource-not-found (e.g. wrong model name). The code identifies which layer broke. GLM 5.2 — Zhipu AI\u0026rsquo;s model, accessed via Z.ai; cheap on Niall\u0026rsquo;s coding plan. ","permalink":"https://griffinai.dev/sessions/2026-06-29-session-slack-expert-agents-glm/","summary":"\u003ch1 id=\"session-brief--29-june-2026\"\u003eSession brief — 29 June 2026\u003c/h1\u003e\n\u003cp\u003eCovers connecting Hermes to Slack, the design of the first expert-trained domain\nagent (neutrality studies, for Prof. Pascal Lottaz), switching the default model\nto GLM 5.2, wiring Claude Code to GLM via Coding Helper, and a still-open GLM\nauthentication bug. Written to be re-read cold: each section states what was done,\nwhy, and what it means.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"starting-point\"\u003eStarting point\u003c/h2\u003e\n\u003cp\u003eHermes was already running on the Hetzner VPS (91.99.141.162), reachable via\nTelegram, with the dashboard accessible over an SSH tunnel, voice transcription\nworking, and the four-project MEMORY.md in place. Today\u0026rsquo;s goals: add Slack as a\nsecond front door, design the first expert-training agent, and move the default\nmodel to GLM 5.2 for cost.\u003c/p\u003e","title":"Session brief — Slack, expert agents \u0026 GLM"},{"content":"Session brief — 23 June 2026 Covers Phase 6 (making the site live via automated deployment) and Phase 7 (connecting the custom domain). Written to be re-read cold: each section states what was done, why, and what it means.\nStarting point The site existed as source files in a GitHub repository (niallgriffin90-ai/niallgriffin90-ai.github.io) but was not yet being served on the internet. The goal today was to make it build and publish automatically, then attach the real domain griffinai.dev.\nPhase 6 — Automated deployment (CI/CD) What was set up A GitHub Actions workflow file was added at .github/workflows/hugo.yaml.\nWhat a workflow is GitHub Actions is an automation system built into GitHub. A workflow is a set of instructions, written in YAML, that GitHub runs on its own servers when a trigger occurs. The trigger here is \u0026ldquo;a push to the main branch.\u0026rdquo; When triggered, the workflow spins up a temporary Linux machine, installs Hugo on it, builds the site, and publishes the result to GitHub Pages.\nThis is what \u0026ldquo;CI/CD\u0026rdquo; means in practice — Continuous Integration / Continuous Deployment. The effect: once set up, publishing a new post is just git push. No manual building, no manual uploading. The pipeline does it.\nThe critical line for this setup with: submodules: recursive The PaperMod theme is included in the repo as a git submodule — a pointer to another repository rather than a copy of its files. Without submodules: recursive, GitHub clones the project but not the theme it points to, and the build fails with a \u0026ldquo;theme not found\u0026rdquo; error. This line tells GitHub to pull the theme in too.\nThe baseURL change hugo.yaml line 1 was changed from the placeholder https://example.org/ to https://griffinai.dev/. This is the canonical address Hugo uses when generating internal links. Note: the deployment workflow temporarily overrides this at build time (via a --baseURL flag) so the site also works correctly at the niallgriffin90-ai.github.io address before the custom domain is connected. Both can coexist; this is expected, not a conflict.\nThe GitHub Pages source setting In the repo: Settings → Pages → Build and deployment → Source was changed from \u0026ldquo;Deploy from a branch\u0026rdquo; to \u0026ldquo;GitHub Actions.\u0026rdquo; This tells GitHub that the workflow file is now responsible for deployment, rather than GitHub trying to serve files directly from a branch.\nResult After pushing, the workflow ran (visible under the repo\u0026rsquo;s Actions tab) and deployed. The site became reachable at https://niallgriffin90-ai.github.io.\nProblems encountered in Phase 6 (and what they taught) These are worth keeping because the reasons generalise.\n1. Commands ran in the wrong directory The workflow file was first created while the terminal was sitting in the home directory (~), not the project folder. The files landed in ~/.github/ instead of inside the project.\nWhy it happened: in VS Code, the folder shown in the sidebar and the folder the integrated terminal is \u0026ldquo;in\u0026rdquo; are independent. Editing a file in the sidebar does not move the terminal. The terminal\u0026rsquo;s location is shown in its prompt — here, ~$ means home, ~/Downloads/niallgriffin$ means inside the project.\nThe lesson: always check the prompt before running file-creating commands. pwd prints the current directory; cd ~/Downloads/niallgriffin moves into the project.\n2. Push rejected — token missing workflow scope The first push of the workflow file was rejected with: refusing to allow a Personal Access Token to create or update workflow ... without 'workflow' scope.\nWhy it happened: GitHub treats files inside .github/workflows/ as sensitive, because a workflow can run arbitrary code on GitHub\u0026rsquo;s servers. A Personal Access Token needs an explicit, separate permission — the workflow scope — to push such files. The token had repo but not workflow.\nThe fix: edit the existing token on GitHub (Settings → Developer settings → Personal access tokens → Tokens classic → select the token → tick workflow → Update token). The token value does not change, so nothing else needed updating.\n3. A note file got committed into the repo The session-explainer note was moved into the project folder and was swept into a commit.\nWhy it matters: anything inside the project folder is part of the git repository and will be pushed to the public GitHub repo — even if it does not appear on the website. (The website only publishes what is inside content/; the repo contains everything.) So a note placed anywhere in the project is heading for the public repo.\nThe rule going forward: notes and drafts live entirely outside the project folder. They are now kept in ~/blog-notes/.\n4. Cleaning the bad commit — git reset --soft Because the commit containing the note had not been successfully pushed (it was blocked by the token error), it existed only locally and could be safely rewritten.\ngit reset --soft HEAD~1 # undo the last commit, keep all file changes git add -A # re-stage the current state (note now removed) git commit -m \u0026#34;...\u0026#34; # make a fresh commit without the note reset --soft HEAD~1 rewinds one commit but leaves the working files untouched. Re-staging then captures the current state, which no longer includes the note. The result is a commit whose history never contained the note. This is only safe for commits that have not been pushed; rewriting already-pushed history causes problems for anything that has pulled it.\n5. The ~/Documents symlink loop Attempts to use ~/Documents/niallgriffin-notes failed with Too many levels of symbolic links (a filesystem loop, ELOOP). The cause was not determined. It is unrelated to the blog. It was sidestepped entirely by using ~/blog-notes/ instead. The ~/Documents issue remains open and can be investigated separately if needed.\nPhase 7 — Connecting the domain griffinai.dev Connecting a domain has two halves that must both be done: tell GitHub to accept the domain, and tell the registrar (Namecheap) where to send visitors.\nHalf 1 — GitHub side Repo → Settings → Pages → Custom domain → entered griffinai.dev → Save.\nThis makes GitHub willing to serve the site under that name, and it creates a CNAME file in the repo so the setting persists across rebuilds.\nDecision made: the apex (bare) domain griffinai.dev is the primary, rather than www.griffinai.dev. The apex is cleaner for a CV/LinkedIn. The www version redirects to it.\nHalf 2 — Namecheap DNS records In Namecheap → Domain List → Manage → Advanced DNS → Host Records.\nWhat DNS is: the Domain Name System is the internet\u0026rsquo;s address book. It translates a human-readable name (griffinai.dev) into the numerical server addresses computers use. A record is one entry in that address book.\nThe following five records were added:\nType Host Value Meaning A @ 185.199.108.153 Apex → GitHub server 1 A @ 185.199.109.153 Apex → GitHub server 2 A @ 185.199.110.153 Apex → GitHub server 3 A @ 185.199.111.153 Apex → GitHub server 4 CNAME www niallgriffin90-ai.github.io. www → the GitHub Pages host Explanations:\nA record maps a name directly to an IP address. @ is Namecheap\u0026rsquo;s notation for the bare domain itself (griffinai.dev with no prefix). Four A records is correct — GitHub Pages publishes four server addresses and traffic is spread across them for reliability. The four IPs are GitHub\u0026rsquo;s standard Pages addresses, identical for every GitHub Pages user. CNAME record maps a name to another name rather than an IP. The www host is pointed at niallgriffin90-ai.github.io, so www.griffinai.dev resolves to the GitHub Pages host. The trailing dot is standard DNS notation for a fully qualified name. Records that were removed The Namecheap defaults included a www CNAME and a URL Redirect record. Both were deleted, because they would conflict with the records above. (The old www CNAME was replaced with the new one pointing at GitHub.)\nA record that was left in place A TXT record with value beginning v=spf1 include:spf.efwd.re... was left untouched. This is an SPF record — it concerns email, not the website. SPF (Sender Policy Framework) lists which servers are permitted to send email claiming to be from the domain; it is an anti-spoofing measure. It does not interact with the A or CNAME records (web traffic and email are governed separately), and it would be needed if email forwarding on the domain is set up later. No reason to remove it.\nCurrent state at end of session Site is live at https://niallgriffin90-ai.github.io. DNS records for griffinai.dev are configured at Namecheap. griffinai.dev is registered as the custom domain in GitHub Pages settings. DNS propagation is in progress — changes ripple across the internet\u0026rsquo;s servers and can take from ~30 minutes up to 24 hours. Nothing to do but wait. Outstanding — to do once propagation completes Confirm https://griffinai.dev loads the site. In GitHub repo → Settings → Pages, tick Enforce HTTPS. This may be greyed out for up to an hour after DNS resolves, while GitHub provisions a free security certificate (via Let\u0026rsquo;s Encrypt). The .dev TLD requires HTTPS, so this step is necessary, not optional. Open item (unrelated to blog) ~/Documents has a symbolic-link loop causing Too many levels of symbolic links. Cause unknown. Parked. Notes are kept in ~/blog-notes/ to avoid it. Glossary of terms used today CI/CD — Continuous Integration / Continuous Deployment. Automation that builds and publishes a project automatically on each change. GitHub Actions — GitHub\u0026rsquo;s built-in automation system; runs workflows. Workflow — a YAML instruction file defining what automation runs and when. Submodule — a git repository referenced inside another repository as a pointer, not a copy. baseURL — the canonical web address Hugo uses to build links. Personal Access Token (PAT) — a generated credential for authenticating with GitHub; carries specific permission scopes. Scope — a specific permission attached to a token (e.g. repo, workflow). DNS — Domain Name System; translates names into IP addresses. A record — maps a name to an IP address. CNAME record — maps a name to another name. Apex / bare domain — the domain with no prefix (griffinai.dev). SPF record — a TXT record listing servers allowed to send email for a domain; anti-spoofing; unrelated to web hosting. Propagation — the delay while DNS changes spread across internet servers. HTTPS / Let\u0026rsquo;s Encrypt — encrypted web connection; Let\u0026rsquo;s Encrypt is the free certificate authority GitHub uses to provide it. ","permalink":"https://griffinai.dev/sessions/2026-06-23-session-deploy-and-domain/","summary":"\u003ch1 id=\"session-brief--23-june-2026\"\u003eSession brief — 23 June 2026\u003c/h1\u003e\n\u003cp\u003eCovers Phase 6 (making the site live via automated deployment) and Phase 7\n(connecting the custom domain). Written to be re-read cold: each section states\nwhat was done, why, and what it means.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"starting-point\"\u003eStarting point\u003c/h2\u003e\n\u003cp\u003eThe site existed as source files in a GitHub repository\n(\u003ccode\u003eniallgriffin90-ai/niallgriffin90-ai.github.io\u003c/code\u003e) but was not yet being served\non the internet. The goal today was to make it build and publish automatically,\nthen attach the real domain \u003ccode\u003egriffinai.dev\u003c/code\u003e.\u003c/p\u003e","title":"Session brief — Deployment and domain connection"},{"content":"Session brief — 16 June 2026 Scope: installing the toolchain, scaffolding the Hugo site, configuring it, adding the legal pages and post template, and pushing the source to GitHub under a separate identity. Covers Phases 1–5 of the build.\nHugo Extended Hugo is a static site generator. Posts are written as plain Markdown files; Hugo converts them into a complete website (HTML and CSS) that any browser can serve.\nHugo ships in two editions, standard and extended. The extended edition processes SCSS/Sass stylesheets, which most themes — including PaperMod — require. The standard edition fails on those themes with an SCSS error. Extended was installed.\nReason for choosing Hugo over a hosted platform (WordPress, Squarespace): the output is just static files. No database, no always-on server, nothing to patch or that can go down. It is fast, free to host, and the entire site lives in Git, which makes it version-controlled and portable.\nGit and GitHub These are distinct things.\nGit is software running locally that tracks changes to files over time. Each git commit records a snapshot of the project. Any snapshot can be returned to, and the difference between any two snapshots can be inspected. It functions as a complete change history for the project.\nGitHub is a website that stores copies of Git repositories remotely. Git is the system; GitHub is one host for it (GitLab, Bitbucket, or a private server are alternatives — all use Git). GitHub was chosen because of GitHub Pages, its free static-site hosting, used in a later phase.\nActions taken: git init created a repository inside the project folder; the first commit recorded the initial state; that commit was pushed to a new GitHub repository under a separate account.\nSite structure hugo new site scaffolds a fixed folder layout. Function of each:\ncontent/ — written content. Each .md file becomes a page. Created here: about.md, privacy.md, disclaimer.md, archives.md. Posts live in content/posts/. themes/ — the visual design. PaperMod sits here. These files are not edited directly; the theme is controlled from the config file. archetypes/ — templates for new content. hugo new posts/x.md uses the template here to pre-fill a new file. static/ — files served as-is (images, favicon, the future llms.txt). Not processed by Hugo. public/ — where Hugo writes the built site. Not edited directly; excluded from Git via .gitignore because the deployment pipeline regenerates it on each push. hugo.yaml — the configuration file. Controls site title, theme, menu, social icons, and SEO settings. The homepage text, the menu, and the social icons are all defined here. PaperMod theme PaperMod is an open-source Hugo theme. It supplies the layout, typography, light/dark toggle, reading-time indicator, and breadcrumb navigation. Only content, identity, and configuration are user-supplied.\nIt was installed as a Git submodule — a reference inside the repository pointing to another repository, rather than a copy of its files. Consequence: theme updates can be pulled with one command, and the project repository stays small, holding a pointer rather than the theme\u0026rsquo;s full file tree.\nFrontmatter Every Hugo content file opens with a metadata block delimited by ---. This is the frontmatter — data about the file rather than its content.\n--- title: \u0026#34;About\u0026#34; layout: \u0026#34;single\u0026#34; url: \u0026#34;/about/\u0026#34; ShowReadingTime: false --- Hugo reads it before rendering: title sets the page title, layout selects the presentation, url sets the page address. Page content follows the second ---. The post archetype pre-fills this block so new posts start with the correct structure.\nIdentity separation — two GitHub accounts Git carries two independent identities:\nCommit identity — the name and email stamped on each commit, visible in public history. Authentication identity — the GitHub account used to connect and push. git config user.name set without --global sets the commit identity for this project only, leaving the global (groggs) identity intact elsewhere. This was done deliberately to keep the blog\u0026rsquo;s commit history under the professional name.\nAuthentication is separate. VS Code\u0026rsquo;s terminal used the system\u0026rsquo;s stored credentials (groggs99) when pushing, producing a 403 Permission Denied: GitHub saw groggs99 pushing to a repository owned by niallgriffin90-ai and refused.\nFix: a Personal Access Token (a generated credential scoped to specific permissions) embedded in the remote URL — https://niallgriffin90-ai:TOKEN@github.com/... — which bypasses the system credential store entirely.\nRepository name convention The repository is named niallgriffin90-ai.github.io. GitHub treats a repository named exactly \u0026lt;username\u0026gt;.github.io as the account\u0026rsquo;s personal GitHub Pages site and serves it at that address. The name is functional, not cosmetic — it is what enables the free hosting.\nState at end of session Toolchain installed (Hugo Extended, Git present). Site scaffolded, PaperMod added, config written. Pages created: About, Privacy, Disclaimer, Archive. Post archetype created (new posts default to draft: true). Source pushed to niallgriffin90-ai/niallgriffin90-ai.github.io. Commit identity confirmed as the professional account, not groggs. Decisions made Separate GitHub account (niallgriffin90-ai) for the blog, isolating it from the existing groggs crypto/Web3 identity. Per-repo Git identity rather than global, so only this project carries the new name. Notes and drafts kept outside the project folder (anything inside it is part of the public repo). Glossary Static site generator — software that builds a website from plain text files. Commit — a recorded snapshot of the project in Git. Submodule — a repository referenced inside another as a pointer, not a copy. Frontmatter — the metadata block at the top of a content file. Personal Access Token (PAT) — a generated GitHub credential with defined scopes. GitHub Pages — GitHub\u0026rsquo;s free static-site hosting. ","permalink":"https://griffinai.dev/sessions/2026-06-16-session-site-setup/","summary":"\u003ch1 id=\"session-brief--16-june-2026\"\u003eSession brief — 16 June 2026\u003c/h1\u003e\n\u003cp\u003eScope: installing the toolchain, scaffolding the Hugo site, configuring it,\nadding the legal pages and post template, and pushing the source to GitHub under\na separate identity. Covers Phases 1–5 of the build.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"hugo-extended\"\u003eHugo Extended\u003c/h2\u003e\n\u003cp\u003eHugo is a static site generator. Posts are written as plain Markdown files; Hugo\nconverts them into a complete website (HTML and CSS) that any browser can serve.\u003c/p\u003e\n\u003cp\u003eHugo ships in two editions, standard and extended. The extended edition processes\nSCSS/Sass stylesheets, which most themes — including PaperMod — require. The\nstandard edition fails on those themes with an SCSS error. Extended was installed.\u003c/p\u003e","title":"Session brief — Site setup and first push"},{"content":"I\u0026rsquo;m Niall Griffin, an ACCA-qualified financial accountant based in Ireland, with a background in audit and accounting. Outside of work I\u0026rsquo;ve become increasingly interested in what AI can actually do — not the hype, but the practical reality of building and using these tools.\nThis blog is where I document that. It runs across a few threads: projects I\u0026rsquo;m building (like GrantCraft, an AI-assisted grant tool for Irish community groups), the tools and infrastructure I\u0026rsquo;m using, AI applied to community and voluntary work, and the occasional broader thought on where automation and optimisation are taking the accounting profession.\nI\u0026rsquo;m not writing to a schedule and I\u0026rsquo;m not selling anything. I do this because I find it genuinely interesting, and because writing things down is how I think.\nViews here are my own and don\u0026rsquo;t represent my employer. Nothing on this site is financial or accounting advice.\n","permalink":"https://griffinai.dev/about/","summary":"About Niall Griffin","title":"About"},{"content":"The views and opinions expressed on this site are my own and do not represent those of my employer or any organisation I\u0026rsquo;m associated with.\nPosts here are written from personal interest and experience. Nothing on this site is professional, financial, accounting, or legal advice, and it shouldn\u0026rsquo;t be relied on as such. If you need advice for your own situation, talk to a suitably qualified professional.\nWhere I write about tools, models, or services, I\u0026rsquo;m describing my own experience at a point in time. Things change quickly in this space, so do your own checking before acting on anything you read here.\n","permalink":"https://griffinai.dev/disclaimer/","summary":"Disclaimer","title":"Disclaimer"},{"content":"This is a personal blog. I\u0026rsquo;ve tried to keep it simple and to collect as little about you as possible.\nHosting. The site is hosted on GitHub Pages. Like most web hosts, GitHub may log standard technical information such as IP addresses for security and operational purposes. See GitHub\u0026rsquo;s own privacy documentation for detail.\nAnalytics. I don\u0026rsquo;t currently run any analytics or tracking on this site. If that changes, I\u0026rsquo;ll update this page to say what\u0026rsquo;s used and why before turning it on.\nCookies. This site doesn\u0026rsquo;t set tracking cookies of its own.\nContact. If you get in touch with me via a link on this site (for example LinkedIn), any information you share is handled by that platform under its own privacy terms, not mine.\nYour rights. If you\u0026rsquo;re in the EU/EEA, you have rights over any personal data relating to you under the GDPR. As this site collects no personal data directly, there\u0026rsquo;s little for me to hold — but if you ever have a question, reach out via the contact links.\nLast updated: {{ now.Format \u0026ldquo;January 2006\u0026rdquo; }}\n","permalink":"https://griffinai.dev/privacy/","summary":"Privacy information for this site","title":"Privacy"}]