Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 68 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ It is not a marketplace and there is no network to join. You run both halves —
product, and [D2](docs/decisions/D2-economics.md) for the arithmetic that ruled out
the alternative.

**This is the v1.0.0 feature-complete milestone — not a maturity claim.** It means the
v1 scope is built and the gate is green, not that anyone has run this in anger. Read
"What is actually true" before relying on anything here.
**This is the v1.0.1 feature-complete milestone — not a maturity claim.** It means the
v1 scope is built and the gate is green on every supported platform, not that anyone
has run this in anger. Read "What is actually true" before relying on anything here.

## What is actually true, as of 2026-08-15
## What is actually true, as of 2026-08-17

Verified, not aspirational. `STATUS.md` is generated from real test runs; this
section summarises it in prose.
Expand All @@ -29,9 +29,18 @@ section summarises it in prose.
Zenoh mesh, advertises the models Ollama actually has, and survives the Scheduler
being unreachable. The Scheduler matchmakes, dispatches over the mesh (which is how
a node behind NAT is reachable at all), and exposes an OpenAI-shaped gateway behind
RS256 JWT auth. State can persist across restarts. CI runs the gate on Linux, macOS
and Windows across Python 3.11–3.14; `STATUS.md` records the last measured result and
the commit it covers.
RS256 JWT auth. State can persist across restarts.

CI runs the gate on Linux, macOS and Windows across Python 3.11–3.14 — ten jobs — and
as of `25fe60c` all ten pass. Worth stating plainly rather than as a badge: **they did
not, from 2026-08-09 to 2026-08-17.** The three Windows legs were red for eight days,
across the `v1.0.0` release commit, and nothing in this repository noticed. See
"What we cannot see" below, because that gap is more instructive than the bug was.

**If `STATUS.md` and the paragraph above disagree, they are both right.** That claim
comes from reading the run directly; `STATUS.md` reports `UNVERIFIABLE` whenever it is
generated on a machine without the `gh` CLI, because that is the only way it knows how
to ask. Regenerate it where `gh` is installed and authenticated and the line resolves.

**Does not work, and is not claimed to:**

Expand All @@ -51,8 +60,59 @@ the commit it covers.
there is no payout path — not "not yet", but a decision
([D2](docs/decisions/D2-economics.md)).
- **There is no content filtering, no meaningful rate limiting, and no backups**, and
nothing verifies that a node ran the model it claims.
nothing verifies that a node ran the model it claims. The rate limiter is a
per-instance abuse dampener, not a quota. Canary checks catch a host running *no*
model; they cannot catch a host running the *wrong* one.
[`docs/OPERATING.md`](docs/OPERATING.md) lists what you take on by running this.
- **`/v1/batch` is not implemented** — it answers 501. It is authenticated and
tenant-scoped, because those were real fixes to a real hole, but it dispatches
nothing.
- **JWTs cannot be revoked.** They are stateless by design; the mitigations are a
server-enforced TTL cap and key rotation. There is no revoke button and this is
said plainly rather than implied away.
- **Nodes installed before [D9](docs/decisions/D9-admission-is-not-identity.md) keep
the old weakness** — one header meaning both fleet admission and node identity —
until they are upgraded. That is a deliberate compatibility choice, not an
oversight: refusing them would strand every running host.

## What we cannot see

Distinct from the list above, which is what does not *work*. This is what this
project's own verification **cannot observe** — the gaps where a defect would not be
caught by anything here. It is written down because
[`docs/PREMISES.md`](docs/PREMISES.md) P8 records that every falsification of "the
gate is the definition of does this pass" has arrived by **absence rather than
failure**, and an unlisted absence is indistinguishable from an all-clear.

