| Timestamp | Outcome | Latency | Tokens | Raw note | Enhanced text |
|---|
How this timeline was assembled
By the morning after Jonathan's interview call, I already had the architecture sketched out: the stack, the commit order, how the failure paths should work. Before Claude Code wrote a single line, I pulled real context about my background at Space Genius from our Azure and ADO data. 136 commits, 170 PRs, 76 work items, all verified. I did not want a README that sounded like it came from a template. Every Space Genius reference in the final doc traces to a source I confirmed.
Three principles kept me honest while building. Failure-first: think about what breaks before what succeeds. Earn your complexity: use the simplest thing that handles the failure mode. Separate the responsibilities: API, service, and data stay in their own lanes. Every tech decision in the README traces back to one of these.
The Railway deploy gave me a day-of failure mode that ended up being a good story. NIXPACKS picked the wrong .NET version, then the container died before it could even print the error because the library needed to format the error was also missing. One line in the csproj fixed it. The deploy fight was failure-first in real time.
Once the site was live I locked it down. Any change from that point forward needed a branch, a local check, my approval, and a manual merge. The governance files themselves went through that same gate to get added to the repo. No direct pushes to main. This timeline went through the same process.
-
M01 | PHASE_0 | Pre-build architecture and planning Verified
Architecture plan written before the spec PDF arrived
April 20, 2026Architecture plan was authored from Jonathan's verbal description at the end of the interview, before the assignment PDF was emailed. The plan locked the three principles (Failure-First, Earn Your Complexity, Separate the Responsibilities), the 16-commit sequence, the failure-first request flow, the system prompt as file decision, and the hard rules including zero em dashes. The pre-spec planning window is the evidence that the architecture preceded the requirements.
Evidence: GranumAssignmentArchPlanv1.md present in project files. Plan content predates spec receipt per conversation record.
spec: Full 16-commit sequence, three principles, failure-first request flow, and hard rules all present in GranumAssignmentArchPlanv1.md.
conversation: Plan written from Otter AI transcript of Jonathan's verbal description before the assignment PDF was emailed.
git: needed from CC
-
M02 | PHASE_1 | Handoff preparation and context lock Verified
Hallucination guards, human gates, and AC verification all locked before CC touched the repo
April 21, 2026CLAUDE.md, PREFLIGHT.md, and SG_CONTEXT.md produced before CC wrote any code. Full audit of the assignment spec against the architecture plan confirmed every required item covered: enhance endpoint, history endpoint, interaction log, error handling, tests. All three bonus items confirmed in scope: SSE streaming, PII guard, frontend UI. Constants block added at the top of CLAUDE.md after a repo name drift (granum-text-enhancer to granum-assignment) and casing drift (CarmenReed lowercase variant) were spotted. Context lock complete before scaffold commit.
Evidence: CLAUDE.md, PREFLIGHT.md, SG_CONTEXT.md produced and downloaded from this session. AC checklist completed in conversation.
conversation: Three handoff files produced. AC and bonus item audit completed. Constants block added after repo name and casing drift were caught.
git: no repo artifact -- handoff files are external to the repo by design
-
M03 | PHASE_2 | Build execution Verified
16-commit build executed by CC, 22 of 22 tests green, em dash scan clean
April 21, 2026Full build executed by CC across 16 intentional commits. Every commit was a standalone working state. xUnit suite landed at 17 tests at the end of the original 16-commit build (M03 baseline); later hardening work (PR #9) grew the suite to 22 tests, all green. Em dash scan returned zero across every file. Python seed script populated 8 interactions per spec. Definition of Done items all satisfied. The build came in clean against the plan with no surprises.
Evidence: 16-commit sequence in arch plan. Test count and DoD verification reported by CC in this session.
spec: 16-commit sequence in COMMIT STRATEGY section of GranumAssignmentArchPlanv1.md.
conversation: CC reported 16 commits landed, 17 tests green at M03 baseline (grew to 22 after PR #9 hardening), em dash scan clean, DoD satisfied.
git: first commit 3510ac6 (init scaffold) through last commit 9658ccd (ADR README), exactly 16 commits verified against git log.
-
M04 | PHASE_3 | Deployment and verification Verified
Railway fight resolved: NIXPACKS SDK mismatch, then ICU globalization diagnosed, fixed by Dockerfile switch
April 21, 2026Railway build failed repeatedly. First failure: NIXPACKS provisioned .NET SDK 6 instead of 8 because the project file was not detected. Fixed by adding nixpacks.toml to force the correct SDK. Second failure: container crashed before managed code could run because ICU globalization libraries were absent. Same missing libraries also broke error formatting so the runtime could not print the exception. ICU/globalization was diagnosed as the proximate cause; tried InvariantGlobalization true in Api.csproj at 7795c29 as a one-line workaround, then reverted it 9 minutes later at 9c28d9d when it did not resolve the deploy. The fix that stuck was replacing Nixpacks with a Dockerfile at 06463e9, which guaranteed a full ICU-enabled runtime image. The deployment fight was failure-first architecture applied live to the deployment layer.
Evidence: Railway build logs pasted into session. InvariantGlobalization added then removed within the same fight; Dockerfile switch is the durable fix on origin/main.
conversation: Sequential Railway failures diagnosed in session. Root cause was ICU globalization missing, also masked by error formatting depending on the same library.
git: Full fight chronology: 175cf43 (force .NET 8 SDK), dd30bba (remove .nixpacks cache), b88e91b (correct start command), 7795c29 (add InvariantGlobalization -- failed experiment), 9c28d9d (remove InvariantGlobalization 9 min later), d39f7f0 (disable Nix dotnet auto-detect), 06463e9 (Dockerfile replaces Nixpacks -- fix that stuck). InvariantGlobalization is not present in the current Api.csproj on main.
-
M05 | PHASE_3 | Deployment and verification Verified
29 of 29 smoke tests passed, Railway green, GitHub Pages live, evidence committed
April 21, 2026All six smoke test categories passed: health endpoint, POST /enhance returning real enhanced text, GET /history showing seed data with pagination, PII rejection returning 422 with no stack trace, SSE streaming validated structurally, em dash scan clean on deployed files. Smoke test evidence committed to main as 02dc26d.
Evidence: 29/29 smoke test report in session. Commit 02dc26d confirmed by CC.
conversation: CC reported 29 of 29 smoke tests passed after Railway and Pages deploys. Evidence committed as 02dc26d.
git: 02dc26d smoke-test evidence commit confirmed in CC git log
-
M06 | PHASE_4 | LIVE and post-LIVE production work Verified
LIVE declared and governance baseline shipped as PR 1
April 22, 2026LIVE declared by operator at commit f8fa2ed with exact quote: I'm calling it LIVE now (timestamp it). All further edits are now consider production edits and will need a PR in GitHub that I merge manually. The baseline commit f8fa2ed was authored late on 2026-04-21 ET (early 2026-04-22 UTC); the LIVE declaration itself was made the following morning when the operator called the protocol into effect. Three governance files produced (PRODUCTION_WORKFLOW.md, UI_CHANGE_TEMPLATE.md, APPROVAL_LOG.md) and shipped as PR 1, merged at c1d3324 (files currently live under logs/ after the M08 cleanup moved them). Note: two different changes carried the number 2 in different contexts. The timeline-sync schema 1.1 skill upgrade was held back per the .claude/ never pushes policy and lives only on local main as commit b7edde1; separately, GitHub PR #2 (the timeline-rendering PR) was merged publicly at 8950dd7. APPROVAL_LOG.md baseline entry seeded. Production workflow has governed every commit since.
Footnote: f8fa2ed itself landed as a direct-to-main commit carrying the Granum branding and UI polish pass (inline SVG logo, Field Notes nav, DM Sans and JetBrains Mono fonts, restyled outcome badges). The PR gate was established in the same work session immediately after, making f8fa2ed the transition point where the production workflow began rather than a workflow violation.
Evidence: APPROVAL_LOG.md baseline entry. f8fa2ed LIVE baseline commit (authored 2026-04-21 ET). c1d3324 PR 1 merge commit.
conversation: Operator declared LIVE in session with exact quote captured. Three governance files produced and shipped through their own gate sequence as PR 1. Commit f8fa2ed predates the LIVE call by approximately 15 hours; the LIVE declaration is the protocol activation event, not the commit timestamp.
git: f8fa2ed LIVE baseline confirmed (authored 2026-04-21 21:30:26 ET). c1d3324 PR 1 merge commit confirmed by CC.
-
M07 | PHASE_4 | LIVE and post-LIVE production work Verified
AI Initiatives tab built (4 cards), then expanded to 12, design language propagated to other tabs
April 22, 2026AI Initiatives tab launched with 4 governance skill cards (brain-dump, sg-ticket-prep, lff, lff-prune) using state pills, pattern tags, and cream card aesthetic ported from the portfolio template. Later expanded to 12 cards across two new subsections: Agentic and Automated Workflows (4 cards) and RAG Implementations (4 cards). Original 4 cards preserved byte for byte and rewrapped in a Governance Skills subsection. State color system (production, build, design) visually validated for the first time across multiple states simultaneously. Assignment and History tabs then aligned to the same design language: cream card wrappers, mono uppercase coral labels, hero callouts with coral left borders, History status pills restyled to match. Brand red preserved on Submit and active tab underline as intentional separation: brand red equals action, coral equals structural accent. CSS scoped with .page-* prefix.
Evidence: AI Initiatives tab live on docs/index.html. 12 cards visible in 3 subsections. Tab styling alignment visible across Assignment and History tabs.
conversation: AI Initiatives tab built then expanded same day. Design language propagated to Assignment and History tabs in a follow-up styling pass.
git: initial tab c0cae36 (PR #3), 12-card expansion c725c1e (PR #5), tab styling alignment 213b27c (PR #6 -- shipped as its own PR, not bundled).
-
M08 | PHASE_4 | LIVE and post-LIVE production work Evidence partial
Cleanup misfire and Dockerfile recovery: live deploy down, restored from git history
April 22, 2026Pre-submission cleanup ran with two intentions: remove unused Docker files (per arch plan rule no Docker or CI/CD) and add a reference directory for assignment artifacts. Two things went wrong. First, a missed branch checkout landed the Docker-removal commit on the AI Initiatives feature branch instead of a dedicated cleanup branch. The reference directory was not shipped in the final state -- the arch plan lives at docs/GranumAssignmentArchPlanv1.md and no reference/ directory exists on origin/main. Second, the cleanup commit message asserted Railway deploys via NIXPACKS based on a misread of the arch plan rule, not the actual config. The actual railway.json said builder DOCKERFILE with dockerfilePath Dockerfile. Within minutes of the cleanup PR merging, the live Railway deploy died. Recovery: worktree-based cherry-pick of the Docker removal onto a proper cleanup branch, then fix/restore-dockerfile branch restored Dockerfile and .dockerignore from git history (git show 84d4861~1:Dockerfile). Live deploy back to green. Governance files later moved to logs/ (logs/PRODUCTION_WORKFLOW.md, logs/UI_CHANGE_TEMPLATE.md, logs/APPROVAL_LOG.md) during subsequent housekeeping. The lesson is the commit message lying to the codebase, not the missing file.
Evidence: Live Railway deploy failure observed within minutes of cleanup PR merge. Recovery commits on fix/restore-dockerfile branch. Reference 84d4861 cited as parent commit for Dockerfile restoration.
spec: Arch plan rule cited in cleanup commit message: no Docker or CI/CD. Misread relative to actual railway.json config.
conversation: Full incident narrated in session: misdirected cleanup, live deploy down, worktree-based recovery, Dockerfile restored from git show 84d4861~1.
git: Docker removal commit 84d4861 (note: commit itself is the removal; 84d4861~1 is the parent used by git show for restore). Dockerfile restore commit e61f685. PR #4 merge b15af4d.
-
M09 | PHASE_4 | LIVE and post-LIVE production work Verified
Streaming endpoint honesty: documented edge buffering, gated UI to localhost, did not chase the workaround
April 22, 2026Stream button confirmed broken on live deploy. Read-only diagnosis revealed the SSE endpoint was structurally correct, framing correct, flushing correct, frontend handler correct. Token-by-token streaming worked on localhost. Root cause traced to Railway routing through Fastly, which buffers chunked responses. The X-Accel-Buffering: no header set by the API is nginx specific and Fastly ignores it. Coalescing scaled with response length, the fingerprint of edge buffering rather than an application issue. Active decision NOT to chase the CDN workaround. Shipped with documented edge behavior instead. Stream button gated to localhost via JavaScript hostname check (visible at localhost / 127.0.0.1, hidden everywhere else). New README ADR section Streaming Endpoint: Documented Edge Behavior added covering what works, what is degraded, root cause, why documented not fixed, failure-first reasoning. Earn-your-complexity in the rejected-alternative direction.
See: README ADR "Streaming Endpoint: Documented Edge Behavior" in the repo root for the full decision record.
Evidence: Stream button gating in docs/index.html. README ADR section. Localhost vs live behavior reproducible.
conversation: Read-only diagnosis ruled out application layer. Root cause Fastly buffering. Active choice to document not work around. UI gated to localhost. README ADR added.
git: streaming gate and README ADR shipped together as f916c88 (PR #7 merge 19c7bc9).
-
M10 | PHASE_4 | LIVE and post-LIVE production work Verified
Final submission readiness: local DB reset, repo housekeeping, full verification pass
April 22, 2026Pre-submission database refresh: ran seed/seed.py locally to reset interactions.db to the clean 8-record seed state, replacing accumulated dev test history (50+ duplicate mowed the lawn entries from streaming-fix testing). The reset is a local operation: interactions.db is gitignored by design, so no commit was produced and the live Railway DB is unaffected by this run. The seed script itself is the durable artifact, already committed as part of the original 16-commit build (M03). Repo housekeeping: 5 merged feature branches deleted locally and on origin (feature/ai-initiatives-tab, chore/pre-submission-cleanup, fix/restore-dockerfile, feature/ai-initiatives-expand, docs/timeline-update-2026-04-22), 2 orphan CC worktrees removed, git worktree prune cleared metadata. End state: only main, only main worktree, fully synced to origin. Final verification pass hit every spec section live with curl: /health, POST /enhance happy path, validation failures (empty + over-2000), PII rejections (email + phone), GET /history with pagination, GET /enhance/stream as informational verification. Frontend visual checklist completed in browser across all 4 tabs. At M10 submission-readiness, dotnet test confirmed 17/17 green; subsequent PR #9 security hardening added tests and the current suite on origin/main is 22/22 green. Submission report generated to .reports/SUBMISSION_REPORT.md with every claim traced to a verification step. Streaming explicitly listed under Documented Constraints rather than Nice-to-Haves Implemented.
Evidence: Local seed/seed.py run completed against interactions.db (gitignored, no commit). Branch deletions confirmed on origin. .reports/SUBMISSION_REPORT.md generated with traced verifications.
conversation: DB refresh was a local seed operation (interactions.db is gitignored, no commit produced). Repo housekeeping (5 branches + 2 worktrees), full verification pass with curl across every spec section, dotnet test 17/17 at M10, submission report generated with every claim traced.
git: no DB commit exists -- interactions.db gitignored by design. Main commit count at M10 submission: 45. Current main commit count after PR #8, #9, and #10 post-submission work: 69 (51 first-parent merges). Branch deletion verified on origin.