Files
command-center/agent/managed-skills/franksign-demo-inspection-stack/SKILL.md
T
Frank 8af40c402b chore(agent): commit the machine tier and the doctrine text the checkout was already running
Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and
`merge --ff-only` refuses while tracked paths are dirty. Discard is not available here
(workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed.

- `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already
  byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new
  prose — the commit exists so the trunk merge can proceed.
- `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat
  owns (AGENTS.md § Live-sync tiers).

`ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the
only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the
inert all-zero AWS example id — and they appear inside the two skill pages that teach
that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged
gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal
dies with this landing. No `--no-verify` was used: the gate ran and its verdict is
recorded here.

Refs #61
2026-10-21 01:44:51 -07:00

3.3 KiB

name, description
name description
franksign-demo-inspection-stack Boot franksign's prod-shaped stack, seed all assignment lifecycle states through the real API, and open a headed inspection tour (platform + storybook) without squatting the e2e port.

Visual-inspection recipe for the franksign repo (Dank boxes). Proven 2026-10-20; use when asked to "show/open the platform" or tour a new slice.

Boot (do NOT squat :3100 — the e2e seam curls whoever owns that port)

node --env-file=.env apps/api/dist/cli.js        # binds :3000 by default; use named service
cd apps/web/storybook-static && python3 -m http.server 6007   # gate seam 12 already built it
curl -s http://127.0.0.1:3000/health              # {"status":"ok","db":"up"}

better-auth sign-up returns a bearer token, but the org routes resolve sessions from cookies only (Authorization: Bearer … → get-session null → 401). Use -c /tmp/jar at sign-up and -b /tmp/jar after; state-changing calls need an origin: header. Keep auth headers out of argv via curl -K <file>.

  1. POST /api/auth/sign-up/email {"email","password"(>=8 chars),"name"} → save cookies (-c)
  2. POST /api/orgs {"name"} → org.id
  3. POST /api/orgs/:org/templates {"name","baseTemplateId":"sample"} → template.id
  4. POST /api/orgs/:org/templates/:tpl/assignments {"email"} → {token, signUrl} (repeat per demo signer)
  5. signed state: POST /api/releases/:token {"values":{"name":…,"date":…,"agreement":true},"signatureName":…} — no auth needed (token seam)
  6. voided state: POST /api/orgs/:org/assignments/:assignmentId/void (cookie session) Remaining pending assignment → three inspectable pages: /app/sign/:token renders form / already-signed / cancelled.

Byte-identity spot check (reconstruction contract, issue #18)

Fetch GET /api/releases/:token/pdf twice with sleep 1.5 between fetches and sha256-compare, plus the org door GET /api/orgs/:org/assignments/:aid/pdf (cookie jar). Same-second-only comparisons are blind to clock leaks (pdf-lib's PDFDocument.load restamps /ModDate unless updateMetadata:false). To see printed text: inflate the content streams and unescape \(, \) — pdf-lib writes hex-string Tj operands.

Inspection browser (managed Chromium via browser eval)

  • viewport must be {width, height} — string fails
  • tab.waitFor(ms) does NOT exist (ms is parsed as selector) → await Bun.sleep(900)
  • open with headed: true, persist: true; window lands on the desktop — confirm with niri msg windows | grep -i chrome

Teardown (hard gate hazard)

A live demo API on :3000 hangs the full tests/run.sh gate for ~10 minutes (observed 2026-10-21: >600s kill with the service up; 14/14 in ~15s without it). Always proc://franksign-demo-api/kill BEFORE running the gate; verify pgrep -f apps/api/dist/cli.js is empty so the next tests/run.sh e2e seam owns :3100 honestly.

Adjacent Gitea quirk (same fleet)

Closing an issue/PR: PATCH {"state":"closed"} → 201; POST → 405. Merging needs form-encoded lowercase do=merge (see gitea-merge-form-encoded). Label assignment: PATCH /issues/N with labels:[id] silently clears labels — use POST /issues/N/labels {"labels":[id]}.