Skip to content

feat: ak admin — maintainer-only local telemetry admin (ADR-0007) - #47

Merged
pacphi merged 2 commits into
mainfrom
feat/maintainer-admin
Jul 24, 2026
Merged

feat: ak admin — maintainer-only local telemetry admin (ADR-0007)#47
pacphi merged 2 commits into
mainfrom
feat/maintainer-admin

Conversation

@pacphi

Copy link
Copy Markdown
Owner

What

ak admin (also ak x admin) — a maintainer-only, loopback-only telemetry admin page on 127.0.0.1:7432: the project-facing sibling of ak dashboard. Where dashboard is offline-first and machine-facing, admin does deliberate GitHub/npm egress to answer "what moved since I last looked, who moved it, and what's waiting on me?" — reach tiles with per-tile caveats, 7d-vs-prior-7d momentum sparklines, a "since you last looked" delta strip over a local baseline, open external threads oldest-first, and humans ranked by recency (bots excluded).

Adapted from the stuinfla/ruvnet-brain explainer admin (MIT, attributed in source), re-architected local-first per ADR-0007 (included).

Security model

  • Fail-closed auth: per-session crypto.randomBytes(32) token, bootstrapped via URL fragment (never hits logs), then x-admin-token header only; timingSafeEqual behind a length guard; 401 carries zero data fields.
  • Server proxies everything: the page makes zero external fetches (CSP default-src 'none'; connect-src 'self'); the GitHub credential (GITHUB_TOKENGH_TOKENgh auth token) is resolved server-side, never persisted, never in payload/page — enforced by credential-leak regression tests.
  • Loopback bind + DNS-rebinding Host guard (incl. [::1]/port variants), nosniff, no-store on /api.

Design seams

  • src/lib/admin-model.mjs is pure (imports nothing) and is both embedded into the served page and imported by node tests — tested code is shipped code. Inherits the reference's three correctness rules: unknown ≠ 0; never diff a rolling window; no control without an executor + undo.
  • openInBrowser extracted to src/lib/browser.mjs, shared with dashboard (behavior-identical).

Process & verification

Built via a gated SPARC pipeline (spec → pseudocode/ADR → TDD implementation → adversarial security review → completion audit) with independent agents per phase. Security review verdict: PASS, 0 critical/high (3 hardening items landed in this PR). Completion audit traced all 6 acceptance criteria + 8 edge cases to named tests. 55 new tests; pnpm run check green (typecheck · eslint · markdownlint · build · full suite) across three independent runs, plus a live smoke test against the real GitHub API (401/403/200 paths).

Try it

ak admin # auto-opens the browser with the session token in the # fragment

Set GITHUB_TOKEN (push access) or be logged into gh to light the traffic panels — they degrade honestly without it.

🤖 Generated with Claude Code

pacphi added 2 commits July 24, 2026 10:18
A loopback-only admin page (127.0.0.1:7432) answering "what moved since I
last looked, who moved it, and what is waiting on me" — adapted from the
stuinfla/ruvnet-brain explainer admin (MIT, attributed) to agentic-kit's
zero-dep, local-first house style.
Server: per-session random token (fragment bootstrap, header-only,
timingSafeEqual, fail-closed), DNS-rebinding Host guard, strict CSP,
GitHub/npm fan-out proxied server-side so the credential (GITHUB_TOKEN →
GH_TOKEN → gh auth token) never reaches page or payload. Client: pure
model module embedded into the page AND node-tested (tested code =
shipped code), with the reference's three correctness rules — unknown is
not zero, never diff a rolling window, no control without an undo.
55 new tests (33 model + 22 server/collect) cover all 6 acceptance
criteria + 8 edge cases, incl. credential-leak regression and constant-
time auth. Extracted openInBrowser to src/lib/browser.mjs (shared with
dashboard). Docs: ADR-0007 + README/MAINTAINER updates.
CI's quality gate (pnpm audit --audit-level=moderate) trips on a fresh
advisory: js-yaml 5.0.0–5.2.1 flow-collection parsing DoS, pulled in
transitively by markdownlint-cli2@0.23.1, which pins 5.2.1 exactly — so
only an override can move it. pnpm ≥11 reads overrides from
pnpm-workspace.yaml (the package.json "pnpm" field is ignored), hence the
new file; pnpm itself appended the minimumReleaseAgeExclude entry since
the patch is newer than the release-age gate. Drop the override once
markdownlint-cli2 ships a bumped js-yaml.
Unrelated to the admin feature — this advisory fails main's audit today
too. Full check green locally after the bump.
@pacphi
pacphi merged commit 82efef4 into mainJul 24, 2026
11 checks passed
@pacphi
pacphi deleted the feat/maintainer-admin branch July 24, 2026 17:24
pacphi added a commit that referenced this pull request Jul 24, 2026
…md target (ADR-0008) (#50)
The block registry knew two guidance targets: machine-wide
~/.claude/CLAUDE.md and the PROJECT AGENTS.md. That asymmetry meant
(a) only synced repos ever got codex-side guidance, and (b) machine
state leaked into git — the dual-mode block exists only when both hosts
are enabled in kit.json, a fact about one machine, yet it was committed
into shared checked-in AGENTS.md files.
- New `agents-user` target → ~/.codex/AGENTS.md (codex's global
guidance file). Dir-exists gated — ak never creates ~/.codex; one-time
.bak before the first managed rewrite, mirroring CLAUDE.md's.
- `ruflo-dual-mode-reference` re-scoped to ['claude','agents-user'];
the project `agents` target stays for genuinely repo-scoped rows.
- Migration: each target now also strips sentinel-present blocks that no
longer list it (`retiredForTarget` forced-strip rows), so project
AGENTS.md files carrying the old block heal on their next sync.
- One shared `guidanceTargets()` helper replaces the duplicated target
lists in sync.mjs/status.mjs.
- Docs aligned with this and #47/#48: template sentinel comment, README
setup/status/dual rows (truthful natives, memory-pin, pre-flight
refusal), MAINTAINER.md registry description, UPGRADING/
TROUBLESHOOTING remedies. ADR-0008 records the scope split.
314 kit tests green (10 new); full check chain green. Live dry-run:
CLAUDE.md upsert + project AGENTS.md strip + ~/.codex/AGENTS.md upsert.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@pacphi