Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@
- name: "epic:agentic-combo"
color: "5319e7"
description: "NetScript agentic combo epic (MCP server + public skills + CLI)"
- name: "epic:frontend-contrib"
color: "1d76db"
description: "Frontend contribution layer epic (plugins that ship UI)"

# ── wave: release-train bucket (maps to milestone) ───────────────────────────
- name: "wave:v1"
Expand Down
53 changes: 53 additions & 0 deletions .llm/runs/plan-frontend-contrib--seed/FILING-LOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# FILING-LOG — plan-frontend-contrib--seed (board filed 2026-07-19)

Owner authorized epic + sub-issue creation in-turn (remote-control, 2026-07-19), including
milestone selection ("look on what milestone it fits best", deploy-lane split as precedent) and
new-milestone authority (not needed — existing milestones fit).

**After this filing, GitHub is the single source of truth for the board.** Run docs carrying
FCB-n / FCL-EPIC tags are the planning record; on conflict, GitHub wins.

- Label created: `epic:frontend-contrib` (#1d76db) — mirrored into `.github/labels.yml` (this branch).
- Epic: **#922** — `Epic: Frontend contribution layer — plugins that ship UI` · milestone `0.0.1-beta.13`.
- Milestone rationale: core waves (0/1/1b/2 + first-party panels) → **beta.13** — the layer is the
dashboard epic's (#400) prerequisite in the same cut, mirroring the deploy lane's W1–W3→beta.13
split (epic #892); consumer frontends + adoption → **beta.15** (parallel to deploy W4);
completion wave → **beta.17** (milestone #19, created 2026-07-19 per owner re-scheduling: no
Backlog items — everything ships before stable).
- Supersession map (RFC §6): #427 KEEP re-baseline · #432 KEEP re-baseline · #400 consumer ·
ai chat-route repositioned — **zero closes at filing time** (folds happen via downstream PRs).

## Draft-ID → live issue

| Draft | Issue | Milestone | Priority | Title |
| --- | --- | --- | --- | --- |
| FCB-1 | #923 | 0.0.1-beta.13 | p0 | P1 proof: mounted sub-app command ordering |
| FCB-2 | #924 | 0.0.1-beta.13 | p0 | P2 proof: literal lazy route loaders + normalizeFreshRouteModule |
| FCB-3 | #925 | 0.0.1-beta.13 | p0 | P3 proof: dependency-island build matrix + plugin-vite pin policy |
| FCB-4 | #926 | 0.0.1-beta.13 | p0 | P4 proof: SSR failure-containment fixtures |
| FCB-5 | #927 | 0.0.1-beta.13 | p0 | P5 proof: gateway threat model + streaming abort |
| FCB-6 | #928 | 0.0.1-beta.13 | p0 | @netscript/plugin-frontend-core contracts/v1 |
| FCB-7 | #929 | 0.0.1-beta.13 | p0 | @netscript/plugin pointer axis (.withFrontend) |
| FCB-8 | #930 | 0.0.1-beta.13 | p0 | Frontend registry emissions: transactional replace-set |
| FCB-9 | #931 | 0.0.1-beta.13 | p0 | @netscript/fresh/plugins host runtime |
| FCB-10 | #932 | 0.0.1-beta.13 | p1 | Scaffold template wiring + HostSurfaceDescriptor + vite feed |
| FCB-11 | #933 | 0.0.1-beta.13 | p1 | Workers dogfood: zone panel + console route + island |
| FCB-12 | #934 | 0.0.1-beta.13 | p1 | Generated deny-by-default procedure gateway |
| FCB-13 | #935 | 0.0.1-beta.13 | p2 | plugin new --with frontend |
| FCB-14 | #936 | 0.0.1-beta.13 | p1 | netscript plugin dev (frontend watch loop) |
| FCB-15 | #937 | 0.0.1-beta.13 | p2 | Doctor frontend check + five-state taxonomy |
| FCB-16 | #938 | 0.0.1-beta.13 | p2 | Quarantine render states + provenance chrome |
| FCB-17 | #939 | 0.0.1-beta.15 | p1 | AppTarget scaffolder seam + plugin resource add --app |
| FCB-18 | #940 | 0.0.1-beta.13 | p1 | defineFrontendTestSuite + budgets enforcement |
| FCB-19 | #941 | 0.0.1-beta.15 | p2 | generate frontend-wiring adoption verb |
| FCB-20 | #942 | 0.0.1-beta.15 | p1 | Auth v1 frontend (account + session widget + signin starter) |
| FCB-21 | #943 | 0.0.1-beta.15 | p1 | AI frontend (durable chat route + assist launcher) |
| FCB-22 | #944 | 0.0.1-beta.13 | p2 | Sagas/triggers/streams dashboard-zone panels |
| FCB-23 | #945 | 0.0.1-beta.17 | p2 | auth-org backend capability (org-console prerequisite) |
| FCB-24 | #946 | 0.0.1-beta.17 | p3 | Convention generator (generate frontend) |

Filing was one-shot from the committed manifest (`briefs`/tmp manifest mirrored here); every
child carries `Part of #922`, `epic:frontend-contrib`, one `status:plan`, `type:`/`area:`/
`priority:`, and its milestone. First pull: p0s #923–#931.

**Amendment 2026-07-19 (owner):** milestone `0.0.1-beta.17` (#19) created; #945/#946 moved Backlog → beta.17. Final split: 18 → beta.13 · 4 → beta.15 · 2 → beta.17.
138 changes: 138 additions & 0 deletions .llm/runs/plan-frontend-contrib--seed/adversarial-sol.md

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions .llm/runs/plan-frontend-contrib--seed/adversarial-triage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Adversarial Triage — per-finding dispositions (generator, stage 2 integration)

Verdict on the review: **high quality; accepted with minor citation corrections.** The reviewer
verified upstream claims against jsr sources and repo code; its seven blockers are real design
flaws, not taste. Two slips noted (S-20 cites a non-existent `05-owner-forks.md` — forks live in
`plan.md`; S-15 misnames my example's adapters as Azure/Docker/K8s — they are cloudflare/aws —
and calls the op set five-op where the example listed six) — neither changes the substance.

| # | Sev | Disposition | Integration |
| --- | --- | --- | --- |
| S-1 mount ordering | blocker | **ACCEPT** — insertion-order compilation + `configure()`-before-fsRoutes means my sketch broke both plugin middleware and host layout wrap | 04 §2 rewritten: strict register order (middleware→layout→routes), mount in a post-fsRoutes composition phase, child `App`/`NotFound` stripped; Wave-0 proof P1 |
| S-2 route normalization | blocker | **ACCEPT** — `App.route()` takes internal `Route`, not a fs route module | literal generated loaders + `normalizeFreshRouteModule` adapter owned by `@netscript/fresh/plugins`; plugin `_layout` forbidden in v1; 01/03/04 updated; Wave-0 proof P2 |
| S-3 islands unproven | blocker | **ACCEPT** — API exists (still true) but cachedOnly resolve, Preact-transform excludes, watcher scope, CSS, HMR are unproved | reclassified from "verified primitive" to "verified API, unproven behavior"; Wave-0 proof P3 with the reviewer's full matrix; plugin-vite pin/compat test |
| S-4 SSR containment | blocker | **ACCEPT** — preact-render-to-string error-boundary mode not enabled by Fresh; async components fail earlier anyway | containment contract downgraded: host-side data resolution catch + route `onError` + client-boundary; SSR zone-throw = page error documented; Wave-0 proof P4 |
| S-5 sugar placement | blocker | **ACCEPT** — runtime helpers cannot live in the framework-free contracts package | `definePluginPage`/`pluginApi`/normalizer moved to `@netscript/fresh/plugins`; real signature over Fresh `PageProps` + state-injected `pluginHost`; 01/02 updated |
| S-6 proxy security | blocker | **ACCEPT** — wildcard forwarding proxy is a confused-deputy surface | replaced by deny-by-default generated **procedure gateway** (owner/method/path/streaming policy from versioned procedure metadata); AI durable streaming stays on its specialized adapter; 04 §4 rewritten; Wave-0 proof P5 (threat model) |
| S-7 schema evolution | blocker | **ACCEPT** — new union members break strict old validators; dashboard kinds can't ride the base schema | envelope/family model: `contract: { family, major }` + per-family registered payload schemas; new base discriminants = major; negotiation tests specified; 01 rewritten |
| S-8 identity conflation | major | **ACCEPT** — package name ≠ canonical kind ≠ installation id ≠ mount id (`officialSource.canonicalName` precedent) | explicit identity quartet in 01; CSS/proxy/route keys derive from host-assigned mount id; examples aligned |
| S-9 context split | major | **ACCEPT** — functions can't cross island serialization; auth type import breaks framework-free claim | `PluginRequestContext` (server) / `PluginClientContext` (serializable) split; auth becomes a principal **port**; 01/04 updated |
| S-10 zones/nav validation | major | **ACCEPT** — open string union destroys validation; nav string ambiguous | `HostSurfaceDescriptor` (versioned, host-published); unknown vs unmounted vs capacity diagnoses; discriminated nav targets (`route`/`href`/`external`); 01/03 updated |
| S-11 registry lifecycle | major | **ACCEPT** — non-transactional emission, stale files on removal, verb is `plugin remove` | complete replace-set, deterministic empty emissions, staged atomic replace + rollback, regenerate on install/update/remove, orphan doctor check; verb corrected; 03 rewritten §4 |
| S-12 CSS/assets | major | **ACCEPT** — layer order is declaration-order, portals escape scoping, copied CSS breaks `url()` | host-owned layer-order prelude, per-plugin portal root, copy-mode url() caveat; full `AssetContribution` deferred with debt entry; 04 §8/03 §2 updated |
| S-13 auth example | blocker | **ACCEPT** — org procedures don't exist in auth v1 | example rewritten: v1 live = the real 5 procedures (account/session widget/sign-out); org console explicitly future `auth-org` capability with backend contract prerequisite |
| S-14 ai example | blocker→major | **ACCEPT** — durable chat needs session target + specialized proxy | example rewritten: v1 = durable-session runtime route (generated specialized route + auth hook); oRPC event-iterator named as the alternative; assist = capability requirement not module import |
| S-15 deploy example | major | **ACCEPT** — op set is 7 (incl rollback/secrets); core importing adapter islands reverses ownership | example rewritten: adapters contribute panels via deploy-family registry; core consumes registry; 7-op or explicitly versioned read-only v1 |
| S-16 DX hidden work | major | **ACCEPT** — exports maintenance + loader generation are Phase-1; props serializability; split JSR/local loops | 02/05/plan updated; `netscript plugin dev` watcher added; F6 resolved (no longer a fork) |
| S-17 i18n/a11y/CSP | major | **ACCEPT (scoped)** — contract-shape-affecting parts land in v1 shapes; full policies staged | message refs (`{ id, default }`) on nav/titles, locale/direction/timezone in client context, CSP/nonce seam documented, a11y gate list added to plan; deeper policy work = implementation wave |
| S-18 quality/perf | major | **ACCEPT** — no end-to-end plugin frontend test kit or budgets existed | `./testing` host-fixture kit spec + per-plugin budget table added to plan gates + 05 §5 |
| S-19 Wave 0 | major | **ACCEPT** — contracts frozen before mechanism proofs is backwards | plan re-phased: **Wave 0 = five disposable proofs (P1–P5)**, Wave 1 re-sliced narrow, gateway its own reviewed wave |
| S-20 fork re-triage | major | **ACCEPT** — technical invariants removed from fork list | F4/F6 resolved by S-7/S-16; F2 expanded to full route-pattern/reserved-path collision rules; genuine policy forks retained (see plan.md revised F-table) |

Integration commit(s) follow this file; each doc carries a change note referencing the S-numbers
it absorbs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use harness

# Adversarial/Collaborative Review — frontend contribution layer seed design

You are the **stage-2 adversarial reviewer** (Codex GPT-5.6 Sol, effort high) for the seed run
`.llm/runs/plan-frontend-contrib--seed/` on branch `plan/frontend-contrib`. The generator (a
Claude Fable 5 session) produced a design for the missing **plugin frontend contribution layer**.
Your mandate from the owner: **enhance, not ruin** — attack the design hard, but every finding
should either kill a real flaw or make the design stronger. The generator will integrate your
legitimate findings afterwards; you do not edit the design docs yourself.

## SKILL

Read these skills/files before reviewing (in order):

1. `.agents/skills/netscript-harness/SKILL.md` — run mechanics (you are the stage-F analog of a
seed run; findings only, supervisor integrates).
2. `.agents/skills/netscript-doctrine/SKILL.md` + `docs/architecture/doctrine/07-composition-and-extension.md`
— layering/extension laws the design claims to honor.
3. `.agents/skills/deno-fresh/SKILL.md` — Fresh 2.x mechanics (islands, routes, vite plugin).
4. The run artifacts, in this order: `research.md`, `plan.md`, `design/canonical/00-overview.md`
through `06-doctrine-fit.md`, `design/examples/{dashboard,auth,ai,deploy}.md`.

## What to attack (minimum coverage)

1. **Upstream API claims** — the design's load-bearing facts: `App.mountApp(path, app)` semantics
(basePath/middleware/layout interaction for mounted sub-apps), `fresh({ islandSpecifiers })`
behavior in `@fresh/plugin-vite@1.0.8` (do dependency-resolved specifiers actually build?
HMR? css handling? Preact dedupe interactions with the NetScript vite plugin?), lazy route
modules via `app.route(path, MaybeLazy)`. Verify against the actual jsr sources
(`https://jsr.io/@fresh/core/2.3.3/...`, `https://jsr.io/@fresh/plugin-vite/1.0.8/...`) or
local cache — cite what you verify. If a mechanism claim is wrong or riskier than stated, that
is a BLOCKER-class finding.
2. **Contract family** (`01-contracts.md`) — missing kinds/fields, schema-evolution traps,
the `ComponentRef`/specifier resolution model, the pointer-axis (D2) vs thinness, zone enum
design, `PluginHostState` adequacy (sessions, i18n?, CSP nonces?, base-path composition).
3. **Discovery/registry** (`03`) — generated-file set completeness, JSR explicit-exports
friction, local-source vs jsr resolution differences, uninstall cleanliness, collision rules,
quarantine mechanics, `deno check` gate realism.
4. **Host runtime** (`04`) — SSR/hydration gaps, the API proxy design (auth header forwarding,
SSE, security of `/api/plugins/*`), CSS layering/scoping realism, nav integration, error
containment claims (can a broken zone component really not break the page?), Tailwind
restriction implications.
5. **DX** (`02`) — is the authoring story actually minimal? Hidden footguns (island props
serialization, deno.json exports maintenance, dev-loop watch behavior for jsr-installed vs
local-source plugins)? Would YOU enjoy authoring against this API? Propose concrete
improvements.
6. **Worked examples** — do they hold against the real backend surfaces they cite
(auth contracts, ai SSE chat, deploy op set)? Is the live-vs-starter split right for each?
7. **Plan** — wave ordering, gate realism, risk register completeness, owner-fork framing
(any decision taken that should be a fork? any fork that has an obviously correct answer?).
8. **What's missing entirely** — i18n, a11y, CSP/nonce policy, mobile, versioned asset caching,
plugin frontend testing story, performance budgets, anything the four consumers will need
that the contracts cannot express.

## Output contract (findings only — DO NOT edit design docs)

Write exactly one file: `.llm/runs/plan-frontend-contrib--seed/adversarial-sol.md`, structured:

```
# Adversarial Review — Sol high (stage 2)
## Verdict summary <3-6 lines: overall soundness + top risks>
## Findings
### S-1 <title> [severity: blocker|major|minor|enhancement] [area: contracts|discovery|runtime|dx|examples|plan|missing]
Claim under attack: <quote/cite file:line>
Evidence: <what you verified, with citations/urls>
Finding: <the flaw or enhancement>
Proposal: <concrete fix/enhancement the generator can apply>
### S-2 …
## Verified-claims log <upstream/repo claims you checked and CONFIRMED, one line each>
```

Number every finding. Severity honestly: a `blocker` means the design as written would fail
implementation; `enhancement` means the design works but you propose better.

## Hard constraints

- Do NOT modify any file except creating `adversarial-sol.md` (and nothing under `packages/`,
`plugins/`, `docs/`, `.github/`).
- No GitHub mutations (no PRs/issues/labels). No `deno cache --reload`. Do not delete lock files.
- Commit exactly once: message
`plan(frontend-contrib): adversarial Sol findings (stage 2)`, then push with the explicit
refspec `git push origin HEAD:refs/heads/plan/frontend-contrib`. Never bare `git push`.
- When done, end your final message with `DONE` on its own line. If blocked, end with
`BLOCKED: <reason>`.
57 changes: 57 additions & 0 deletions .llm/runs/plan-frontend-contrib--seed/briefs/kimi-docs-brief.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use harness

# Stage 3 — Public docs & API story (Kimi K3, docs-first concretion)

You are the **stage-3 docs agent** for seed run `.llm/runs/plan-frontend-contrib--seed/` on
branch `plan/frontend-contrib`. The frontend contribution layer has been designed (rev 2,
post-adversarial). Your job — the owner's rationale, verbatim intent: *forecasting the docs
makes the public API concrete and forces DX-first implementation.* You write the public-facing
documentation as if the feature had shipped. Where writing the docs exposes an API wart, you
record it — you do not change the contracts.

## SKILL

Read in order: `.agents/skills/netscript-harness/SKILL.md` (context only — you produce docs
drafts, no evals), then the run docs: `design/canonical/00-overview.md` → `06-doctrine-fit.md`,
`design/examples/*.md`, `plan.md`. Treat `design/canonical/01-contracts.md` (rev 2) as the
normative API. For voice/format, look at 2-3 existing public docs pages under `docs/site/` and
the README of `packages/fresh-ui/` or `packages/plugin/`.

## Deliverables (create exactly these files)

1. `design/docs-story/guide-plugin-frontend.md` — the future docs-site guide **"Ship frontend
from your plugin"**, written as-if-shipped: 5-minute quickstart (the crons example),
authoring model (routes/islands/zones/nav/theme), the dev loop (`plugin new --with frontend`,
`plugin dev`, local-source vs published modes — honest about both), data access via the
gateway + typed clients, starters vs live (`plugin resource add`), theming with `--ns-*`
tokens, troubleshooting (quarantine states, doctor).
2. `design/docs-story/reference-plugin-frontend-core.md` — API reference for
`@netscript/plugin-frontend-core` (`defineFrontend`, envelope, the five `app`-family kinds,
identity, `HostSurfaceDescriptor`, contexts, `requires`, `./testing` kit) in deno-doc-style
sections with signatures + one example each.
3. `design/docs-story/reference-fresh-plugins.md` — API reference for `@netscript/fresh/plugins`
(`defineFreshApp` `frontend` option, `mountPluginFrontends`, `definePluginPage`, `pluginApi`,
`PluginZone`, `pluginNavSections`, `normalizeFreshRouteModule`, the generated gateway).
4. `design/docs-story/readme-fragments.md` — the README section each affected package gains
(plugin-frontend-core, fresh, plugin, cli), each a self-contained fragment.
5. `design/docs-story/docs-story-notes.md` — **the point of this stage**: every place where
writing the doc was awkward — a name that reads badly, a concept needing two paragraphs where
one should do, a step authors will forget, an asymmetry between kinds — as numbered notes
(K-1, K-2, …) with a concrete suggestion each. Honest and specific; the generator integrates
these next.

## Hard rules

- **No invented APIs.** Every symbol/field you document must exist in the rev-2 contracts docs.
Mechanisms the design marks [P1]–[P5] (proof-gated) are documented without the proof caveat in
the as-if-shipped guide BUT listed in docs-story-notes.md as pending proofs. If a doc needs an
API the design lacks, that is a K-note, not a new API.
- **Public-clean prose** in files 1–4: no internal run/process/PR references, no harness
vocabulary, no model/agent names. File 5 is internal and may reference anything.
- Files land ONLY under `.llm/runs/plan-frontend-contrib--seed/design/docs-story/`. No other
file edits; nothing under `packages/`, `plugins/`, `docs/`, `.github/`.
- Match the repo's Markdown style (100-col wrap, fenced ts/tsx blocks).
- Commit exactly once: `plan(frontend-contrib): Kimi K3 docs story (stage 3)` and push with
`git push origin HEAD:refs/heads/plan/frontend-contrib` (never bare push). If push fails,
leave the commit local and say so.
- End your final message with `DONE` (or `BLOCKED: <reason>`).
Loading
Loading