Status: Implemented and manually qualified by operator report on 2026-10-15. The pin, generated metadata, shared map contract, qualification baseline, and regression tests are updated. The assistant performed offline verification only; the operator subsequently confirmed the manual checks and existing-sign audit below. Existing unrelated feature gates remain unchanged. This report does not authorize deployment or establish that a deployment occurred.
Archived: 2026-10-16 (UTC). Current map-sign behavior and qualification limitations are in the world administration guide.
The operator confirmed all of the following passed:
Test context was supplied as “Personal Commit”. No exact commit hash, room/environment, logs, or independently captured evidence was supplied. These results are recorded as operator attestation, not assistant-observed qualification or proof for every deployment target. Reconfirm applicability before releasing a different build or targeting a different room/environment. This qualification is specific to Beta2/map-sign preservation; it does not qualify Bunny native timers, appearance mutations, or other feature gates.
| Work item | Delivered evidence |
|---|---|
| BC-01 | Exact a6b3e70272ea1f0715d3e947df2bd47f7ec8be12 pin; 11-file upstream range reviewed; two formatted generations have identical SHA-256 hashes. Wire declarations are byte-identical; patch/map metadata changes only revision. |
| BC-02 | Shared optional bounded sign schema; canonical keys, plain record, strict config, exact UTF-16 rejection boundary, content-safe diagnostics; registered map-definition boundary tests. |
| BC-03 | Room construction reuses the shared schema; missing-room creation and defensive client-template tests retain signs and room settings. |
| BC-04 | Save/edit/revision/backup/restore/template round trips and invalid-head/no-partial-write tests use the real map repository with an offline database fake. |
| BC-05 | Full/partial sync, defensive snapshots, and guarded object-action tests retain unrelated signs without optimistic observed-state mutation or sign journaling. |
| BC-06 | Copy validates top-level and nested legacy maps using the shared schema; allowlist/isolation unchanged. Normalization does not project room maps and requires no change. |
| BC-07 | Appearance and Bunny share pinned browser URL/version helpers; wrong-version, HTTPS/origin, and live-approval rejection tests remain offline. |
| BC-08 | Current baseline, authority diagrams, map policy/privacy, qualification limits, rollout and rollback guidance updated; historical evidence remains version-specific. |
Asset generation retains 85 groups, 2,634 assets, and 201 identical unsupported-source
diagnostics. Its five semantic leaf changes are the revision, AssetStrings hash,
two corrected narration strings, and removal of their obsolete third option.
The new AssetStrings SHA-256 is
9b4eec35477e1cca2a9b50b53da99ceb45b470f778e6bb8f4e83de41aa2e1cc8.
Asset capabilities and the selected 170-tile/280-object map projection are unchanged.
This evidence does not certify a deployed BC release or live sign rendering.
The registered end-to-end regression connects an offline fake socket to the real client, repository, admin service, template loader, and missing-room creation packet. The complete 439-test suite, lint, formatting, type-check, and production/API-documentation build pass.
Structure two related but independently verifiable changes:
The second change fixes an existing projection gap, not a new wire-format
requirement introduced by Beta2. Both revisions already declare optional
ServerChatRoomMapData.CellData. Existing door and casino location behavior
does not require a new packet or a browser runtime.
| Baseline | Commit | Declared browser version |
|---|---|---|
| Imported source | 5eb495c5ced4ee92d40385b7521e6ca63ace12e5 |
R133Beta1 |
| Proposed target | a6b3e70272ea1f0715d3e947df2bd47f7ec8be12 |
R133Beta2 |
The local comparison found 11 changed files. Reconfirm this exact commit range before implementation; do not silently substitute a newer checkout HEAD.
| Upstream change | Bot impact and implementation decision |
|---|---|
Scripts/Game.js: Beta1 to Beta2 |
Update the shared revision/version pair and qualification version expectations together. A source pin does not certify the deployed server. |
Assets/MapData.js, Scripts/Map.js, Screens/Online/ChatRoom/ChatRoomMapView.js: sign UI, object-config sanitation, undo/dirty handling |
Preserve validated CellData in our own map contract. Do not port browser interaction or undo behavior. |
Scripts/Activity.js, Scripts/Dialog.js, Scripts/Typedef.d.ts: blocked-group/hand-use fixes and removal of activity restriction unavail |
Browser activity generation is not implemented by this bot. No new runtime logic is indicated; verify generated declaration dependencies during regeneration. |
Assets/AssetStrings.csv: corrected option narration |
Regenerate appearance string metadata. Do not claim all catalog bytes are unchanged merely because asset definitions are unchanged. |
Scripts/ImageCache.js, Screens/Room/MaidQuarters/MaidQuarters.js, Screens/MiniGame/ClubCard/Text_ClubCard.csv |
Browser-only cache, NPC, and card-text fixes; no corresponding bot runtime changes. |
Direct comparison found unchanged Messages.d.ts, MessagesPatch.d.ts,
Assets/Female3DCG.js, and Assets/Female3DCGExtended.js. The map generator’s
selected metadata projection was also unchanged: 170 tiles and 280 objects.
This is not evidence that every extracted appearance dependency is identical.
Review the complete regenerated catalog, source hashes, and unsupported-source
diagnostics before accepting the repin.
At the proposed upstream commit, the sign editor advertises 150 characters and
MapSanitizeSignText slices at ChatRoomMapSignTextMaxLength = 150. However,
the map constructor’s sanitizer actually slices text at
ChatRoomMapMaxLength, which is 1,600 for the 40x40 map. Its index parsing uses
parseInt, which also accepts noncanonical keys.
Therefore 150 is an editor-aligned bot policy, not a proven wire/server limit. This proposal recommends explicit rejection above 150 UTF-16 code units and canonical index validation, rather than copying the permissive parser or silently truncating stored text. Approval of that stricter policy is required. If existing operator signs exceed it, stop rollout and resolve the policy/data conflict; do not silently destroy their contents.
Extend the existing mapDataSchema and its inferred StoredMapData with an
optional bounded CellData projection:
{
CellData?: {
[cellIndex: string]: {
Type: "Sign";
Text: string;
};
};
}
The sketch describes JSON object keys, not a new ambient BC declaration. Implement it with the existing zod dependency and proper inferred types.
CellData may be absent or an empty object. Both are valid. An absent field
stays absent; do not seed empty config records.null.0 through 1599, representing
x + y * 40. Reject negatives, fractions, whitespace, leading zeros except
0, suffixes, exponent notation, and prototype-related names.Type: "Sign" and Text.
Reject unknown config types and extra per-config fields.Text must be a string of at most 150 UTF-16 code units under the proposed
policy. Preserve empty strings, whitespace, newlines, and supported Unicode
exactly; do not trim, interpret HTML, interpolate, or split surrogate pairs.
There is no minimum content length.Reuse this schema at stored-map and room-creation boundaries. Existing maps
without CellData remain valid without a migration or schema-version bump.
Malformed supplied CellData becomes an explicit validation failure rather
than a silently stripped field.
The inbound BC observation remains server-owned. Do not normalize or mutate
the client’s room snapshot to make persistence pass. MapAdminService.save()
validates a fresh same-room observation, then clones the validated projection.
If sign validation fails, create no revision and return a private, bounded
diagnostic identifying the invalid field/index, never the sign text.
Stored-map loading must reject an invalid selected head; do not fall back to a
lower revision, cached document, or sign-free map. Room creation must include
the validated CellData or fail before dispatch. Use repository-standard error
reporting rather than logging zod input payloads.
Successful Mongo persistence proves only a stored revision. Restore continues to append a new stored revision and refresh the room-creation template; it does not update an existing BC room. A creation dispatch is not proof that signs were rendered or retained by BC. Such claims require later authoritative observation and, for rendering, an approved browser check.
Sign text is deliberately persisted room-map configuration, not captured chat
or a player appearance snapshot. Operators must not put credentials, keypad
codes, private messages, or account data in signs. Do not automatically ingest
chat into CellData, log its contents, echo it in validation replies, or add it
to action-journal metadata.
| Authority | Role |
|---|---|
| Pinned source commit | Defines the selected protocol/catalog baseline, not the actual live release. |
| Fresh inbound BC map | Source of a live save and subsequent BC state observations. |
| Validated Mongo map revisions/backups | Stored configuration and future room-creation input; not proof of live state. |
| Action journal | Existing dispatch/observation lifecycle only; never a substitute for map state. |
All names below refer to existing modules unless marked as a proposed test. Use shared schemas/helpers in their current owning layer rather than adding a new map service or importing browser code.
| ID | Work package and existing surfaces | Required outcome / verification |
|---|---|---|
| BC-01 | source-revision.ts; sync-bc-protocol.ts, sync-bc-map.ts, sync-bc-assets.ts | Select the exact Beta2 revision/version pair. Run the existing combined sync and review all generated declarations, map metadata, asset strings, source hashes, capabilities, and diagnostics. |
| BC-02 | map-definition.ts | Add the optional bounded sign-config schema here as the single stored-map projection. Keep StoredMapData inferred; preserve absent-field compatibility and reject malformed supplied entries. |
| BC-03 | room-definition.ts | Reuse the shared map validation instead of creating a separate CellData validator. Include validated config in MapData for missing-room creation; preserve existing defaults and target/database guards. |
| BC-04 | map-admin-service.ts, map-admin-repository.ts, map-admin-model.ts | Wire the inferred type through live save, metadata edit, append/read revision, backup, revision restore, backup restore, and template reload. Preserve cloning, optimistic conflict handling, and append-only history. Adapt only surfaces that need changes. |
| BC-05 | client.ts, protocol.ts, map-grid.ts, map-object-action.ts | Trace full/partial room sync, map observation, and guarded door updates. Prove valid unrelated CellData survives object changes; keep one socket/send queue/journal owner and server-driven snapshots. No generic dispatch replacement. |
| BC-06 | copy-veratown-config.ts, migrate-mongodb-contracts.ts, map schemas and their callers | Check for other projections that could discard configs. Preserve the fixed copy allowlist and dry-run/apply semantics. No new backfill or production/source database access; change script validation only if the traced path requires it. |
| BC-07 | run-browser-correction.ts, retired Bunny qualification runner and associated tests | Ensure both URL selection and version assertions use the shared Beta2 version. An override URL must not bypass origin/server/version checks. Do not relabel historical runs or treat repinning as native-timer approval. |
| BC-08 | README, BC API plane, acknowledgement matrix, runtime architecture, world guide, map guide, appearance guide, Location Entry Behavior guide, documentation index | Update active source-pin references, preservation behavior, validation policy, and operations guidance. Keep historical qualification evidence explicitly bound to the version actually tested. |
| Area / existing test surface | Required cases |
|---|---|
Proposed tests/unit/adapters/mongo/map-definition.test.ts |
Absent/empty CellData; indices 0 and 1599; reject -1 and 1600 and noncanonical keys; null/array/wrong types; extra fields; exact 150/151 UTF-16 boundary; empty/newline/Unicode preservation; no payload-bearing errors. Register the new file explicitly in package.json. |
| copy-guard.test.ts | Room-definition round trip with/without signs; unchanged isolation/copy behavior; malformed config rejected before creation. |
| map-admin-service.test.ts | Save -> read -> metadata edit -> backup -> restore revision/backup -> load room definition preserves exact sign text/config. Mutating original observation after save cannot mutate stored data. Invalid live input creates no revision; invalid head has no fallback. |
| map-grid.test.ts, client.test.ts, map-object-action.test.ts | Door/object mutation preserves unrelated configs in outbound map data; client snapshot changes only after inbound sync. Preserve existing room settings and acknowledgement behavior. |
| bc-assets-extractor.test.ts, appearance-catalog.test.ts | Generated target revision consistency, supported capabilities, updated string metadata, and no unexplained extraction-diagnostic regression. |
| appearance-browser-correction.test.ts, bunny-qualification.test.ts | Shared version/path agreement, existing approval/origin/version safeguards, and cleanup behavior remain intact without live accounts. |
flowchart LR
Pin["Shared source revision/version"] --> Sync["Existing sync scripts"]
Blobs["Pinned BC Git blobs"] --> Sync
Sync --> Generated["Wire declarations + map/appearance catalogs"]
Pin --> Harness["Browser qualification runners"]
BC["Inbound BC map"] --> Client["Existing BcClient"]
Client --> Save["MapAdminService.save"]
Save --> Schema["Shared mapDataSchema + CellData validation"]
Schema --> Repo["MongoMapAdminRepository"]
Repo --> Stored[("Map revisions / backups")]
Stored --> Load["loadEffectiveMap"]
Load --> Schema
Schema --> Definition["buildRoomDefinition"]
Definition --> Create["Existing missing-room creation path"]
classDiagram
class StoredMapData {
+Type
+Tiles
+Objects
+Fog?
+Effects?
+CellData?
}
class SignObjectConfig {
+Type: Sign
+Text: bounded string
}
class MapAdminService {
+save(actor)
+applyEdit(draft, actor)
+backup(createdBy, note)
+restore(revision, actor)
+restoreBackup(id, actor)
}
class MongoMapAdminRepository {
+appendRevision(...)
+loadEffectiveMap(roomKey)
+createBackup(...)
+findRevision(...)
}
StoredMapData o-- SignObjectConfig : bounded cell-index record
MapAdminService --> StoredMapData : shared validation
MapAdminService --> MongoMapAdminRepository
MongoMapAdminRepository --> StoredMapData : read and write validation
flowchart LR
Maintainer((Maintainer)) --> Repin([Regenerate against reviewed Beta2 commit])
Admin((Room admin)) --> Save([Save observed map including signs])
Admin --> Restore([Restore stored revision or backup])
Operator((Operator)) --> Restart([Start bot with selected stored map])
Save --> Validate([Validate bounded configuration])
Restore --> Validate
Restart --> Validate
Validate --> Store([Preserve configuration without live-room overwrite])
flowchart TD
Start([Admin requests map save]) --> Auth{Authorized and fresh same-room observation?}
Auth -->|No| Deny([Private failure; no write])
Auth -->|Yes| Parse[Validate map and every supplied sign config]
Parse --> Valid{Valid?}
Valid -->|No| Deny
Valid -->|Yes| Clone[Clone validated projection]
Clone --> Append[Append revision through existing repository]
Append --> Result{Write verified?}
Result -->|No| Failure([Report conflict or persistence failure])
Result -->|Yes| Template[Refresh creation template]
Template --> Reply([Report stored revision; live room unchanged])
stateDiagram-v2
[*] --> Proposed
Proposed --> Approved: pin and validation policy approved
Approved --> Implementing
Implementing --> OfflineVerified: schemas, round trips, generation and checks pass
Implementing --> Blocked: unexplained generated delta or destructive projection
OfflineVerified --> LiveQualified: separately approved test-room checks pass
LiveQualified --> Released: reviewed deployment separately authorized
Blocked --> Implementing: conflict resolved and reviewed
Released --> [*]
sequenceDiagram
participant Admin
participant Service as MapAdminService
participant Client as BcClient observation
participant Schema as Shared map schema
participant Repo as MongoMapAdminRepository
participant Loader as Room template loader
Admin->>Service: authorized world map save
Service->>Client: fresh same-room map observation
Client-->>Service: server-observed map including optional CellData
Service->>Schema: validate bounded safe projection
alt Invalid sign configuration
Schema-->>Service: field/index validation failure
Service-->>Admin: private failure without sign contents; no revision
else Valid map
Schema-->>Service: typed map including exact sign text
Service->>Repo: append cloned map revision
Repo-->>Service: verified revision or explicit failure
Service->>Loader: refresh future room-creation definition after success
Loader->>Schema: validate selected stored map
Service-->>Admin: stored revision; existing BC room unchanged
end
BC_REPO=../Bondage-College npm run sync:bc, then format generated files
with existing tooling. Regenerate a second time and require no further
diff. Reject unexplained wire, capability, asset-ID, or diagnostic changes.npm run lint,
npm run format:check, npm run check, npm test, and npm run build.
Do not bypass hooks or hand-edit generated catalogs.Existing sign-free maps require no backfill. New revisions and backups preserve validated signs additively. Text previously stripped by old saves can only be captured again from a fresh authorized observation or supplied operator config; do not fabricate a recovery.
A rollback to older code can silently strip signs on subsequent save, edit, backup, or recreation. Suspend those operations before rollback and retain the new map documents unchanged. Do not promise lossless old-code round trips. Reverting the source pin alone does not undo database writes or change the BC server/browser version.
Approval is requested for the exact target revision, editor-aligned 150-code-unit rejection policy, canonical cell-index validation, durable room-sign content as bounded map configuration, and the staged implementation/qualification plan. Do not infer approval from this document’s existence.
Implementation is complete only when:
CellData survives every supported map round trip exactly.