feat+docs+release(v0.4.3): D76 — README install-path overhaul + OLP_BIND env + AI-install prompt + ADR 0011 amendment (#48)

10 README install gaps catalogued and fixed in one D-day after v0.4.2's
PI231 E2E session exposed that the v0.4.0-v0.4.2 README Quick Start was
fictional (npm package isn't published; olp setup/start commands don't
exist). F5 (OLP_BIND env) ships in the same patch so the documented LAN
onboarding flow actually works. AI-driven install prompt added per Phase 4
charter brainstorm Top-5 inheritance candidate #2 (D64-D67 built the
doctor framework; D76 closes the README half).

## G1-G7: README Quick Start now real

Rewrote § "Manual install" from placeholder text to the empirically-verified
sequence:
- Prerequisites (Node >= 18 + provider CLI install matrix)
- git clone + npm test verify
- olp-keys keygen --owner FIRST (allow_anonymous=false default needs a key)
- Per-provider OAuth (claude setup-token / codex login --device-auth /
  MISTRAL_API_KEY)
- ~/.olp/config.json with the minimum that actually serves traffic
- npm start
- Smoke-test via curl + olp doctor
- IDE pointing

## G8 / F5: OLP_BIND env shipped

server.mjs:
- const BIND = process.env.OLP_BIND ?? '127.0.0.1' (safe default unchanged)
- server.listen(PORT, BIND, ...) replaces hard-coded '127.0.0.1'
- New startup warn anonymous_key_advertised_with_lan_bind fires when
  OLP_BIND is non-loopback AND auth.advertise_anonymous_key: true
  (operator visibility into trust-context overlap)

Pre-D76 the server only accepted loopback connections, so the documented
olp-connect <ip> family-onboarding flow was unreachable from LAN without
SSH tunneling. F5 makes ADR 0011 operational instead of aspirational.

## G10: AI-driven install prompt

README § "Install with your AI (the fast path)" — verbatim prompt the
operator pastes into Claude Code / Cursor / Copilot / Aider. The AI
follows README + uses olp doctor --json next_action.ai_executable[] for
self-repair, stopping only when human_required[] is non-empty (provider
OAuth dances). Closes the Phase 4 brainstorm #2 inheritance candidate.

## Opening compressed

§ "Why OLP" (3 paragraphs of Anthropic 2026-06-15 billing history)
removed from the top. The OCP-trigger context moved to § "Migration
from OCP" at the bottom, condensed into a single paragraph. New users
land on value-prop + § "What you get" + install paths without needing
to digest 2026-05-14 billing history first. OCP users get a one-line
pointer at the top.

## Configuration + Env Variables sections updated

- § Configuration: placeholder replaced with full ~/.olp/config.json
  schema documentation, every field cross-referenced to its ADR
- § Environment Variables: added OLP_BIND, OLP_API_KEY, OLP_OWNER_TOKEN,
  OLP_PROXY_URL rows that were used in the manual-install flow but
  previously undocumented

## ADR 0011 § Deployment configurations amendment

Codifies the three deployment trust contexts:
- 127.0.0.1 (loopback only) — safe with any auth posture
- RFC1918 / tailnet / specific LAN IP — anonymous_key OK (the documented
  trusted-LAN zero-config family onboarding flow)
- Public IP — incompatible with advertise_anonymous_key: true

Documents the new anonymous_key_advertised_with_lan_bind startup warn
event. Closes ADR 0011's pre-D76 dangling reference to a non-existent
BIND_ADDRESS concept.

## Test count

714 (v0.4.2) -> 717 (v0.4.3). +3 D76 regression tests in Suite 36
(36s/36t/36u) pinning OLP_BIND wiring + safety warn + ADR amendment.

## Process learning

Every D-day reviewer rubric should add "open README §-Quick-Start and
verify the commands literally exist + work in the current repo" — would
have caught G1-G7 at v0.4.0 close. Combined with D74 (review-against-spec)
+ D75 (review-without-deployment), D76 (review-without-following-README)
codifies the third tier of review discipline.

## Out of D76 scope (deferred)

- F6 (doctor client-side vs server-side check separation) — needs design
  ADR for --remote mode. Phase 5.
- D75 reviewer P2-1 (ADR 0004 per-hop schema amendment) + P2-2 (defensive
  typeof hopModel === 'string') — both genuine follow-ups, neither
  blocking.
- scripts/migrate-from-ocp.mjs — Phase 7.

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dtzp555-max
2026-05-26 13:32:02 +10:00
committed by GitHub
co-authored by taodeng Claude Opus 4.7
parent 6edf6e0b94
commit 6605b7b14a
6 changed files with 327 additions and 41 deletions
@@ -214,6 +214,24 @@ alongside the "using server-advertised key" notice.
---
## Deployment configurations (D76 amendment, 2026-05-26)
Original ADR 0011 referenced a `BIND_ADDRESS` concept that did not exist in the v0.4.0v0.4.2 codebase — the server was hard-coded to `server.listen(PORT, '127.0.0.1', ...)`. D76 closes this gap by adding the `OLP_BIND` env var (default `127.0.0.1`), making the deployment-context discussion below operational rather than aspirational.
Three deployment configurations are supported:
| `OLP_BIND` value | Reachability | Anonymous-key publication |
|---|---|---|
| `127.0.0.1` (default) | Loopback only | Safe with any auth posture (no LAN exposure at all) |
| RFC1918 IP / tailnet IP / `0.0.0.0` on a trusted LAN | LAN clients only | Safe when `advertise_anonymous_key: true` — the documented "trusted-LAN" zero-config family onboarding flow |
| Public IP / `0.0.0.0` on a public-facing host | Public internet | **Incompatible with `advertise_anonymous_key: true`.** Operator MUST keep `advertise_anonymous_key: false` (default). |
The server emits a startup warn event `anonymous_key_advertised_with_lan_bind` when `OLP_BIND` is non-loopback AND `advertise_anonymous_key: true` (per the `lib/keys.mjs` + `server.mjs` checks). The warn is a **checkpoint, not a hard gate** — the server cannot tell from the bind address alone whether the operator is on a trusted LAN (RFC1918 / tailnet) or has accidentally exposed a public IP. The Re-evaluation trigger #1 below escalates to a hard gate when OLP gains a public-internet deployment mode.
`olp-connect <ip>` consumes `/health.anonymousKey` over the network — therefore requires `OLP_BIND` to include the LAN interface on the server side. Without setting `OLP_BIND=<lan-ip>` (or `0.0.0.0`), `olp-connect <ip>` will fail with `connect ECONNREFUSED` because the server only accepts loopback connections.
---
## Re-evaluation triggers
Re-open this ADR when ANY of the following fires: