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
Locked program spec. Base: clean alpha.16 (@netscript/* all-31 published, e2e-cli-prod
green). This issue is the single authority for the procedure, the Claude-workflow contract, the
greenfield-first sequencing, and every binding technical requirement. Nothing here self-certifies;
every gate below is hard.
Summary
After #172 achieved functional plugin unification (type-soundness, unified CLI, unified
scaffolding, unified registration, base plugin contract + base service seam), the plugin structure, semantics, readability, and doctrine adherence are still not enterprise-grade.
Incremental convergence kept the old CLI-scaffold/registration assumptions as fixed constraints, so
each plugin accreted adapter files, "for convenience" root re-exports, and "make-the-test-pass"
workarounds. A developer wanting to add (e.g.) a multi-payment-provider plugin with swappable
backends — like auth — finds no discoverable conventions, too many barrel/re-export files, and
unclear filenames.
This issue tracks Plugin RE-ARCHITECTURE v2: take the plugin layer to professional /
enterprise-grade quality with an EXTRA-THIN plugin surface — proven greenfield first, then
conform every existing plugin to it.
The standard
A plugin's only role is to implement the seams from its own -core into NetScript.
If a plugin needs many adapter files + workarounds to fit a standard pattern (triggers, sagas,
workers, streams, auth) into NetScript, that is proof the design is wrong — fix the design,
not the plugin.
Every convention-bearing or by-design-repeating primitive lives in core (@netscript/plugin);
plugins are thin, predictable, and carry only their specifics.
Reference the well-crafted packages — packages/cli, @netscript/fresh — for how doctrine is
applied: thin abstract public surface, well-defined implementation, well-structured package.
New issue / fresh program off the clean base — this issue.
A COMPLETE Claude dynamic Workflow analyzes ALL 5 existing plugins and, for EACH, drafts
the most idiomatic MINIMAL plugin structure. Reports differ per plugin. Output is analysis +
a plan + agent/evaluator briefs only — never framework-source edits (per the Claude Workflow
Policy).
Merge the best decisions from each plugin's report into ONE unified plugin architecture.
Build netscript plugin new <name> GREENFIELD first — constraints removed, so it produces the
absolute best DX and proves the new architecture E2E before any refactor. (This is the pending
Unified S9 work, built first as the reference shape.)
THEN conform existing plugins + the feeder packages to the proven architecture, by strong
design principles. Having proven it greenfield greatly simplifies each refactor.
B. Claude-workflow contract (generator / analysis-only)
The Claude dynamic Workflow is the analysis + planning lane ONLY. Per CLAUDE.md Claude Workflow
Policy and the harness Agent Delegation Contract:
It produces per-plugin minimal-arch analysis → ONE unified architecture → plan + agent briefs +
evaluator prompts. It does not write framework source and does not self-certify.
Workflow agents return structured analyses; the supervisor writes all artifacts (worktree-pin
landmine: agents cannot redirect Edit/Write across worktrees).
PLAN-EVAL (OpenHands, minimax-M3, separate session) is a hard gate before any implementation
slice.
Implementation runs as WSL Codex daemon-attached slices (mobile-visible, steerable), one
trackable slice at a time (branch, thread id, files, tests, commit, push, PR comment).
IMPL-EVAL (OpenHands, qwen3.7-max, separate session) before merge.
Confirmed workflow topology (locked)
PHASE 1 — analyze (5 parallel agents, 1 per plugin: workers/sagas/triggers/streams/auth)
each returns a STRUCTURED minimal-arch report:
{ current tree, public surface, doctrine smells (barrels/workarounds/anti-thinness),
shared-vs-specific split, proposed MINIMAL connector + -core shape }
PHASE 2 — critic (1 doctrine/adversarial agent per report)
doctrine + thinness-law + adversarial pass over each proposed shape
(catches convenience barrels, workaround adapters, fabricated routes, naming drift)
PHASE 3 — synthesize (1 agent)
merge all reports + critiques into:
- ONE unified plugin architecture
- the `plugin new` GREENFIELD spec (both tiers, see C)
- a PLAN-EVAL brief (scope, gates, debt implications, evaluator prompt)
supervisor writes ALL artifacts to the run dir; nothing self-certifies.
C. plugin new GREENFIELD output contract (then conform)
netscript plugin new <name> MUST ship BOTH tiers as a single compiling / green / publishable
vertical slice:
packages/plugin-<name>-core — contract extends the base contract; domain/, ports/, application/ layering; ./contracts/v1; README "the engine lives here."
plugins/<name> — thin connector; service extends the base service; manifest;
composition root; README "thin connector."
workspace wiring + lockstep versions across both tiers.
Rules:
The auth-style 3-tier split (core + swappable backend sibling packages, e.g. workos / better-auth / kv-oauth) is documented in the core README, NOT pre-scaffolded (A11; optional
later --with-adapter).
READMEs are generated from a shared core-owned template and double as JSR landing pages.
@netscript/plugin exports BASE_PLUGIN_ROUTES (meta fragment: health + info/version + capability
descriptor) + a BasePluginContracttype. Each -core contract spreads the fragment and is satisfies BasePluginContract (coverage = compile error).
createPluginService() factory wraps the createService builder via composition (A5, not
inheritance) and bakes mandatory infra in the one valid chain order
(…withContext → withRPC → withHealth → withServiceInfo); caller only .serve(). oRPC has no .extend() / .merge().
Decision A:streams = proxy/infra archetype carrying base-meta ONLY (do not fabricate
feature routes, A11).
Decision B:sagas adopts the evolved plugin-sagas-core contract.
Decision C: base contract = shared error set (NOT_FOUND / VALIDATION_ERROR / INTERNAL) +
ONE mandatory TYPED oRPC describe/capabilities route per feature plugin.
Contracts live in -coreby design (anti-cyclic; core derives seam types from the contract);
connector contracts/v1 is a thin re-export.
D2 — Scaffold surface = typesafe codegen
The scaffold surface imports the installed plugin + core and emits ONLY userland glue
(entrypoint + config edits + sample stubs + sensible Prisma schema) via a typesafe factory / AST — NEVER string templates, NEVER copies plugin internals. String codegen is banned for the scaffold
surface.
D3 — Thinness / core-centralization LAW
Every convention-bearing OR by-design-repeating primitive lives in core; plugins are thin /
predictable / specifics-only; a plugin must NEVER invent convention/standard. The auth pillar
(auth-core + thin adapter packages) is the reference shape. Run a completeness sweep, not just
known-dup fixes. Guard byte-identical generated output.
D4 — Re-architecture license (widens latitude, not the bar)
Explicit license to deeply re-architect packages/plugin + packages/cli internals — "don't be
afraid to rethink / re-architect." All invariants still bind: doctrine layering + axioms (A4/A5, no
cross-package inheritance), JSR-readiness, no plugin-source leak into userland, host-side
config-wiring preserved, 2-cast limit, no any, no deno.lock churn, forward-only.
Waivers → arch-debt; rescopes → drift.
Scope
plugins/{workers,sagas,triggers,streams,auth} — all 5 connectors.
packages/plugin (@netscript/plugin) — contract base, adapter, ItemScaffolder, runner, factory. In scope — the feeder bends to the architecture, it is not a fixed constraint.
Plugin RE-ARCHITECTURE v2 — enterprise-grade, EXTRA-THIN plugin surface
Summary
After #172 achieved functional plugin unification (type-soundness, unified CLI, unified
scaffolding, unified registration, base plugin contract + base service seam), the plugin
structure, semantics, readability, and doctrine adherence are still not enterprise-grade.
Incremental convergence kept the old CLI-scaffold/registration assumptions as fixed constraints, so
each plugin accreted adapter files, "for convenience" root re-exports, and "make-the-test-pass"
workarounds. A developer wanting to add (e.g.) a multi-payment-provider plugin with swappable
backends — like
auth— finds no discoverable conventions, too many barrel/re-export files, andunclear filenames.
This issue tracks Plugin RE-ARCHITECTURE v2: take the plugin layer to professional /
enterprise-grade quality with an EXTRA-THIN plugin surface — proven greenfield first, then
conform every existing plugin to it.
The standard
-coreinto NetScript.workers, streams, auth) into NetScript, that is proof the design is wrong — fix the design,
not the plugin.
@netscript/plugin);plugins are thin, predictable, and carry only their specifics.
packages/cli,@netscript/fresh— for how doctrine isapplied: thin abstract public surface, well-defined implementation, well-structured package.
A. Procedure (locked, user-mandated step order)
not done-when-pretty).
the most idiomatic MINIMAL plugin structure. Reports differ per plugin. Output is analysis +
a plan + agent/evaluator briefs only — never framework-source edits (per the Claude Workflow
Policy).
netscript plugin new <name>GREENFIELD first — constraints removed, so it produces theabsolute best DX and proves the new architecture E2E before any refactor. (This is the pending
Unified S9 work, built first as the reference shape.)
design principles. Having proven it greenfield greatly simplifies each refactor.
B. Claude-workflow contract (generator / analysis-only)
The Claude dynamic Workflow is the analysis + planning lane ONLY. Per CLAUDE.md Claude Workflow
Policy and the harness Agent Delegation Contract:
evaluator prompts. It does not write framework source and does not self-certify.
landmine: agents cannot redirect Edit/Write across worktrees).
slice.
trackable slice at a time (branch, thread id, files, tests, commit, push, PR comment).
Confirmed workflow topology (locked)
C.
plugin newGREENFIELD output contract (then conform)netscript plugin new <name>MUST ship BOTH tiers as a single compiling / green / publishablevertical slice:
packages/plugin-<name>-core— contract extends the base contract;domain/,ports/,application/layering;./contracts/v1; README "the engine lives here."plugins/<name>— thin connector; service extends the base service; manifest;composition root; README "thin connector."
Rules:
workos/better-auth/kv-oauth) is documented in the core README, NOT pre-scaffolded (A11; optionallater
--with-adapter).{ connector + -core + dual exhaustive role READMEs }. Greenfield (plugin new, Unified S9) is thereference shape built FIRST; then existing plugins conform to it.
D. Technical requirements (binding invariants)
D1 — Base contract/service seam
@netscript/pluginexportsBASE_PLUGIN_ROUTES(meta fragment: health + info/version + capabilitydescriptor) + a
BasePluginContracttype. Each-corecontract spreads the fragment and issatisfies BasePluginContract(coverage = compile error).createPluginService()factory wraps thecreateServicebuilder via composition (A5, notinheritance) and bakes mandatory infra in the one valid chain order
(
…withContext → withRPC → withHealth → withServiceInfo); caller only.serve(). oRPC has no.extend()/.merge().streams= proxy/infra archetype carrying base-meta ONLY (do not fabricatefeature routes, A11).
sagasadopts the evolvedplugin-sagas-corecontract.NOT_FOUND/VALIDATION_ERROR/INTERNAL) +ONE mandatory TYPED oRPC
describe/capabilities route per feature plugin.-coreby design (anti-cyclic; core derives seam types from the contract);connector
contracts/v1is a thin re-export.D2 — Scaffold surface = typesafe codegen
The scaffold surface imports the installed plugin + core and emits ONLY userland glue
(entrypoint + config edits + sample stubs + sensible Prisma schema) via a typesafe factory / AST —
NEVER string templates, NEVER copies plugin internals. String codegen is banned for the scaffold
surface.
D3 — Thinness / core-centralization LAW
Every convention-bearing OR by-design-repeating primitive lives in core; plugins are thin /
predictable / specifics-only; a plugin must NEVER invent convention/standard. The auth pillar
(auth-core + thin adapter packages) is the reference shape. Run a completeness sweep, not just
known-dup fixes. Guard byte-identical generated output.
D4 — Re-architecture license (widens latitude, not the bar)
Explicit license to deeply re-architect
packages/plugin+packages/cliinternals — "don't beafraid to rethink / re-architect." All invariants still bind: doctrine layering + axioms (A4/A5, no
cross-package inheritance), JSR-readiness, no plugin-source leak into userland, host-side
config-wiring preserved, 2-cast limit, no
any, nodeno.lockchurn, forward-only.Waivers →
arch-debt; rescopes →drift.Scope
plugins/{workers,sagas,triggers,streams,auth}— all 5 connectors.packages/plugin(@netscript/plugin) — contract base, adapter,ItemScaffolder, runner, factory.In scope — the feeder bends to the architecture, it is not a fixed constraint.
packages/cli— plugininstall/new/verify+ scaffold surface (Marketplace foundation: Deno-native JSR-URL plugin add (dx scaffolder protocol) #167). In scope.finalize), Marketplace foundation: Deno-native JSR-URL plugin add (dx scaffolder protocol) #167-task (S8
plugin verifyauthor-grade doctor), Issue #167: Deno-native JSR-URL plugin add — marketplace foundation (S1-S12 + adversarial hardening) #168 (S9plugin newgreenfield generator).
Non-scope
-corepackages' internal runtime behavior, except where the seam exposed to the connector mustchange for thinness. Net-new triggers-core runtime is tracked separately as the Triggers
feature-backing program (TaskList feat(fresh): restore inline .withRouteContract shorthand + codegen page-module route binding (WI-12) #181): triggers connector backs only ~5 of 11 oRPC routes;
6 routes (
fireTrigger,testWebhook,previewSchedule,enableTrigger/disableTrigger,subscribeEvents) are honestly deferred pending-coreruntime (enabled-state store +namefield, manual-fire helper, cron-preview engine, SSE subscription port, DLQ backing).
Governance (harness)
IMPL-EVAL (qwen3.7-max) before merge.
Acceptance
plugin new <name>emits a conforming plugin (both tiers + dual role READMEs) that builds,type-checks, and runs E2E with zero legacy constraints.
adapters, discoverable conventions, role-named files.
deno task arch:checkgreen across@netscript/plugin+ the 5 plugins; scoped check/lint/testgreen;
deno publish --dry-runSuccess.scaffold.runtimeE2E green ande2e-cli-prod(JSR-installed) green — prod e2e is a hardacceptance gate.
Grounding (current state, alpha.16)
src/adapter/plugin.ts(<kind>AdapterPlugin: NetScriptPlugin),src/public/mod.ts(manifest +inspect<Kind>),contracts/v1/mod.ts,services/,streams/,tests/,src/adapter/resources/scaffolders.health-probe templates, e2e gate structure, services HTTP middleware.
triggers kinds/ingress/fire; streams schema+producer; auth backend-selection+session-state.
-coreand migrateDeno.openKv→@netscript/kv(docs(site): align plugin/CLI/architecture prose to alpha.13 surface #182 done for relocation gate; KV-engine migration tracked).