Skip to content

Go-parity audit: lagotto-ts vs lagotto (tracking) #5

Description

@scttfrdmn

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)
list B #4
status <id> B #4
cancel <id> B #4 — note the Go version also releases an active ODCR (Holder.Release) so it stops billing
extend <id> B #4 (ExtendWatch, incl. the reactivate path)
history B #4
launch --at/--after/--cron B #3 (pure expression) + Scheduler is CORS-open
setup D/E creates DynamoDB tables — provisioning, CLI's job
teardown D/E 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.go Evaluatesrc/core/matcher.ts — both branches, both rejection paths, the candidateAzs carry, the "spot watch with no price = no match" fallthrough
  • azAllowed / orderAZssrc/core/azs.ts — including "empty az is always allowed" and pin-order-wins
  • wildcardToRegexsrc/core/pattern.ts — same metachar set ^$()[]{}+\, same escape order
  • ParseDurationsrc/core/duration.ts (ms instead of ns, documented)
  • searchBestMatchCapacityWatcher.check — same cheapest-wins fold

B — portable, missing → filed:

C/D — needs a daemon or a node:

  • 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.
  • 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 + 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.ts already 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions