# Native development and verification The original assignment remains in [ASSIGNMENT.md](ASSIGNMENT.md). The Go implementation requires Go 1.26 and an existing PostgreSQL server. This submission was tested on Linux with Go 1.26.4 and PostgreSQL 17.10. No Docker or VM is needed. Follow [the quick start](README.md#run-locally) to build the two binaries and initialize the database. `contentd` owns migrations and serving; `harness` owns test data, contract verification, and benchmarks. `bin/build` only compiles them. Both binaries use `DATABASE_URL`, defaulting to `dbname=assignment_harness_native` when unset or empty. Harness commands also accept `--db` to override it. Use libpq-style `PGHOST`, `PGPORT`, `PGUSER`, and `PGPASSWORD` when your server differs. Keep passwords out of shell history; a `.pgpass` file with mode `0600` also works. Your database role needs permission to create the task database. If it does not, ask the database administrator to create `assignment_harness_native` owned by your role, then run these commands from the repository root against that empty database: ```sh export DATABASE_URL='dbname=assignment_harness_native' bin/build go-service/contentd migrate harness/harness claim --db "$DATABASE_URL" harness/harness fixture --db "$DATABASE_URL" ALLOWED_HOSTS=127.0.0.1,localhost go-service/contentd ``` Add the connection's host and user to `DATABASE_URL` as needed. `claim` requires that your role owns the database and refuses populated, unmarked application tables. The harness refuses to manage an existing unmarked database automatically. `harness/harness seed` replaces task data with the full synthetic fixture, 1,000 users, 50 tags, 100,000 posts, 500,000 comments and 243,116 tag links. It is deterministic and does not reproduce the literal Faker strings from the original seed. Never point the fixture or benchmark commands at real application data. ## Tests ```sh bin/check ``` This additionally requires Python 3.14, uv, and curl. It installs locked reference dependencies, runs unit/race/static checks and the original three smoke tests, checks migrations and production behavior, then replays all 66 contract cases against Django, Go and the final optimized-Django control. It starts temporary servers on 18000/18001 and stops them on exit. It resets only the named, marked task databases. Run it with those ports free. The native CI workflow uses the same command without a container. `bin/check` uses fixed `assignment_harness_native` and `assignment_harness_django` database names. Set `PGHOST`, `PGPORT`, and `PGUSER` for a nondefault PostgreSQL connection; a custom `DATABASE_URL` does not redirect the entire check suite. For an existing server, replay just the external suite. Start it with `APP_PROFILE=compat go-service/contentd` and the same `DATABASE_URL` first; the contract suite expects reference error responses. This resets its small fixture and performs test writes: ```sh harness/harness verify --db 'dbname=assignment_harness_native' \ --url http://127.0.0.1:18001 --golden fixtures/contract ``` `capture` deliberately overwrites captures. Use it only for a reviewed contract change against the reference, never to make a failing candidate test pass. ## Measurements See `reports/methodology.md` for the comparison policy and limits. Before timing, ensure the host is otherwise idle and run one application at a time without coverage or SQL tracing. ```sh harness/harness bench --db 'dbname=assignment_harness_native' \ --url http://127.0.0.1:18001 --pid SERVER_PID \ --requests 1000 --repeats 5 --concurrency 8 --output reports/new-run.json bin/compare ``` The benchmark restores the small fixture per repetition unless `--full` is given. For full data, seed first; use `--workload user` to select one endpoint. `/proc` must expose the server PID and workers. Record your own revision, hardware and process configuration alongside new results. `bin/compare` evaluates the checked-in declared pairs; it does not run fresh workloads. Diagnostics are separate commands: `plans` records SELECT-only EXPLAIN ANALYZE output; `waits` samples PostgreSQL waits during hot-post requests. `SQL_TRACE` on either adapter writes request-associated statements/counts/durations without bind values. Do not use instrumented timings as the uninstrumented benchmark result. ## Coverage Python: run `bin/reference coverage`, replay the external cases, interrupt the server cleanly, then use `coverage json` or `coverage html` through `.venv/bin/python`. Go: build with `go build -buildvcs=false -cover`, set `GOCOVERDIR` to a fresh directory, replay the same cases, and stop with SIGTERM. Use `go tool covdata textfmt` and `go tool cover` from the `go-service` directory. Never mix counters from different binary builds. Coverage is diagnostic, not a benchmark or proof of equivalence.