Skip to content

generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)#1611

Merged
100yenadmin merged 4 commits into
mainfrom
focal-dressing
Jul 16, 2026
Merged

generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)#1611
100yenadmin merged 4 commits into
mainfrom
focal-dressing

Conversation

@100yenadmin

Copy link
Copy Markdown
Member

Cycle-2 of the generated dungeon wing produced STRUCTURALLY HONEST plates (the count/shape/door-wall
locks from the same cycle killed the Gemini feature-multiplication + reshape classes) — and the blind
control-anchored panels still returned 6-vs-9, Δ−3.0 OUT OF BAND, 2/2, with a unanimous critique:
"clean but generic — boxy symmetric composition, generic asset-kit clutter, empty floor, no narrative
focal point". Per the geometry-richness principle (CRYPT-REPLICATE; the snug c3 +1-median geometry
lever), the fix belongs in the GENERATOR, not the prompt.

dress_focal (tools/dungen_to_fixtures.py) gives every generated room one deterministic narrative
focal set chosen by door count: dead-end → ALTAR flanked by two BRAZIERS; through-room → two BRAZIERS
flanking the lane; hub → two BRAZIERS at the crossing. Fire also hands the paint stage its warm-core
chiaroscuro anchor (the panel's own lever) and the runtime its animated-VFX anchor. It runs BEFORE
dress_tall_anchors (an altar can satisfy the tall-mass bar) and reuses the same safety machinery:
deterministic candidates, door/landing/adjacency exclusion, flood-fill connectivity verification, and
the generator self-gate re-checks every room.

Wing regeneration: room_0 = altar + 2 braziers + 2 pillars; room_1 = 2 braziers + pillar; room_2 =
2 braziers + native pillar — all three check_geometry GREEN. Tests: new focal unit (presence, off-
landing, gate-green) + the anchor test relaxed to ≥1 pillar (focal occupancy can leave one
connectivity-safe pair; one tall mass clears the flat-interior bar). 9/9 + walk_static suite green.

…uty-floor lesson

Structurally-honest cycle-2 plates paneled 6-vs-9 OUT OF BAND 2/2 with a unanimous scorer
critique: 'clean but generic — no narrative focal point, empty floor, asset-kit clutter'. The
geometry-richness principle (CRYPT-REPLICATE, snug c3) says the lever is GEOMETRY, not prompt.
dress_focal gives every generated room ONE deterministic focal set by door count: 1 door ->
ALTAR + 2 flanking BRAZIERS (sealed shrine-store); 2 doors -> 2 BRAZIERS flanking the lane;
3+ -> 2 BRAZIERS at the crossing. Fire doubles as the paint's warm-core chiaroscuro anchor and
the runtime's VFX anchor. Runs BEFORE dress_tall_anchors; same landing/connectivity safety
machinery; self-gate still enforces. Anchor test relaxed to >=1 pillar (focal occupancy can
leave one connectivity-safe pair; one tall mass clears the flat-interior bar).
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 21 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3023028c-d021-4d88-8f89-0fa1db366acd

📥 Commits

Reviewing files that changed from the base of the PR and between 0b5cc68 and 9212479.

📒 Files selected for processing (3)
  • qa/test_generate_town.py
  • tools/dungen_to_fixtures.py
  • tools/generate_town.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch focal-dressing

Comment @coderabbitai help to get the list of available commands.

@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

evaOS review status: completed

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: 4f923bedfacf595607cfee69c7fe68e9a334522e
Updated: 2026-07-16T05:55:16.180Z

evaOS review completed for this PR head.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #1611

Review URL: #1611 (review)

@evaos-code-review-bot evaos-code-review-bot 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.

Walkthrough

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: 4f923bedfacf595607cfee69c7fe68e9a334522e into main. Review event: COMMENT.
Provider: GLM/Z.ai through ZCode (zcode-glm, zcode, model GLM-5.2).

Estimated review effort: 1/5 (~12 min)

Changed Files

File Status Churn Purpose Risk
qa/test_generate_town.py modified +23/-5 Test coverage Moderate: validated P3 finding

Review Signal

Validated inline findings: 2 (P0: 0, P1: 0, P2: 0, P3: 2).
Dropped findings before posting: 0. High-severity findings: 0.

Risk Taxonomy

  • Docs only: 1
  • Proof gap: 1

Validation and Proof

1 required validation/proof recommendation(s) selected from changed files.

  • required: Unity editor or Play Mode smoke - WorldOS repo profile implies Unity runtime risk. Proof: Unity editor smoke; Play Mode log; scene/prefab screenshot or recording.
    Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
    Profile validation hints: Prefer correctness, persistence, CI, release, and regression findings over style-only feedback.
    Profile proof expectations: Look for Unity editor, play-mode, fixture, or focused smoke evidence when runtime behavior changes.

Related Context

Related issues/PRs: none detected from PR metadata.
Suggested labels: tests.
Suggested reviewers: none from current metadata.

Review Settings Preview

  • Profile: assertive
  • Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Suggested labels (suggestion_only); Review status comment (sticky_status)
  • Path instructions: Assets/** - Prioritize scene, prefab, save-state, asset-reference, and gameplay regressions.
  • Path instructions: ProjectSettings/** - Treat build, platform, input, graphics, and release behavior changes as high risk.
  • Label suggestions: unity, gameplay, regression-hardening
  • Reviewer suggestions: none
  • Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
  • Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks

Pre-merge checklist

  • Inline comments target current RIGHT-side diff lines.
  • No secret-like content survived into posted inline comments.
  • REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
  • Required behavior proof is present or not applicable.
  • Labels and reviewers are suggestions only; the bot did not auto-apply them.

Comment thread qa/test_generate_town.py Outdated
focal_cells = {tuple(c) for p in geo["props"] if p["kind"] in d2f._FOCAL_KINDS
for c in p["cells"]}
assert not (focal_cells & landings), f"{rid}: focal on a door landing"
assert check_geometry(rid, geo) == [], f"{rid}: static gate regressed after focal dressing"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: check_geometry name arg uses rid while sibling tests use f"{town}_{rid}"

test_every_generated_room_has_a_narrative_focal calls check_geometry(rid, geo) whereas test_committed_rooms_pass_static_gate uses check_geometry(f"{TOWN}{rid}", geo). The first argument to check_geometry is only a label (used inside failure strings), so behavior is identical, but the inconsistency makes the static-gate signal harder to grep/correlate across failures and breaks the local convention. Use f"{TOWN}{rid}" here for consistency.

Category: Docs only

Why this matters: Minor, but consistency in the gate label aids triage when the same geometry fails in two tests and reviewers correlate by the documented dwing_ id.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adopted — the focal test now labels with f"{_TOWN}_{rid}" matching the sibling tests.
🤖 Addressed by Claude Code

Comment thread qa/test_generate_town.py Outdated
for rid in ("room_0", "room_1"):
anchors = [p for p in town[rid]["props"] if p.get("id") in ("anchor_a", "anchor_b")]
assert {p["id"] for p in anchors} == {"anchor_a", "anchor_b"}, f"{rid} needs both anchors"
assert anchors, f"{rid} needs at least one pillar anchor"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Anchor assertion weakened without a paired test pinning focal-placement success

test_flat_rooms_get_pillar_anchors was lowered from 'both anchor_a and anchor_b present' to 'at least one pillar anchor'. The new comment attributes this to focal dressing (brazier/altar) consuming connectivity-safe interior space. That causal link is plausible (dress_focal runs first and uses the same flood-fill gate), but there is no test that actually pins the focal pass succeeding, nor one that asserts the focal-vs-anchor floor budget directly. If a future layout or dress_focal change makes the focal consume MORE floor, the anchor count could silently drop from 1 to 0 and this weakened assertion would still pass while a flat-interior room regresses. Consider either (a) asserting a lower bound that encodes the intended budget (e.g. at least one anchor AND at least one focal), or (b) adding a dedicated test that dress_focal + dress_tall_anchors together still leave >=1 anchor on the committed rooms — making the weakening's premise observable rather than asserted in a comment.

Category: Proof gap

Why this matters: The PR's central behavior change is focal-first dressing that competes with anchor placement for the same interior floor; the suite now only asserts a loose lower bound on the loser of that competition, so the interaction it introduces is effectively untested for regression.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Partially adopted. Note the joint coverage that already existed: anchors→0 FAILS both test_flat_rooms_get_pillar_anchors (asserts non-empty) and test_every_room_has_a_tall_prop (asserts a ≥2.6 mass in EVERY room) — only 2→1 was tolerated, deliberately. The deeper budget concern is now enforced at EMIT time, not just on the committed fixture: check_dressing_bars() folds tall-mass + focal presence into generate_town's self-gate (fails loud; --allow-undressed escape), with a dedicated unit.
🤖 Addressed by Claude Code

…-4 catch)

Ortho-only pins were the 2026-07-15 camera-bug SHAPE. The #1591 client fix defaults the 30/45
contract rig when only ortho is pinned, so they're no longer dangerous — but every shipped manifest
entry carries pitch/yaw explicitly and walk_static lints them when present; the emitter now matches
the convention. + fragment test (10/10).
@100yenadmin

Copy link
Copy Markdown
Member Author

Round-4 sidecar catch folded in: the plates-fragment emitter stamped ortho-only cameraPins (the 2026-07-15 bug shape — safe since #1591's client default, but off-convention). Now stamps pitch/yaw + a fragment regression test. 10/10.

@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

evaOS review status: failed

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: d54c410570c7bc32e3dc1128b8550b4a199e1b0c
Updated: 2026-07-16T06:04:17.752Z

evaOS review failed for this head and needs retry or operator attention.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #1611

Details: Review failed; see bot evidence for operator-only details.

@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: 4f923bedfa

ℹ️ 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 tools/generate_town.py Outdated
for rid in room_ids:
geo = _stamp_room(build_geometry(ctx, room=rid),
material=args.material, wall_height=args.wall_height)
geo = dress_focal(geo, name=loc_of[rid]) # narrative focal set FIRST (an altar also satisfies the tall-anchor bar)

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 Reserve tall-anchor space before focal dressing

In narrow flat crops (for example a one-cell-wide 3×6 room with a single perimeter door), adding the low brazier/altar focal props before dress_tall_anchors can occupy the only connectivity-safe vertical pair that the anchor pass would have used. Since those focal kinds are below _ANCHOR_MIN_TALL, the generator can now emit a static-green room with no tall interior mass, reintroducing the flat-interior drift class this path was meant to prevent; run/place tall anchors first or have focal placement reserve a valid anchor footprint.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adopted via emit-time enforcement rather than reordering: placing anchors first would just flip the failure mode onto the focal pass (braziers/altar are LOW kinds, 2.0–2.2 — they never satisfy the tall bar; also corrected a wrong comment claiming otherwise). check_dressing_bars() now makes the generator FAIL LOUD when a crop leaves NO connectivity-safe tall footprint, so the flat-interior class can't ship silently; the operator/loop then treats that crop deliberately.
🤖 Addressed by Claude Code

geo["props"].append({"id": pid, "kind": kind, "cells": [list(c) for c in cells]})
used |= set(cells)
break
if used:

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 Fail when no focal can be placed

For small or densely occupied room crops where every connectivity-safe candidate is rejected (e.g. a 3×3 one-door crop whose only interior cell is the door landing), used stays empty and this function returns successfully without adding any _FOCAL_KINDS. generate_town then still passes the static gate and writes a room with no narrative focal point, so the new beauty-floor guarantee is silently skipped instead of failing or using a fallback placement.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adopted — same mechanism: check_dressing_bars() in the self-gate fails loud when no _FOCAL_KINDS prop landed (the silent-return case you found), unit-tested on a crafted bare crop. --allow-undressed is the documented escape for genuinely bare classes.
🤖 Addressed by Claude Code

… consistency (evaos P3)

check_dressing_bars(): emit-time enforcement that every generated room carries (1) a tall interior
mass >= 2.6 (a narrow crop can defeat dress_tall_anchors AFTER focal placement) and (2) a narrative
focal prop (dress_focal returns silently when every candidate is rejected). Either silent miss
re-ships the class the dressing exists to fix -> the generator fails LOUD; --allow-undressed is the
deliberate escape hatch (e.g. a bare corridor class). Also corrected a wrong code comment (altar is
2.0 < the 2.6 tall bar). 11/11 + end-to-end self-gate green on the committed wing.
@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

evaOS review status: completed

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: 249b2bd8b60d73226d18ccb3d71956965c9c4909
Updated: 2026-07-16T06:10:12.384Z

evaOS review completed for this PR head.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #1611

Review URL: #1611 (review)

@evaos-code-review-bot evaos-code-review-bot 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.

Walkthrough

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: 249b2bd8b60d73226d18ccb3d71956965c9c4909 into main. Review event: COMMENT.
Provider: GLM/Z.ai through ZCode (zcode-glm, zcode, model GLM-5.2).

Estimated review effort: 1/5 (~12 min)

Changed Files

File Status Churn Purpose Risk
qa/test_generate_town.py modified +61/-5 Test coverage Moderate: validated P2 finding

Review Signal

Validated inline findings: 2 (P0: 0, P1: 0, P2: 1, P3: 1).
Dropped findings before posting: 0. High-severity findings: 0.

Risk Taxonomy

  • API compatibility: 1
  • CI/build: 1

Validation and Proof

1 required validation/proof recommendation(s) selected from changed files.

  • required: Unity editor or Play Mode smoke - WorldOS repo profile implies Unity runtime risk. Proof: Unity editor smoke; Play Mode log; scene/prefab screenshot or recording.
    Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
    Profile validation hints: Prefer correctness, persistence, CI, release, and regression findings over style-only feedback.
    Profile proof expectations: Look for Unity editor, play-mode, fixture, or focused smoke evidence when runtime behavior changes.

Related Context

Related issues/PRs: none detected from PR metadata.
Suggested labels: tests.
Suggested reviewers: none from current metadata.

Review Settings Preview

  • Profile: assertive
  • Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Suggested labels (suggestion_only); Review status comment (sticky_status)
  • Path instructions: Assets/** - Prioritize scene, prefab, save-state, asset-reference, and gameplay regressions.
  • Path instructions: ProjectSettings/** - Treat build, platform, input, graphics, and release behavior changes as high risk.
  • Label suggestions: unity, gameplay, regression-hardening
  • Reviewer suggestions: none
  • Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
  • Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks

Pre-merge checklist

  • Inline comments target current RIGHT-side diff lines.
  • No secret-like content survived into posted inline comments.
  • REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
  • Required behavior proof is present or not applicable.
  • Labels and reviewers are suggestions only; the bot did not auto-apply them.

Comment thread qa/test_generate_town.py
[sys.executable, str(_ROOT / "tools" / "generate_town.py"), str(_LAYOUT),
"--rooms", "room_0", "--town-id", "pin", "--out-dir", str(out), "--material", "stone"],
capture_output=True, text=True)
assert r.returncode == 0, r.stderr[-500:]

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: Subprocess cameraPin test omits the PIL importorskip guard the sibling test uses for the same reason

test_plates_fragment_pins_carry_the_full_camera_contract shells out to tools/generate_town.py, which imports greybox_render_headless at module top-level (qa/greybox_render_headless.py:45 from PIL import Image, ImageDraw), so importing generate_town.py hard-requires PIL. The sibling test_generator_self_gate_passes calls pytest.importorskip("PIL") (line 169) for exactly this case, with the comment 'skip the end-to-end run where those render deps are absent (e.g. the minimal engine test venv)'. This new test omits that guard. In the minimal engine/servers test venv (PIL/numpy absent — the environment the sibling test explicitly anticipates), the subprocess crashes at import with ModuleNotFoundError, r.stderr[-500:] is non-empty, and the test FAILS (not skips) with an opaque traceback. Add pytest.importorskip("PIL") at the top of this test, mirroring line 169, so it skips cleanly where render deps are unavailable.

Category: CI/build

Why this matters: A test that errors instead of skipping in the documented minimal venv turns a green CI lane red for a non-defect, and the failure message (an ImportError buried in subprocess stderr) does not point at the real cause. The PR already establishes the correct pattern one test above; this is an inconsistency with a concrete CI-breaking footprint.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adopted — pytest.importorskip("PIL") added at the top of the fragment-pin test, mirroring test_generator_self_gate_passes' guard for the same subprocess in the minimal engine venv.
🤖 Addressed by Claude Code

Comment thread qa/test_generate_town.py Outdated
for rid in ("room_0", "room_1"):
anchors = [p for p in town[rid]["props"] if p.get("id") in ("anchor_a", "anchor_b")]
assert {p["id"] for p in anchors} == {"anchor_a", "anchor_b"}, f"{rid} needs both anchors"
assert anchors, f"{rid} needs at least one pillar anchor"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Flat-room anchor assertion weakened from 'both anchors' to 'at least one'

test_flat_rooms_get_two_pillar_anchors was renamed and its contract weakened: it previously asserted {anchor_a, anchor_b} == {anchor_a, anchor_b} (both pillars present), now it asserts only anchors is truthy (≥1). The production contract in dress_tall_anchors' docstring still says it 'authors two pillar anchors (anchor_a/anchor_b)'. The weakening is justified in-comment (focal placement can consume the second connectivity-safe pair), and the new check_dressing_bars self-gate plus test_every_room_has_a_tall_prop still cover the flat-interior bar. But the renamed test no longer pins the two-anchor authoring contract; if dress_tall_anchors regressed to emitting a single anchor even when two would fit, this test would not catch it. Consider asserting len(anchors) >= 1 explicitly and adding a comment that the ≥2 case is best-effort under focal occupancy, or keep a separate test on a no-focal fixture that still expects both.

Category: API compatibility

Why this matters: Coverage assertions that name a contract ('two pillar anchors') and then silently drop to 'at least one' reduce the regression surface the suite was added to lock down. This is advisory: the underlying flat-interior bar is still enforced elsewhere.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adopted in the advisory form: the assertion is now an explicit len(anchors) >= 1 with an in-test rationale — ≥1 is the HARD flat-interior bar (also enforced end-to-end by check_dressing_bars + test_every_room_has_a_tall_prop), while two anchors is documented best-effort under focal occupancy (dress_focal runs first and may legitimately consume the second connectivity-safe pair, so pinning ==2 would flake on valid layouts).
🤖 Addressed by Claude Code

@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: 249b2bd8b6

ℹ️ 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 qa/test_generate_town.py
Comment on lines +202 to +206
r = subprocess.run(
[sys.executable, str(_ROOT / "tools" / "generate_town.py"), str(_LAYOUT),
"--rooms", "room_0", "--town-id", "pin", "--out-dir", str(out), "--material", "stone"],
capture_output=True, text=True)
assert r.returncode == 0, r.stderr[-500:]

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 Skip the camera-pin subprocess when Pillow is absent

In environments without Pillow, this new test fails before it can inspect the generated fragment because generate_town.py imports greybox_render_headless, which imports PIL; the nearby test_generator_self_gate_passes already guards the same subprocess with pytest.importorskip("PIL") for the minimal engine/test venv case. Running python -m pytest qa/test_generate_town.py -q in that environment now goes red with ModuleNotFoundError: No module named 'PIL', so this test should use the same skip or avoid the Pillow-dependent script import.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Adopted — same fix as the evaOS twin thread: importorskip("PIL") guards the subprocess, so the minimal venv skips cleanly instead of failing on ModuleNotFoundError.
🤖 Addressed by Claude Code

…dex P2 — minimal-venv lane went red on a non-defect) + explicit >=1 anchor bar with the best-effort-two rationale (evaOS P3)
@evaos-code-review-bot

evaos-code-review-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

evaOS review status: completed

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: 92124797e060386171a3e9dc5f2d9cac40866a02
Updated: 2026-07-16T09:52:57.672Z

evaOS review completed for this PR head.

Automation note: agents should wait for this comment to reach completed, stale_head, closed_or_merged_before_review, skipped, or failed before treating evaOS review as settled for this head. provider_deferred means evaOS still intends to retry.

PR URL: #1611

Review URL: #1611 (review)

@evaos-code-review-bot evaos-code-review-bot 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.

Walkthrough

PR: #1611 - generate_town: narrative FOCAL dressing (beauty-floor lever from the dwing panel negatives)
Head: 92124797e060386171a3e9dc5f2d9cac40866a02 into main. Review event: COMMENT.
Provider: GLM/Z.ai through ZCode (zcode-glm, zcode, model GLM-5.2).

Estimated review effort: 1/5 (~12 min)

Changed Files

File Status Churn Purpose Risk
qa/test_generate_town.py modified +67/-5 Test coverage Moderate: validated P3 finding

Review Signal

Validated inline findings: 2 (P0: 0, P1: 0, P2: 0, P3: 2).
Dropped findings before posting: 0. High-severity findings: 0.

Risk Taxonomy

  • Flaky test risk: 1
  • Release regression: 1

Validation and Proof

1 required validation/proof recommendation(s) selected from changed files.

  • required: Unity editor or Play Mode smoke - WorldOS repo profile implies Unity runtime risk. Proof: Unity editor smoke; Play Mode log; scene/prefab screenshot or recording.
    Proof status: missing - 1 required validation/proof recommendation(s) missing from PR metadata.
    Profile validation hints: Prefer correctness, persistence, CI, release, and regression findings over style-only feedback.
    Profile proof expectations: Look for Unity editor, play-mode, fixture, or focused smoke evidence when runtime behavior changes.

Related Context

Related issues/PRs: none detected from PR metadata.
Suggested labels: tests.
Suggested reviewers: none from current metadata.

Review Settings Preview

  • Profile: assertive
  • Enabled sections: Review summary (inline_review); Walkthrough (inline_review); Changed-files table (walkthrough); Effort estimate (walkthrough); Related issues/PRs (walkthrough); Suggested labels (suggestion_only); Review status comment (sticky_status)
  • Path instructions: Assets/** - Prioritize scene, prefab, save-state, asset-reference, and gameplay regressions.
  • Path instructions: ProjectSettings/** - Treat build, platform, input, graphics, and release behavior changes as high risk.
  • Label suggestions: unity, gameplay, regression-hardening
  • Reviewer suggestions: none
  • Suggestion behavior: suggestions only; labels and reviewers are not auto-applied.
  • Roadmap-only settings: auto-apply labels; auto-request reviewers; required status checks

Pre-merge checklist

  • Inline comments target current RIGHT-side diff lines.
  • No secret-like content survived into posted inline comments.
  • REQUEST_CHANGES is only used when eligible P0/P1 findings survive validation.
  • Required behavior proof is present or not applicable.
  • Labels and reviewers are suggestions only; the bot did not auto-apply them.

Comment thread qa/test_generate_town.py
base = {"cols": 5, "rows": 5, "door_cells": [[0, 2]], "walls": [],
"props": [{"id": "w", "kind": "wall_run", "cells": [[0, 0]]}]}
both_missing = d2f.check_dressing_bars(dict(base, props=list(base["props"])), name="bare")
assert len(both_missing) == 2 and any("tall" in f for f in both_missing) and any("focal" in f for f in both_missing)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Compound single-line assertion is hard to read and gives a poor failure message

Line 227 crams two any(...) substring checks and a length check into one assert ... and ... and ... on a single line. When this fails, pytest reports the whole boolean expression with no indication of which clause failed or the actual both_missing contents. Splitting into three separate asserts (length == 2; a 'tall' failure present; a 'focal' failure present) preserves intent and makes a future regression message immediately diagnostic. Purely a clarity/observability nit; behavior is correct as written (the 'NO tall interior mass' and 'NO narrative focal prop' substrings are both emitted by check_dressing_bars).

Category: Flaky test risk

Why this matters: This test is the emit-time enforcement guard for the codex P2 pair; when it fires in CI it should pinpoint which bar regressed without a maintainer having to re-run with prints.

Comment thread qa/test_generate_town.py
# test_every_room_has_a_tall_prop enforce it end-to-end). Two anchors is BEST-EFFORT under
# focal occupancy: dress_focal runs first and may consume the second connectivity-safe pair,
# so pinning ==2 here would make the suite flake on legitimate focal layouts (evaOS P3).
assert len(anchors) >= 1, f"{rid} needs at least one pillar anchor"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Anchor-count assertion weakened from exactly-two to at-least-one; rationale mislabels deterministic behavior as 'flake'

The renamed test relaxes assert {p['id'] for p in anchors} == {'anchor_a','anchor_b'} to assert len(anchors) >= 1. The accompanying comment (lines 110-113) justifies this by claiming that pinning ==2 'would make the suite flake on legitimate focal layouts.' That rationale does not hold: _build_town_geometries (and dress_focal/dress_tall_anchors) are fully deterministic — no random module, fixed committed layout — so the post-dressing anchor count is a single fixed integer per room, not a distribution. Pinning the exact count would either always pass (proving the suite reliably yields two anchors) or always fail (surfacing a genuine placement regression introduced by running dress_focal first). The >= 1 bar therefore hides whether the focal-first ordering actually dropped room_0/room_1 from two anchors to one on this layout. The functional flat-interior bar is still enforced elsewhere (test_every_room_has_a_tall_prop + check_dressing_bars), so this is a test-strength gap, not a product regression. Recommendation: after merging, run the suite once and pin the actual emitted count per room (e.g. assert len(anchors) == N with the observed N, or assert the specific id set), and rewrite the comment to say 'deterministic count pinned to the observed post-focal value' rather than 'flake'.

Category: Release regression

Why this matters: A deterministic regression suite that asserts a weaker invariant than the code intends will silently accept a future change that drops the second anchor (the documented 'two pillar anchors' contract in dress_tall_anchors' docstring and the original #1588 fix), eroding the regression guard without any signal.

@100yenadmin
100yenadmin merged commit 9281a9b into main Jul 16, 2026
30 of 36 checks passed
@100yenadmin
100yenadmin deleted the focal-dressing branch July 16, 2026 09:53
100yenadmin pushed a commit that referenced this pull request Jul 16, 2026
…geometry bar, #1618)

The dwing recovery proved the focal braziers double as plate-registration
beacons. Two braziers on the same row are a collinear pair, blind to vertical
scale in the 2-point similarity fit (room_1: 0.07-cell beacon error beside
~1.5 cells of wall misfit — plate unfixable by warping).

dress_focal v2: after the door-count plan lands its two lane/shrine braziers,
author a THIRD fire beacon (corner watch-brazier) at the connectivity-safe
cell that maximises the three-beacon triangle area — deterministic, reusing
the existing candidate/landing-exclusion/flood-fill machinery.

check_dressing_bars gains a third bar: >=3 fire-kind props with best triangle
area >= 2.0 cell^2, or fail loud (beacon-geometry class). --allow-undressed
still skips all bars.

Tests: every committed wing room now carries 3 fire beacons (areas 12/5/11);
the bar unit-tested on 2-fire, 3-collinear, 3-non-collinear geos; existing
dressing-bar test updated for the third bar.

Refs #1618 (lands after #1611).
100yenadmin added a commit that referenced this pull request Jul 16, 2026
…geometry bar, #1618) (#1621)

The dwing recovery proved the focal braziers double as plate-registration
beacons. Two braziers on the same row are a collinear pair, blind to vertical
scale in the 2-point similarity fit (room_1: 0.07-cell beacon error beside
~1.5 cells of wall misfit — plate unfixable by warping).

dress_focal v2: after the door-count plan lands its two lane/shrine braziers,
author a THIRD fire beacon (corner watch-brazier) at the connectivity-safe
cell that maximises the three-beacon triangle area — deterministic, reusing
the existing candidate/landing-exclusion/flood-fill machinery.

check_dressing_bars gains a third bar: >=3 fire-kind props with best triangle
area >= 2.0 cell^2, or fail loud (beacon-geometry class). --allow-undressed
still skips all bars.

Tests: every committed wing room now carries 3 fire beacons (areas 12/5/11);
the bar unit-tested on 2-fire, 3-collinear, 3-non-collinear geos; existing
dressing-bar test updated for the third bar.

Refs #1618 (lands after #1611).

Co-authored-by: Eva <arncalso@gmail.com>
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