- **`install.ps1` has never been executed, by anything, ever.** `install.sh` gets a
real run against a throwaway tree (`scripts/verify_install.sh`); the PowerShell
installer is only ever *read* — `scripts/audit_system.py` greps it for strings and
`tests/test_installer_parity.py` ratchets its structure. Every Windows install
defect to date (W1–W5, W8) was therefore found by a person on a real machine, not
by the gate. Assume the next one will be too.
- **The repository cannot read its own CI.** `scripts/generate_status.py` shells out
to `gh`; where `gh` is absent it reports `UNVERIFIABLE — cannot query run history`.
That is honest, and it reads like "no known problem". It is the mechanism by which
a red build sat under a published release for eight days. **The fix is known and
not yet made:** fall back to the GitHub REST API so the answer does not depend on
which machine regenerated the file.
- **Work on a branch is unverified until it becomes a pull request.** The workflow
triggers only on `push` to `main` and on PRs, so a feature branch gets no CI at all.
- **The local gate is one operating system and one interpreter.** CI is nine legs; a
developer's run is one. Platform-specific defects are structurally invisible
locally, and there have now been three: a cp1252 text encoding (2.9), CRLF line
endings (V1), and wall-clock resolution (V2). A local `PASS` is a weaker claim than
a CI `PASS` and the gate says so in its own output.
- **The gate skips checks it cannot run**, naming them as `DID NOT RUN`: a missing
interpreter, `shellcheck` if absent, the website suite without `node_modules`. The
honesty is real; the coverage still is not there.
- **`docker-compose.test.yml` has never run.** Two defects were found in it by
reading (`tests/test_compose_env_matches_settings.py`) rather than by executing it.
- **Four module pairs in `experimental/` remain duplicated** — `quantization`,
`local_boundary`, `kv_cache`, `transport`. Drift is ratcheted, not eliminated.
- **No human outside this project has reviewed any of it.** Two independent AI desk
reviews of the market premises are in [`docs/review/`](docs/review/) and they
converged, which is evidence but not independence.

## What this project has decided, and what it hasn't

Expand Down
14 changes: 11 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# ROADMAP — v1

Status: **Stages 0–4, C and D are complete. 1.5 is half earned — a second machine
served a real request over the mesh on 2026-08-11, but not across a real NAT.
D7 is open. W1–W10 are done; W7 is done in code and unexercised on real hardware.**
Status: **Stages 0–4, C and D are complete. Released as `v1.0.1` on 2026-08-17, with
CI green on all ten jobs (Linux/macOS/Windows × Python 3.11–3.14) at `25fe60c`.
1.5 is half earned — a second machine served a real request over the mesh on
2026-08-11, but not across a real NAT. D7 is open. W1–W10 are done; W7 is done in
code and unexercised on real hardware. V1–V3 closed the Windows CI failure that had
been red since 2026-08-09, including across the `v1.0.0` release commit.**

**`v1.0.0` was released on 2026-08-15 over a red CI run, and the tag is deliberately
left where it is.** Moving it would have silently changed the bytes its published
release hands out. `v1.0.1` is the first release whose commit CI has ever passed on
every supported platform. Both tags stand: `v1.0.0` → `39f0227`, `v1.0.1` → `25fe60c`.

What is NOT done, and why, so this line does not have to be re-derived:

Expand Down
29 changes: 9 additions & 20 deletions STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
<!-- Regenerate with: python3 scripts/generate_status.py -->
<!-- Every value below came from a command run at the timestamp shown. -->

**Generated:** 2026-08-17 03:27 UTC
**Generated:** 2026-08-17 05:19 UTC
**Test status:** PASSING

## Tests

| Suite | Status | Passed | Failed | Skipped | Time |
| --- | --- | --- | --- | --- | --- |
| Scheduler | PASS | 397 | 0 | 0 | 11.40s |
| Node | PASS | 260 | 0 | 1 | 2.83s |
| Root E2E | PASS | 249 | 0 | 0 | 26.42s |
| Scheduler | PASS | 397 | 0 | 0 | 13.39s |
| Node | PASS | 260 | 0 | 1 | 3.85s |
| Root E2E | PASS | 249 | 0 | 0 | 28.35s |
| **Total** | **PASSING** | **906** | **0** | **1** | |

Reproduce:
Expand All @@ -26,23 +26,12 @@ Reproduce:

## Git

