Commit Graph
40 Commits
Author SHA1 Message Date
ducoterra 999cd7d6b8 replace em dashes with hyphens in visible page copy
Build and Push Container / build-and-push (push) Successful in 18s
Brain of Reese card description and the ServWaf preview code line
no longer use em dashes. (The two em dashes on the rewritten Huntington
bullet already shipped with the past-tense change.)

LLM-Generated: true
2026-10-23 13:28:41 -04:00
ducoterra f5f6d2322a unify experience bullets to past tense and reorder project cards
All timeline bullets now open with past-tense action verbs (Huntington
gerunds become Built/Created/Led; stray 'Lead a high-performing team'
becomes 'Led'). The Local AI Stack card moves to second position,
right after Brain of Reese; the test-locked grid test is updated in
the same change.

LLM-Generated: true
2026-10-23 13:28:33 -04:00
ducoterra a03dcc9e7e add validate.sh pipeline gate and audit convention notes
.agents/validate.sh is the commit gate: full E2E suite, container
security-header check, and repo-hygiene checks must all pass before a
phase is committed. AGENTS.md now documents the audit-driven
conventions (M-1 innerHTML/terminal input, M-2 simulated curl/wget,
M-4 security-header snippet, L-2 server_tokens) and the test-locked
featured-projects grid.

LLM-Generated: true
2026-10-23 13:27:40 -04:00
ducoterra ba7f5e7d06 bump @playwright/test to 1.63.0 (user-approved re-pin)
Re-pin to the cached chromium-1243 revision; full E2E suite green on
1.63.0. Approval recorded in the PLAN.md review history.

LLM-Generated: true
2026-10-23 13:27:30 -04:00
ducoterra 1fe932cf39 phase: 05_update_projects_section
Build and Push Container / build-and-push (push) Successful in 16s
**Phase 05 final pass — all 4 tasks already complete; verified phase-level criteria + docs. Repo 100% green.**

- Verified: 6 `project-card fade-in` cards; order Brain of Reese → Reverse Proxy → Dynamic DNS → Local AI Stack → Deployment Automation → ServWaf; `src/index.html` diff hunks (lines 293–538) all inside `#projects` (286–542).
- `./build.sh` → `Build complete: dist/` (exit 0); `npm test` → **48 passed, 0 failed**; `bash .agents/validate.sh` → **exit 0** (48 E2E + `HEADER CHECK PASSED` on `/`, `/index.html`, hashed CSS via podman + repo-hygiene gates). No linter exists in this repo (no `lint` script/eslint config). Coverage: no JS/CSS touched — vacuous per phase spec; E2E is the binding gate.
- Completion criteria: card count 6 in `src/` **and** `dist/` ✅ · first card "Brain of Reese" with `…/Experimental/brain-of-reese` href in `dist/index.html` ✅ · `grep -c "Self-Hosted Services\|Kubernetes Cluster" src/index.html` = **0** ✅ · AI card has vLLM/Gufo/llama.cpp + LocalAI/LiteLLM/Langfuse, no "Ollama" ✅ · regression test present in `tests/e2e/01-page.spec.js` and passing ✅ · `./build.sh && npm test` green (48 ≥ 45) ✅ · no edits outside `#projects` ✅ · README/AGENTS consistent ✅.
- Docs: README **updated** (new paragraph stating what the E2E suite covers, incl. the six featured cards, so future content edits update the matching test). AGENTS.md **updated** (convention: the `#projects` grid is test-locked by `01-page.spec.js`). All other README claims re-checked against reality (Dockerfile builds `dist/` internally, `listen 8080`, snippet `include`s, `check-headers.sh` port/paths/output, `--bind 0.0.0.0` config, Node ≥20 engine floor, CI `main`+tag publishing) — consistent.
- Notable: `.agents/validate.sh` is still **untracked** though AGENTS.md/README reference it — harness should `git add` it (I ran no git index commands). `.agents/PLAN.md` §4/§5 still say "44 tests" (suite is 48 since Phases 04/05); PLAN.md is off-limits, so this drift needs an explicit user-approved edit. No live-infrastructure touched.
- Next pending phase: none in `.agents/phases/todo/` (05 was last). Remaining unphased audit items (L-3 CSP `unsafe-inline`, L-5 SSH-key labelling, L-7 CI pinning, L-8 build.sh CI check) would need new phases via `phase-authoring`.
2026-10-23 01:32:52 -04:00
ducoterra 2f6f2dc0b9 phase: 04_huntington_role
Build and Push Container / build-and-push (push) Successful in 16s
**Phase 04 final verification — all green**

