Columbia Pages Skill Test Run

An end-to-end exercise of the current agent skill and house theme, using the Columbia Pages repository itself as a realistic open-source and self-hosting review.

Executive read

Columbia Pages is a compact Go service for turning agent-authored, body-only HTML into public reports at unguessable URLs. The current repository combines a CLI, an authenticated JSON API, SQLite persistence, an embedded house theme, deployment configuration, and the skill that produced this page.

Go packages
5
CLI, server, store, web, theme
Test functions
12
Across 4 test files
Runtime services
1
One container plus one volume
License
MIT
Permissive open-source terms
Strong candidate for a first public release

The scope is legible, the deployment story is concrete, the current test suite passes, and the repository already contains contribution, security, and self-hosting guidance.

Primary language
Go 1.25
Persistence
SQLite in WAL mode
Deploy target
Railway via Dockerfile and railway.json
Public content
Themed body HTML or complete raw documents
Management auth
One shared bearer passcode in the current implementation

Architecture

The system deliberately keeps its moving parts small: an agent calls cpages, the CLI sends authenticated API requests, the server stores HTML in SQLite, and browsers retrieve a public page that links the embedded theme.

  1. The agent writes semantic, body-only HTML.
  2. cpages create posts it to the authenticated API.
  3. The server stores page metadata and HTML inline in SQLite.
  4. GET /p/{id} wraps themed content or returns raw content verbatim.
Non-test Go lines by subsystem Horizontal bars show 782 lines in the CLI, 435 in web routing, 255 in storage, 96 in server startup, and 9 in theme embedding. Non-test Go lines by subsystem CLI 782 Web routes 435 Storage 255 Server startup 96 Theme embed 9 0 200 400 600 800 lines
Measured from the seven non-test Go source files. Every bar carries its literal count; color is supplemental.

The CLI is the largest subsystem at 782 of 1,577 non-test Go lines, about half of the measured implementation. The public web and persistence layers remain comparatively compact.

Server wiring

The core server setup is conventional Go and keeps timeout behavior explicit:

srv := &http.Server{
    Addr:              ":" + port,
    Handler:           web.New(st, passcode, baseURL),
    ReadHeaderTimeout: 10 * time.Second,
    ReadTimeout:       30 * time.Second,
    WriteTimeout:      30 * time.Second,
    IdleTimeout:       60 * time.Second,
}

Verification

The test run executed go test ./... and go vet ./... against the current working tree. Both commands exited successfully.

Distribution of twelve test functions A donut chart shows four CLI configuration tests, four web tests, three store tests, and one theme test. Test functions by package 12 test functions CLI config — 4 (33%) Web — 4 (33%) Store — 3 (25%) Theme — 1 (8%)
The legend names every segment and gives its count and share, so the chart does not rely on color.
Current automated test coverage surface
Package Test functions Observed result Primary behavior
cmd/cpages 4 Pass Credential configuration and permissions
internal/web 4 Pass API auth, rendering, headers, and log redaction
internal/store 3 Pass Storage lifecycle and database permissions
theme 1 Pass Theme contract
cmd/server 0 No test file Startup composition and shutdown loop
CI mirrors the local checks

The GitHub Actions workflow checks formatting, runs go test ./..., and runs go vet ./... on pull requests and pushes to main.

Self-hosting

Railway is the documented blessed provider. The repository supplies a multi-stage container build, a /healthz health check, retry policy, and an operator guide covering deployment, upgrades, custom domains, and complete-volume backups.

Minimal deployment sequence

  1. Create a Railway service from the repository.
  2. Mount a persistent volume at /data.
  3. Generate a public domain and set the two required variables.
  4. Wait for /healthz, then connect the CLI.
# Railway service variables
COLUMBIA_PAGES_PASSCODE=<generated-high-entropy-secret>
PUBLIC_BASE_URL=https://${{RAILWAY_PUBLIC_DOMAIN}}

# Connect without putting the passcode on the command line
cpages login --server https://your-service.up.railway.app
cpages status
  • The container defaults SQLite to /data/columbia-pages.db.
  • Railway provides PORT; operators should not override it.
  • Backups must preserve the full SQLite volume, including WAL sidecars.
  • The complete guide links to official Railway documentation for templates, volumes, and public networking.

Agent experience

The skill is short enough to load quickly but explicit about the critical contract: run cpages status first, publish body-only semantic HTML in themed mode, place flags before positional arguments, and treat every resulting URL as public.

What worked in this run

  • Preflight produced a clear authenticated status before any HTML was written.
  • The component reference provided exact accessible markup for navigation, stats, callouts, tables, and facts.
  • Default themed mode accepted complex semantic content without requiring a custom stylesheet or JavaScript.
  • Inline SVG remained available for purpose-built, printable data graphics.

Publishing contract exercised

<header>
  <h1>Columbia Pages Skill Test Run</h1>
  <p class="dek">An end-to-end exercise of the current skill.</p>
</header>

<section id="verification">
  <h2>Verification</h2>
  <p>Semantic body content receives the house theme.</p>
</section>

Risks and next steps

The content origin is intentionally trusted

Published HTML is not sanitized, and raw pages may run JavaScript. Browser-authenticated administration must stay on a different origin from public page content.

  • Release ergonomics: the README currently installs the CLI from Go source because release binaries are not yet available.
  • Authentication: the shared passcode is workable for a single operator but less ergonomic than scoped, revocable device tokens.
  • Server composition tests: cmd/server has no direct test file, although its major dependencies are tested independently.
  • Operational proof: a public Railway template and tested restore drill would reduce the final self-hosting steps.

The repository already documents a safer browser-assisted device authorization design with separate control.example.com and pages.example.com origins, finite token lifetimes, scopes, revocation, and polling controls.

Recommendation

Open-source the repository after one release-readiness pass. Tag an initial release, publish installable CLI binaries, turn the Railway configuration into a one-click template, and keep the planned device-login work behind the documented control/content origin boundary.

The current skill and theme are already capable of producing a structured, accessible report with navigation, responsive tables, code samples, callouts, and custom data graphics without dropping into raw mode.