- **Last commit:** `b31fce3` one command to host a node
- **Author / date:** Claude — 2026-08-16 16:21:21 +0000
- **Last commit:** `214bcb8` docs: record the real state, including what we cannot see
- **Author / date:** Claude — 2026-08-17 05:18:43 +0000
- **Branch:** claude/v1-wrap-up-checklist-6uadua
- **Total commits:** 50
- **Total commits:** 52
- **Remote:** origin https://github.com/Epichlo/Public-Intelligence (fetch)
- **Working tree:** 8 uncommitted change(s)

```
M ROADMAP.md
M packages/scheduler/src/scheduler/api/openai.py
M packages/scheduler/tests/test_metering_and_accrual.py
M packages/website/package.json
M tests/test_source_parity.py
?? .gitattributes
?? specs/ci-green-on-windows.md
?? tests/test_line_endings.py
```
- **Working tree:** clean

## CI

Expand All @@ -58,7 +47,7 @@ _Measured, not asserted. Re-run to refresh._

| Repo | Remote | Branch | Tracking |
| --- | --- | --- | --- |
| root | `https://github.com/Epichlo/Public-Intelligence` | claude/v1-wrap-up-checklist-6uadua | **none** |
| root | `https://github.com/Epichlo/Public-Intelligence` | claude/v1-wrap-up-checklist-6uadua | origin/claude/v1-wrap-up-checklist-6uadua |

- **`.gitmodules`:** absent, which is correct — `packages/` are ordinary directories since the 2026-08-04 monorepo migration, and CI's fresh-clone job asserts this file does not come back.
- **root venv interpreter:** Python 3.11.15
Expand Down
22 changes: 19 additions & 3 deletions VERIFY.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,22 @@ The first grep returns four benign hits, and no others:
**Everything else it returns is real.** If it comes back completely clean, the
pattern is broken, not the code.

The auth-bypass grep returns one hit, `packages/website/src/app/architecture/page.tsx:42`,
which is prose containing the word "bypassing", not code.
The auth-bypass grep returns **three** hits, all of them prose rather than code:

- `packages/website/src/app/architecture/page.tsx:42` — page copy containing the word
"bypassing".
- `packages/scheduler/src/scheduler/api/ingress.py:69` — a comment explaining how a
`kid`-aware verifier turns into a bypass, naming the test that pins it
(`test_an_unknown_kid_does_not_bypass_verification`).
- `packages/scheduler/src/scheduler/core/rate_limiter.py:54` — a comment explaining
why evicting a depleted bucket would be a rate-limit bypass.

