One host.
Many factories.
Shared infrastructure.

Factory runs the ticket pipeline for one repository. District manages the fleet: shared configuration, engine upgrades, host policy, and operational status that tells you what is running, what needs attention, and what is still unknown.

Current milestone: graphical Overview and on-demand fleet reporting; operator acceptance and console cutover remain pending.
Progress through September 18, 2026

district statusexit 1 · operational attention
$ district status
Illustrative fleet · not live telemetry

rocm-cli   scheduled waiting  unknown
gpuflo     running            normal
rocm-app   capped             attention

# status keeps operating state, execution
# and observation quality separate
# exit: 0 normal · 1 attention · 2 unknown
Reel

From issue to fleet in 45 seconds.

Factory works each ticket from triage to merge; District runs the fleet of factories on one host.

The problem

The second factory creates concerns no single factory can own.

Repository autonomy is useful. Duplicating host configuration, upgrade procedures, and operational checks across every repository is not.

01

One place for host settings

Keep model endpoints, worker defaults, dashboard ports, and timer cadence in the host registry, not scattered across public repositories.

02

Repeatable maintenance

Reconcile generated units and labels, check prerequisites, and upgrade the shared engine without replacing each repository's own rules.

03

Bounded failure, explicit recovery

Cap repeatedly failing timers and check package-age policy. Restore a capped factory only after an explicit reset pass succeeds.

04

A fleet answer you can inspect

See operational findings and source freshness together. A review requesting changes is project work, not automatically broken machinery.

Ownership model

Classified by where it lives, not by feature.

Every setting District touches is either host-side or committed to a repo. The split is the product.

District owns — host-side, never committed

  • mikeroySoft/factory install and upgrade
  • triage endpoint and model
  • worker / reviewer argv defaults
  • dashboard port allocation, timer cadence, bind host
  • systemd units, rendered via factory install
  • registry of managed repos
  • GitHub labels, re-applied idempotently
  • supply-chain policy (minimum package age)
  • consecutive-failure cap on each timer

Factory owns — committed to its repo

  • [[gate.check]] commands
  • [leak_scan] excludes
  • [repo].upstream for forks
  • .github/ISSUE_TEMPLATE/agent_task.md
  • .factory-lessons.md
  • .gitignore lines
  1. District writes committed files exactly once, at onboarding, and only reports drift afterwards.
  2. District rewrites host-side artifacts on every apply without asking.
  3. District never commits to a managed repo. It prints the commit line.
Commands

Nine verbs. Each one shells out to the host tools it checks or manages.

District never imports from mikeroySoft/factory and never reimplements a factory command. If it needs a per-repo fact, the fix is a flag on factory.

district add
Onboard a path or URL, or adopt a repo that already has .factory.toml. Detects fork parent, ecosystem, and the next free port; proposes gate checks from CI; lifts host-owned keys out of the repo file.
district apply
Reconcile units, labels, doctor checks, failure caps, and host policy. Hourly reconciliation is available through dashboard --install. When [defaults].factory_ref is set, every apply installs the changed remote Factory commit only after all GitHub checks succeed, without touching the source checkout. --upgrade explicitly reinstalls the shared engine from the local checkout with the registry's selected factory_extras; --reset SLUG requires a successful pass before restoring a capped timer.
district doctor
Check District's host prerequisites, registered repository remotes, dashboard ports, package policy, and units. Reports every check as PASS, WARN, or FAIL.
district status
Operating state, execution state, observation quality, and evidence-backed findings, with version and project metrics alongside. Text or --json; exit 0 for normal, 1 for operational attention, 2 for unknown without attention.
district report
Print one on-demand, read-only Markdown fleet review from a bounded observation round and existing metric caches. Every repository, source age, coverage gap, and actual producer window stays visible; partial counts are labeled and rates are pooled only from compatible producer counts and windows.
district metrics
Per-factory size, people, velocity, work, quality, resolution, and traffic — sourced from git and gh, never estimated. Cached hourly.
district dashboard
Serve the shared cached fleet and scoped console. Atlas and management remain at the default route until cutover. Optional LAN viewing is read-only; management stays on direct localhost access. See current routes and access boundaries.
district update
Resolve an official ref to one immutable SHA, require the successful ci.yml test job for that SHA, and transactionally replace only District's uv tool. Supports query-only --dry-run, machine-readable --json, and retained offline --rollback; Factory and unit files are unchanged.
district rm
Disable and delete the units, drop the registry entry. Repo files untouched; the factory can be re-added later.
Available now

