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
Tracking issue holding the command-by-command parity classification against Go lagotto. Filed because "parity" had never been written down anywhere: this repo had zero issues and zero milestones, so nothing distinguished a deliberate omission from an oversight.
Headline
Go is ~6,858 non-test lines across 11 commands; lagotto-ts is 699 lines across 10 files. The gap is real but concentrated, and the audit overturned the expected verdict on its biggest piece (persistence — see #4).
Command tiers
Go command
tier
where
watch (create)
B
the matching is ported (evaluate, compilePattern, azs, duration); creating a persisted watch needs #4
poll
A/B
CapacityWatcher.check/poll ports searchBestMatch faithfully — but see #1 (regions)
deletes tables and user data — must never be a browser action
deploy
D/E
CloudFormation stack + pkg/runtimeiam IAM policy
Package tiers
A — at parity, verified line-by-line:
matcher.goEvaluate → src/core/matcher.ts — both branches, both rejection paths, the candidateAzs carry, the "spot watch with no price = no match" fallthrough
azAllowed / orderAZs → src/core/azs.ts — including "empty az is always allowed" and pin-order-wins
wildcardToRegex → src/core/pattern.ts — same metachar set ^$()[]{}+\, same escape order
ParseDuration → src/core/duration.ts (ms instead of ns, documented)
searchBestMatch → CapacityWatcher.check — same cheapest-wins fold
poller.go (722) — the sweep: filters, leases, recordOutcome state machine, PollSummary. The per-watch matching is ported; the multi-watch supervisor loop is a daemon.
spawner.go (383) — calls spawn to launch; AZ-retry within a cycle. Belongs to spawn-ts's launch path, not here.
holder.go (84) — CreateCapacityReservation ODCR hold. Actually browser-reachable (EC2 is CORS-open) but it creates a billable reservation, so it needs the same human-in-the-loop treatment as RunInstances; classify as B-with-a-guard rather than a free port.
scheduled.go (207) — scheduled-launch records + IfExists overlap policy (skip default for one-shots so an --at into a Capacity Block can't double-launch).
lambda/capacity-poller (320), pkg/deploy (283), pkg/runtimeiam (144), pkg/awscfg (65 — no ~/.aws in a browser), pkg/testutil (114).
E — deliberately excluded:sagemaker.go (155) + the --service sagemaker surface. Symmetric to truffle-ts's SageMaker exclusion; ValidateWatchPattern's ml.* guard is still worth porting (#3).
Also missing from the domain model
src/core/types.ts documents itself as a trimmed subset, which is fair, but two omissions have behavioural weight:
WatchStatus lacks completed — Go added it for goal-driven fleet watches (--until became true), and it's distinct from matched (a single-shot that fired once). Collapsing them loses the difference between "the work is done" and "we launched something".
DesiredCount / CompletionCondition — the fleet-supervisor fields. conditions.tsalready ports the --until parser, so lagotto-ts can evaluate a completion condition it has no field to store. Either carry the fields or say in the type doc that fleet watches are out of scope.
Priority
#1 (silent single-region watch) → #2 (failure classifier) → #4 read-only half → #3. #1 is blocked on truffle-ts#31.
Tracking issue holding the command-by-command parity classification against Go
lagotto. Filed because "parity" had never been written down anywhere: this repo had zero issues and zero milestones, so nothing distinguished a deliberate omission from an oversight.Headline
Go is ~6,858 non-test lines across 11 commands; lagotto-ts is 699 lines across 10 files. The gap is real but concentrated, and the audit overturned the expected verdict on its biggest piece (persistence — see #4).
Command tiers
watch(create)evaluate,compilePattern,azs,duration); creating a persisted watch needs #4pollCapacityWatcher.check/pollportssearchBestMatchfaithfully — but see #1 (regions)liststatus <id>cancel <id>Holder.Release) so it stops billingextend <id>ExtendWatch, incl. thereactivatepath)historylaunch --at/--after/--cronsetupteardowndeploypkg/runtimeiamIAM policyPackage tiers
A — at parity, verified line-by-line:
matcher.goEvaluate→src/core/matcher.ts— both branches, both rejection paths, thecandidateAzscarry, the "spot watch with no price = no match" fallthroughazAllowed/orderAZs→src/core/azs.ts— including "empty az is always allowed" and pin-order-winswildcardToRegex→src/core/pattern.ts— same metachar set^$()[]{}+\, same escape orderParseDuration→src/core/duration.ts(ms instead of ns, documented)searchBestMatch→CapacityWatcher.check— same cheapest-wins foldB — portable, missing → filed:
pkg/failure) — the retry taxonomy is the tool's core judgement #2pkg/failure(148 lines) — the capacity/terminal/unknown retry taxonomy. Highest-value pure port available.schedule_expr.go,service.go,validation.golist/status/cancel/extend/historyare portable #4store.goread/update half (759 lines total; the provisioning half is D)C/D — needs a daemon or a node:
poller.go(722) — the sweep: filters, leases,recordOutcomestate machine,PollSummary. The per-watch matching is ported; the multi-watch supervisor loop is a daemon.spawner.go(383) — calls spawn to launch; AZ-retry within a cycle. Belongs to spawn-ts's launch path, not here.holder.go(84) —CreateCapacityReservationODCR hold. Actually browser-reachable (EC2 is CORS-open) but it creates a billable reservation, so it needs the same human-in-the-loop treatment asRunInstances; classify as B-with-a-guard rather than a free port.notifier.go(224) — SNS + webhook POST with the dial-time SSRF guard, which a browser cannot reproduce (see Port the small pure helpers: schedule expressions, service/pattern validation, webhook URL vetting #3).snipe.go(255) — the stateless block-and-wait acquire. Interesting for a browser once Port the launch-failure classifier (pkg/failure) — the retry taxonomy is the tool's core judgement #2 lands, since it needs no store; blocked on launch capability.scheduled.go(207) — scheduled-launch records +IfExistsoverlap policy (skipdefault for one-shots so an--atinto a Capacity Block can't double-launch).lambda/capacity-poller(320),pkg/deploy(283),pkg/runtimeiam(144),pkg/awscfg(65 — no~/.awsin a browser),pkg/testutil(114).E — deliberately excluded:
sagemaker.go(155) + the--service sagemakersurface. Symmetric to truffle-ts's SageMaker exclusion;ValidateWatchPattern'sml.*guard is still worth porting (#3).Also missing from the domain model
src/core/types.tsdocuments itself as a trimmed subset, which is fair, but two omissions have behavioural weight:WatchStatuslackscompleted— Go added it for goal-driven fleet watches (--untilbecame true), and it's distinct frommatched(a single-shot that fired once). Collapsing them loses the difference between "the work is done" and "we launched something".DesiredCount/CompletionCondition— the fleet-supervisor fields.conditions.tsalready ports the--untilparser, so lagotto-ts can evaluate a completion condition it has no field to store. Either carry the fields or say in the type doc that fleet watches are out of scope.Priority
#1 (silent single-region watch) → #2 (failure classifier) → #4 read-only half → #3. #1 is blocked on truffle-ts#31.