Implemented/verified
- Both phase tasks already complete (`complete/04_huntington_role/01`,`02`); this pass was final verification + docs.
- `src/index.html` HNB "Lead MLOps Engineer · Jun 2026 – Present" entry first with 3 bullets; Nimbis closed at `Jan 2022 – Apr 2026`.

Tests / lint / gate
- `./build.sh` → `dist/` rebuilt (9 hashed assets) · `npm test` → **47 passed, 0 failed**
- `bash .agents/validate.sh` → **exit 0**: 47/47 E2E, `HEADER CHECK PASSED` (real podman image, `/`, `/index.html`, hashed css), hygiene checks clean
- `node --check` all `src/*.js` + `tests/e2e/*.js` + `playwright.config.js` OK; `bash -n` on `build.sh`, `scripts/check-headers.sh`, `.agents/validate.sh` OK (no JS lint toolchain by design)

Completion criteria
- `grep -c "Huntington National Bank" dist/index.html` = **1**; `Jun 2026 – Present` at dist:118 — PASS
- Nimbis `Jan 2022 – Apr 2026` at dist:138; only one `– Present` in file — PASS
- Regression test `experience timeline leads with Huntington National Bank role` present at `tests/e2e/01-page.spec.js:28` and passing — PASS
- `./build.sh && npm test` fully green (47 ≥ 45) — PASS · No behavior change: terminal/vim/achievements/menu specs all pass — PASS
- Coverage >90% on new/modified code: vacuous (HTML + test only, no JS/CSS touched) — PASS

Documentation (fixed)
- README: `check-headers.sh` claimed "aborting at the first failing path" — it actually checks all three paths then exits non-zero; also added the real webServer command (`--bind 0.0.0.0`) and `npm run test:headed`.
- AGENTS.md: `innerHTML` allowance scoped precisely (only the `cmdText === 'neofetch'` branch in terminal.js; vim/achievements only static or `escapeHtml()`-escaped).

Notable: `.agents/PLAN.md` §4/§5 still say "44 tests" (now 47) — PLAN.md is locked to me; flagged for user approval.

Next pending phase: `.agents/phases/todo/05_update_projects_section`
2026-10-23 00:36:58 -04:00
ducoterra 47b7b4fc23 phase: 03_nginx_security_headers
Build and Push Container / build-and-push (push) Successful in 23s
**Phase 03 final verification — all green**

- Verified (all tasks already in `complete/`): snippet/Dockerfile/nginx.conf wiring, `scripts/check-headers.sh`, guardrail teeth, restored config byte-identical.
- Tests (full suite): `./build.sh` → OK; `npm test` → **46 passed, 0 failed**; `bash .agents/validate.sh` → **exit 0** (46/46 + `HEADER CHECK PASSED` + hygiene gates); no leftover podman images.
- Completion criteria:
  - `nginx-security-headers.inc` with 4 `add_header … always;` lines — ✅
  - `nginx.conf`: 0 inline security `add_header` (cache headers only), 3/3 locations `include` snippet — ✅
  - `server_tokens off;` in server block — ✅ (live proof: `Server: nginx`, no version)
  - `./scripts/check-headers.sh` → `HEADER CHECK PASSED`, OK on `/`, `/index.html`, hashed asset — ✅ (also confirmed all 4 headers + correct Cache-Control on 404 fallback)
  - `./build.sh && npm test` fully green — ✅
  - No behavior change (terminal/vim/achievements/menu suites) — ✅
  - Negative check re-run: dropping one `include` → `FAIL … on /style.<hash>.css`, exit 1 — ✅
