Skip to content

feat: add Mailbox level, drop Object Chest, restructure curriculum#9

Closed
km631 wants to merge 4 commits into
mainfrom
feat/mailbox-curriculum-restructure
Closed

feat: add Mailbox level, drop Object Chest, restructure curriculum#9
km631 wants to merge 4 commits into
mainfrom
feat/mailbox-curriculum-restructure

Conversation

@km631
Copy link
Copy Markdown
Collaborator

@km631 km631 commented May 26, 2026

Summary

  • New Level 9: Mailbox (mailbox + mailbox_relay) — teaches Sui's transfer-to-object pattern via a trust-by-typed-value cross-module bug.
  • Removed Object Chest (was level 4); ids stay gapped, no URL breakage.
  • Renamed blackbooknight_ledger (and BlackbookFlagNightLedgerFlag) so every contract module name matches its level name.

Curriculum + UI

  • Auto display order: easy → medium → hard, tiebreak by id. Single comparator in difficulty.ts, threaded through getLevels().
  • Sidebar / header / mobile picker now show position (1..N) instead of id; URLs still use the stable id; body H1 in instructions is generated from position + name so chrome and body always agree.
  • Tightened all descriptions to goal + minimal structure cue (no analysis bullets). Removed the hints field across every level.
  • Fixed LocaleSwitcher checkmark: vertical alignment (top-1/2 -translate-y-1/2) and Arabic RTL positioning (Tailwind rtl: variant via :lang(ar)/[dir=rtl] + explicit lang attribute on each SelectItem).
  • Full i18n updates across all 12 locales.

Test plan

  • npm run dev — open /en/levels/9 (Mailbox), confirm both contract tabs render
  • Solve Mailbox with the relay handle forgery (see PR description in code)
  • Open /en/levels/8 and confirm contract paths show move_over::night_ledger
  • Switch language to Arabic in the locale dropdown; checkmark sits beside the option name (not above, not overlapping)
  • Switch between locales and confirm "Level N" badge in the header matches the sidebar position number for the active level
  • Confirm /en/levels/4 404s (Object Chest removed)

🤖 Generated with Claude Code

- New Level 9 "Mailbox" (mailbox + mailbox_relay) teaching Sui's
  transfer-to-object pattern via a trust-by-typed-value cross-module bug.
- Removed "Object Chest" (was level 4); ids stay gapped for URL stability.
- Renamed blackbook -> night_ledger / NightLedgerFlag so contract module
  names match level names everywhere.
- Curriculum order auto-derived: easy -> medium -> hard, tiebreak by id.
  Display position (1..N) shown in sidebar/header/mobile picker while URLs
  continue to use the stable id; body H1 in instructions generated from
  position + name so chrome and body always agree.
- Tightened all descriptions to goal + minimal structure cue (no analysis);
  removed the hints field across all levels.
- Fixed LocaleSwitcher checkmark vertical alignment and RTL positioning
  (Tailwind rtl: variant via :lang(ar)/[dir=rtl] + explicit lang attribute
  on each SelectItem).
- Full i18n updates across all 12 locales.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@km631 km631 requested a review from kosedogus May 26, 2026 11:48
km631 and others added 3 commits May 26, 2026 15:37
- Level ids are now snake_case slugs (e.g. "artifact", "coin_collector",
  "night_ledger", "mailbox") instead of integers. Used as the JSON key in
  meta.config.json + every locale's content, and as the URL segment
  (`/levels/artifact`, `/levels/mailbox`, etc.).
- `Level.id` typed as string; numeric tiebreak dropped from compareLevels
  (stable sort preserves meta.config.json insertion order within a
  difficulty).
- One-time localStorage migration (`progressStorage.ts`) rekeys solved set,
  saved solutions, hint counter, and last-visited level from the old numeric
  ids to slugs on first access. Idempotent via a sentinel key. Drops the
  removed Object Chest's id 4. Slug entries win over numeric on collision.
- Route handlers updated to accept slug params (no more `Number(id)`);
  redirect-on-not-found targets `levels[0].id` so it stays correct as the
  curriculum changes.
- Hardcoded `/levels/0` removed from Landing, How-to-play, and Completion —
  all now use `LEVEL_IDS[0]`.
- runConfig keyed by slug; per-level solution module name is `<slug>_solution`.
- sync-meta / create-level / delete-level scripts updated for slug ids
  (create derives the slug from the module name; delete no longer reindexes).
- Old `/levels/{number}` URLs intentionally 404 (no redirect layer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sweep of dead references left over from the older numeric-id + different
level set. No functional changes; cleanups across content, i18n, code, docs,
and a vestigial script.

Content (per-locale en/es/pt/fr/ja/ko/ru/ar/tr/uk/zh-Hans/zh-Hant):
- Strip the stale `# Level N: Name` H1 prefix from every level's instructions
  (the renderer prepends a fresh, position-based H1 at runtime; the source
  H1 went stale on every reorder).
- Rewrite `artifact.explanation` to drop the "Level 0" self-reference.

i18n (per-locale x 12):
- `landing.cta` / `level.runNotSupported` / `howToPlay.startLevel0`: numeric
  "Level 0" / "Nivel 0" / "Уровень 0" / "レベル0" / etc. bumped to "Level 1"
  (position-based; durable across renames).
- `landing.feedLine2`: `genesis, lockbox, fallout` → `artifact,
  coin_collector, sticky_treasure` (real modules).
- `landing.recommendedBody`: Genesis/Lockbox/Fallout → Artifact/Sticky
  Treasure/Flash Vault.
- `level.solutionPlaceholder`: `genesis::create(t)` → real Artifact API
  (`artifact::forge / charge / shatter`).

Code:
- `CompletionCard.tsx`: `level_8::solve(margin_note)` + `BlackbookFlag` →
  `night_ledger::solve(margin_note)` + `NightLedgerFlag`.
- `contractCode.ts` doc-comment example: `genesis` → `artifact`.

Vestigial cleanup:
- Delete `scripts/sync-contracts.mjs` (synced from `move_over/sources/`, a
  directory that no longer exists in the repo).
- Delete `public/contracts/_manifest.json` (auto-generated by the deleted
  script; listed `fallout.move`/`genesis.move`/`lockbox.move` and
  `level_N_solution.move` filenames that never existed in the current set).
- Remove `npm run sync:contracts` from package.json and its README row.

Docs:
- ADD_LEVEL_README.md: rewrite the manual-add example using slug ids;
  drop the H1 from the example instructions.
- DELETE_LEVEL_README.md: rewrite to reflect that deletion no longer
  reindexes higher ids (slugs are stable).
- README.md: drop the "reindex ids" line; drop the sync:contracts row.

CI:
- Add `.github/workflows/codeql.yml` pinned to a working `github/codeql-action@v3`
  so the repo overrides GitHub's default code-scanning (the default was
  resolving `@v4` to a SHA that returns 404 from upstream).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@km631
Copy link
Copy Markdown
Collaborator Author

km631 commented May 26, 2026

Superseded by #10 (same content, but signed commits — the original branch's force-push to add signatures was blocked locally).

@km631 km631 closed this May 26, 2026
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.

2 participants