You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(skills): curl-to-REST fallback for overview maintenance in broken-CLI sandboxes (#2164)
The weekly SANA sandbox routes egress through a mandatory TLS-intercepting
proxy that the compiled Bun CLI binary can't traverse (a Bun proxy/HTTP-2
bug, not a config issue — see #2163). Every admin CLI command in these
skills wraps an existing REST route, so document a curl-to-REST fallback:
- regenerating-overviews: new "Running without the CLI" section covering
overview inputs (GET), generate, overview update (POST), and the plan
manifest, plus the --max-content-chars client-side-clipping nuance.
- maintaining-orgs: pointer to the fallback; notes admin source fetch has
no curl equivalent yet (skip fetch, regen from indexed data in-sandbox).
Refs #2163
> **Sandbox without a working CLI?** If the compiled `releases` binary can't reach the API through a TLS-intercepting egress proxy (the weekly SANA sandbox), the overview steps have a curl-to-REST fallback — see `regenerating-overviews` → _Running without the CLI (curl fallback)_, including the plan manifest (`GET /v1/admin/overviews?format=plan`) that drives target selection below. **Step 1 (`admin source fetch`) has no curl fallback yet** — it dispatches a managed update run and polls, not a single REST call. In a broken-CLI sandbox, skip the fetch and regenerate from current indexed data (surface that the fetch was skipped); a proper fetch-trigger fallback is tracked in [#2163](https://github.com/buildinternet/releases/issues/2163).
43
+
42
44
For orgs with `scrape` or `agent` sources, skim the playbook before fetching — it documents source-specific quirks that may affect `--max` or require crawl flags:
Copy file name to clipboardExpand all lines: .claude/skills/regenerating-overviews/SKILL.md
+63Lines changed: 63 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,8 @@ No managed-agent task exists for this today. You — the Claude Code instance re
25
25
26
26
Three steps. Each step is a single CLI invocation; no other tools needed.
27
27
28
+
> **Sandbox without a working CLI?** In an environment where the compiled `releases` binary can't reach the API through a TLS-intercepting egress proxy (e.g. the weekly SANA sandbox), skip the CLI and hit the REST routes directly — see [Running without the CLI (curl fallback)](#running-without-the-cli-curl-fallback). Same three steps, same contracts.
29
+
28
30
### 1. Fetch inputs
29
31
30
32
```bash
@@ -208,6 +210,67 @@ Optional flags:
208
210
209
211
The CLI POSTs to `/v1/orgs/:slug/overview` (dumb upsert). Last-write-wins on conflict for both the body and the citations.
210
212
213
+
## Running without the CLI (curl fallback)
214
+
215
+
Use this when the compiled `releases` binary can't complete requests — the known case is the weekly SANA sandbox, whose mandatory TLS-intercepting egress proxy the compiled Bun binary can't get through. This was chased to ground in [releases#2163](https://github.com/buildinternet/releases/issues/2163): it is **not** a configuration problem. The failure (`socket connection was closed unexpectedly`) persists across every lever — the correct ambient `HTTPS_PROXY` (the sandbox's proxy port rotates per shell, but Bun reads it correctly each time), all of `NODE_EXTRA_CA_CERTS` / `SSL_CERT_FILE` / `NODE_USE_SYSTEM_CA=1`, and even bypassing the proxy via `NO_PROXY` (which just hits the sandbox's blocked direct egress). Meanwhile `curl` through the same proxy works cleanly (CONNECT + TLS 1.3, cert verified against `/root/.ccr/ca-bundle.crt`), so the fault is inside the compiled Bun binary's proxy/TLS networking layer, not anything an env var fixes. Every CLI command in this skill is a thin wrapper over a REST route, so call the route directly with `curl` — the contracts are identical.
216
+
217
+
Use the admin token already in the environment — `$RELEASES_API_KEY`, the same credential the CLI uses. Do **not** read `.env` or fetch secrets of any kind (the [Don't Confabulate](#dont-confabulate-around-tool-failures) rule still holds). A `relu_` user key won't work here: these are admin routes and the write needs `write` scope, which user keys can't hold — you need the root `RELEASES_API_KEY` or a `relk_` admin/write token.
`GET /v1/orgs/:slug/overview/inputs?window=30` — admin-only, Bearer auth. The `--max-content-chars` flag is **client-side clipping in the CLI, not a query param**, so the wire payload is never capped. Write the full response to a file (files have no stdout cap), then read a content-clipped view — this preserves the "never generate from a truncated slice" rule:
Read `/tmp/$SLUG-inputs-clipped.json`. It carries `org`, `sources`, `existingContent`, `selected`, `totalAvailable`, `windowDays` — same shape as the CLI's `--json`. Same stop rules apply: `selected` empty (`totalAvailable: 0`) → stop, don't generate. Clipping only trims each `content` string, never drops entries, so `selected.length` is unchanged between the raw and clipped files — if the counts differ, something else truncated and you should re-fetch. Lightweight pre-flight (like the CLI's default non-`--json` check): add `&check=true`.
237
+
238
+
### Step 2 — generate
239
+
240
+
Unchanged — this is the parent harness's Anthropic call described above. Build the `search_result` blocks from `/tmp/$SLUG-inputs-clipped.json`.
+ (if $lastAt=="" then {} else {lastContributingReleaseAt:$lastAt} end)' \
254
+
> /tmp/$SLUG-overview-body.json
255
+
256
+
curl -fsS -X POST -H "$AUTH" -H "Content-Type: application/json" \
257
+
--data @/tmp/$SLUG-overview-body.json \
258
+
"$API/v1/orgs/$SLUG/overview"
259
+
```
260
+
261
+
-`$TOTAL_AVAILABLE` — `totalAvailable` from step 1 (the CLI defaults `--release-count` to this).
262
+
-`$LAST_CONTRIBUTING_AT` — the first selected release's `publishedAt`; leave the var empty to omit it (the server defaults it).
263
+
-**No citations?** Drop the `--slurpfile`/`citations` key entirely. Omitting `citations` clears any prior citations on the page (replace-all semantics) — matching the CLI.
264
+
- Body field names are exactly `content`, `releaseCount`, `lastContributingReleaseAt`, `citations`; the citations array is `{ startIndex, endIndex, sourceUrl, title?, citedText }` per step 2.
265
+
266
+
`curl -fsS` exits non-zero on any non-2xx — treat that as a hard stop and surface it, exactly like a CLI error. Never fall back to regenerating from stale inputs.
267
+
268
+
### Cross-org target selection (plan manifest)
269
+
270
+
`maintaining-orgs` picks targets from `releases admin overview plan`, which is `GET /v1/admin/overviews?format=plan` — the freshness fields (`overviewUpdatedAt`, `releasesSinceOverview`, `recentReleaseCount`, `needsFetch`) come back directly, no CLI needed.
271
+
272
+
> The remote MCP server does **not** expose these admin routes as tools (it's a read-only public catalog surface). So in a broken-CLI sandbox, curl-to-REST — not MCP — is the fallback for all three steps. Exposing them as write-scoped MCP tools is a separate, deliberate decision tracked in [#2163](https://github.com/buildinternet/releases/issues/2163).
273
+
211
274
## Failure Modes to Watch For
212
275
213
276
-**Empty selection** → stop and report no-op. Don't generate.
0 commit comments