Skip to content

feat(ahbg): close construction (UCNS authority) + pass-5 release assets - #24

Merged
erinepshovel-code merged 1 commit into
mainfrom
feat/ahbg-construction
Sep 2, 2026
Merged

erinepshovel-code merged 1 commit into
mainfrom
feat/ahbg-construction

Conversation

@erinepshovel-code

Copy link
Copy Markdown
Contributor

Pass 5 — close construction, then shipping

1. Construction closed (core-mechanics blocker)

  • UCNS first: merged The-Interdependency/ucns PR #218
    (ucns.mobius_seed_construction@0.1.0, merge 828c0b8) — smallest correct
    construction state: built slots + buildable-next from the seed's own
    structural-vesica relations. No AHBG semantics in UCNS.
  • AHBG consumes it: ahbg/runtime/construction.py maps UCNS buildable-next
    onto UCNS-derived tiles; libs/ucns pin bumped in stack-manifest.json.
  • Harness contract now advertises executable construct; A0 and external
    harnesses build through the same observe/plan/act path.
  • Construct intents resolve with moves each turn; ledger persists/replays.
  • Regression: external harness constructs (12 runtime tests OK), A0 builds,
    out-of-boundary builds fail closed.

2. Android release-grade

  • versionCode 2 / versionName 0.2.0; production HTTPS endpoint; release
    signing config via gradle properties (keys never committed); network
    security config restricts cleartext to debug emulator hosts; adaptive icon.

3–4. RevenueCat + publish/submission assets

  • ahbg/submission/: store listing, privacy policy, ≤2-min demo storyboard,
    Devpost material, RevenueCat provisioning runbook, and explicit external
    blockers (Play Console, keystore, live RevenueCat project, demo recording).

Gates

  • runtime 12 OK · grok 6 OK · presentation 11 OK · node check · compileall ·
    UCNS construction import verified locally; CI will run runtime/android/grok.

hmmm

  • Everything after construction is shipping: store publication and live
    RevenueCat provisioning require the production accounts (documented in
    ahbg/submission/SUBMISSION_BLOCKERS.md).