A shared operational picture. Not another project inbox.

The scoped console and graphical Overview are merged: stable diagrams show real cached state, concurrent stage occupancy, capacity, source ages, findings, and evidence-backed motion. Detailed Flows and Brief work, combined operator acceptance, and console cutover are still pending.

Merged · graphical Overview

Observe state, not decoration.

Equally weighted factory diagrams show concurrent stages and bounded recent activity. Fresh confirmed active stages can pulse, while newly observed transitions and completions move once; watch, pause, hidden-tab, and reduced-motion behavior preserve the facts.

Merged · scoped navigation

Keep your place.

Overview, Flows, and Brief routes share all-factory or single-factory scope. Deep links, browser Back, scroll restoration, and focus-preserving updates keep navigation usable while the fleet changes.

Merged · read-only LAN

View remotely. Manage locally.

Opt into LAN viewing without exposing host controls. Remote requests cannot run management or detection; browser data is bounded and sanitized rather than a copy of host configuration.

Try the current console: after starting the dashboard, open http://127.0.0.1:8760/?view=overview for the implemented graphical watch surface. Change view to flows or brief for the shared scoped shells; detailed flow lanes, the evidence panel, and the full Brief are still planned. Combined Overview/Flows visual acceptance and the default-route cutover remain pending. Atlas and existing management remain at / and /legacy.

LAN viewing requires an explicit bind such as --host 0.0.0.0. Manage and detect require direct HTTP to numeric loopback or localhost at the actual server port. LAN URLs remain read-only even on the host; DNS aliases and reverse proxies are unsupported, and forwarded headers fail closed. Network policy.

Design decisions

What we chose. What we chose not to build.

District started with a city-shaped Atlas. The new operating surface puts work and evidence ahead of architecture and repository size, while Atlas remains the default until acceptance and cutover.

Host infrastructure, not repo control

District owns the shared machinery. Gate commands, reviewable files, and project decisions stay with each Factory. It shells out to public commands rather than importing the engine's internals.

Operational attention, not project noise

A failing runner and a failing product test are different events. Ordinary CI waits, review revisions, and human decisions do not independently turn into fleet incidents.

Unknown is an answer

Missing or stale observations stay visible. Re-reading a cache does not make old evidence fresh, and an unavailable snapshot does not prove that a dispatcher stopped.

Evidence before animation

The implemented graphical Overview uses equally weighted factories and concurrent execution lanes, not taller buildings for bigger repos. Its motion describes observed activity, never fictional progress or an invented ETA; detailed Flows and Brief graphics remain separate held work.

Read the approved operations-console specification · One operator, one Linux host. Multi-host orchestration, team management, and an LLM-generated Brief are outside this console's scope.

Operational model

One classification for the CLI and dashboard.

Machinery findings, project context and observation quality are separate. CLI status takes one bounded runtime/full collection round through the same source adapters as the server. Missing execution telemetry is explicit, not reconstructed from artifacts.

DimensionValues
Operatingrunning · scheduled waiting · deliberately paused (recorded intent only) · capped · unexpectedly stopped (authoritative evidence only) · unknown
Executionstage-active · known wait · blocked · completed · failed · interrupted · unknown
Observationfresh · stale · partial · unavailable; source times are retained across rereads

Exit 0: every entry normal, or an empty fleet. Exit 1: any supported operational attention. Exit 2: unknown observation or state without attention. Attention takes precedence, but unknowns remain visible. Engines without execution telemetry report partial/unknown rather than silently healthy.

The CLI and dashboard share source adapters and classification. Runtime and full snapshots refresh independently; producer timestamps, record-level quality, bounded history, and gaps remain explicit. A slow full snapshot does not need to block publication of runtime evidence.