- Docs: README.md & AGENTS.md reviewed in full against actual state (commands, ports 8123/18099, header mechanism, CI tags vs `.gitea/workflows/build-push.yml`, Node ≥20 engine floor, innerHTML/neofetch exception at `terminal.js:487`, simulated curl/wget guards) — **verified consistent, no changes needed**.
- Notable: check-headers.sh aborts at the first failing path via `set -e` before printing `HEADER CHECK FAILED` — README's wording matches this exactly (verified empirically). PLAN.md's "44 tests" count is stale (now 46) but PLAN.md is locked — left for the user.
- No live-infra changes (no HSTS in container; edge/Caddy untouched).
- Next pending phase: `04_huntington_role`.
2026-10-23 00:07:13 -04:00
ducoterra bcfaa1cac6 phase: 02_simulate_fetch_commands
Build and Push Container / build-and-push (push) Successful in 26s
All green. Final report:

**Phase 02 — final verification pass** (both tasks already in `.agents/phases/complete/02_simulate_fetch_commands/`)
- Verified: no `fetch(` remains in `src/` (grep exit 1) or in built `dist/*.js`
- Verified: `simulatedCurlOutput()` / `simulatedWgetOutput()` in `src/terminal-commands.js` (lines 63/73), wired into `src/terminal.js` curl/wget branches
- Verified: regression test `curl/wget are simulated — no real network request leaves the origin` in `tests/e2e/02-terminal.spec.js` — asserts simulated bodies, `web_navigator` toast + localStorage persistence, and zero non-`baseURL` requests
- Tests: `./build.sh` → OK; `npm test` → **46 passed, 0 failed** (≥46 required); `bash .agents/validate.sh` → **exit 0** (E2E + repo-hygiene gates)
- No linter configured beyond validate.sh (vanilla JS, LOCKED no-toolchain)
- Completion criteria: ①no `fetch(` ✅ ②simulators present ✅ ③regression tests present & passing ✅ ④build+test 46 green ✅ ⑤no behavior change (page/terminal/vim/achievements/menu suites all green) ✅
- Documentation: full README/AGENTS.md review — both already updated in working tree and consistent with the project (simulated curl/wget, validate.sh gate, Podman build flow vs Dockerfile, Node ≥20 matches `@playwright/test` engines, M-4 header gap correctly documented as pending Phase 03) — **verified consistent, no changes needed**
- Note: `PLAN.md` still says "44 tests" (now 46) but PLAN is locked — flagged for the harness/user, not edited
- Next pending phase: `03_nginx_security_headers`
2026-10-22 23:14:49 -04:00
ducoterra dcd066d953 phase: 01_fix_history_xss
Build and Push Container / build-and-push (push) Successful in 26s
**Phase 01 — final verification pass (all criteria green)**

