Summary
emit is advertised by three deploy adapters, implemented by them, and given a router description —
but it is not routed, so no netscript deploy <target> emit command exists. netscript deploy list reports an operation nobody can invoke.
Evidence
Verified at cd24e1679:
-
Advertised. packages/cli/src/kernel/adapters/aspire/aspire-compose-deploy-target.ts:64-71
declares operations = ['plan', 'emit', 'up', 'down', 'status', 'logs']. The cloud and service
deploy adapters advertise it too.
-
Implemented. aspire-compose-deploy-target.ts:95-97 implements the emit branch.
-
Described. target-deploy-command.ts OPERATION_DESCRIPTIONS carries
emit: 'Emit deployment artifacts'.
-
Not routed. target-deploy-command.ts:15-23:
const ROUTED_OPERATIONS: readonly DeployOperation[] = [
'plan', 'up', 'down', 'status', 'logs', 'rollback', 'secrets',
];
Subcommands are generated from ROUTED_OPERATIONS filtered by the adapter's advertised set
(:42, :59), so an operation absent from ROUTED_OPERATIONS can never become a command
regardless of what the adapter advertises. The public verb surface is the intersection, and
emit is not in it.
Why it matters
The repo already states the correct convention for the opposite case:
service-deploy-target.ts:14-20 documents rollback/secrets as not advertised precisely so the
router does not expose them. emit is the inverse — advertised without being reachable — and
nothing enforces the invariant in either direction.
The user-visible consequence is netscript deploy list: it reports each target's advertised
operations, so it prints emit as available while netscript deploy <target> emit does not exist.
A reader who trusts deploy list gets a command-not-found. This also cost documentation work: a
docs pass counting advertised operations concluded the surface was six verbs and nearly shipped
that into the CLI reference; it is five.
Scope
Decide which side is right, then make the other match:
- if
emit should be public, add it to ROUTED_OPERATIONS; or
- if it is internal (a
plan implementation detail — note plan's own description is "Emit or
preflight deployment artifacts", suggesting plan already covers it), stop advertising it and
drop its OPERATION_DESCRIPTIONS entry.
Then close the class: a test asserting every advertised operation across every registered adapter
is routable, so advertise-without-route cannot recur silently. deploy list should report the
commands a user can run, not the adapter's internal capability set.
Boundaries
Acceptance criteria
The negative test is drawn from the live defect, so the predicate is known to be satisfiable.
Provenance
Found by the 0.0.6 documentation-lane authoring pass for #1377 while verifying the deploy verb
surface against the command tree rather than against the adapter's operations array.
Summary
emitis advertised by three deploy adapters, implemented by them, and given a router description —but it is not routed, so no
netscript deploy <target> emitcommand exists.netscript deploy listreports an operation nobody can invoke.Evidence
Verified at
cd24e1679:Advertised.
packages/cli/src/kernel/adapters/aspire/aspire-compose-deploy-target.ts:64-71declares
operations = ['plan', 'emit', 'up', 'down', 'status', 'logs']. The cloud and servicedeploy adapters advertise it too.
Implemented.
aspire-compose-deploy-target.ts:95-97implements theemitbranch.Described.
target-deploy-command.tsOPERATION_DESCRIPTIONScarriesemit: 'Emit deployment artifacts'.Not routed.
target-deploy-command.ts:15-23:Subcommands are generated from
ROUTED_OPERATIONSfiltered by the adapter's advertised set(
:42,:59), so an operation absent fromROUTED_OPERATIONScan never become a commandregardless of what the adapter advertises. The public verb surface is the intersection, and
emitis not in it.Why it matters
The repo already states the correct convention for the opposite case:
service-deploy-target.ts:14-20documentsrollback/secretsas not advertised precisely so therouter does not expose them.
emitis the inverse — advertised without being reachable — andnothing enforces the invariant in either direction.
The user-visible consequence is
netscript deploy list: it reports each target's advertisedoperations, so it prints
emitas available whilenetscript deploy <target> emitdoes not exist.A reader who trusts
deploy listgets a command-not-found. This also cost documentation work: adocs pass counting advertised operations concluded the surface was six verbs and nearly shipped
that into the CLI reference; it is five.
Scope
Decide which side is right, then make the other match:
emitshould be public, add it toROUTED_OPERATIONS; orplanimplementation detail — noteplan's own description is "Emit orpreflight deployment artifacts", suggesting
planalready covers it), stop advertising it anddrop its
OPERATION_DESCRIPTIONSentry.Then close the class: a test asserting every advertised operation across every registered adapter
is routable, so advertise-without-route cannot recur silently.
deploy listshould report thecommands a user can run, not the adapter's internal capability set.
Boundaries
five reachable verbs. This issue is the source defect behind that discrepancy.
rollback/secretsnon-advertisement, which isdeliberate and correctly documented.
Acceptance criteria
emitis either routable or no longer advertised — decision recorded on this issue.netscript deploy listreports only operations that resolve to a runnable command.ROUTED_OPERATIONS.exit non-zero.
The negative test is drawn from the live defect, so the predicate is known to be satisfiable.
Provenance
Found by the 0.0.6 documentation-lane authoring pass for #1377 while verifying the deploy verb
surface against the command tree rather than against the adapter's
operationsarray.