Ink & Ember / Arnow Solutions

Romance & suspense writing academy · live at ink-and-ember.srv1738752.hstgr.cloud · audited 2026-09-15 · full 00–35 artifact run

Verdict: PASS — production-ready personal platform

Honest overall 7.0 / 10 = min(rubric 7.2, quality-gate matrix 7.0). The teaching product itself is excellent — the published app and its source are byte-identical, the curriculum data layer is 100% valid, every live probe (auth, progress, AI critic) passed. Two things hold the score at 7: a dead "Next Passage" button in one game, and zero scheduled backups of the single SQLite store that holds ALL learner progress. Both fixes are small; both are in the 2-week sprint below.
7.0/10

Evidence base

  • Live production probes: login, RBAC (403 verified), progress persistence, AI critic (4.0s, real JSON)
  • Served copy = repo source (md5 verified both HTML and backend)
  • Curriculum integrity: 0 violations across 6 tracks / 75 sections / 46 check questions
  • Dogfood bug-hunt + 13 views walked at 390×844 · 0 unexpected console errors
  • XSS injection probe on user-written drafts: escaped, no execution

Scorecard — 11 dimensions

Architecture
8.0
Correctness
7.0
Security
7.0
Design / UX
7.5
Testing
4.0
Performance
8.0
Ops
6.0
Docs
7.0
Conversion
6.5
DX
6.5
Brand
9.0
Anchor reasons (from the mechanical matrix, artifact 25): Correctness 7.0 — one live dead-button bug. Ops 6.0 — no DB backup cron + no /api/health. Testing 4.0 — zero automated tests (real evidence: no test files, no CI). Design 7.5 — one AA contrast miss. All dimensions measured, none estimated; Design/Performance held under the cap rules with real journey evidence.
Phase 10a mechanical gate (design audit, run 2026-09-15): impeccable_detect.sh47 anti-pattern patterns + 1 advisory. Waived as deliberate brand identity: cream palette + Fraunces/Inter. Backlogged: 13 sub-AA contrast sites (the runtime miss was one of thirteen soft-ink metatexts at 3.1–3.2:1), 8 kicker-over-heading patterns, 9 left-border "side-tab" cards, 6 bottom-tab labels at 9.5px (below the 11px legibility floor — new P2). Full evidence in artifact 10a; all non-waived findings folded into the sprint.

Findings Heatmap

Dimension
P0
0
P1
2
P2
6
P3
4
Correctness
·
1
1
1
Ops / DR
·
1
2
1
Design / UX
·
·
1
2
Security
·
·
2
·
Testing / DX
·
·
·
·

Testing/DX deductions are system-level (no suite, no git), not per-finding. Full dimension×severity detail in artifact 12.

P1 — must fix 2 findings

1 · Find-the-Flaw: "Next Passage" button is dead

The button calls nextFlawPassage(), which no fragment defines. Clicking it after finishing a passage throws ReferenceError and nothing advances — the player must find the "New Passage" ghost button instead. Harvested live as a pageerror during the walkthrough.

Fix: define nextFlawPassage() as clear-score → newFlawPassage(). 15 minutes, include a regression step in the smoke harness.

2 · arnow.db has zero scheduled backups

/root/backup-db.sh (3 AM cron) covers Postgres only. The single SQLite store holding every lesson pass, capstone draft, and reflection is unprotected against host loss. A manual probe confirmed sqlite3 .backup works on the VPS — the fix is one line in an existing script + one restore drill.

P2 — should fix 6 findings

FindingEvidenceWhere
.author-desc contrast 3.29:1Computed pair on author cards — below AA 4.5:1Learn grid sublines
No /api/health on app backendGET /api/health → 404 (critic backend HAS one)accounts.py
CORS wildcard + allow_credentials=Trueaccounts.py:30-36middleware
Empty lesson submit shows no inline feedbackDogfood D1: submit with zero answers → silencelesson engine
Admin view reachable-but-blank for regular usersNav shows tab; API correctly 403s; learner lands on a dead screenadmin view
Source tree not under gitNo history, no rollback pathrepo root