- Verified M-1 fix in `src/terminal.js`: ArrowUp / ArrowDown(`>0`) / ArrowDown-else now route through `updateDisplay()` (`textContent`); no `innerHTML` sink touches `cmdLine`/`commandHistory`.
- `grep -n innerHTML src/terminal.js` → 12 hits, all allowed (static prompt literals, `clear`/prank wipes, `outLine.innerHTML = output` gated on the static canned `neofetch` string). **C1 ✓**
- XSS regression test at `tests/e2e/02-terminal.spec.js:156` present + passing; re-proved it is a real guard: re-injected the old `innerHTML` recall into `dist/terminal.*.js` → test failed (`#xss-marker` received 1); rebuild → byte-identical to `src/`. **C2 ✓**
- `./build.sh` → `dist/` OK; `npm test` → **45 passed (0 failed)**; `bash .agents/validate.sh` → **exit 0** (suite + repo-hygiene gates). **C3 ✓**
- Branch coverage of modified code: all 3 recall arms asserted (ArrowUp ×2 specs, ArrowDown `>0` in the existing history spec, ArrowDown-else → empty prompt in the new spec) → >90% gate met; no JS coverage/lint toolchain exists in the locked stack, so lint = `node --check src/*.js tests/e2e/*.js playwright.config.js` + `bash -n build.sh .agents/validate.sh` — clean.
- C4 ✓ terminal/vim/achievements/menu specs all green; only the three recall branches changed.
- Docs (step 6, full README/AGENTS review): README — run section now states the image already contains the built `dist/` (mount `dist/`, never `src/`); new “Serving & configuration” section for `nginx.conf`, incl. **empirically measured** (built image on 127.0.0.1:8124) that `/`, `/index.html` and hashed assets currently return *only* cache headers — the `add_header` non-merge gap = finding M-4/Phase 03; TLS/HSTS-at-edge rule; Quadlet section fixed (unit is not in this repo; Quadlet generates `homepage.service`, so `… start homepage.service`, and `systemctl enable` is a no-op for transient Quadlet units → `[Install]` + `daemon-reload` + linger); Development gained the Node 20+ floor, `npx playwright install chromium`, and `.agents/validate.sh`. AGENTS.md — added the validate.sh gate, flagged `./scripts/check-headers.sh` as not yet in the repo (Phase 03), and scoped the M-1 rule with the allowed-`innerHTML` list.
- Notable: `.agents/PLAN.md` still says “44 tests” (3 places) and its §7 roadmap omits phases 04/05 — left untouched per the no-PLAN-edit rule; flag for the next PLAN review. No live-infra touched (temp podman image built/removed for the header measurement only).
- Next pending phase: `02_simulate_fetch_commands`.
2026-10-22 22:45:40 -04:00
ducoterra a2f331e526 Add phased-execution planning structure
Build and Push Container / build-and-push (push) Successful in 11s
Introduce .agents/ (PLAN.md with locked architectural anchors,
phase roadmap under phases/todo/) and AGENTS.md rules for
agents working in the repo. Queues the pending phases: fix
history XSS, simulate fetch commands, and nginx security
headers.
2026-09-18 17:23:41 -04:00
ducoterra 010758b3e9 Move server rack inline styles to CSS classes
Replace the per-element inline positioning in createServerRack()
with rack-*-pos utility classes in style.css. Also stop drawing
a random switch face brand from a list (only Framework ships)
and simplify the hero-click terminal toggle to use the shared
expand/collapse helpers.
2026-09-18 17:23:37 -04:00
ducoterra 3898dc3c5e Add Playwright E2E suite against the built dist/
Pin @playwright/test 1.62.0 (matches the cached chromium
revision) and serve dist/ via python3 http.server, so the
deployed artifact is what gets tested. Covers page load,
terminal commands, vim mode, achievements, and the nav menu.
Ignore node_modules, test-results, playwright-report, and the
phased-execution runtime scratch (.agents/phase-sessions,
pipeline.log).
2026-09-18 17:23:30 -04:00
ducoterra 7f4f0b4ef1 Split terminal into flat command, achievement, and vim modules
Move canned command data (terminal-commands.js), the achievement
system (terminal-achievements.js), and the vim simulator
(terminal-vim.js) out of terminal.js, which keeps the core
terminal loop. Load order is fixed in index.html with the
modules before terminal.js. Also share expand/collapse helpers
with the hero click handler and drop the real fetch I/O in
favour of simulated curl/wget output.
2026-09-18 17:23:25 -04:00
ducoterra 2dcf44bc0b Update profile picture
Build and Push Container / build-and-push (push) Successful in 1m24s
2026-06-05 14:19:54 -04:00
ducoterra d95f6a1cd6 update favicon
Build and Push Container / build-and-push (push) Successful in 28s
2026-06-03 10:17:52 -04:00
ducoterra 136cf16cfd add favicon
Build and Push Container / build-and-push (push) Failing after 34s
2026-06-02 21:06:17 -04:00
ducoterra 2c1beda59f vim working
Build and Push Container / build-and-push (push) Successful in 1m1s
2026-05-31 14:45:49 -04:00
ducoterra 6cc2c8db3a add curl, wget, apt, and dnf
Build and Push Container / build-and-push (push) Successful in 18s
2026-05-31 00:28:21 -04:00
ducoterra 5f0cfbd4cb fix the help command 2026-05-31 00:18:39 -04:00
ducoterra d59d08b7e1 add tab autocomplete and cycling commands
Build and Push Container / build-and-push (push) Successful in 1m11s
2026-05-30 22:47:04 -04:00
ducoterra 13a7306d5b add formatting 2026-05-30 21:32:35 -04:00
ducoterra f34ac3210e I like trains
Build and Push Container / build-and-push (push) Successful in 39s
2026-05-28 21:58:56 -04:00
ducoterra f2246a3386 add actual profile picture
Build and Push Container / build-and-push (push) Successful in 19s
2026-05-28 17:02:01 -04:00
ducoterra 20100800a1 fade in and out terminal on focus
Build and Push Container / build-and-push (push) Successful in 28s
2026-05-28 16:33:56 -04:00
ducoterra 23ed5b510b fix menu fade in and server drive bay overflow
Build and Push Container / build-and-push (push) Successful in 28s
2026-05-28 16:28:46 -04:00
ducoterra 54746f4636 add cache busting
Build and Push Container / build-and-push (push) Successful in 16s
2026-05-28 16:01:42 -04:00
ducoterra 6a30145171 accessibility updates 2026-05-28 15:44:42 -04:00
ducoterra 96034abeea remove redundant css classes
Build and Push Container / build-and-push (push) Successful in 27s
2026-05-28 15:29:41 -04:00
ducoterra ee2f8a34b3 have terminal grow on focus to allow better mobile input
Build and Push Container / build-and-push (push) Successful in 26s
2026-05-28 15:13:08 -04:00
ducoterra 28feb0e50e clean up nginx.conf
Build and Push Container / build-and-push (push) Successful in 21s
2026-05-28 14:03:22 -04:00
ducoterra 02f2b0ef49 don't cache so hard
Build and Push Container / build-and-push (push) Successful in 14s
2026-05-28 13:41:48 -04:00
ducoterra 79c491d7ee add achievements
Build and Push Container / build-and-push (push) Successful in 1m19s
2026-05-28 13:02:10 -04:00
ducoterra 5004b68817 fix mobile keyboard
Build and Push Container / build-and-push (push) Successful in 36s
2026-05-28 11:40:41 -04:00
ducoterra 74edb71167 destructo mode
Build and Push Container / build-and-push (push) Successful in 37s
2026-05-28 10:45:18 -04:00
ducoterra b12029da81 add server background with working terminal
Build and Push Container / build-and-push (push) Successful in 31s
2026-05-28 10:29:02 -04:00
ducoterra 2c6cd1c45b add work experience section
Build and Push Container / build-and-push (push) Successful in 23s
2026-05-28 09:18:58 -04:00
ducoterra f62b530277 add profile picture
Build and Push Container / build-and-push (push) Successful in 40s
2026-05-27 23:03:08 -04:00
ducoterra 44e196d6b0 add gpg keys to website
Build and Push Container / build-and-push (push) Successful in 33s
2026-05-27 22:52:14 -04:00
ducoterra a9c8147296 update gitea link to take you to the homelab project
Build and Push Container / build-and-push (push) Successful in 22s
2026-05-27 22:38:55 -04:00
ducoterra 43bae61c0a init
Build and Push Container / build-and-push (push) Successful in 23s
2026-05-27 21:52:36 -04:00