# Phase 9.1 Arbitrary-Party First-Session Implementation Contract > Status: `FROZEN` > Contract revision: `p9.1-contract-r2` > Frozen: 2026-08-13 > Accepted predecessor product source: `41204acafa911a505f5b24a493aa032983e706d1` > Predecessor closure: `f0b7d7b0234d8ad304f7b9d39fa99ded1dbfc27d` > Expert inputs: `GAMEPLAY_EXPERIENCE_SPEC.md`, `UX_VISUAL_FLOW_SPEC.md`, > `RUNTIME_ARCHITECTURE_SPEC.md` ## 1. Product Outcome And Stopping Point P9.1 carries every unordered pair selected from the four current Recruits through one truthful five-battle first session: ```text choose any two -> automatic formation -> battle 1 -> diagnosis -> adaptation -> battle 2 -> Guild response -> battle 3 -> route -> battle 4 -> growth -> battle 5 -> first-session result ``` The player chooses people, never front/rear slots. The system forms the line, automatic combat makes each actual profession act, and every decision page shows current evidence, gain, cost and foregone alternative before commit. The final page ends the bounded experience or restarts it; it does not claim a saved run, next chapter, permanent item, authoritative XP or release readiness. This is one deterministic vertical slice. Complete combat, economy, save, Market, promotion, injury/recovery, difficulty, chapters and bulk content remain frozen. ## 2. Reconciled Authorities This contract resolves the three expert inputs. Implementation follows this precedence: 1. This frozen contract for reconciled behavior and ownership. 2. `p9_1/GAMEPLAY_EXPERIENCE_SPEC.md` for the complete numeric matrix, transaction rules and causal values. 3. `p9_1/UX_VISUAL_FLOW_SPEC.md` for layouts, copy, controls, accessibility and evidence states, except where this contract explicitly reconciles a conflict. 4. `p9_1/RUNTIME_ARCHITECTURE_SPEC.md` for APIs, migration and final file paths. 5. P9.0R1-R10 contracts for unchanged regression anchors. The expert files remain immutable source records. Developers do not amend them to fit implementation. ## 3. Reconciled Product Decisions ### 3.1 Stable identities and automatic formation The stable member/profession IDs are the existing runtime IDs: ```text Hearthguard, Wayrunner, Farstring, Kindhand ``` Automatic priority is: ```text Hearthguard -> Wayrunner -> Farstring -> Kindhand ``` `starting_pair` is normalized by this priority. `initial_second_id` and `marked_id` remain the identity that began second, regardless of later visible position. Selection order never affects formation. A Guild addition may reform the whole line. It must preserve the two original members' relative order while inserting the new member at its priority position. For `Farstring + Kindhand`, adding Hearthguard therefore changes the lead from Farstring to Hearthguard and yields `Hearthguard, Farstring, Kindhand`. The receipt must state: - who was added and at which position; - every original member whose visible number changed; - that the original two retained their relative order; - why the system reformed the line. Existing actors move to their new positions; they do not disappear and respawn. This reconciles the UX continuity rule with the gameplay re-formation rule. ### 3.2 Exact decision and content IDs ```text adaptation: EQ-002 | EQ-061 Guild response: retain_loan | add_recruit route: R6-01 | R6-02 | R6-03 growth: exactly one current member ID ``` The Guild addition allowlist, route coverage, battle values, rewards and growth effects are exactly those in the gameplay specification. UI does not infer an action from `front`, `rear`, `second` or `added`; it presents domain-resolved member IDs, facts and events. ### 3.3 Final screen and legacy naming The final domain/presentation screen is `session_result`, surfaced as `P91-FIRST-SESSION-RESULT`. During migration it maps to the historical `AppPage.THIRD_CYCLE_RESULT`; P9.1 does not add another final page. New code and evidence use the P9.1 name. The legacy enum remains facade-only until its stated deletion gate is met. ### 3.4 One result grammar All five result pages use exactly this order in Chinese and English: ```text 发生了什么:{outcome_clause} 为什么:{cause_clause} 决定造成的差异:{decision_clause} 现在改变了:{changed_state_clause} 下一步:{next_action_clause} ``` For Result 1 only, line three is `系统编队造成的差异`. The gameplay specification's result templates supply the facts and numeric substitutions, but the UI formats them into these five labels. No separate `状态变化` line or unlabeled decision chain is shown. Result 5 may append the compact chain after line four, never before cause or changed state. `P91_RESULT` therefore contains already-resolved `outcome_clause`, `cause_clause`, `decision_clause`, `changed_state_clause`, `next_action_clause`, `reward_receipt` and `decision_chain`. It never contains only totals that require UI-side causal reconstruction. ## 4. Screen Snapshot And Action Contract Every render receives one immutable snapshot, plus named callbacks for only the listed `available_actions`. A missing required fact renders `P91-BINDING-ERROR`; the UI must not invent a fallback result. | Screen family | Required snapshot facts | Available actions | |---|---|---| | Boot/Title/Menu/Intro/Settings | resource status, locale/settings, caller/focus, no transient run claim | existing R8 navigation/settings actions only | | Commission/Recruit 0-2 | four member identities, selected IDs, capacity, automatic-order preview, disabled reasons | `open_recruit`, `toggle_recruit`, `review_formation`, `home` | | Formation review | normalized `starting_pair`, lead/second responsibility, order reason | `revise_formation`, `commit_formation`, `home` | | Battles 1-5 | encounter/phase, party order/origin/HP/level, enemy HP, ordered semantic events, current committed decision | `pause`, `captions`; domain progression is clock/event driven | | Results 1-5 | the five resolved result clauses, exact resource/HP/time facts, receipt state | the one next-flow action; final result also offers inspect, restart review and finish | | Adaptation 0-1 | both options' gain/cost/foregone state, actual lead, pending/committed ID | `choose_adaptation`, then `commit_adaptation`; Back before commit | | Guild 0-1 | current party/order/origin, Coin, loan, mapped Recruit, both exact consequences | `choose_guild_response`, then `commit_guild_response`; Back before commit | | Route 0-1/review | three routes, pressure, target, reward, domain-resolved coverage/reason, pending ID | `choose_route`, `review_route`, `cancel_route_review`, `commit_route` | | Growth 0-1/review | every present member, order/origin/level, exact next-battle delta, one mark | `choose_growth`, `review_growth`, `cancel_growth_review`, `commit_growth` | | Pause/Home/Restart review | frozen caller snapshot and exact transient state to preserve or clear | resume/cancel plus separately focused confirm | Choice screens always open unselected. Selection is reversible and free. Commit is the only mutation boundary, revalidates the complete precondition and increments domain revision once. Rejected or duplicate commands change no snapshot field, event, reward, clock or revision. ## 5. Domain And Presentation Boundary The final paths are the architect's paths, not placeholder `foundation/` directories. ### 5.1 Exclusive foundation writes ```text runtime/main.gd runtime/domain/p9_1/contracts.gd runtime/domain/p9_1/session_state.gd runtime/domain/p9_1/session_service.gd runtime/domain/p9_1/battle_fixture.gd runtime/presentation/presentation_settings.gd runtime/presentation/battle_clock.gd runtime/presentation/animation_adapter.gd runtime/presentation/audio_adapter.gd runtime/presentation/feedback_presenter.gd runtime/ui/session_presenter.gd runtime/ui/widgets.gd runtime/compat/p9_0_root_facade.gd ``` The foundation is behavior-equivalent. It introduces one authoritative state object, commands, snapshots, semantic events and compatibility forwarding; it adds no P9.1-only decision branch or changed player value. ### 5.2 Parallel extension writes after foundation PASS | Role | Exact write scope | |---|---| | Domain | new files only under `runtime/domain/p9_1/content/` and `runtime/domain/p9_1/rules/` | | UI | new files only under `runtime/ui/p9_1/` | | Tests | new files under `runtime/tests/p9_1/` and `runtime/tests/support/p9_1/` | | Integration | shared entry/foundation files, exact shared P9.1 runner/manifest, and `runtime/project.godot` only when needed | No parallel developer edits `runtime/main.gd`, foundation API files, existing P9.0 tests or another role's directory. Integration is the sole shared-file owner after foundation. ### 5.3 Domain and time invariants - Domain scripts do not extend/read `Node`, `Control`, SceneTree, Input, AudioServer, textures, paths, viewport or render FPS. - `FirstSessionService` is the only run mutator. Snapshots are deep copies. - `BattleClock` requests named impacts; it never decides HP, rewards or result. - An impact is keyed by encounter + phase + impact ID and commits at most once. - Render FPS, locale, viewport, mute, reduced motion/flashes and low power do not change the final domain snapshot. - Low power may reduce presentation sampling, particles and nonessential idle animation only. It preserves event order, actor state transitions, captions, number feedback, battle duration and every transaction. ## 6. Behavior-Equivalent Foundation Gate The exact accepted P9.0R10 regression manifest is the retained 22-test summary whose SHA-256 is `3de791bb6da14be19d97c194368cd14bc8bfb906013470e81b6e12da83736bf7`: ```text p9_0r1_domain_test.gd p9_0r1_dynamic_slice_test.gd p9_0r1_layout_test.gd p9_0r1_touch_test.gd p9_0r2_character_animation_test.gd p9_0r2_dynamic_slice_test.gd p9_0r3_audio_lifecycle_test.gd p9_0r3_battle_feedback_test.gd p9_0r4_second_cycle_test.gd p9_0r4_touch_test.gd p9_0r5_first_session_arc_test.gd p9_0r5_full_route_touch_test.gd p9_0r6_route_touch_test.gd p9_0r6_second_cycle_route_test.gd p9_0r7_growth_touch_test.gd p9_0r7_individual_growth_test.gd p9_0r8_front_door_test.gd p9_0r8_front_door_touch_test.gd p9_0r9a_auto_formation_test.gd p9_0r9a_auto_formation_touch_test.gd p9_0r10_pair_adaptation_test.gd p9_0r10_pair_adaptation_touch_test.gd ``` The foundation task must run these exact 22 scripts serially from a clean import, require each script's unique accepted terminal marker and scan all logs for strict diagnostics. It also reruns the preserved normal-render R8 front door, R9A formation, R10 adaptation, and R3 feedback capture scripts at `844x390` to detect presentation drift. Capture output is development evidence, not a new candidate. Tracked `runtime/domain/run_state.gd`, the five pre-existing `runtime/tests/p9_1_*` scripts, `p9_0_boot_title_test.gd`, `p9_0_layout_test.gd` and `p9_0_touch_test.gd` belong to the older opening/Market lineage. The latter three still require `game.run`, which the accepted R10 runtime no longer exposes. `p9_0r3_dynamic_slice_test.gd` was not part of the accepted R10 22-test summary. P9.1 foundation leaves all of these unchanged and excludes them from its pass claim. A later integration-only commit may retire or reclassify them only with explicit source search, replacement coverage and a contract amendment. ## 7. P9.1 Implementation And Evidence Gate The gameplay specification's compact functions expand to: ```text 6 unordered pairs x 2 click orders 12 pair/adaptation paths 24 pair/adaptation/Guild paths 72 paths through three routes each route path x every present two- or three-member growth target ``` Tests assert identity, origin, relative order, actual profession events, lead/marked/enemy HP, time, Coin, Company, item state, route coverage/reward, exactly one Lv.2 member, commit flags and the five result clauses. Negative coverage includes invalid IDs, stale/duplicate commits, insufficient Coin, duplicate Recruit, absent growth member, premature reward and reset cleanup. Runtime evidence requires: - one uninterrupted parsed-ScreenTouch path through all five battles with fallback/direct zero; - all six pairs reaching the final result; - small/reference/large landscape, zh_CN/EN, 130%, reduced motion/flashes, mute/captions, contrast and low-power representative states; - the UX specification's 25 named frames and battle-event states; - visible party-line continuity, melee contact, ranged attack, heal/guard, damage/heal numbers, result cause and persistent decision change; - strict scan covering script/parse/resource/import/assertion/ObjectDB and owned-process cleanup failures. Automated or visual agent evidence cannot close Owner understanding, fun, visual/listening, physical device, packaging or release gates. ## 8. Bounded Representative Visual Slice The Owner authorizes current-task image generation without another per-call prompt. The visual task may make at most four paid image calls and spend at most USD 5 equivalent total, including retries. It records prompts, provider task IDs, returned cost, source/output hashes and acceptance or rejection. The visual slice is limited to the representative first-battle/diagnosis chain: ```text formation review -> approach/contact -> profession response -> damage/heal feedback -> first causal result ``` It may produce a bounded layered battlefield/UI reference or replacement asset set only after graybox composition. It must preserve the accepted four Recruit identities, Japanese hand-painted direction, landscape party scale and event readability. It does not authorize bulk chapter assets, new character families, audio, video, store media or silent provider expansion. Generated material is not integrated unless play-size review and provenance checks pass. ## 9. Submission And Remaining Gates The developer legal terminal is: ```text Aetherbound Guild P9.1 candidate ready ``` or: ```text Aetherbound Guild P9.1 redesign required: ``` Submission requires a focused pushed source, clean/upstream repository, complete contract evidence and no owned process. A fresh visible independent reviewer then reruns the fixed candidate from zero. Only reviewer PASS authorizes a new private H5. Packaging, TestFlight, devices, stores and release remain frozen.