**This line said "one hit" until 2026-08-17, when there were three.** Both extra hits
are comments describing bypasses being *prevented*, and both predate the correction —
so nothing was wrong with the code, and the count was wrong for long enough that the
instruction two paragraphs down ("check each hit against that list, because a new one
hides among them") had become harder to follow than it looks. A known-good list that
is stale by two is a list that trains you to skim.

**Known pre-existing hits as of 2026-08-03** — these are real and unfixed. Do not
let them mask a *new* one, and do not report them as clean:
Expand Down Expand Up @@ -197,7 +211,9 @@ git check-ignore -q .secrets/probe && echo ".secrets/ ignored" || echo "!! .secr
these are **source files**, not credential files. The private-key grep matches
`test_credential_issuance.py`, whose fixture is the literal string
`-----BEGIN PRIVATE KEY-----\nnonsense\n-----END PRIVATE KEY-----`, used to assert
that an unreadable key produces a 503 carrying no key material.
that an unreadable key produces a 503 carrying no key material — **and this file**,
`VERIFY.md`, which matches because the previous sentence quotes that fixture. Two
hits, both benign, one of them self-referential.

## 6. Regenerate STATUS.md

Expand Down
63 changes: 56 additions & 7 deletions docs/PREMISES.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,27 @@ shape of the second.
than failure.** The gate did not lint `tests/`. It did not type-check `tests/`. It did
not touch the website. It ran an installer dry-run that returned early from every
step. Each gap was invisible precisely because the gate was trusted as total.

**2026-08-17 added a new shape of falsification, and it is worse than the others.**
The gate ran, CI ran, CI *failed* — and no one read it for eight days, across a
published `v1.0.0` release. Every prior instance was a check that did not exist. This
was a check that existed, executed, and reported red into a void, because
`scripts/generate_status.py` shells out to `gh` and reports `UNVERIFIABLE` where `gh`
is absent. "I could not look" is honest and scans as "nothing is wrong".

The current known gaps, enumerated so that an unlisted absence is not mistaken for an
all-clear (kept in sync with the README's "What we cannot see"):

- `install.ps1` has **never been executed by anything**; it is only ever read. Every
Windows install defect so far was found by a person, not by the gate.
- The repository **cannot read its own CI** without `gh` on the PATH. Fix known
(REST API fallback), not yet made.
- **Branches get no CI** — the workflow triggers on `push` to `main` and on PRs only.
- The local gate is **one OS and one interpreter**; platform-specific defects are
structurally invisible to it. Three so far: cp1252 encoding, CRLF line endings,
wall-clock resolution.
- **`docker-compose.test.yml` has never run.**

**Confidence:** high that it catches what it checks; **low that anyone knows what it
does not check**. The correct posture toward this file's own subject.

Expand All @@ -135,12 +156,39 @@ interpretation of the project's own history rather than a claim about the world.
is listed anyway because it drives more process than anything else on this page, and
process justified by an unfalsifiable belief is worth naming as such.

## P10 — Sending a prompt to a peer's machine is an acceptable trade for pooling

**Supports:** the whole multi-machine framing; whatever survives of P1's federation
half after the desk review.
**Evidence:** none gathered. This premise was surfaced by the 2026-08-14 desk review
as "the privacy paradox" and sat outside this register until 2026-08-17, which is
itself the finding — the register's own instruction is that an unregistered
assumption is one nobody can attack.

The tension is direct. The motivation for running models locally is usually *"nothing
leaves hardware I own."* Routing a request to somebody else's node breaks exactly that
property. P6 constrains what this **code persists**; it says nothing about where a
prompt **travels**, and the two are routinely conflated.

**Falsifier:** the users who want local inference want it for privacy, in which case
pooling across other people's machines is not a smaller version of the same product —
it is the opposite product, and the addressable set is only people who trust every
host in their pool. Note this does **not** fire for the self-hosted-fleet case
([D6](decisions/D6-is-there-a-network.md)), where every machine belongs to the same
person or organisation. It fires precisely for the cross-party pooling the desk review
identified as the one surviving differentiator.
**Confidence:** **low, and load-bearing.** If P10 fails, cross-party pooling fails
with it, and P2 has already been moved to low confidence — which would leave the
project's differentiator resting on two low-confidence premises at once.

---

## How to attack this list

- Pick the premise with the lowest stated confidence (**P2**), and ask whether the
people it describes exist.
- Pick either of the lowest-confidence premises (**P2**, **P10**) and ask whether the
people they describe exist. They are now the same question from two sides: P2 asks
whether anyone needs this to reach a machine, P10 asks whether anyone who does would
accept where their prompt goes. A single answer can falsify both.
- Pick the one with the largest downstream commitment (**P3**), and check the inputs
against a real electricity bill and a real card.
- Pick the one whose falsifier says "none available" (**P9**), and ask whether the
Expand All @@ -162,8 +210,9 @@ routes a whole request to one node); the codebase refutes that specific claim. S
review's addendum. **Neither run closes D7** — two models gathered external evidence;
neither is an external human judge.

A candidate new premise surfaced and is not yet in this register: **the privacy
paradox** — routing a prompt to a *peer's* machine breaks the "nothing leaves hardware
I own" property that motivates local AI (P6 covers only what this code persists, not
where a prompt travels). If the product continues, that belongs here as its own
falsifiable claim.
The candidate premise that review surfaced — **the privacy paradox** — was registered
as **P10** on 2026-08-17. It had sat outside this file for three days while the file's
own argument is that an unregistered assumption is one nobody can attack.

Last updated 2026-08-17: P8 gained the enumerated verification gaps, P10 was added.
**Still reviewed only by the author, and still the problem.**
Loading