Integrating with District? The source and JSON contract documents observation bounds, findings, and the migration from the old health/reasons fields. district status --json exposes the normalized state keyed by repository slug.

Failure cap

Ten consecutive failed passes disable a timer. Fix the cause, then use district apply --reset SLUG: the timer resumes only after a successful pass.

Supply-chain policy

Workers install packages with the operator's credentials. District checks the host-wide minimum package age for uv, npm, and cargo. Missing policy is a WARN, never a silent skip.

Context without false alarms

First-gate pass rate and review bounce remain useful project metrics. They do not independently label the underlying machinery unhealthy.

Changelog

From fleet registry to operational evidence.

Selected milestones through September 18, 2026. Dates below use UTC merge history for PRs; these are source milestones, not tagged releases or a claim about every installed host.

  1. Merged

    An on-demand fleet review joins the command line.

    district report prints one read-only Markdown report from a bounded, non-atomic observation round and existing metric caches. It retains source ages, lists every registered repository and coverage gap, discloses actual producer windows and bounded GitHub queries, labels partial counts, and pools rates only when numerators, denominators, and windows are compatible.

    Boundary: this is an operator-requested snapshot, not a scheduled report, provider-written narrative, new collector, automatic publication, or claim of autonomous delivery.

    Report #52 · Issue #51 · Source milestone 3ab332d

  2. Merged

    District can update itself without updating the fleet.

    • district update pins an official commit with successful CI, prepares it before downtime, preserves the dashboard bind and active District timers, and verifies the replacement collector. Query-only planning, offline rollback, and a retained recovery helper cover both normal upgrades and interrupted replacements.
    • Separately, a shared Factory engine reinstall now preserves the optional [defaults].factory_extras selected in the host registry instead of silently returning to a bare install.

    Why: District self-update must not also update Factory or rewrite units; an explicit Factory reinstall must retain the operator's selected extras.

    District update and recovery · Factory extras preservation cc66f1b

  3. Merged · implementation

    The graphical Overview renders observed fleet activity.

    Stable, equally weighted diagrams show concurrent stage occupancy, capacity, freshness, findings, resources, and bounded recent activity. Fresh confirmed active stages may pulse; distinct observed transitions and completions animate once, with watch, pause, hidden-tab, reduced-motion, keyboard, and narrow-screen safeguards.

    Still gated: merge is not human acceptance or cutover. A real fresh-active pulse, real resource/capacity waits, and real capped/unexpected-stop observations remain uncaptured or fixture-only; the operator's combined Overview/Flows visual acceptance is pending.

    D04 · #27 · Source milestone 7e17b14 · Evidence and remaining exit gap

  4. Merged

    The scoped console lands; telemetry and upgrades get tighter.

    • Overview / Flows / Brief navigation over real cached state, with factory scope, honest loading and expired-selection messages, and Back / scroll / focus preservation.
    • CLI status now collects the same runtime evidence as the dashboard. Record-scoped diagnostics preserve partial observations without flattening unrelated current evidence.
    • Shared-engine upgrades wait for every managed active pass and restore timers before reporting their state. Full-snapshot collection has its own bounded deadline.

    Why: agreement between surfaces and safe maintenance matter more than adding another visualization.

    Console #35 · Telemetry #38 · Upgrade safety #39 · Record quality #41

  5. Merged

    One classification, one collector, an explicit trust boundary.

    • Operating state, execution state, observation quality, and findings replace the old mixed health verdict.
    • Independent runtime/full refresh, bounded collection work, and sanitized cache-only browser reads become the common console data source.
    • LAN viewing becomes read-only; host mutations fail closed outside trusted local requests.
    • Host doctor, CI-derived gate proposals, and locked hourly reconciliation join the everyday workflow.

    Why: more viewers should not create more collection work, and remote visibility should not grant remote control.

    Classification #33 · Collector #34 · LAN boundary #32 · Doctor #16 · Onboarding #18 · Reconciliation #19

  6. Design approved

    From an architecture map to an operations console.

    Approved the Overview / Flows / Brief direction, a shared evidence model, and dependency-gated implementation tickets. Atlas stays available until the new console passes its implementation and human acceptance checkpoints.

    Why: repository size is not operational importance. The operating screen should answer whether work is flowing and what the operator can actually act on.

    Approved specification and ticket plan

  7. September 3–4, 2026Initial implementation

    A district around the factories.

    Introduced the host registry, onboarding and adoption, shared defaults, port allocation, reconciliation, upgrades, failure caps, and fleet status. Added cached repository metrics, the Atlas, local management, dashboard installation, and a reusable agent skill.

    Why: centralize what every factory needs without taking ownership of its committed configuration or project decisions.

    Initial implementation · Live Atlas · Agent skill

