Skip to main content

Phase 2 Implementation Guide — Gold Standard Project & Credibility Baseline

Phase: Phase 2 (Credibility & Quality Foundation)
Estimated Duration: 19–32 hours (2–4 weeks at 10–15 hrs/week)
Status: ✅ Complete (2026-01-21)
Last Updated: 2026-01-21

Purpose​

Phase 2 establishes credibility by transforming the Portfolio App from a "professional foundation" into a demonstrable showcase of senior-level engineering discipline. Rather than building many mediocre examples, Phase 2 creates one exemplary "gold standard" project with comprehensive evidence: complete dossier, threat model, operational runbooks, automated testing, and governance artifacts. This sets the quality bar for all future portfolio entries.

What Phase 2 Delivers​

  • Gold standard project selection: Portfolio App chosen as the exemplary case study (documented in ADR-0010)
  • Smoke test infrastructure: Playwright E2E tests with 100% route coverage, integrated into CI pipeline
  • Enhanced Portfolio App dossier: Comprehensive 7-page documentation covering architecture, security, deployment, testing, operations, and troubleshooting
  • Threat model: Complete STRIDE analysis with mitigations, controls, and residual risks
  • Operational runbooks: Deploy, CI triage, rollback, and secrets incident response procedures
  • Security hardening: Secrets scanning (TruffleHog), CI permission hardening, pre-commit hooks
  • Enhanced project pages: Gold standard badge component, verification checklists, evidence links
  • Meaningful CV page: Capability-to-proof mapping with deep links to evidence artifacts
  • Phase 2 completion artifacts: Release notes, compliance reports, updated roadmap

Prerequisites​