P3 — polish 4 findings

  • Seed passwords appear in module docstring (accepted single-user trade-off)
  • curriculum-v2.json unused legacy file in repo root
  • .mpFilters chips slightly under 44 px tap target
  • Critic fallback echoes raw model output on malformed JSON (truncate instead)

Quick wins (time-boxed)

  • Day 1: nextFlawPassage fix + regression step in harness — 15 min
  • Day 1: arnow.db cron line in backup-db.sh + one restore drill — 30 min
  • Day 2: contrast token darken — 20 min
  • Day 2: /api/health endpoint — 15 min
  • Day 3: CORS origins pinned to the 2 known hosts — 15 min
  • Day 3: git init + first commit — 10 min

Phases: Static audit (00–12)

PhaseHeadline
01–02 Profile & ArchitectureSingle-file app + 2 small FastAPI services + SQLite; clean boundaries; build contract enforced by build_v3.py
03 Code review10 numbered findings; auth & lesson engine praised; the dead-button found here
04 Dependencies3 deps, all used, zero supply-chain surface in the browser bundle
05 Test healthNo suite/CI; testing anchored at 4.0; harness promoted as sprint item
06 DocumentationExcellent ops docs in the skill; repo needs its own README
07 TypeScriptN/A — vanilla JS equivalent-pass (syntax valid, 0 runtime errors)
08 API surfaceAll frontend fetches resolve to real routes; 1 API-only route idle
08a Data integritySeed-live drift: none; backup gap (P1) sits here
09 MobileZero overflow at 390; all touch targets ≥48; 1 contrast miss
10 Bundle795 KB single file = the curriculum content; 286 KB gzip; 735 ms load
10a/10b DesignWarm editorial light theme rules: all 6 PASS; strategy forward is print-artifact + motion-ease
11–12 Roadmap & backlog2-week sprint + 6-month vision; 12-point backlog

Phases: Advanced (13–30)

PhaseScoreHeadline
13 Event architecture7.5Timer hygiene clean; debounced sync races handled
14 Multi-tenancy7.0Server-side identity threading; RBAC verified live
15 Contract tests5.06/6 API shapes verified manually; schema-snapshot test recommended
16 Accessibility7.0Strong keyboard/touch/labels; 1 AA contrast miss
17 IaC & deploy6.5systemd + Traefik solid; deployment procedure skill-only
18 Observability5.5Logs clean; missing health endpoint + no alerting
19 Compliance6.0No PHI/PCI; public critic endpoint noted (rate-limit note)
20 Onboarding6.5In-product excellent; repo README missing
21 Disaster recovery5.0App stateless-easy; the ONE data store unprotected (P1)
22 Performance8.0735 ms / 757 nodes / 0.04 s TTFB measured
23–24 Remediation & loopFixes deferred to sprint window; loop exits PARTIAL, projected 8.2 post-sprint
25 Quality-gate matrix7.020 checks, 18 PASS, real evidence each — honest anchor of the overall
26 Visualization7.5All dashboard numbers derived from live state; zero fake-data class
27 UX failures sweep7.01 dead button hit; confirm-protected destructive op correct
28 Above-the-fold8.0Login + first dashboard self-explanatory, mobile-fit with no scroll
29 Page flow7.57 journeys walked; 6 clean, 1 broken at final step
30 Integration probes18/20 live checks PASS; md5 deployment-identity proven

Lenses (31–35)

LensHeadline
31 Role experienceAdmin-lacks-nav-hiding is the only friction; roles otherwise clean
32 Logic & policyAll teaching-gate math verified (pass rules, capstone gates, flaw scoring = observed values); critic score clamp suggested
33 Operational reportingZero fake-data; gap = no export; "time-spent" report is ripe (data already stored)
34 Baseline dispositionRun is the baseline; all skill-history incidents dispositioned RESOLVED with live proof
35 Design & motion (live)13 views walked at 390×844 + dogfood; publishing-house identity coherent (9.0); contrast + motion notes; theme-toggle N/A by design

Strategic Roadmap

2-week sprint

