From 36b366c1105750f7e08ba1316a0bb952cc5d9c0b Mon Sep 17 00:00:00 2001
From: Andrew Nordstrom <89470090+AndrewNordstrom@users.noreply.github.com>
Date: Tue, 21 Jul 2026 13:09:52 -0700
Subject: [PATCH 1/5] PROJ-153 Overhaul Corgi README
---
README.md | 392 +++++++++++++++++++++++-------------------------------
1 file changed, 168 insertions(+), 224 deletions(-)
diff --git a/README.md b/README.md
index e6b2d8ad..295bc405 100644
--- a/README.md
+++ b/README.md
@@ -1,306 +1,250 @@
-
+
+
+
Corgi
- Community-shaped Bluesky ranking with inspectable policy and receipts.
+ A Bluesky feed communities can inspect and shape.
-[](https://github.com/andrewnordstrom-eng/bluesky-community-feed/actions/workflows/deploy.yml)
-[](https://github.com/andrewnordstrom-eng/bluesky-community-feed/actions/workflows/deploy-docs.yml)
-[](https://github.com/andrewnordstrom-eng/bluesky-community-feed/actions/workflows/ci.yml)
-[](https://github.com/andrewnordstrom-eng/bluesky-community-feed/actions/workflows/codeql.yml)
-[](https://opensource.org/licenses/MIT)
-[](https://nodejs.org/)
-[](https://www.typescriptlang.org/)
+
+ Community-shaped ranking · Inspectable policy · Reproducible shadow demo
+
-Corgi Commons is a production Bluesky custom feed shaped through a limited governance pilot. Approved participants can vote on five global ranking signals, topic priorities that shape relevance, and content rules that shape eligibility. Closed results are reviewed and approved before the complete policy is applied and the feed is rescored. Bluesky shows the ordered posts; Corgi exposes the policy and available ranking receipts.
+
+ Open Corgi Commons
+ ·
+ Try the demo
+ ·
+ Watch the walkthrough
+ ·
+ Read the docs
+
-> **Research question:** Can communities meaningfully govern their own recommendation algorithms?
+
+
+
+
+
+
+
+
-
+Corgi Commons is a production Bluesky custom feed and a limited governance pilot. Anyone can view the public feed. Approved pilot participants can vote on five global ranking signals, topic priorities, and content rules. A closed round is reviewed and approved before its complete policy is applied and the feed is rescored.
----
+Bluesky renders the ordered posts. Corgi provides the governance and explanation layer: the active policy, score decomposition, epoch history, counterfactuals, and available ranking receipts.
-## Try It
+> **Research question:** Can a community meaningfully govern its own recommendation algorithm without giving up speed, legibility, or operational control?
-**No coding required.** Anyone can use the anonymous demo; a Bluesky account is needed only to save or subscribe to the feed.
+## Start Here
-1. **Open Corgi Commons** — view or subscribe to the public feed without a Corgi account:
- [Open Corgi Commons on Bluesky](https://bsky.app/profile/corgi-network.bsky.social/feed/community-gov)
+| Surface | What it is | Access |
+|---|---|---|
+| **Corgi Commons** | The live public custom feed served to Bluesky clients | [View or subscribe on Bluesky](https://bsky.app/profile/corgi-network.bsky.social/feed/community-gov) |
+| **Shadow governance demo** | An anonymous, isolated replay over a frozen Corgi Commons comparison corpus | [Try the interactive demo](https://feed.corgi.network/demo/) |
+| **Product walkthrough** | A 4:14 tour of the governance loop and reviewer-safe demo | [Watch how Corgi works](https://feed.corgi.network/how-it-works/) |
+| **Pilot access** | The waitlist for approved production-governance participation | [Request access](https://feed.corgi.network/start/) |
+| **Developer documentation** | Public API, architecture, and operating references | [Open docs.corgi.network](https://docs.corgi.network/) |
-2. **Try isolated shadow governance** — propose a policy, combine it with 24 scripted deterministic voter archetypes, and inspect how a frozen comparison corpus reranks without changing production:
- [feed.corgi.network/demo](https://feed.corgi.network/demo)
+## Watch the Governance Loop
-3. **Request pilot access** — production governance participation is currently available through an approved waitlist:
- [feed.corgi.network/start](https://feed.corgi.network/start)
+
+
+
+
+
----
+The published walkthrough follows the complete path from candidate posts to a community ballot, an approved policy, the ordered Bluesky feed, and an inspectable Corgi receipt. The [How Corgi Works](https://feed.corgi.network/how-it-works/) page pairs the video with an interactive policy replay.
-## Features
+## How a Vote Becomes a Feed
-**Governance**
-- Ballots can cover five global ranking signals, topic priorities, and include/exclude content rules
-- Include rules act as an allowlist, excludes take precedence, and rule adoption requires at least 30% support among content-rule ballots
-- Scheduled or manual rounds with configurable voting windows, arithmetic mean below 10 ballots, 10% trimmed mean at 10 or more, results review, operator approval, and post-approval rescoring
-- Append-only audit log (DB-enforced, no edits or deletes)
+1. **Ingest candidates.** Corgi reads public Bluesky activity from Jetstream, persists posts and interactions, and classifies post topics.
+2. **Compute reusable signals.** The scorer evaluates each candidate across recency, engagement, bridging, source diversity, and topic relevance.
+3. **Collect a complete ballot.** Approved participants can vote on global signal weights, topic priorities, and include/exclude content rules.
+4. **Aggregate and review.** Ballots aggregate after the configured voting window. The proposed policy must pass results review and operator approval; a direct transition cannot bypass that lifecycle.
+5. **Rescore and publish.** The approved policy becomes a new epoch, the candidate set is rescored, and the current feed snapshot is served through the AT Protocol feed-generator endpoint.
+6. **Inspect what happened.** Corgi exposes per-post score components, governance history, feed-level statistics, counterfactual rankings, and an append-only governance audit log.
-**Scoring & Transparency**
-- Score decomposition persisted per post per epoch — raw, weight, and weighted contribution for every registered component, in a normalized long table
-- Transparency endpoints: per-post explanations, counterfactual analysis, feed-level statistics
-- Redis-backed feed serving with snapshot cursors (<50ms response time)
+## What Is Live — and What Is a Demo
-**Feed Intelligence**
-- Jetstream ingestion with cursor persistence and automatic reconnection
-- Bluesky `acceptsInteractions` support (See More / See Less feedback buttons)
-- AT Protocol content label filtering (NSFW, moderation labels)
-- Interaction analytics: scroll depth, engagement attribution, keyword performance
+| Surface | What the repository supports | Boundary |
+|---|---|---|
+| **Production feed** | A live Bluesky custom feed backed by Jetstream ingestion, scheduled scoring, PostgreSQL, Redis, and AT Protocol XRPC routes | Viewing is public; production voting is limited to approved pilot participants |
+| **Production governance** | Signal, topic, and content-rule ballots with a review-and-approval lifecycle before application | Corgi is a limited pilot, not an open self-serve network of community feeds |
+| **Shadow demo** | One reviewer ballot plus 24 deterministic scripted voter archetypes rerank the same frozen comparison corpus | Demo state is isolated in dedicated Redis and never writes production governance, feed state, audit logs, or research exports |
+| **Synthetic voters** | Five transparent preference blocs demonstrate aggregation, inertia, and repeatable multi-epoch behavior | They are not LLM agents and are not validated models of human behavior |
+| **Ranking explanations** | Corgi shows raw signals, weights, contributions, publication adjustments, provenance, and counterfactuals | Rank badges and receipts are Corgi annotations; they are not native Bluesky UI |
+| **Research support** | Participant gating, consent flows, deterministic anonymization, and consent-aware exports | These capabilities make Corgi a research instrument; they are not a claim of completed participant-study results |
-**Research Mode**
-- Approved governance-participant list for the limited pilot; viewing Corgi Commons and using the shadow demo stay public
-- Research consent flow with IRB-ready architecture
-- Anonymized data export (deterministic hashing, correlatable across tables)
-- Legal framework: Terms of Service, Privacy Policy, research consent separation
+The demo contract is deliberately stricter than a marketing mock. It freezes an approved snapshot of published Corgi Commons inputs, holds the comparison corpus constant across shadow epochs, and labels any fallback mechanics fixture. See the [shadow-governance contract](docs/lab/demo-shadow-governance-contract.md) for its endpoints, isolation rules, snapshot gates, and receipt semantics.
-**Admin & Tooling**
-- Admin dashboard: governance controls, feed health, interactions, audit log
-- CLI tool (`feed-cli`): full admin operations from any terminal, no VPS access required
-- MCP server: Streamable HTTP admin tools for natural-language feed management
-- Public API reference at [docs.corgi.network](https://docs.corgi.network), auto-deployed from `docs/docs-site/`
-- Admin Swagger UI at `/api/docs` (production-gated); `/docs` is the public product documentation
-- Research data export: votes, scores, engagement, epochs, audit log (CSV/JSON)
+## Ranking Model
-**Engineering**
-- Automated unit, integration, contract, and stress tests with PR-gated CI
-- Genuinely pluggable scoring components: implement the `ScoringComponent` interface from `@corgi/feed-sdk`, register, ship. No schema migration required. See the [contribution guide](docs/contributing-scoring-components.md) and the [civility example](examples/civility-component/) for an end-to-end walk-through. ADR-0001 covers the design.
-- Pre-commit hooks (husky + lint-staged + tsc)
-- Dependabot for automated dependency updates
-- CodeQL + npm audit gates on pull requests
-- Shared types between frontend and backend (compile-time contract)
-- Code generators for new scoring components and routes
+The current production registry contains five normalized scoring components:
----
+| Component | What it measures | Current method |
+|---|---|---|
+| **Recency** | How recently a post was created | Exponential decay within the configured scoring window |
+| **Engagement** | Likes, reposts, and replies | Log-scaled weighted engagement with diminishing returns |
+| **Bridging** | Whether engagement crosses otherwise dissimilar audiences | Average pairwise Jaccard distance between engager follow sets, with an explicit insufficient-evidence state |
+| **Source diversity** | Whether one author is dominating a ranking batch | Diminishing score for repeated posts from the same author |
+| **Topic relevance** | How well a post's classified topics match community priorities | Confidence-dampened topic-vector relevance against approved topic weights |
-## Architecture
+The component score is:
```text
-┌─────────────────────────────────────────────────────────────┐
-│ INTERFACES │
-│ Web Dashboard │ CLI (feed-cli) │ MCP Server │
-└────────┬────────┴────────┬─────────┴────────┬───────────────┘
- │ │ │
- ▼ ▼ ▼
-┌─────────────────────────────────────────────────────────────┐
-│ FASTIFY SERVER │
-│ Governance APIs │ Admin APIs │ Export APIs │ XRPC │
-└────────┬──────────┴──────┬───────┴──────┬───────┴─────┬─────┘
- │ │ │ │
- ▼ ▼ ▼ ▼
-┌──────────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
-│ GOVERNANCE │ │ SCORING │ │ EXPORT │ │ FEED │
-│ Epochs │ │ 5 components│ │ CSV/JSON│ │ Skeleton│
-│ Votes │ │ Pipeline │ │ Anonymize│ │ Cursors │
-│ Aggregation │ │ (batch/5min)│ │ │ │ (<50ms) │
-└──────┬───────┘ └──────┬───────┘ └──────────┘ └────┬─────┘
- │ │ │
- ▼ ▼ ▼
-┌─────────────────────────────────────────────────────────────┐
-│ DATA LAYER │
-│ PostgreSQL 16 (posts, scores, epochs, votes, audit) │
-│ Redis 7 (feed snapshots, sessions, caches) │
-└─────────────────────────────────────────────────────────────┘
- ▲
- │
-┌──────┴──────┐ ┌───────────────┐
-│ INGESTION │◄───│ Bluesky │
-│ Jetstream │ │ Firehose │
-│ WebSocket │ │ (AT Proto) │
-└─────────────┘ └───────────────┘
+component score = Σ(raw component × approved signal weight)
```
-## Tech Stack
+Global signal weights sum to `1.0`. Topic priorities affect the relevance component. Eligibility rules and publication-stage adjustments are applied separately. Corgi persists each component's raw value, approved weight, and weighted contribution so a ranking can be reconstructed rather than merely described.
-| Layer | Technology |
-|-------|-----------|
-| Backend | Node.js 20, TypeScript 6, Fastify 5 |
-| Data | PostgreSQL 16, Redis 7 |
-| Frontend | Next.js 15 (React 19) static export, Tailwind, TanStack Query |
-| Protocol | `@atproto/api`, `@atproto/xrpc-server` |
-| NLP | winkNLP (topic classification) |
-| Testing | Vitest, Fastify inject |
-| Deploy | Docker, GitHub Actions CI/CD |
+The scoring contract is registry-driven and extensible. External authors can implement `ScoringComponent` against the public `@corgi/feed-sdk` surface, then follow the [component contribution guide](docs/contributing-scoring-components.md) and [working civility example](examples/civility-component/).
+
+## Architecture
----
+```mermaid
+flowchart LR
+ J["Bluesky Jetstream"] --> I["Ingestion and topic classification"]
+ I --> P["PostgreSQL"]
-## Quickstart
+ V["Approved participant ballots"] --> G["Governance epoch and approved policy"]
+ P --> S["Scoring pipeline"]
+ G --> S
+ S --> P
+ S --> R["Redis feed snapshot"]
+
+ B["Bluesky clients"] --> X["AT Protocol XRPC feed endpoint"]
+ X --> R
+
+ U["web-next · CLI · MCP"] <--> A["Fastify governance, transparency, and admin APIs"]
+ A <--> P
+```
+
+- PostgreSQL is the durable source for posts, governance state, score decomposition, audit data, and research records.
+- Redis is the serving layer for the current ranked feed. Anonymous demo sessions use a separate, non-persistent Redis namespace and instance.
+- `web-next/` is the canonical public frontend. `web/` is the legacy Vite frontend retained during migration and is still exercised by the full verification gate.
+
+## Repository Map
+
+| Path | Responsibility |
+|---|---|
+| [`src/ingestion/`](src/ingestion/) | Jetstream ingestion, cursor recovery, content-label filtering, topic classification |
+| [`src/scoring/`](src/scoring/) | Component registry, scoring pipeline, persistence, publication ordering |
+| [`src/governance/`](src/governance/) | Participant auth, ballots, aggregation, content rules, epoch lifecycle |
+| [`src/feed/`](src/feed/) | Fastify server and AT Protocol feed-generator routes |
+| [`src/transparency/`](src/transparency/) | Public explanations, statistics, counterfactuals, governance audit views |
+| [`src/demo/`](src/demo/) | Isolated deterministic shadow-governance service and frozen release snapshot |
+| [`web-next/`](web-next/) | Canonical Next.js public site, demo, voting, and transparency UI |
+| [`web/`](web/) | Legacy React/Vite compatibility frontend |
+| [`packages/feed-sdk/`](packages/feed-sdk/) | Public scoring-component type surface |
+| [`cli/`](cli/) | `feed-cli` operator interface |
+| [`docs/`](docs/) | Product, architecture, deployment, operations, security, and research evidence |
+
+## Local Development
### Prerequisites
-- Node.js >= 20
-- Docker and Docker Compose (for PostgreSQL + Redis)
-- A Bluesky account with an [app password](https://bsky.app/settings/app-passwords)
-### Setup
+- Node.js `>=20.19.0`
+- Docker with Docker Compose
+- A Bluesky feed identity and app password if you intend to publish or update a feed record
+
+### Install and run
```bash
git clone https://github.com/andrewnordstrom-eng/bluesky-community-feed.git
cd bluesky-community-feed
-# Install dependencies
+# The full verification gate covers the backend and both frontends.
+npm install
+cd web-next
+npm install
+cd ../web
npm install
-cd web && npm install && cd ..
+cd ..
-# Configure environment
+# Fill every value marked REQUIRED before starting the full service.
cp .env.example .env
-# Edit .env with your Bluesky credentials and service config
-# Start PostgreSQL + Redis
+# Start local PostgreSQL and the primary Redis instance.
docker compose up -d
-# Run migrations and seed initial governance epoch
npm run migrate
npx tsx scripts/seed-governance.ts
-# Build and run
-npm run build
-npm run dev
-
-# Frontend (separate terminal)
-cd web && npm run dev
+# Build the canonical static frontend, then serve it from Fastify.
+npm --prefix web-next run build
+WEB_DIST_DIR=web-next/out WEB_ROUTING_MODE=export npm run dev
```
-### Verify
-
-```bash
-npm run verify
-npm run docs:verify
-python3 -m py_compile scripts/generate-report.py scripts/generate-report-pdf.py scripts/report_utils.py
-MPLCONFIGDIR=/tmp python3 scripts/generate-report.py --csv tests/fixtures/report/report-sample.csv --epoch-json tests/fixtures/report/epoch-sample.json --dry-run
-MPLCONFIGDIR=/tmp python3 scripts/generate-report-pdf.py --csv tests/fixtures/report/report-sample.csv --epoch-json tests/fixtures/report/epoch-sample.json --dry-run
-npm audit --audit-level=moderate
-cd web && npm audit --audit-level=moderate
-curl http://localhost:3000/health # {"status":"ok"}
-```
+The base Compose file starts PostgreSQL and the primary Redis instance. Running the anonymous demo locally also requires its isolated Redis instance; its invariants and configuration are documented in the [shadow-governance contract](docs/lab/demo-shadow-governance-contract.md).
-### Quick Smoke Test
+### Verify a change
```bash
-# 1) Service health should return {"status":"ok"}
-curl -sS http://localhost:3000/health
+# Backend, tests, CLI, SDK, legacy web lint/build, and canonical web-next build
+npm run verify
-# 2) Feed describe should return a DID and feed URI payload
-curl -sS http://localhost:3000/xrpc/app.bsky.feed.describeFeedGenerator
+# Documentation links, commands, freshness, and repository references
+npm run docs:verify
-# 3) Direct CLI read against local DB should return JSON (epoch may be null on fresh DB)
-DATABASE_URL="postgresql://postgres:postgres@localhost:5432/community_feed" npm run cli -- --direct --json epoch status
+# Useful narrow checks
+npm test -- --run
+npm --prefix web-next run build
+npm run cli -- --help
```
----
-
-## Scoring Formula
-
-Five components, each normalized to 0.0–1.0:
-
-| Component | Signal | Method |
-|-----------|--------|--------|
-| Recency | Post age | Exponential decay (18hr half-life) |
-| Engagement | Likes, reposts, replies | Log-scaled (likes×1 + reposts×2 + replies×3) |
-| Bridging | Cross-community appeal | Jaccard distance of engager follow sets |
-| Source Diversity | Author variety | Diminishing returns per author (1.0 → 0.7 → 0.5 → 0.3) |
-| Relevance | Topic match × community preference | Weighted dot product of topic vectors and governance weights |
-
-**Component score:** `total = Σ(component_raw × approved_signal_weight)` where the five global signal weights sum to 1.0. Topic preferences affect the relevance component only; eligibility rules and publication adjustments are applied separately.
-
-All 15 numeric values (5× raw, weight, weighted) are persisted per post per epoch for full auditability.
-
----
+## Interfaces
-API Surface
-
-**Public (no auth)**
-- `GET /xrpc/app.bsky.feed.getFeedSkeleton` — Feed skeleton (AT Protocol)
-- `GET /xrpc/app.bsky.feed.describeFeedGenerator` — Feed metadata
-- `POST /xrpc/app.bsky.feed.sendInteractions` — See More/See Less signals
-- `GET /api/transparency/*` — Score explanations, stats, counterfactuals, audit log
-- `GET /health`, `/health/ready`, `/health/live` — Health checks
-
-**Governance (session auth)**
-- `POST /api/governance/auth/login` — Bluesky handle + app password
-- `POST /api/governance/vote` — Submit weight + keyword + topic votes
-- `GET /api/governance/weights`, `/epochs`, `/content-rules` — Current governance state
-
-**Admin (session auth + DID allowlist)**
-- `GET /api/docs` — OpenAPI / Swagger UI (admin-gated in production)
-- `/api/admin/status`, `/epochs`, `/governance/*` — Governance controls
-- `/api/admin/feed/*` — Feed health, rescore, Jetstream reconnect
-- `/api/admin/interactions/*` — Scroll depth, engagement, keyword analytics
-- `/api/admin/participants/*` — Research participant management
-- `/api/admin/export/*` — Research data export (votes, scores, engagement, epochs, audit)
-
-**MCP Server**
-- `POST /mcp` — Streamable HTTP endpoint for programmatic admin tooling
+Public and authenticated API surfaces
+
+- **AT Protocol:** `getFeedSkeleton`, `describeFeedGenerator`, and feed interactions under `/xrpc/app.bsky.feed.*`
+- **Transparency:** per-post explanations, feed statistics, counterfactuals, and the governance audit log under `/api/transparency/*`
+- **Governance:** session auth, ballots, current weights, topic catalog, content rules, epochs, research consent, and waitlist routes under `/api/governance/*`
+- **Admin:** protected governance lifecycle, feed health, participant, topic, interaction, and export routes under `/api/admin/*`
+- **MCP:** Streamable HTTP admin tooling at `/mcp`
+- **OpenAPI:** public reference at [docs.corgi.network](https://docs.corgi.network/); Swagger UI at `/api/docs` is admin-gated in production
-CLI
+Operator CLI
-Full admin operations from any terminal. Authenticates via the same session system as the web dashboard — no VPS credentials required.
+The CLI uses the same authenticated backend as the web administration surface; it does not require direct VPS access.
```bash
-npm run cli -- login your-handle.bsky.social xxxx-xxxx-xxxx-xxxx
+npm run cli -- --help
npm run cli -- epoch status
npm run cli -- votes summary --epoch 1
npm run cli -- feed health
-npm run cli -- export votes --epoch 1 --format csv
npm run cli -- topics list
-npm run cli -- announce send "Voting opens tomorrow"
```
-See `npm run cli -- --help` for all commands.
-
----
-
## Documentation
-| Document | Description |
-|----------|-------------|
-| [`docs/SYSTEM_OVERVIEW.md`](docs/SYSTEM_OVERVIEW.md) | Architecture and data flow |
-| [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) | Production deployment guide |
-| [`docs/OPS_RUNBOOK.md`](docs/OPS_RUNBOOK.md) | Operations and troubleshooting |
-| [`docs/SECURITY.md`](docs/SECURITY.md) | Security model and threat analysis |
-| [`ROADMAP.md`](ROADMAP.md) | Product and engineering roadmap |
-| [`RELEASING.md`](RELEASING.md) | Semantic versioning and release process |
-| [`docs/ISSUE_TRIAGE.md`](docs/ISSUE_TRIAGE.md) | Issue labels, triage, and newcomer flow |
-| [`docs/MCP_SETUP.md`](docs/MCP_SETUP.md) | MCP server connection guide |
-| [`docs/STABILITY_TEST.md`](docs/STABILITY_TEST.md) | Stability and load testing |
-| [`docs/dev-journal.md`](docs/dev-journal.md) | Development log with decisions |
-| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contributor guidelines |
-| [`CHANGELOG.md`](CHANGELOG.md) | Version history |
-| [`SECURITY.md`](SECURITY.md) | Vulnerability reporting policy |
-| [`SUPPORT.md`](SUPPORT.md) | Support channels and issue guidance |
-| [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) | Community code of conduct |
-| [`legal/`](legal/) | Terms of Service, Privacy Policy |
-
----
-
-## Research Context
-
-This project is a research instrument for studying algorithmic governance. It is developed in the context of work on community-governed recommendation systems for decentralized social networks.
-
-The system is designed so that:
-- Every ranking decision is decomposable and auditable
-- Community preferences are captured through structured governance votes
-- The effect of governance changes on feed behavior is measurable across epochs
-- Research data can be exported with deterministic anonymization for analysis
-
-If you use this system in research, cite the repository URL and commit SHA used for your analysis.
-
----
+| Document | Use it for |
+|---|---|
+| [`docs/PRD.md`](docs/PRD.md) | Current mission, outcomes, and non-goals |
+| [`docs/SYSTEM_OVERVIEW.md`](docs/SYSTEM_OVERVIEW.md) | Deeper system and data-flow tour |
+| [`docs/lab/demo-shadow-governance-contract.md`](docs/lab/demo-shadow-governance-contract.md) | Exact public-demo behavior and evidence boundary |
+| [`docs/contributing-scoring-components.md`](docs/contributing-scoring-components.md) | Adding a scoring component through the public SDK |
+| [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) | Production deployment and rollback |
+| [`docs/OPS_RUNBOOK.md`](docs/OPS_RUNBOOK.md) | Operations, health checks, incidents, and recovery |
+| [`docs/SECURITY.md`](docs/SECURITY.md) | Security architecture and threat analysis |
+| [`SECURITY.md`](SECURITY.md) | Private vulnerability reporting |
+| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contribution and pull-request workflow |
+| [`CHANGELOG.md`](CHANGELOG.md) | Released changes |
+
+## Research and Citation
+
+Corgi is an open-source research instrument for studying community-governed recommendation. The system is designed to make policy changes measurable across epochs while keeping participant consent and export boundaries explicit.
+
+If you use Corgi in research, cite the repository URL and the exact commit SHA used for the analysis. Treat the software's capabilities, the public shadow demo, and any human-study findings as separate claims.
## License
From d23302e8d9d5ceac6c55a20f1a37ac53c327b3e9 Mon Sep 17 00:00:00 2001
From: Andrew Nordstrom <89470090+AndrewNordstrom@users.noreply.github.com>
Date: Tue, 21 Jul 2026 13:28:46 -0700
Subject: [PATCH 2/5] PROJ-153 Address README review feedback
---
README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 295bc405..2c1b7aa1 100644
--- a/README.md
+++ b/README.md
@@ -168,8 +168,9 @@ cd ..
# Fill every value marked REQUIRED before starting the full service.
cp .env.example .env
-# Start local PostgreSQL and the primary Redis instance.
-docker compose up -d
+# Start local PostgreSQL and the primary Redis instance, then wait for both
+# Compose health checks to pass before running migrations.
+docker compose up -d --wait --wait-timeout 60 postgres redis
npm run migrate
npx tsx scripts/seed-governance.ts
@@ -196,6 +197,8 @@ npm --prefix web-next run build
npm run cli -- --help
```
+> **Known limitation (2026-07-21):** `npm run docs:verify` exits nonzero on a clean checkout because 12 tracked documents in `docs/freshness.json` exceed the 120-day review window. The command still checks links, commands, and repository references before reporting that repository-wide freshness debt.
+
## Interfaces
From f26e110e846992db2c5378f69682c321f0a9b41d Mon Sep 17 00:00:00 2001
From: Andrew Nordstrom <89470090+AndrewNordstrom@users.noreply.github.com>
Date: Tue, 21 Jul 2026 13:33:44 -0700
Subject: [PATCH 3/5] PROJ-153 Document Compose version requirement
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 2c1b7aa1..d26dbf35 100644
--- a/README.md
+++ b/README.md
@@ -148,7 +148,7 @@ flowchart LR
### Prerequisites
- Node.js `>=20.19.0`
-- Docker with Docker Compose
+- Docker with Docker Compose v2.17.0 or newer
- A Bluesky feed identity and app password if you intend to publish or update a feed record
### Install and run
From 37c208d765ad93a2f6b094af09e80090cf828631 Mon Sep 17 00:00:00 2001
From: Andrew Nordstrom <89470090+AndrewNordstrom@users.noreply.github.com>
Date: Tue, 21 Jul 2026 13:40:46 -0700
Subject: [PATCH 4/5] PROJ-153 Clarify total score formula
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index d26dbf35..49d1a5fb 100644
--- a/README.md
+++ b/README.md
@@ -93,10 +93,10 @@ The current production registry contains five normalized scoring components:
| **Source diversity** | Whether one author is dominating a ranking batch | Diminishing score for repeated posts from the same author |
| **Topic relevance** | How well a post's classified topics match community priorities | Confidence-dampened topic-vector relevance against approved topic weights |
-The component score is:
+Each component first produces a raw score. Corgi multiplies those raw values by the approved signal weights, then sums the weighted contributions into the total score:
```text
-component score = Σ(raw component × approved signal weight)
+total score = Σ(raw component score × approved signal weight)
```
Global signal weights sum to `1.0`. Topic priorities affect the relevance component. Eligibility rules and publication-stage adjustments are applied separately. Corgi persists each component's raw value, approved weight, and weighted contribution so a ranking can be reconstructed rather than merely described.
From 1e466c289183482594073c1fa5d9e99357a4b8c9 Mon Sep 17 00:00:00 2001
From: Andrew Nordstrom <89470090+AndrewNordstrom@users.noreply.github.com>
Date: Tue, 21 Jul 2026 15:43:23 -0700
Subject: [PATCH 5/5] PROJ-153 Align README with demo paper
---
README.md | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 49d1a5fb..c203a5a9 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,9 @@
-Corgi Commons is a production Bluesky custom feed and a limited governance pilot. Anyone can view the public feed. Approved pilot participants can vote on five global ranking signals, topic priorities, and content rules. A closed round is reviewed and approved before its complete policy is applied and the feed is rescored.
+Corgi — short for Community-Oriented Recommendation: Governance and Infrastructure — treats a shared recommender as a community resource.
+
+Corgi Commons is a production Bluesky custom feed and a limited governance pilot. Anyone can view the public feed. Approved pilot participants can collectively govern five global ranking signals, topic priorities, and content rules. A closed round is reviewed and approved before its complete policy is applied and the feed is rescored.
Bluesky renders the ordered posts. Corgi provides the governance and explanation layer: the active policy, score decomposition, epoch history, counterfactuals, and available ranking receipts.
@@ -63,7 +65,7 @@ The published walkthrough follows the complete path from candidate posts to a co
1. **Ingest candidates.** Corgi reads public Bluesky activity from Jetstream, persists posts and interactions, and classifies post topics.
2. **Compute reusable signals.** The scorer evaluates each candidate across recency, engagement, bridging, source diversity, and topic relevance.
-3. **Collect a complete ballot.** Approved participants can vote on global signal weights, topic priorities, and include/exclude content rules.
+3. **Collect valid ballots.** Approved participants can vote on global signal weights, topic priorities, include/exclude content rules, or any combination of those channels. A ballot must include at least one channel; a signal-weight vote includes the complete normalized five-weight vector.
4. **Aggregate and review.** Ballots aggregate after the configured voting window. The proposed policy must pass results review and operator approval; a direct transition cannot bypass that lifecycle.
5. **Rescore and publish.** The approved policy becomes a new epoch, the candidate set is rescored, and the current feed snapshot is served through the AT Protocol feed-generator endpoint.
6. **Inspect what happened.** Corgi exposes per-post score components, governance history, feed-level statistics, counterfactual rankings, and an append-only governance audit log.
@@ -245,7 +247,9 @@ npm run cli -- topics list
## Research and Citation
-Corgi is an open-source research instrument for studying community-governed recommendation. The system is designed to make policy changes measurable across epochs while keeping participant consent and export boundaries explicit.
+Corgi is an open-source research instrument for studying community-governed recommendation. Its central question is collective rather than individual: how can a community set the objective of a recommender it shares? The system makes the resulting policy, score decomposition, and changes across epochs inspectable while keeping participant consent and export boundaries explicit.
+
+The shadow demo demonstrates the mechanism, not a result about human behavior. One reviewer ballot and 24 deterministic synthetic voters rerank a fixed post set so within-session rank changes can be attributed to policy changes rather than corpus drift. The synthetic electorate is not evidence that the voter archetypes model people or that a human community has reached consensus.
If you use Corgi in research, cite the repository URL and the exact commit SHA used for the analysis. Treat the software's capabilities, the public shadow demo, and any human-study findings as separate claims.