Before starting Phase 2, ensure:

  • ✅ Phase 1 complete and verified (Portfolio App deployed with CI/CD governance)
  • ✅ ADR-0010 documented (gold standard project decision)
  • ✅ GitHub issues created in both repos (portfolio-app #9, portfolio-docs #24)
  • ✅ Development environment ready (pnpm, Node.js, local testing capabilities)
  • ✅ Portfolio-docs build infrastructure operational

Verification checklist:

# Verify Phase 1 state
cd portfolio-app
git pull origin main
pnpm install
pnpm lint && pnpm format:check && pnpm typecheck && pnpm build
# All should pass

# Verify docs build
cd portfolio-docs
pnpm build
# Should complete without errors

Implementation Approach​

Phase 2 follows a sequential steps implementation pattern, where each step builds on the previous to create a comprehensive evidence foundation. The steps are organized chronologically as they were executed, with all completion status and outcomes documented.


Implementation Steps (Completed)​

STEP 1: Decide on the "Gold Standard" Project ✅ (1–2 hours)​

Goal: Choose which project will be your exemplary case study.

Options:

  • portfolio-app itself (what you're building now): Advantage—already deployed, live evidence, deep governance records
  • portfolio-docs (the documentation system): Advantage—also deployed, demonstrates ops maturity
  • A past project (if public/shareable): Advantage—potentially more complex real-world example
  • A mini-demonstration project (written as part of Phase 2): Advantage—can be designed specifically to showcase capabilities

Recommendation for your situation: Start with portfolio-app as the gold standard. Rationale:

  • Already deployed and operational
  • Demonstrates full SDLC (Phase 1 already documented)
  • Can showcase governance, testing, observability
  • Sets precedent for all future projects

Action items:

  1. ✅ Decision documented in ADR-0010 — see ADR-0010: Portfolio App as Gold Standard Exemplar

    • Portfolio App selected as the exemplary project
    • Rationale, consequences, and implementation approach documented
    • Alternatives considered and rejected
  2. Create GitHub issue in portfolio-app repo titled: Phase 2: Portfolio App as Gold Standard Exemplar Project

    • Issue template: GITHUB_ISSUE_TEMPLATE_PHASE2.md
    • Tracks all Phase 2 deliverables (portfolio-app + portfolio-docs)
    • Links to ADR-0010
    • Assign to yourself; label phase-2
  3. Create GitHub issue in portfolio-docs repo for documentation work

    • Dossier, threat model, runbooks, ADR, release note
    • Link back to portfolio-app issue for cross-repo visibility

Success check:


STEP 2: Set Up Smoke Test Infrastructure ✅ (3–5 hours)​

Goal: Create test infrastructure that validates core routes, content, and evidence links.

Tools: Playwright (recommended) or Vitest for unit-style content validation

Implementation:

2a. Install test dependencies​

cd portfolio-app
pnpm add -D @playwright/test

2b. Create Playwright configuration​

Create playwright.config.ts at repo root:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './tests/e2e',
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
],
webServer: process.env.CI
? undefined
: {
command: 'pnpm dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});

2c. Create smoke test suite​

Create tests/e2e/smoke.spec.ts:

import { test, expect } from '@playwright/test';

const ROUTES = [
{ path: '/', title: 'Portfolio App' },
{ path: '/cv', title: 'CV' },
{ path: '/projects', title: 'Projects' },
{ path: '/contact', title: 'Contact' },
{ path: '/projects/portfolio-app', title: 'Portfolio App' },
];

test.describe('Smoke tests', () => {
ROUTES.forEach(({ path, title }) => {
test(`Route ${path} should render`, async ({ page }) => {
const response = await page.goto(path);
expect(response?.status()).toBeLessThan(400);
// Basic content check
expect(page.locator('h1')).toBeTruthy();
});
});

test('Evidence links resolve to docs', async ({ page }) => {
await page.goto('/projects/portfolio-app');
const docsLink = page.locator('a[href*="/docs/"]').first();
expect(docsLink).toBeTruthy();
});

test('Project registry has no broken slugs', async ({ page }) => {
const { PROJECTS } = await import('../src/data/projects');
for (const project of PROJECTS) {
const response = await page.goto(`/projects/${project.slug}`);
if (project.status !== 'planned') {
expect(response?.status()).toBeLessThan(400);
}
}
});
});

2d. Add test script to package.json​

{
"scripts": {
"test": "playwright test",
"test:ui": "playwright test --ui",
"test:debug": "playwright test --debug"
}
}

2e. Add tests to CI workflow​

Update .github/workflows/ci.yml to include:

- name: Run smoke tests
run: pnpm test
continue-on-error: false

2f. Update .gitignore​

test-results/
playwright-report/

Success check:

  • Playwright installed and configured
  • Smoke test suite runs locally: pnpm test
  • Tests pass on pnpm dev server
  • Test script added to package.json
  • Tests integrated into CI workflow
  • PR created with test infrastructure (PR #10)

Files to create/modify:

  • playwright.config.ts (new)
  • tests/e2e/smoke.spec.ts (new)
  • package.json (update scripts)
  • .github/workflows/ci.yml (add test step)
  • .gitignore (add test results)

STEP 3: Enhance Portfolio App Dossier to Gold Standard ✅ (4–6 hours)​

Goal: Enhance the existing 7-file dossier structure with gold standard content, following the established project dossier contract.

Location: /portfolio-docs/docs/60-projects/portfolio-app/ (existing dossier files)

Approach: The portfolio-app dossier already exists with the standard 7-file structure. This step enhances each file with comprehensive "gold standard" content that demonstrates senior-level engineering discipline.

Dossier Contract (from /docs/60-projects/index.md):

  • ✅ 01-overview.md — purpose, audiences, NFRs, evidence strategy
  • ✅ 02-architecture.md — system design, content model, component boundaries
  • ✅ 03-deployment.md — CI/CD, environments, release governance
  • ✅ 04-security.md — threat surface, controls, validation
  • ✅ 05-testing.md — quality gates, test strategy, coverage
  • ✅ 06-operations.md — runbooks, maintenance, recovery
  • ✅ 07-troubleshooting.md — failure modes, diagnostics, fixes

3a. Enhance 01-overview.md with executive summary and key metrics​

Add/Update sections:

## Executive Summary

The Portfolio App is a production TypeScript web application that serves as an interactive CV and project showcase, intentionally designed to demonstrate enterprise-grade engineering discipline. Built with Next.js and deployed on Vercel with comprehensive CI/CD governance, it proves competency across modern web development, security hygiene, operational maturity, and evidence-first documentation practices.

**Key value:** Not just a portfolio site—a working exemplar of how senior engineers build, secure, operate, and document production systems.

## Key Metrics (Phase 2 Baseline)

- **Lines of code:** ~500 (application), ~200 (tests)
- **Routes:** 5 core routes (/, /cv, /projects, /contact, /projects/[slug])
- **CI checks:** 2 required (quality, build)
- **Test coverage:** 100% route coverage (Playwright smoke tests - 12 tests)
- **Deployment frequency:** On every merge to main (automatic)
- **Mean time to rollback:** ~1 minute (Git revert + CI)
- **Quality gates:** Lint, format, typecheck, build, smoke tests (all enforced)
- **Dependencies:** 17 production, 11 dev (Dependabot weekly updates)

## What This Project Proves

### Technical Competency

- Modern full-stack web development (Next.js 15+, React 19+, TypeScript 5+)
- Component-driven architecture with App Router
- Responsive design with Tailwind CSS
- Evidence-first UX (deep links to documentation)

### Engineering Discipline

- CI quality gates (ESLint max-warnings=0, Prettier, TypeScript strict)
- Automated smoke testing (Playwright multi-browser)
- Frozen lockfile installs (deterministic builds)
- PR-only merge discipline (GitHub Ruleset enforcement)

### Security Awareness

- Public-safe by design (no secrets, internal endpoints, or auth)
- CodeQL + Dependabot enabled (supply chain hardening)
- Environment variable hygiene (documented, validated)
- PR template security checklist

### Operational Maturity

- Deploy/rollback runbooks (tested and documented)
- CI triage procedures (deterministic troubleshooting)
- Vercel production promotion gating (required checks)
- Evidence-based release notes

### Documentation Excellence

- Complete dossier (7 comprehensive pages)
- ADRs for durable decisions (hosting, CI gates, gold standard choice)
- Threat model (STRIDE analysis - Step 4)
- Operational runbooks (deploy, CI triage, rollback)

Files to update:

  • docs/60-projects/portfolio-app/01-overview.md

3b. Enhance 02-architecture.md with detailed technology stack and flow diagrams​

Add/Update sections:

## Technology Stack (Complete Inventory)

### Core Framework

- **Next.js:** v16.1.3 (App Router, React Server Components, static optimization)
- **React:** v19.2.3 (concurrent features, automatic batching)
- **TypeScript:** v5+ (strict mode, noEmit for type-only checks)

### Styling & UI

- **Tailwind CSS:** v4 (utility-first, JIT compilation)
- **@tailwindcss/postcss:** v4 (CSS processing)
- **CSS Modules:** Built-in (component-scoped styles)

### Build & Development

- **pnpm:** v10.0.0 (fast, efficient, frozen lockfiles in CI)
- **Next.js Compiler:** SWC-based (Rust, faster than Babel)
- **React Compiler:** babel-plugin-react-compiler v1.0.0 (optimization)

### Testing & Quality

- **Playwright:** v1.57.0 (E2E smoke tests, multi-browser)
- **ESLint:** v9 (flat config, Next.js presets, TypeScript integration)
- **Prettier:** v3.8.0 (code formatting, Tailwind plugin)
- **wait-on:** v9.0.3 (dev server readiness in CI)

### CI/CD & Governance

- **GitHub Actions:** Quality + build jobs
- **Vercel:** Preview + production deployments
- **CodeQL:** JavaScript/TypeScript security scanning
- **Dependabot:** Weekly dependency updates (grouped, majors excluded)

### Notable Decisions

- **No authentication:** Intentionally deferred (public portfolio)
- **No database:** Static content model (scalable via data files)
- **No form backend:** Contact via static methods (email link)
- **Evidence links:** Deep integration with Docusaurus documentation

## High-Level Request Flow

┌─────────────┐ │ Browser │ └──────┬──────┘ │ HTTPS GET /projects/portfolio-app ↓ ┌─────────────────────┐ │ Vercel Edge │ (CDN, SSL termination) └──────┬──────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ Next.js App Router │ │ - Route: /projects/[slug] │ │ - Server Component (async params) │ │ - getProjectBySlug(slug) │ │ - notFound() if missing │ └──────┬──────────────────────────────┘ │ ↓ ┌─────────────────────────────┐ │ Project Data (src/data/) │ │ - PROJECTS array │ │ - Static metadata │ └──────┬──────────────────────┘ │ ↓ ┌──────────────────────────────────┐ │ Component Rendering │ │ - Section components │ │ - Evidence links (to /docs) │ │ - Tailwind styling │ └──────┬───────────────────────────┘ │ ↓ ┌──────────────────────┐ │ HTML Response │ (static-optimized, RSC payload) └──────────────────────┘


## Component Architecture

src/ ├── app/ # Next.js App Router │ ├── layout.tsx # Root layout (global nav, metadata) │ ├── page.tsx # Landing page (/) │ ├── cv/ │ │ └── page.tsx # CV route │ ├── projects/ │ │ ├── page.tsx # Projects list │ │ └── [slug]/ │ │ └── page.tsx # Dynamic project detail │ └── contact/ │ └── page.tsx # Contact page ├── components/ # Reusable components │ ├── Section.tsx # Content section wrapper │ └── Callout.tsx # Highlighted content blocks ├── data/ │ └── projects.ts # Project registry (typed) └── lib/ └── config.ts # Environment config helpers


## Scalability Patterns

**Current (Phase 2):**
- Static project data in TypeScript (typed, version-controlled)
- Manual content updates via code changes + PRs
- Evidence links hardcoded per project

**Planned (Phase 3+):**
- CMS or API-driven project data (Contentful, headless CMS)
- Automated evidence link validation
- Tag-based filtering and search

Files to update:

  • docs/60-projects/portfolio-app/02-architecture.md

3c. Update 04-security.md with public-safety rules and controls​

Add/Update sections:

## Public-Safety Rules (Enforced)

### Environment Variables

- ✅ All `NEXT_PUBLIC_*` variables are client-visible by design
- ✅ No secrets in any `NEXT_PUBLIC_*` variable
- ✅ `.env.example` documents all required variables
- ✅ Local `.env.local` gitignored

**Validation procedure:**

```bash
# Check for secrets in env vars
grep -r "NEXT_PUBLIC.*SECRET\|NEXT_PUBLIC.*KEY\|NEXT_PUBLIC.*TOKEN" src/
# Should return: no results
```

Code Scanning​

  • ✅ CodeQL enabled (JavaScript/TypeScript)
  • ✅ Runs on every push to main and PR
  • ✅ Scans for: SQL injection, XSS, path traversal, hardcoded secrets

Supply Chain Security​

  • ✅ Dependabot enabled (weekly updates, grouped by type)
  • ✅ Major version updates excluded (manual review required)
  • ✅ Lockfile formatting automated (prevents CI failures)
  • ✅ Frozen lockfile installs in CI (--frozen-lockfile)

PR Security Checklist​

Every PR must confirm:

  • No secrets added
  • No sensitive endpoints added
  • Environment variables documented in .env.example
  • CodeQL scan passes

Known Limitations & Accepted Risks​

Out of Scope (Intentional)​

  • No authentication: Public portfolio, no user accounts
  • No backend processing: Static content, no server-side logic
  • No database: No persistent user data or state
  • No contact form backend: Email link only (prevents spam/abuse surface)

Residual Risks (Acceptable)​

  • Dependency vulnerabilities: Mitigated by Dependabot + CodeQL
  • DDoS: Mitigated by Vercel's edge network
  • Content injection: Not applicable (static content, no UGC)

**Files to update:**
- `docs/60-projects/portfolio-app/04-security.md`

---

#### 3d. Verify other dossier files are complete

**Already comprehensive (no major changes needed):**
- ✅ `03-deployment.md` — Updated in PR #29 with smoke tests, Dependabot hardening
- ✅ `05-testing.md` — Updated in PR #29 with Playwright details, CI hardening
- ✅ `06-operations.md` — Updated in PR #29 with smoke test requirements, Dependabot automation
- ✅ `07-troubleshooting.md` — Existing comprehensive troubleshooting guide
- ✅ `index.md` — Dossier hub with complete navigation

**Minor additions needed:**

**`index.md` — Add Phase 2 current state:**

```markdown
## Current State (Phase 2)

- ✅ Route skeleton: 5 core routes implemented and smoke-tested
- ✅ CI quality gates: lint, format, typecheck, build, smoke tests (all enforced)
- ✅ Smoke test coverage: 100% routes (12 tests, Chromium + Firefox)
- ✅ Dependabot hardening: Auto-format + lockfile exclusions
- ✅ Deployment governance: Vercel promotion gated by required checks
- ✅ Dossier enhancement: All 7 pages updated to gold standard
- 🟡 Threat model: Planned for Step 4 (STRIDE analysis)
- 🟡 Enhanced project page: Planned for Step 7 (gold standard badge)
- 🟡 Meaningful CV page: Planned for Step 8 (capability-to-proof mapping)

Files to update:

  • docs/60-projects/portfolio-app/index.md
  • docs/60-projects/portfolio-app/01-overview.md
  • docs/60-projects/portfolio-app/02-architecture.md
  • docs/60-projects/portfolio-app/04-security.md

Success check:

  • 01-overview.md enhanced with executive summary, key metrics, "what this proves"
  • 02-architecture.md enhanced with complete tech stack, flow diagrams, component architecture
  • 04-security.md enhanced with public-safety rules, controls, validation procedures
  • index.md updated with Phase 2 current state
  • All dossier files verified complete and aligned with project dossier contract
  • Links to ADRs, threat model (placeholder), runbooks verified
  • Build verification passes (pnpm build)
  • PR created with dossier enhancements (PR #31)

STEP 4: Create/Update Threat Model ✅ (2–3 hours)​

Goal: Document security assumptions, threats, and controls for the project.

Location: /portfolio-docs/docs/40-security/threat-models/portfolio-app-threat-model.md

Approach: Use STRIDE or a simple trust boundary diagram.

Template:

---
title: 'Threat Model: Portfolio App'
description: 'Security analysis of the Portfolio App...'
tags: [security, threat-model, portfolio-app]
---

# Threat Model: Portfolio App

## Trust Boundaries Diagram

[Simple ASCII diagram showing public users → portfolio app → docs app → GitHub]

## Assets at Risk

- Source code (GitHub)
- Deployment credentials (Vercel)
- Custom domain (DNS)
- Reputation (if compromised)

## Threats (STRIDE)

### Spoofing

- **Threat:** Attacker spoofs the portfolio domain
- **Mitigation:** Use TLS/HTTPS, HSTS header, domain registration lock

### Tampering

- **Threat:** Attacker modifies deployed content
- **Mitigation:** Deployments only via authenticated Git + Vercel; no manual edits

### Repudiation

- **Threat:** Attacker denies making changes
- **Mitigation:** Git commit audit trail; GitHub Actions logs

### Information Disclosure

- **Threat:** Attacker exfiltrates environment variables or secrets
- **Mitigation:** No secrets in `NEXT_PUBLIC_*` variables; secrets never committed

### Denial of Service

- **Threat:** Attacker floods the app or docs domain
- **Mitigation:** Vercel DDoS protection; docs served as static files

### Elevation of Privilege

- **Threat:** Attacker gains elevated access to deployment pipeline
- **Mitigation:** GitHub Rulesets enforce PR reviews; required checks gate merges

## Residual Risks (Accepted)

- Dependabot alerts may not catch all zero-days immediately
- Manual review required for major dependency updates

## Controls Summary

- ✅ Code review (GitHub Rulesets + PR template)
- ✅ CI/CD gating (required checks)
- ✅ Supply chain: CodeQL + Dependabot
- ✅ Static deployment (no runtime secrets)
- ✅ Immutable deployments (Git revert only)

Success check:

  • Threat model document created (comprehensive STRIDE analysis)
  • Trust boundaries identified and diagrammed
  • STRIDE analysis complete (6 categories, 12 threats with mitigations)
  • Mitigations documented (Phase 1 baseline + Phase 2+ recommended)
  • Residual risks accepted and reviewed
  • Linked from dossier security page
  • Build verification passes
  • PR created with threat model enhancements (PR #32 — pending)

STEP 4a: Phase 2 Security Enhancements (Hardening Controls) ✅ (2–3 hours)​

Goal: Implement optional Phase 2 hardening controls that enhance Information Disclosure and Tampering threat mitigations.

Scope: These enhancements are beyond Phase 1 baseline but strengthen enterprise-grade posture.

Enhancement 1: Secrets Scanning Gate

Location: .github/workflows/ci.yml

Approach: Add TruffleHog job to CI pipeline to detect hardcoded secrets before merge.

Implementation:

  1. Update CI workflow to add secrets-scan job:
secrets-scan:
name: secrets-scan
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v6

- name: TruffleHog Secret Scanning
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --debug --only-verified
  1. Update build job to depend on secrets-scan:
needs: [quality, secrets-scan]
  1. Update package.json to add local secret scanning script:
{
"scripts": {
"secrets:scan": "trufflehog filesystem . --debug --only-verified"
}
}

Enhancement 2: CI Permission Hardening (Least-Privilege)

Location: .github/workflows/ci.yml

Approach: Replace global permissions: contents: write with job-specific least-privilege permissions.

Implementation:

  1. Remove global permissions:
# OLD (too broad):
permissions:
contents: write

# NEW (no global permissions):
permissions: {}
  1. Add job-specific permissions:
quality:
permissions:
contents: write # Needed for Dependabot auto-format
pull-requests: read

build:
permissions:
contents: read # Read-only for build artifacts

Enhancement 3: Pre-commit Hooks for Local Scanning

Location: .pre-commit-config.yaml (new file)

Approach: Enable local TruffleHog scanning before commits.

Implementation:

  1. Create .pre-commit-config.yaml:
repos:
- repo: https://github.com/trufflesecurity/trufflehog
rev: v3.63.0
hooks:
- id: trufflehog
name: TruffleHog secrets scan
description: Detect secrets in code
entry: trufflehog filesystem .
language: python
stages: [commit]
types: [python, typescript, javascript, json, yaml, toml, markdown]
  1. Users enable locally:
pre-commit install
git config core.hooksPath .git/hooks # One-time setup

Benefits:

  • Information Disclosure (T1): Secrets scanning gate catches leaks before CI
  • Tampering (T2): CI permission hardening reduces attack surface
  • Elevation of Privilege (E1): Least-privilege permissions prevent unauthorized deployments

Threat Model Alignment:

Success check:

  • Secrets scanning gate added to CI workflow
  • CI permissions set to least-privilege (per-job)
  • Pre-commit hooks configured for local scanning
  • secrets:scan CI stage added; local verify uses a lightweight pattern-based scan
  • All CI checks pass with new gates
  • Team documentation updated with secret scanning procedures
  • STRIDE compliance report generated (see

Files to create/modify:

  • .github/workflows/ci.yml (add secrets-scan job; scoped permissions)
  • .pre-commit-config.yaml (new; TruffleHog hook)
  • package.json (secrets:scan script used by CI; optional local run)

PR Reference: Phase 2 enhancements merged as part of threat model PR (PR #33)


STEP 4b: Phase 2 Operational Readiness (Incident Response) ✅ (1–2 hours)​

Goal: Create incident response runbooks aligned to threat model procedures.

Scope: Formalize secret publication and incident response procedures.

Enhancement: Secrets Incident Response Runbook

Location: /portfolio-docs/docs/50-operations/runbooks/rbk-portfolio-secrets-incident.md

Approach: Create comprehensive runbook covering detection, containment, investigation, and recovery.

Key Sections:

  1. Triage (≤5 min): Assess severity; determine containment strategy
  2. Emergency Contain (≤5 min for Critical): Stop the leak; rotate credentials
  3. Investigation (5–30 min): Determine scope, timeline, exposure duration
  4. Remediation (15–60 min): Remove secret from history; rotate credentials; update systems
  5. Validation (5–10 min): Confirm leak is contained; CI/CD healthy
  6. Postmortem (30 min–1 hr): Document; prevent recurrence

Threat Model Alignment:

Success check:

  • Secrets incident response runbook created
  • 5-phase procedure documented with timelines
  • Severity levels defined (Critical, High, Medium)
  • Checklists provided for each phase
  • Escalation criteria documented
  • Runbook index updated with reference

Files to create/modify:

  • docs/50-operations/runbooks/rbk-portfolio-secrets-incident.md (new)
  • docs/50-operations/runbooks/index.md (add reference)

PR Reference: Phase 2 incident response runbook merged as part of runbooks enhancement


Phase 2 Security Enhancements — Quick Reference​

This section summarizes all Phase 2 security and operational hardening applied to the Portfolio App (completed in STEP 4a and 4b).

CI/CD Hardening​

  • ✅ Secrets scanning added to CI using TruffleHog with verified detectors
    • Runs on pull requests only to avoid TruffleHog BASE==HEAD failures on direct pushes to main
    • Required check before merge via GitHub branch protection rules
    • Ensures all production code is scanned before merge
  • ✅ Least-privilege permissions implemented
    • Removed global workflow permissions
    • Added minimal job-level permissions per workflow job
  • ✅ Deterministic builds enforced via pnpm install --frozen-lockfile in CI
  • ✅ Required checks before merge: ci / quality, ci / build, secrets-scan, CodeQL

Developer Workflow Hardening​

  • ✅ Pre-commit hooks added via .pre-commit-config.yaml with TruffleHog
    • Optional local opt-in for developers
    • Prevents committing sensitive material before push
  • ✅ Local verification uses lightweight pattern-based secret scan
    • Full TruffleHog scanning runs only in CI (performance optimization)
  • ✅ Quality gates maintained: TypeScript strict mode, ESLint zero-warnings, Prettier enforcement

Operational Hardening​

Evidence Artifacts​


STEP 5: Create/Update Operational Runbooks ✅ (2–4 hours)​

Goal: Document repeatable procedures for deployment, CI triage, and rollback.

Files to create:

5a. Deploy Runbook​

Location: /docs/50-operations/runbooks/rbk-portfolio-deploy.md

---
title: 'Runbook: Deploy Portfolio App'
description: 'Step-by-step procedure for deploying changes to production.'
tags: [operations, runbooks, portfolio-app, deployment]
---

# Runbook: Deploy Portfolio App

## Overview

This runbook describes the standard deployment workflow for the Portfolio App.
Deployments are automatic after merge to `main` (no manual steps required).

## Prerequisites

- GitHub Ruleset requires passing checks before merge
- Vercel Deployment Checks verify production promotion readiness

## Procedure

### 1. Create PR with changes

```bash
git checkout -b feat/my-feature
# Make changes
pnpm lint
pnpm format:check
pnpm typecheck
pnpm build
git commit -am "feat: add my feature"
git push origin feat/my-feature
```

2. Open PR and wait for checks​

  • GitHub Actions runs ci / quality and ci / build
  • Vercel creates preview deployment

3. Validate preview deployment​

  • Open preview URL from Vercel comment
  • Test routes and evidence links
  • Spot-check styling and rendering

4. Merge PR (GitHub Ruleset enforces checks)​

  • All checks must pass
  • At least 1 review (configure as needed)
  • Click "Merge" (Ruleset prevents merge if conditions not met)

5. Automatic production deployment​

  • Vercel monitors main branch
  • After merge, Vercel runs same checks
  • If checks pass, Vercel deploys to production domain
  • Production domain updates automatically (no manual step)

Rollback​

If an issue is discovered post-deployment, see rbk-portfolio-rollback.md.

Troubleshooting​


#### 5b. CI Triage Runbook

**Location:** `/portfolio-docs/docs/50-operations/runbooks/rbk-portfolio-ci-triage.md`

```markdown
---
title: 'Runbook: CI Triage — Portfolio App'
description: 'How to diagnose and fix CI failures.'
tags: [operations, runbooks, portfolio-app, ci]
---

# Runbook: CI Triage — Portfolio App

## Quick diagnostics

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| `ci / quality` fails | Lint, format, or typecheck error | Run `pnpm lint`, `pnpm format:check`, `pnpm typecheck` locally |
| `ci / build` fails | Next.js build error | Run `pnpm build` locally |
| Playwright tests fail | Route or content regression | Review test output; run `pnpm test --debug` |
| Vercel preview fails | Build succeeds but deployment fails | Check Vercel logs in deployment dashboard |

## Step-by-step triage

### 1. Identify which check failed
- Look at GitHub PR checks (scroll to "Checks" tab)
- Click on failed check name to see logs

### 2. Reproduce locally
```bash
git fetch origin
git checkout feat/my-feature
pnpm install
# Run the same command as CI
pnpm lint # if ci/quality failed
pnpm build # if ci/build failed
pnpm test # if smoke tests failed

3. Fix the issue​

  • Edit source files to fix errors
  • Rerun the command to verify

4. Commit and push​

git add .
git commit -m "fix: resolve ci/quality lint error"
git push origin feat/my-feature

5. Monitor re-run​

  • GitHub Actions automatically re-runs checks
  • Watch for green checkmarks on the PR

Common issues and fixes​

ESLint errors​

pnpm lint -- --fix

Prettier formatting​

pnpm format

TypeScript type errors​

  • Open the file and fix based on error message
  • No auto-fix for type errors

Next.js build errors​

  • Usually caused by missing exports or dynamic import issues
  • Check the build log for specific file and line

Escalation​

If issues persist after triage:

  1. Check GitHub Actions logs for full error context
  2. Verify .env.local has all required vars from .env.example
  3. Clear .next cache: rm -rf .next and rebuild
  4. Ask for help in team/community channels

#### 5c. Rollback Runbook

**Location:** `/portfolio-docs/docs/50-operations/runbooks/rbk-portfolio-rollback.md`

```markdown
---
title: 'Runbook: Rollback Portfolio App'
description: 'Emergency rollback procedure if production deployment has issues.'
tags: [operations, runbooks, portfolio-app, incident-response]
---

# Runbook: Rollback Portfolio App

## When to rollback
- Critical bug discovered in production
- Performance degradation observed
- Security issue identified and needs immediate remediation

## Rollback procedure

### 1. Identify the problematic commit
```bash
git log --oneline -10 # Find the commit to revert

2. Create revert commit​

git checkout main
git pull origin main
git revert <commit-hash> # Creates a new commit that undoes the change
git push origin main

3. Wait for checks and deployment​

  • GitHub Actions runs checks on the revert commit
  • After checks pass, Vercel deploys the previous version to production
  • Time to rollback: ~2–3 minutes

4. Verify rollback​

  • Open production domain
  • Spot-check that issue is resolved

5. Investigate root cause​

  • Create a new branch to investigate
  • Create ADR or incident postmortem documenting the issue

Quick rollback (if needed immediately)​

If waiting for CI is unacceptable, you can manually redeploy a previous commit in Vercel dashboard:

  1. Go to Vercel project settings
  2. Deployments → find good deployment
  3. Click "Redeploy"
  4. Confirm

(This bypasses GitHub checks, use only in true emergency)

After rollback​

  1. Fix the underlying issue in a new PR
  2. Add regression test to prevent repeat
  3. Document lessons learned (postmortem)

**Success check:**
- [ ] Deploy runbook created and linked from dossier
- [ ] CI triage runbook created with common issues
- [ ] Rollback runbook created with both automated and manual steps
- [ ] All runbooks tested (at least mentally walkthrough)
- [ ] Links cross-reference correctly
- [ ] Build verification passes

---

### STEP 6: Create/Update ADRs for Phase 2 Decisions ✅ (1–2 hours)

**Goal:** Document any significant decisions made during Phase 2.

**Likely ADRs:**
- **Testing strategy** (Playwright for smoke tests, planned unit tests)
- **Gold standard project criteria** (what makes a project "gold standard")

**Example ADR:**

**Location:** `/portfolio-docs/docs/10-architecture/adr/adr-0009-portfolio-app-test-strategy.md`

```markdown
---
title: 'ADR-0000: Portfolio App Testing Strategy'
status: 'accepted'
date: 2026-01-17
tags: [adr, architecture, testing, portfolio-app]
---

# ADR-0000: Portfolio App Testing Strategy

## Context

The Portfolio App has reached Phase 2 (gold standard credibility baseline). To support this and future scaling, we need a clear testing strategy that:

1. Validates core functionality (routes, content, evidence links)
2. Catches regressions as we add features
3. Scales as the project registry grows
4. Integrates with CI/CD without adding excessive overhead

## Decision

We will adopt a **phased testing approach**:

### Phase 2 (now)
- **Smoke tests (Playwright):** Route accessibility, content rendering, evidence link integrity
- **Manual spot-checks:** Evidence links resolve to docs; styling renders correctly

### Phase 3 (planned)
- **Unit tests (Vitest):** Content validation (slug formats, required fields)
- **Property-based tests:** Ensure all projects in registry follow consistent schema

### Phase 3+ (future)
- **E2E tests (Playwright):** Full user flows, cross-domain evidence link validation
- **Performance tests:** Lighthouse CI for Core Web Vitals

## Rationale

1. **Start simple:** Smoke tests catch 80% of issues (broken routes, missing content) with minimal maintenance
2. **Progressive:** Add unit tests once content model stabilizes (Phase 3)
3. **Scale-ready:** Schema validation prevents inconsistent project data
4. **CI-friendly:** Tests run in ~2 minutes; fast feedback on PRs

## Consequences

- Smoke tests may not catch subtle bugs (UI logic, edge cases)
- Unit tests require schema formalization (good practice but more upfront work for Phase 3)
- E2E tests initially manual (acceptable for Phase 2 given low volume)

## Alternatives considered

1. **Full e2e tests from day 1:** Too much maintenance burden for current project size
2. **No tests initially:** Higher risk of regressions; harder to catch broken evidence links
3. **Only unit tests:** Wouldn't catch routing or integration issues

## Implementation

See: [Smoke test setup in Phase 2 guide]

Success check:

  • ADR created for testing strategy (or other Phase 2 decision)
  • Decision rationale clear
  • Alternatives considered
  • Consequences documented
  • Linked from dossier
  • Build verification passes

STEP 7: Enhance Project Detail Page ✅ (2–3 hours)​

Goal: Make the project page showcase the evidence trail and governance posture.

Current state: Basic project detail with evidence links

Enhancements:

7a. Add "What This Project Proves" section (already exists, enhance)​

Update /portfolio-app/src/app/projects/[slug]/page.tsx to display:

<Section
title="What this project proves"
subtitle="Senior-level engineering discipline demonstrated."
>
<ul className="list-disc pl-5 space-y-2 text-sm text-zinc-700 dark:text-zinc-300">
<li>
<strong>Clear scope & architecture:</strong>{' '}
<a className="underline" href={docsUrl(evidence?.dossierPath)}>
See dossier
</a>
</li>
<li>
<strong>Enterprise SDLC:</strong> PR discipline, CI gates, governance
</li>
<li>
<strong>Security-aware:</strong> Threat modeling, safe-publication rules
</li>
<li>
<strong>Operational readiness:</strong> Deploy/rollback/triage procedures
</li>
<li>
<strong>Tested:</strong> Automated checks, smoke tests, reproducibility
</li>
</ul>
</Section>

7b. Create "Gold Standard Badge" component​

Create /portfolio-app/src/components/GoldStandardBadge.tsx:

export function GoldStandardBadge() {
return (
<div className="flex items-center gap-2 rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-900 dark:bg-amber-950">
<span className="text-lg">🏆</span>
<p className="text-sm font-medium text-amber-900 dark:text-amber-100">
This is a gold standard portfolio project — comprehensive documentation,
full governance trail, and operational readiness.
</p>
</div>
);
}

Add to project detail page:

import { GoldStandardBadge } from '@/components/GoldStandardBadge';

// In the component:
<GoldStandardBadge />;

7c. Add "Verification Checklist" section​

<Section
title="How to verify"
subtitle="Independent validation steps for reviewers."
>
<ul className="list-disc pl-5 space-y-2 text-sm text-zinc-700 dark:text-zinc-300">
<li>
Visit{' '}
<a className="underline" href={project.repoUrl}>
GitHub repository
</a>{' '}
— check commit history, PR discipline, CI checks
</li>
<li>
View{' '}
<a className="underline" href={project.demoUrl}>
live deployment
</a>{' '}
— test routing, rendering, performance
</li>
<li>
Review{' '}
<a className="underline" href={docsUrl(evidence?.dossierPath)}>
project dossier
</a>{' '}
— architecture, decisions, operational procedures
</li>
<li>
Check{' '}
<a className="underline" href={docsUrl(evidence?.threatModelPath)}>
threat model
</a>{' '}
— security assumptions and controls
</li>
<li>
Read{' '}
<a className="underline" href={docsUrl(evidence?.adrIndexPath)}>
ADRs
</a>{' '}
— rationale for durable decisions
</li>
</ul>
</Section>

Success check:

  • Enhanced project detail page components created
  • Gold standard badge displays for chosen project
  • Evidence links are comprehensive and organized
  • Verification checklist guides reviewers
  • Smoke tests validate links resolve
  • Build passes
  • PR created with enhancements

STEP 8: Enhance CV Page with Capability Mapping ✅ (2–3 hours)​

Goal: Transform CV from skeleton into meaningful capability-to-proof mapping.

Current approach: Create a structured CV that links capabilities to projects/evidence

Update /portfolio-app/src/app/cv/page.tsx:

'use client';
import Link from 'next/link';
import { Section } from '@/components/Section';
import { docsUrl } from '@/lib/config';

type TimelineEntry = {
title: string;
organization: string;
period: string;
description: string;
keyCapabilities: string[];
proofs: { text: string; href: string }[];
};

const TIMELINE: TimelineEntry[] = [
{
title: 'Full-Stack Engineer',
organization: 'Portfolio Program',
period: '2026',
description:
'Designed and built an enterprise-grade portfolio demonstrating modern web development, governance, and operational maturity.',
keyCapabilities: [
'Next.js / React / TypeScript',
'CI/CD governance',
'Security & threat modeling',
'Docs-as-code culture',
'Vercel deployment',
],
proofs: [
{
text: 'Portfolio App on GitHub',
href: 'https://github.com/bryce-seefieldt/portfolio-app',
},
{ text: 'Live deployment', href: 'https://your-portfolio.com' },
{
text: 'Full dossier with architecture & decisions',
href: docsUrl('projects/portfolio-app'),
},
{
text: 'Complete threat model & security posture',
href: docsUrl('security/threat-models/portfolio-app-threat-model'),
},
{
text: 'Operational runbooks (deploy, rollback, triage)',
href: docsUrl('operations/runbooks/'),
},
],
},
// Add more timeline entries as you accumulate projects/roles
];

export default function CVPage() {
return (
<div className="flex flex-col gap-8">
<header className="flex flex-col gap-3">
<h1 className="text-3xl font-semibold tracking-tight">
Experience & Capabilities
</h1>
<p className="max-w-3xl text-zinc-700 dark:text-zinc-300">
Evidence-first CV: each role links to proofs (projects, dossiers,
architecture decisions, operational maturity).
</p>
</header>

{TIMELINE.map((entry, idx) => (
<Section
key={idx}
title={entry.title}
subtitle={`${entry.organization} — ${entry.period}`}
>
<p className="mb-4 text-sm text-zinc-700 dark:text-zinc-300">
{entry.description}
</p>

<div className="mb-4">
<h4 className="font-medium text-zinc-900 dark:text-white">
Key Capabilities
</h4>
<div className="mt-2 flex flex-wrap gap-2">
{entry.keyCapabilities.map((cap) => (
<span
key={cap}
className="rounded-full border border-zinc-200 px-2 py-1 text-xs text-zinc-700 dark:border-zinc-800 dark:text-zinc-300"
>
{cap}
</span>
))}
</div>
</div>

<div>
<h4 className="font-medium text-zinc-900 dark:text-white">
Proofs & Evidence
</h4>
<ul className="mt-2 list-disc space-y-1 pl-5 text-sm">
{entry.proofs.map((proof, pIdx) => (
<li key={pIdx}>
<a
className="underline hover:text-zinc-950 dark:hover:text-white"
href={proof.href}
>
{proof.text}
</a>
</li>
))}
</ul>
</div>
</Section>
))}
</div>
);
}

Success check:

  • CV page displays timeline with capability mapping
  • Each entry links to projects, dossiers, threat models, runbooks
  • Evidence links resolve in smoke tests
  • Styling integrates with rest of site
  • Smoke tests pass
  • PR created with CV enhancements

STEP 9: Create Release Note for Phase 2 ✅ (1–2 hours)​

Goal: Document Phase 2 completion with all additions and changes.

Location: /portfolio-docs/docs/00-portfolio/release-notes/20260120-portfolio-app-phase-2-gold-standard.md

Success check:

  • Release note created with all Phase 2 features
  • Links to dossier, threat model, ADRs, runbooks, security enhancements
  • Success criteria clearly documented
  • Build verification passes
  • PR created and merged

Completion notes:

release-notes/20260120-portfolio-app-phase-2-gold-standard.md(/docs/00-portfolio/release-notes/20260120-portfolio-app-phase-2-gold-standard.md)

  • All evidence artifacts linked and verified

STEP 10: Create PR and Verify End-to-End ✅ (1–2 hours)​

Goal: Document Phase 2 completion with all additions and changes.

Location: /portfolio-docs/docs/00-portfolio/release-notes/20260124-portfolio-app-phase-2-gold-standard.md (adjust date)

Template:

---
title: 'Release Notes: Portfolio App Phase 2 Complete (Gold Standard Project + Testing)'
description: 'Phase 2 completion: comprehensive project dossier, smoke test infrastructure, enhanced CV with capability mapping, threat model, and operational runbooks.'
tags: [release-notes, portfolio-app, phase-2, testing, projects]
date: 2026-01-24
---

# Release Notes: Portfolio App Phase 2 Complete (Gold Standard Project + Testing)

## Summary

Phase 2 of the Portfolio App establishes credibility through one exemplary "gold standard" project. The Portfolio App itself serves as the proof, with comprehensive documentation, automated testing, full threat model, and operational procedures.

**Status:** ✅ **Phase 2 Complete** (2026-01-24)

---

## Highlights

- **Gold standard project page** with full evidence trail and verification checklist
- **Smoke test infrastructure** (Playwright) with 100% route coverage
- **Comprehensive dossier** covering architecture, security, deployment, operations
- **Threat model** documenting security assumptions and controls
- **Operational runbooks** for deploy, CI triage, rollback
- **Enhanced CV page** with capability-to-proof mapping
- **Gold standard badge** component highlighting exemplary project quality

---

## Added

### Portfolio App features

- **Smoke test suite (Playwright):**
- Route accessibility tests (all 5 core routes)
- Content rendering validation
- Evidence link integrity checks
- Integrated into CI pipeline (required before merge)

- **Enhanced project detail page:**
- Gold standard badge
- "What this project proves" section with detailed capabilities
- "Verification checklist" section guiding independent validation
- Comprehensive evidence links (dossier, threat model, ADRs, runbooks)

- **Meaningful CV page:**
- Timeline of experience with capability-to-proof mapping
- Each entry links to projects, dossiers, threat models, runbooks
- Evidence-first approach: each claim is verifiable

### Documentation artifacts

- **Project dossier (10 sections):**
- Executive summary, overview, architecture, security, testing, deployment, operations, limitations, troubleshooting, related artifacts
- ~4,000 words

- **Threat model:**
- Trust boundary diagram
- STRIDE analysis
- Mitigation controls
- Residual risks documented and accepted

- **Operational runbooks:**
- Deploy runbook (standard workflow)
- CI triage runbook (troubleshooting common failures)
- Rollback runbook (emergency recovery procedure)

- **ADR for testing strategy:**
- Justification for phased testing approach (smoke → unit → e2e)
- Rationale for Playwright + Vitest stack

---

## Changed

### Testing & quality

- `package.json` updated with Playwright test scripts
- `.github/workflows/ci.yml` updated to run smoke tests (required check)
- `.gitignore` updated to exclude test results and reports

### Project detail page

- Now displays gold standard badge for exemplary project
- Enhanced evidence links section
- Added verification checklist for reviewers

### CV page

- Converted from skeleton to comprehensive capability-to-proof mapping
- Timeline entries link to deep evidence artifacts
- Demonstrates evidence-first hiring/evaluation approach

---

## Verification (Phase 2 Success Criteria — All Complete ✅)

The Phase 2 release is valid when:

- ✅ One "gold standard" project page is fully polished
- ✅ Comprehensive dossier covers architecture, security, deployment, operations
- ✅ Threat model documents security posture and controls
- ✅ Operational runbooks (deploy, CI triage, rollback) are complete
- ✅ Smoke tests validate all core routes and evidence links
- ✅ CV page meaningfully maps capabilities to proofs
- ✅ A reviewer can validate senior-level engineering discipline through one project
- ✅ All evidence links resolve correctly

---

## Architecture & Governance References

- [Portfolio App Dossier](/60-projects/portfolio-app/index.md) (location TBD during implementation)
- [Threat Model: Portfolio App](/40-security/threat-models/) (location TBD during implementation)
- Operational runbooks (created during Phase 2):
- Deploy runbook
- CI triage runbook
- Rollback runbook

---

## Phase 3 Planning (Next Increments)

With Phase 2 establishing credibility through one exemplary project, Phase 3 will focus on:

- **Scale content model:** Repeatable project publishing pipeline with validation
- **Unit tests:** Content/slug validation, project registry schema enforcement
- **E2E tests:** Full user flows, cross-domain evidence link validation
- **Add additional projects:** Now that gold standard is proven, add portfolio entries at same quality bar

---

## Known Limitations (Phase 2 scope)

- Smoke tests only (unit/e2e planned for Phase 3)
- Single gold standard project (additional projects planned for Phase 3+)
- Manual evidence link testing (automated in Phase 3)
- No performance or accessibility audit yet (planned for Phase 4)

Success check:

  • Release note created with all Phase 2 features
  • Links to dossier, threat model, ADRs, runbooks
  • Success criteria clearly documented
  • Build verification passes
  • PR created with release note

STEP 10: Create PR and Verify End-to-End (1–2 hours)​

Goal: Consolidate all Phase 2 work into a single PR and validate everything works together.

Process:

# Ensure you're on main and up-to-date
cd portfolio-app
git checkout main
git pull origin main

# Create Phase 2 feature branch
git checkout -b feat/phase-2-gold-standard

# Make all changes (test infrastructure, components, documentation)
# ...commit as you go...

# Run all checks locally
pnpm lint
pnpm format:check
pnpm typecheck
pnpm build
pnpm test # Run Playwright smoke tests

# Verify documentation builds
cd ../portfolio-docs
pnpm build

# If all passes, create PR
cd ../portfolio-app
git push origin feat/phase-2-gold-standard
# Open PR on GitHub

PR template checklist:

## Phase 2 Implementation: Gold Standard Project & Testing

### Changes
- [ ] Smoke test infrastructure (Playwright)
- [ ] Enhanced project detail page with gold standard badge
- [ ] Meaningful CV page with capability mapping
- [ ] Local test commands and CI integration

### Documentation updates (portfolio-docs repo)
- [ ] Project dossier (10 sections)
- [ ] Threat model
- [ ] Operational runbooks (deploy, CI triage, rollback)
- [ ] ADR for testing strategy
- [ ] Phase 2 release note

### Evidence
- [ ] All smoke tests pass locally: `pnpm test`
- [ ] CI checks pass on main
- [ ] Production deployment successful
- [ ] Evidence links resolve to docs (verified in smoke tests)

### No secrets added
- [ ] No `NEXT_PUBLIC_*` secrets added
- [ ] No API keys or credentials in code or config

Success check:

  • All local checks pass (lint, format:check, typecheck, build, test)
  • Documentation builds pass
  • PRs created with comprehensive descriptions
  • GitHub Actions CI runs successfully
  • Vercel preview deployments work
  • Production deployments automatic and successful
  • All evidence links resolve to docs app
  • Smoke tests pass in CI

Completion notes:

  • Multiple PRs created and merged throughout Phase 2
  • Portfolio App PRs: #10 (smoke tests), #20 (gold standard page), #21 (CV page), #25 (verification script)
  • Portfolio Docs PRs: #32 (threat model), #33 (enhancements summary), #39 (dossier), #40 (STRIDE compliance)
  • All CI gates passing consistently
  • Production deployments stable and verified

Phase 2 Completion Summary​

Timeline & Effort Actual​

StepTaskEstimatedActualStatus
1Choose gold standard project1–2 hrs2 hrs✅
2Set up smoke tests (Playwright)3–5 hrs4 hrs✅
3Enhance project dossier4–6 hrs6 hrs✅
4Create threat model2–3 hrs3 hrs✅
4aSecurity enhancements2–3 hrs3 hrs✅
4bIncident response runbooks1–2 hrs2 hrs✅
5Create operational runbooks2–4 hrs3 hrs✅
6Create/update ADRs1–2 hrs1 hr✅
7Enhance project detail page2–3 hrs3 hrs✅
8Enhance CV page2–3 hrs3 hrs✅
9Create Phase 2 release note1–2 hrs1 hr✅
10Create PRs & verify end-to-end1–2 hrs2 hrs✅
TotalPhase 2 Complete19–32 hrs33 hrs✅

Completion date: 2026-01-21
Duration: ~3 weeks (January 2–21, 2026)


Success Criteria — All Achieved ✅​

Phase 2 is complete when all criteria are met:

Functionality Criteria​

  • ✅ One "gold standard" project page is fully polished with evidence trail
  • ✅ Comprehensive dossier covers architecture, security, deployment, operations, testing, troubleshooting
  • ✅ Threat model documents security posture, controls, and STRIDE analysis
  • ✅ Operational runbooks (deploy, CI triage, rollback, secrets incident) are complete and tested
  • ✅ Smoke tests validate all core routes and evidence links
  • ✅ CV page meaningfully maps capabilities to verifiable proofs

Quality Criteria​

  • ✅ All CI checks pass: quality (lint, format, typecheck), secrets-scan, build with smoke tests, CodeQL
  • ✅ 100% route coverage in Playwright smoke tests (12 tests, Chromium + Firefox)
  • ✅ No broken links between portfolio-app and portfolio-docs
  • ✅ All evidence artifacts published and accessible
  • ✅ GitHub Rulesets enforce PR discipline and required checks

Evidence Criteria​

  • ✅ ADR-0010 (Gold Standard Exemplar) published and referenced
  • ✅ Threat model with STRIDE analysis published
  • ✅ STRIDE compliance report generated
  • ✅ 4 operational runbooks complete (deploy, CI triage, rollback, secrets incident)
  • ✅ Dossier enhanced to 7 comprehensive pages
  • ✅ Release note published with completion evidence

Reviewer Validation Criteria​

A senior engineer reviewing the Portfolio App can validate engineering discipline through:

  • ✅ "What, why, how" clarity: Project purpose, technical decisions, implementation approach documented
  • ✅ Security posture: Threat model, controls, public-safety rules enforced
  • ✅ Operational readiness: Runbooks tested, deployment/rollback procedures documented
  • ✅ Testing discipline: Automated smoke tests, CI gates, reproducible builds
  • ✅ Evidence trail: All claims link to verifiable artifacts (dossier, ADRs, threat model, runbooks)

Acceptance Criteria (Reviewability)​

A reviewer can validate Phase 2 completion through:

  1. Portfolio App Repository:

    • Browse https://github.com/bryce-seefieldt/portfolio-app
    • Verify CI checks are passing (quality, secrets-scan, build)
    • Review merged PRs (#10, #20, #21, #25) for smoke tests, enhanced pages, verification scripts
    • Check .github/workflows/ci.yml for secrets scanning and smoke test integration
  2. Live Deployment:

    • Visit portfolio app production URL
    • Navigate to all 5 core routes (/, /cv, /projects, /contact, /projects/portfolio-app)
    • Verify gold standard badge displays on portfolio-app project page
    • Click evidence links to docs; verify they resolve correctly
  3. Documentation Evidence:

  4. Automated Tests:

    • Clone portfolio-app repo
    • Run pnpm install && pnpm test
    • Verify all 12 smoke tests pass (5 route tests, evidence link tests, registry validation)

Compliance Review (2026-01-19)​

Status: ✅ Compliant — All documented STRIDE threats and Phase 2 security enhancements verified.

Scope reviewed:

  • STRIDE Threat Model (12 threats across 6 categories)
  • STRIDE Compliance Report (evidence mapping for each mitigation)
  • Phase 2 security enhancements (secrets scanning, least-privilege CI, pre-commit hooks, incident response)
  • SDLC controls in CI/CD, repo governance, and operational runbooks

Verification highlights:

  • CI/CD: Required checks (ci / quality, ci / build, secrets-scan, CodeQL), job-scoped permissions, frozen lockfile installs
  • Secrets hygiene: No secrets in NEXT_PUBLIC_*; .env.example documents schema; TruffleHog in CI and pre-commit
  • Operations: Secrets incident response runbook; deploy/rollback/CI triage runbooks validated
  • Security headers: HSTS verified on production deployment; Vercel-managed TLS
  • Dependency governance: Dependabot weekly updates (grouped), minimal dependencies, no postinstall hooks

Evidence:


Key Deliverables Reference​

Portfolio App Artifacts​

  • Smoke tests: tests/e2e/smoke.spec.ts (12 tests, 100% route coverage)
  • Playwright config: playwright.config.ts
  • CI workflow: .github/workflows/ci.yml (quality, secrets-scan, build with tests)
  • Gold standard component: src/components/GoldStandardBadge.tsx
  • Enhanced project page: src/app/projects/[slug]/page.tsx
  • Enhanced CV page: src/app/cv/page.tsx
  • Pre-commit hooks: .pre-commit-config.yaml

Documentation Artifacts​

  • Project dossier: /docs/60-projects/portfolio-app/ (7 pages)
  • Threat model: /docs/40-security/threat-models/portfolio-app-threat-model.md
  • ADR-0010: /docs/10-architecture/adr/adr-0010-portfolio-app-as-gold-standard-exemplar.md
  • Runbooks: /docs/50-operations/runbooks/ (4 runbooks)
    • rbk-portfolio-deploy.md
    • rbk-portfolio-ci-triage.md
    • rbk-portfolio-rollback.md
    • rbk-portfolio-secrets-incident.md
  • Release notes: /docs/00-portfolio/release-notes/20260120-portfolio-app-phase-2-gold-standard.md
  • STRIDE compliance report: /docs/40-security/threat-models/portfolio-app-stride-compliance-report.md

Lessons Learned & Retrospective​

What Went Well​

  1. Sequential execution: Breaking work into 10 discrete steps made progress measurable and allowed for course-correction
  2. Evidence-first approach: Creating documentation alongside code prevented documentation debt
  3. Smoke tests early: Catching broken links and routing issues before manual testing saved significant debugging time
  4. Security hardening: Adding TruffleHog and pre-commit hooks provided immediate value and prevented potential leaks
  5. ADR discipline: Documenting decisions (ADR-0010, testing strategy) created durable reference points

Challenges & Mitigations​

  1. Scope creep: Initially planned Phase 2 for ~20 hours; actual was ~33 hours due to security enhancements
    • Mitigation: Broke enhancements into STEP 4a/4b; documented as "recommended" vs "required"
  2. Cross-repo coordination: Portfolio-app and portfolio-docs PRs needed careful sequencing
    • Mitigation: Created tracking issues in both repos with cross-links
  3. Documentation volume: Dossier alone was 4,000+ words
    • Mitigation: Used templates and structured approach; content reusable for future projects

Recommendations for Phase 3​

  1. Continue evidence-first approach (documentation before/during implementation)
  2. Plan for ~1.5x estimated hours to account for polish and hardening
  3. Create issue templates for Stage/Step granularity (see Phase 3 planning docs)
  4. Establish registry schema early to avoid rework

Future Enhancements & Optional Improvements​

Optional improvements identified during Phase 2 (not required for Phase 3):

Security & Compliance​

  • Dependabot for GitHub Actions: Enable SHA pinning for workflow actions (enhanced supply chain security)
  • Content Security Policy (CSP): Add CSP headers via vercel.json for additional XSS protection
  • SBOM generation: Consider automated Software Bill of Materials for dependency tracking

Performance & Observability​

  • Lighthouse CI: Integrate performance budgets and automated Lighthouse scoring in CI
  • Web Vitals monitoring: Add RUM (Real User Monitoring) for production performance tracking
  • Error tracking: Consider Sentry or similar for production error aggregation

Testing & Quality​

  • Visual regression testing: Add Playwright screenshot comparison for UI consistency
  • Accessibility testing: Automated a11y checks (axe-core) in smoke tests
  • Load testing: Basic performance testing for critical routes

Documentation & Evidence​

  • Architecture diagrams: Generate C4 or similar architecture diagrams for dossier
  • API documentation: If APIs added in Phase 3+, generate OpenAPI/Swagger docs
  • Runbook automation: Convert manual runbooks to executable scripts where applicable

Phase 3 Planning (Next Steps)​

With Phase 2 establishing credibility through one exemplary project, Phase 3 will focus on:

Phase 3 Objectives​

  • Data-driven project registry: YAML-backed registry with Zod validation (Stage 3.1)
  • Evidence visualization components: EvidenceBlock, VerificationBadge, BadgeGroup (Stage 3.2)
  • Unit tests: Content/slug validation, registry schema enforcement (Stage 3.3)
  • E2E tests: Full user flows, cross-domain evidence link validation (Stage 3.4)
  • Publish runbook: Repeatable project publishing pipeline (Stage 3.5)

Planning Documents​



Owner: Portfolio Program
Phase: 2 of 5
Status: ✅ Complete (2026-01-21)
Next Phase: Phase 3 — Repeatable Project Publishing Pipeline