Full commit history · All merged pull requests

Roadmap

Make the machinery readable. Then make it the home screen.

Shared state, collection, the LAN boundary, the scoped shell, and D04's graphical Overview implementation are merged. As of September 18, 2026, the current held console milestone is D05 Flows, followed by D06 Brief and the acceptance-gated management/cutover sequence — not a release-date promise.

Implemented · merged September 9

Graphical Overview

Stable factory positions, concurrent stage occupancy, capacity, source freshness, bounded activity, and evidence-backed motion are implemented. Real fresh-active pulse, resource/capacity-wait, and capped/stopped observations are still incomplete or fixture-only; combined operator visual acceptance remains pending.

D04 · #27 · merged source.

Following · held

Flows & Brief

Investigate concurrent executions, waits, and review loops through one reusable evidence panel. Then read a deterministic Brief of findings, changes, recoveries, and maintenance from that same snapshot.

D05 · Flows #28 → D06 · Brief #29.

Acceptance-gated · held

Management & cutover

Bring existing management into explicit, safe operator workflows. Make the console the default only after dependency checks, human visual approval, desktop/LAN acceptance, and a retrievable prototype archive.

D08 · Management #30 · D09 · Cutover #31.

Merged is not accepted or cut over. D04 is implemented in source, but its remaining live-state evidence and the operator's combined Overview/Flows visual checkpoint still apply. D05 Flows #28, D06 Brief #29, management #30, and cutover #31 remain open and held. Atlas remains the default; successful CI alone does not authorize console cutover.

Also on the horizon — open backlog, not part of the console release promise

Follow the live issue tracker for current status, dependencies, and discussion. Scope or order may change as real operation provides evidence.

Install

Python 3.11+, one dependency, a stdlib HTTP server.

For a Linux host with user systemd, Factory, git, and an authenticated gh CLI. Runtime execution detail requires a Factory build supporting dashboard --runtime-json.

shell
$ npx skills add mikeroysoft/district
$ uv tool install git+https://github.com/mikeroySoft/district
$ district doctor                       # check this host before onboarding
$ district add ~/dev/owner/repo        # or a GitHub URL; adopts an existing .factory.toml
$ district apply                        # reconcile units, labels, doctor, caps, policy
$ district dashboard --install          # dashboard + hourly metrics and apply timers
$ district status
$ district report                       # on-demand read-only Markdown review on stdout
$ district update --dry-run             # exact SHA, CI eligibility, service plan; no mutation

The host config file at ~/.config/factory/config.toml is the registry. No second store. A repo is managed iff it has a [repo."owner/name"] table with a path.

Optional Factory features survive every shared, host-wide engine reinstall when selected in the registry, for example:
[defaults]
factory_extras = ["atlas"]

Omit the setting or use an empty array to keep installing bare Factory; run district apply --upgrade to apply the selection to the one engine used by every managed repository.

Set factory_ref = "main" under [defaults] to make every hourly district apply follow the Factory clone's GitHub origin. District resolves and installs the immutable remote SHA only when every check run has completed successfully, records it under [defaults.engine], and leaves the installed engine unchanged while CI is pending or failed. Omit factory_ref to keep upgrades explicit.

District self-update supports only a non-editable uv install from the official repository. It prepares the target before downtime, runs replacement and recovery from a retained stdlib helper outside the managed environment, and keeps the prior successful installation for district update --rollback. Metadata lives under ${XDG_STATE_HOME:-~/.local/state}/district/update, never in Factory's registry. A source checkout can bootstrap the installed tool with uv run python -m district update --to <eligible-sha> --yes.