Skip to content

feat: read the abgen registry from the AB status commands - #397

Merged
dalkia merged 5 commits into
mainfrom
feat/abgen-registry-status
Sep 10, 2026
Merged

dalkia merged 5 commits into
mainfrom
feat/abgen-registry-status

Conversation

@dalkia

@dalkia dalkia commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

--platform abgen (#396) can queue an abgen conversion, but nothing in the CLI could read the result: pointer-consistency and world-ab-status both hardcode https://asset-bundle-registry.decentraland.<env>, while abgen publishes to asset-bundle-registry-abgen.decentraland.<org|zone>.

  • --registry unity|abgen on both status commands, defaulting to unity — existing invocations are unchanged.
  • abgen + today is rejected up front: no abgen queue there, and the hostname does not resolve.
  • New ab-queue-status command: per-platform pending counts and the 1-indexed position of any --cid passed, instead of curling the full queue.
  • Registry URLs, statusLabel, formatVersion and the reported-platform list (what keeps decommissioned webgl out of the output) move to helpers/ab-registry.ts.
  • Drops two maps in world-ab-status that were populated and never read.
  • Fixes a pre-existing vv49: the registry already stores the version prefixed, and both commands added another v.

Tested against org and zone with a scene, a world and a base wearable — same payload shape from both registries, today guard exits in 0.3s with no network call.

🤖 Generated with Claude Code

The abgen generator publishes to asset-bundle-registry-abgen.decentraland.
<org|zone>, which nothing in the CLI could reach: pointer-consistency and
world-ab-status both hardcoded the Unity registry URL, so checking an abgen
conversion meant curling /entities/active by hand and trimming a ~160 KB
entity payload down to the handful of fields that get reported.

Both commands now take --registry unity|abgen, defaulting to unity so
existing invocations are unchanged, and abgen on today is rejected up front
(no abgen queue there, and the hostname does not resolve). Adds
ab-queue-status for the same reason: /queues/status was another raw curl,
and it prints per-platform counts plus the 1-indexed position of the entities
you asked about instead of the whole queue.

The registry URLs, the shared statusLabel, the reported-platform list (which
is what keeps decommissioned webgl out of the output) and the separate-version-
series note now live in helpers/ab-registry.ts.
The registry stores the version already prefixed ("v49"), so both status
commands printed "vv49". Share one formatVersion helper, print the value as
it comes, and treat an empty version string as N/A — a platform key with an
empty version means it never built.
The [abgen] label in the header already says which registry is being read;
the extra line was documentation printed on every run.

@decentraland-bot decentraland-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: feat: read the abgen registry from the AB status commands

PR: #397 · Branch: feat/abgen-registry-status → main
Files changed: 6 (+175/−55) · CI: pending (build)


Summary

Adds --registry unity|abgen to pointer-consistency and world-ab-status, creates a new ab-queue-status command, and extracts shared helpers (statusLabel, REPORTED_PLATFORMS, formatVersion, parseRegistry, registryUrlFor) into src/helpers/ab-registry.ts — eliminating the duplicated statusLabel function and hardcoded platform lists.

The refactoring is clean: the shared module is well-scoped, the new command follows existing patterns exactly, and the --registry flag defaults to unity so existing invocations are unaffected.

Findings

No P0 or P1 issues.

[P2] Unconsumed response body on error path — ab-queue-status.ts:23-25
When !response.ok, the response body is not consumed before throwing. For a CLI that exits immediately this is benign (process termination cleans up the socket), but adding await response.body?.cancel() before the throw would set the right pattern for new code. Same pre-existing pattern in pointer-consistency.ts:62-64 and world-ab-status.ts:79-82.

[P2] formatVersion drops the manual v prefix — intentional bug fix
Old code: v${version.version} → "vv49" if the registry stores "v49".
New code: ${version.version} → "v49" as-is.
The inline comment at ab-registry.ts:43 confirms the registry already stores the prefix, and the PR body confirms live verification. This is a fix, not a regression. The secondary improvement (version?.version guard instead of just truthy object check) is strictly more robust.

[P2] Dead code in world-ab-status.ts — pre-existing
Two maps (registryByEntityId at line 92 and entityIdByPointer at line 57) are populated but never read. The actual lookup uses registryEntities.find(...). Good cleanup opportunity if you're touching the file.

[P2] RegistryKind imported as value, used only as type — pointer-consistency.ts:7
import { type RegistryKind, ... } would be clearer intent, though no runtime impact since verbatimModuleSyntax is not enabled.

What looks good

  • Type safety: RegistryKind union + isRegistryKind type guard + parseRegistry validation is well-structured. The QueueStatus record type is appropriate for the dynamic ${platform}PendingJobs key pattern.
  • Input validation: parseRegistry rejects unknown registry values and the invalid abgen + today combination up front with clear error messages.
  • URL safety: encodeURIComponent(world) used in both URL paths and query strings in world-ab-status.ts. registryUrlFor constructs URLs from a validated RegistryKind — no injection risk.
  • Fetch bodies consumed: All happy-path fetches consume bodies via .json().
  • Pattern consistency: The new ab-queue-status command follows the exact same structure as existing commands (arg parsing, CliError, console output).
  • Deduplication: Extracting the shared module eliminates real duplication without over-abstracting.
  • README: Thorough documentation including the registry table, version series caveat, and today/abgen rejection.

Consumer Impact

Backward-compatible. --registry defaults to unity; ab-queue-status is additive. Output labels now include [unity]/[abgen], which the agent-server ab-status skill accounts for in stacked PR #266. No public API surface changed.

Git Conventions (ADR-6)

  • PR title: feat: read the abgen registry from the AB status commands ✅
  • Branch: feat/abgen-registry-status ✅

Security

  • Read-only endpoints, no credentials or authentication involved
  • No new dependencies added
  • URL construction from validated inputs only

DEPENDENCY_REVIEW: PASS

Verdict: ✅ APPROVE

No P0 or P1 findings. The code is clean, well-structured, and backward-compatible. The P2s are minor — the dead-code cleanup is the most actionable if you want to tidy up while you're in the files.


Reviewed by Jarvis 🤖 · Requested by Juan Ignacio Molteni (<@U03JSUQ5Z7U>) via Slack

entityIdByPointer and registryByEntityId were populated and then ignored;
the scene/registry match goes through registryEntities.find().

@decentraland-bot decentraland-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review: feat: read the abgen registry from the AB status commands

PR: #397 · Branch: feat/abgen-registry-status → main
Files changed: 6 (+175/−55) · CI: build pending
Commits: 5 (feat + fix + 2 chores + style)
Head: 4ee1869


Summary

Adds --registry unity|abgen to pointer-consistency and world-ab-status, creates a new ab-queue-status command, and extracts shared helpers (statusLabel, REPORTED_PLATFORMS, formatVersion, parseRegistry, registryUrlFor) into src/helpers/ab-registry.ts.

Since the first review, the PR picked up four follow-up commits:

  • fix: stop double-prefixing the bundle version — the vv49 bug fix cleanly separated
  • chore: drop the version-series reminder line — the [abgen] label already signals which registry
  • style: collapse the import prettier can now fit on one line
  • chore: drop two maps world-ab-status never read — removes entityIdByPointer and registryByEntityId (addressed from the earlier P2)

Findings

No P0 or P1 issues.

[P2] Unconsumed response body on error path — ab-queue-status.ts:23-24
When !response.ok, the body is not consumed before throwing CliError. For a CLI that exits on throw this is benign, but await response.body?.cancel() before the throw would be clean. Same pre-existing pattern in pointer-consistency.ts:62-64 and world-ab-status.ts:79-81.

[P2] RegistryKind imported as value, used only as type — pointer-consistency.ts:7
RegistryKind is only used as the type annotation for the kind parameter at line 50. Using import { type RegistryKind, ... } would be clearer. No runtime impact.

What looks good

  • Shared helper module (ab-registry.ts): Well-scoped extraction — RegistryKind union + isRegistryKind type guard + parseRegistry validation is solid. parseRegistry rejects invalid kinds and the abgen + today combination up front with clear error messages.
  • New ab-queue-status command: Follows the exact same structure as existing commands. QueueStatus type is appropriate for the dynamic ${platform}PendingJobs keys. Jobs presence is checked before accessing .length.
  • Dead code cleaned up: Both unused maps (registryByEntityId, entityIdByPointer) removed in a dedicated commit. The pointer collection simplified to allPointers.push(...scene.parcels).
  • formatVersion fix: Correctly drops the manual v prefix (registry already stores "v49"), and the guard is now version?.version (truthy string) instead of just truthy object — handles empty-string edge case.
  • URL safety: encodeURIComponent(world) in both URL paths and query strings. registryUrlFor builds URLs from a validated RegistryKind.
  • Fetch bodies consumed: All happy-path fetches consume bodies via .json().
  • Backward compatible: --registry defaults to unity; ab-queue-status is additive. Existing invocations unchanged.
  • Commit structure: Clean semantic separation — feature, fix, chores, style. Each commit is self-contained.
  • README: Thorough documentation including the registry table, version series caveat, and today/abgen rejection.

Consumer Impact

Backward-compatible. The agent-server ab-status skill (PR #266) accounts for the new output labels and ab-queue-status command. No other known consumers of the output format.

Git Conventions (ADR-6)

  • PR title: feat: read the abgen registry from the AB status commands ✅
  • Branch: feat/abgen-registry-status ✅
  • Individual commits follow semantic format ✅

Security

  • Read-only endpoints, no credentials or authentication
  • No new dependencies
  • URL construction from validated inputs only
  • No injection vectors

DEPENDENCY_REVIEW: PASS

Verdict: ✅ APPROVE

No P0 or P1 findings. The code is clean, well-structured, and backward-compatible. The follow-up commits addressed the dead-code and version-prefix findings from the first pass. Only two minor P2s remain.


Reviewed by Jarvis 🤖 · Requested by Juan Ignacio Molteni (<@U03JSUQ5Z7U>) via Slack

@dalkia
dalkia merged commit d00f7bd into main Sep 10, 2026
1 check passed
@dalkia
dalkia deleted the feat/abgen-registry-status branch September 10, 2026 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants