chore: scrub private infrastructure for a public repo, rewrite README

Audited the working tree and all 26 commits of history for credentials: none
found. No API keys, no private keys, no tokens — the live bot token, webhook
secret and admin token appear nowhere in the repo or its history.

What was there was infrastructure disclosure, which is recon material rather
than a leak, but has no business in a public repo:

- Tailnet addresses and cluster-internal hostnames in code, docs and the CI
  template. The model endpoint is now supplied at runtime via
  PRAGENT_MODEL_BASE_URL and patched into opencode.json by install_config();
  the committed config carries a placeholder, guarded by a test.
- A host path (/home/marcos) as the default rtk directory — now unset.
- Real usernames in the onboarding docs — now alice/acme.
- A standing list of one-time setup tokens that were never revoked, named
  individually. Removed. Note that removing the list does not revoke the
  tokens: they should still be revoked in the Gitea admin UI.

The substitution happens in Python rather than via opencode's {env:VAR} config
templating, because the reviewer subprocess runs with an allow-listed
environment — resolving it before the process starts keeps that allow-list from
having to grow.

README rewritten for a reader who has never seen the project: what it does and
what that output looks like, honest status (pilot works, framework designed but
unbuilt), the security model up front given what this thing is, and the measured
cost numbers including the two effects that make naive estimates wrong.

History still contains the old addresses. They are tailnet-only and not
credentials, so no rewrite.

Tests: 131 -> 137.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B11e8TZZxJyzHW7jj7KWUN
This commit is contained in:
Marcos
2026-08-18 12:59:52 +00:00
parent 46513585ae
commit f59b906395
11 changed files with 292 additions and 164 deletions
+40 -7
View File
@@ -37,7 +37,7 @@ Env:
PRAGENT_OPENCODE_BIN path to the opencode CLI (default: shutil.which / the
known linuxbrew path).
PRAGENT_RTK_DIR dir holding the `rtk` binary, prepended to PATH for the
agent's bash tool (default: /home/marcos/.headroom/bin).
agent's bash tool (default: unset).
PRAGENT_WORK_ROOT parent for temp workdirs (default: /tmp/pragent-work).
PRAGENT_KEEP_WORK if set, leave the workdir on disk for debugging.
PRAGENT_REVIEW_TIMEOUT seconds to allow opencode to run (default: 480).
@@ -59,7 +59,7 @@ import urllib.request
# repo root (this file is at <root>/pilot/opencode_review.py).
_DEFAULT_FACTORY = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
RTK_DIR = os.environ.get("PRAGENT_RTK_DIR", "/home/marcos/.headroom/bin")
RTK_DIR = os.environ.get("PRAGENT_RTK_DIR", "")
WORK_ROOT = os.environ.get("PRAGENT_WORK_ROOT", "/tmp/pragent-work")
TIMEOUT = int(os.environ.get("PRAGENT_REVIEW_TIMEOUT", "480"))
@@ -371,14 +371,47 @@ def sanitize_workdir(workdir: str) -> list[str]:
return removed
def install_config(src: str, dst: str) -> bool:
"""Copy `opencode.json` from src to dst, substituting the model endpoint.
The committed `opencode.json` carries a neutral placeholder for the model
provider's `baseURL`, so the repo can be public without publishing the
address of a private network. The real endpoint is supplied at runtime by
`PRAGENT_MODEL_BASE_URL` and patched in here.
This is done in Python rather than with opencode's own `{env:VAR}` config
templating because the reviewer subprocess runs with an allow-listed
environment (see `_build_env`) — substituting before the process starts
keeps that allow-list free of anything opencode needs to resolve config.
Returns True if a config was installed.
"""
if not os.path.isfile(src):
return False
base_url = os.environ.get("PRAGENT_MODEL_BASE_URL", "").strip()
if not base_url:
shutil.copy2(src, dst)
return True
try:
with open(src, encoding="utf-8") as f:
cfg = json.load(f)
for prov in (cfg.get("provider") or {}).values():
if isinstance(prov, dict) and isinstance(prov.get("options"), dict):
prov["options"]["baseURL"] = base_url
with open(dst, "w", encoding="utf-8") as f:
json.dump(cfg, f, indent=2)
except (OSError, ValueError, AttributeError):
# A malformed config is opencode's problem to report, not ours to hide.
shutil.copy2(src, dst)
return True
def drop_factory(workdir: str) -> None:
"""Copy the pragent `opencode.json` + `.opencode/` into the workdir so
`opencode run --dir <workdir>` discovers them as project config. Overwrites
any existing ones (the workdir is a throwaway archive checkout)."""
src = _factory_dir()
oc_json = os.path.join(src, "opencode.json")
if os.path.isfile(oc_json):
shutil.copy2(oc_json, os.path.join(workdir, "opencode.json"))
install_config(os.path.join(src, "opencode.json"), os.path.join(workdir, "opencode.json"))
src_oc = os.path.join(src, ".opencode")
dst_oc = os.path.join(workdir, ".opencode")
if os.path.isdir(dst_oc):
@@ -491,9 +524,9 @@ def _ensure_global_config(home: str) -> None:
src = os.path.join(_factory_dir(), "opencode.json")
if not os.path.isfile(src):
return
# Copy if missing or changed (compare mtime/size to avoid pointless writes).
# Copy if missing or changed (compare mtime to avoid pointless writes).
if not os.path.isfile(dst) or os.path.getmtime(src) > os.path.getmtime(dst):
shutil.copy2(src, dst)
install_config(src, dst)
# The ONLY host env vars forwarded to opencode. This is an allow-list, not a