Days 1–3: the six quick wins above. Days 4–5: pytest-ify the smoke harness (3 assertions: lesson pass, flaw-next regression, capstone gate). Days 6–9: inline empty-submit feedback + hide admin nav by role. Day 10: print-capstone stylesheet start.

6-month vision (what to add next)

  • Anthology export — capstones become typeset, printable "author's anthology" extracts with shareable no-login links
  • Daily commitment layer — 20-minute writing streaks; habit beats intensity for a 10K-books/month goal
  • Curriculum tier 2 — 6 more deep lessons per author + a true Suspense track; the content pipeline is proven to scale
  • Coach intelligence — index the learner's own drafts: "you lean on filter verbs in high-tension scenes"; author-voice practice prompts
  • Time-instrument report — "when you actually write" (event timestamps exist already)
  • Multi-learner mode — only when the academy grows; single-learner design is the product's strength

Backlog (12 points)

IDStoryPtsTag
BL-1Learner finishing a flawed passage wants to advance without leaving the tab → define nextFlawPassage()1P1
BL-2Admin wants progress survivable → arnow.db in daily backup + restore drill2P1
BL-3Learner reads author sublines in sun → contrast ≥4.5:11P2
BL-4Operator wants status probe → /api/health1P2
BL-5Security → pin CORS origins1P2
BL-6Learner clicks Check too early → inline prompt2P2
BL-7Regular user never sees a blank admin screen → hide tab by role1P2
BL-8Maintainer wants rollback → git init1P2
P3 batchLegacy file removal · docstring passwords · chip targets · critic clamp2P3

Forward-looking recommendations

New features (ranked by ROI)

  1. Anthology/capstone export — the app's signature print artifact; differentiates it from every generic writing app
  2. Streak habit layer — cheapest behavior lever, data exists
  3. Second curriculum tier — highest long-term value; pipeline validated
  4. Draft-pattern intelligence — the "coach that knows your writing" is the differentiator the AI backend enables

UI / design & graphics

  1. Reading-position rail on lessons-in-progress (bookish, small)
  2. Lesson-modal 150 ms custom-bezier ease (motion polish)
  3. Critique results as an "editor's letter" typography treatment (looks like a letter from a mentor)
  4. Print stylesheet (manuscript look) for any exercise/capstone
  5. Warm-duotone author portraits — the last text-only surface

Path to 9.0 (Artifact 36 — score-path)

StageWhat landsScoremin() held by
1 · Sprint (2 wks, 12 pts)BL-1 dead button · BL-2 backup · all 13 contrast sites · /api/health · CORS · git init · tab-label size · contract snapshot test8.2Correctness 8.5, Testing 5.5
2 · Verification layer (wk 3)pytest harness (5 flows) · make verify · kicker/side-tab polish8.7Testing 7.5, Ops 8.0
3 · CI + monitoring (wks 4–6)GitHub Actions (test+build+smoke on push) · uptime/health alerting on /api/health + critic · repo runbook + deploy.sh · critic hardening9.0Testing 9.0, Ops 8.5 (Conversion waived ≤7.0 by design)

Explicit non-goals (what 9.0 does NOT require): architecture rebuild, dark mode (brand waiver), compliance suite, redesign — the publishing-house identity already holds 9.0 brand. Full dimension×work math in artifact 36-roadmap-to-9.md.

Certificate of Compliance

Ink & Ember / Arnow Solutions

Full ce:full run · 00–35 artifacts · 2026-09-15
7.0 / 10
min(rubric 7.2, quality-gate matrix 7.0) · status: PASS with sprint conditions
0 P0 · 2 P1 · 6 P2 · 4 P3 · projected 9.0 via artifact 36 score-path (sprint 8.2 → +CI/verification 8.7 → 9.0)
Certification gates: architecture ✓ · security RBAC ✓ · data integrity ✓ ·
contract shapes ✓ · integration probes ✓ · curriculum integrity ✓
Conditional gates: ops (backup) · testing (no suite) — close in the 2-week sprint
Audited by the CE:full framework · run directory .hermes/ce/full/2026-09-15-ink-and-ember/ · all evidence live-probed 2026-09-15