Construction (core mechanics):
- Pin libs/ucns to The-Interdependency/ucns@828c0b8 (PR #218), the new
  authoritative mobius_seed_construction state.
- ahbg.runtime.construction binds AHBG construct to UCNS buildable-next;
  no parallel geometry.
- Harness contract adds executable 'construct' capability; A0 and external
  harnesses build through the same observe/plan/act path (regression tests).
- Construct intents resolve with moves each turn and persist in a replayable
  ledger beside the engine state.

Android release-grade:
- versionCode 2 / versionName 0.2.0; production HTTPS runtime endpoint;
  release signing config via gradle properties (keys never committed);
  network security config (cleartext only for emulator hosts in debug);
  adaptive launcher icon.

Submission assets:
- ahbg/submission/: store listing, privacy policy, demo storyboard, Devpost
  material, RevenueCat provisioning runbook, and explicit external blockers.

Gates local: runtime 12 OK, grok 6 OK, presentation 11 OK, node check OK,
compileall OK, UCNS construction import OK.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T01:38:05.517602Z 359ba7e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@erinepshovel-code
erinepshovel-code merged commit ecdcb4b into main Sep 2, 2026
9 checks passed
@erinepshovel-code
erinepshovel-code deleted the feat/ahbg-construction branch September 2, 2026 01:34

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 359ba7e359

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ahbg/runtime/server.py
Comment on lines +132 to +133
ledger.dump(self.out_dir)
self._ledger = ledger

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Make construction and turn persistence atomic

If the process exits or _keep.dump_field() fails after this write, construction.json records the build while the field/event chain remains on the previous turn; start_observation() then reloads and combines those mismatched snapshots, and the construct event cannot be recovered from the chain. Persist the construction transition in the same recoverable transaction/journal as the turn state rather than writing the two authorities independently.

Useful? React with 👍 / 👎.

Comment thread ahbg/runtime/runtime.py
Comment on lines +163 to +167
legal = list(build_legal_actions(opened))
if "construct" in capabilities:
for unit in opened.occupants.values():
for tile_id in ledger.legal_build_tiles(opened):
legal.append(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Put construct actions where the shipped client can select them

In the Android/web flow, board.js submits only lastObservation.legal[0]; this code always places relocation actions before the newly appended construction actions. With the default single unit there is always an empty neighbor, so every Play Turn submits a relocation and the production client never exercises construction, making the advertised build flow and demo impossible unless the client explicitly selects a construct action or these actions are prioritized.

Useful? React with 👍 / 👎.

Comment thread ahbg/runtime/server.py
Comment on lines 223 to +225
"field": field.snapshot(),
"presentation": field_to_presentation(field),
"construction": ConstructionLedger.load(field, session.out_dir).as_dict(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Project construction state into the presentation

After a construct succeeds, this response still derives presentation solely from the unchanged field, which already contains all seven tiles; the new construction object is separate, and board.js renders only payload.presentation. Consequently a build has no visible board consequence and persisted reload looks identical, so the release storyboard's rings cannot appear even for clients that submit construct intents.

Useful? React with 👍 / 👎.

Comment on lines +75 to +79
built = [str(slot) for slot in raw.get("built", [])]
from ucns.mobius_seed import BandSlot

slots = [BandSlot(slot) for slot in built if slot in {item.value for item in BandSlot}]
return cls(from_built(slots))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject unknown persisted construction slots

When a ledger contains an unknown slot—for example after corruption or loading state written by a newer schema—this comprehension silently drops it and reconstructs a smaller built set. The next dump then permanently normalizes away the missing construction instead of failing closed, so validate every persisted entry and raise ConstructionError on any value outside BandSlot.

Useful? React with 👍 / 👎.

Comment thread ahbg/runtime/runtime.py
Comment on lines 223 to +226
chain = Chain()
chain.append(KIND_PLANE_INIT, 0, {"field": opened.snapshot()})
cycle = Cycle(opened, chain)
ledger = ConstructionLedger.load(opened, output_root) if (output_root / "construction.json").exists() else ConstructionLedger.open(opened)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reset construction when starting a new run

When callers reuse an output directory, run_plane() creates a fresh field and event chain but loads the previous run's construction ledger. A second run—even with a different seed—therefore starts with the old built set and can report a fully constructed plane at turn zero; this breaks repeatable CLI runs and contaminates experiment results unless the field and ledger are resumed together or both are reset.

Useful? React with 👍 / 👎.

Comment on lines +43 to +44
- Purchase/restore Benchmark Lab: code path complete; live verification needs
the RevenueCat dashboard and a store sandbox purchase.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep purchase and restore in the source blocker list

The repository has no purchase or restore implementation: PremiumStore only calls getCustomerInfo(), and the Benchmark Lab button has no purchase/restore handler. Provisioning a RevenueCat product therefore cannot make a new user buy or restore it in-app, so declaring this code path complete incorrectly removes a release blocker; implement both flows and entitlement refresh before moving them to live-only verification.

Useful? React with 👍 / 👎.

Comment on lines +10 to +13
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">10.0.2.2</domain>
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">127.0.0.1</domain>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope emulator cleartext exceptions to debug builds

The domain-config is outside debug-overrides, so its cleartext exceptions apply to release builds as well as debug builds. A release assembled with a localhost or emulator runtimeUrl can therefore send the runtime protocol over HTTP despite the documented debug-only boundary; put these domains in a debug-specific network-security resource or manifest overlay.

Useful? React with 👍 / 👎.

Comment thread ahbg/runtime/runtime.py
Comment on lines +276 to +283
build_events: list[dict[str, Any]] = []
for build in builds:
ledger, event = ledger.apply_build(
opened,
unit_id=build.unit_id,
from_tile_id=build.from_tile_id,
to_tile_id=build.to_tile_id,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Include construction in the canonical state digest

Construction is applied only after cycle.close_turn() has produced the recorded state_digest, and neither the ledger nor its events update that digest. Two runs at the same field position and turn therefore receive the same digest even when they built different UCNS slots, so result comparison and cache/integrity checks cannot distinguish materially different game states; incorporate the construction state into the canonical digest.

Useful? React with 👍 / 👎.

Comment thread ahbg/runtime/server.py
Comment on lines +124 to +130
for build in builds:
ledger, event = ledger.apply_build(
field,
unit_id=build.unit_id,
from_tile_id=build.from_tile_id,
to_tile_id=build.to_tile_id,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return a client error for invalid construct intents

When a client submits a construct target that is already built or outside the UCNS boundary, ledger.apply_build() raises ConstructionError, which is not a ProtocolError; the HTTP handler consequently reports an internal 500 rather than rejecting the plan with 422. This is reachable with a stale observation or concurrent plan submission and misclassifies an expected contract violation as a server failure, so validate construction before resolution and translate this exception at the protocol boundary.

Useful? React with 👍 / 👎.

Comment on lines +22 to +24
- **Benchmark Lab** (premium): advanced scenarios, saved/replayed run
comparison, and adversarial benchmark packs. Basic play and external
harness connectivity stay free.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not advertise unimplemented Benchmark Lab features

The shipped premium surface only changes a status label based on isBenchmarkLabUnlocked(); there are no UI or runtime paths for advanced scenarios, saved-run comparison, or adversarial benchmark packs. An already-entitled customer therefore receives none of the features promised in this store listing, independently of the missing purchase flow, so implement the premium surfaces or remove these claims before publication.

Useful? React with 👍 / 👎.

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.

1 participant