# Implementation patterns

Select the smallest pattern that faithfully implements the brief, then enrich
the presentation in the real Workbench.

## Single submission

Use for a score, time, count, rating, percentage, yes/no result, or short text
produced outside the app. Initialize ready, accept one submit command, record
the declared measurements, and complete immediately. This is the generated
scaffold and the best baseline for many manual activities.

## Multi-step attempt

Use state to model a bounded sequence such as targets, puzzle items, splits, or
repetitions. Every command advances one deterministic step. Project current
progress and recent results, but emit final measurements and completion only at
the true terminal condition. Include duplicate and stale-revision fixtures.

## Timed activity

The host clock and `hostElapsedMs` are authoritative. Never call wall-clock APIs
inside package logic. Model start, checkpoints, finish, and abort as explicit
transitions. A future connector can observe external timing without changing
the Attempt contract.

## Connector-assisted activity

Declare accepted observation protocols with one package-owned JSON payload
schema per semantic type and positive contract version. Packing canonicalizes
the schema into the immutable protocol identity. The connector independently
owns external protocol translation; the package owns meaning and scoring.
Always retain a deterministic fixture representation and define whether manual
fallback or correction is allowed.

When manual and automatic input represent the same player action, converge them
before applying rules:

```text
manual command ─────┐
                    ├─> normalized action -> one reducer policy
host observation ───┘
```

Prove both routes end with equivalent canonical state, measurements,
completion, and Story Events. Workbench's automatic-input simulator is for this
portable contract. It is not a native connector process and grants no network,
device, filesystem, credential, Station, or OBS access.

Native connector authoring is a separate trust lane with its own scaffold,
supervisor-backed lab, resource-grant review, packaging, and signing workflow.
Do not put a connector executable inside the portable activity just to make a
preview work.

## Rich player UI

Ship a portable `web_ui` artifact using the public package UI bridge. It may
render any experience achievable in sandboxed HTML/CSS/JavaScript, including
boards, puzzles, animation, audio cues, and responsive layouts. It sends typed
commands; it never mutates canonical state or reaches host APIs directly.

## Overlay and Story Events

Ship `overlay_ui` only when a broadcast view adds value. Keep it glanceable and
render host-provided committed state. Map that state into the strict public
`activityPresentationSchema`; do not hand arbitrary projection JSON to a shared
renderer. Use the exact `@chasingmastery/presentation-kit` when a fixed compact
and 16:9 shell is appropriate, but keep scoring, goals, ranks, thresholds, and
the meaning of change inside package code. Always provide explicit unavailable
and disconnected behavior, retain the last committed state while stale, use
text as well as color for tone, and honor reduced motion. Emit Story Events for editorially useful
moments—personal bests, milestones, failures near the goal, dramatic recovery—
not every interaction. Suggested media windows should help an editor find the
story without pretending the package owns recording.

## Progression

Tie progression to a declared directed numeric metric. Thresholds increase for
`higher` metrics and decrease for `lower` metrics. Prefer transparent personal
progression; governed comparison requires a separate product decision.

## Correction and deterministic replay

Use stable transition or evidence keys from the original Attempt. A correction
is an immutable replacement/removal instruction whose reducer result can be
rebuilt from pinned release bytes and the retained transition stream. Declare
whether terminal correction is denied or replays and reopens. Retract or
supersede any Story Event and narration fact whose premise no longer exists.
Never overwrite the original Measurement, delete the Attempt, or make the UI the
only holder of correction identity.

## Coordinated multiplayer

Keep coordination separate from activity truth. The coordination engine may
decide who is eligible to act, shared versus independent input arbitration,
round and team state, and match completion. It emits host effects that open or
signal atomic Practice Mode Attempts and compose their committed results. It
does not create a second mutable scoring implementation.

Ship one immutable preset for each ordinary topology the suite promises. Test
ready/start order, ineligible input, shared-board exclusivity or independent
routes, round advance, terminal match result, disconnect/reconnect, duplicate
signals, and correction of a previously terminal activity result. Use
`createCoordinationWorkerHandler` for the isolated artifact.

## Narration policy

Activities emit bounded `broadcast.emit` facts only after relevant evidence is
committed. A narration director converts those facts into optional cues and
cancellations. Keep domain language, priority, pacing, expiry, and voice roles
package-owned; keep provider calls and audio delivery host-owned. Include
fixtures for normal, notable, terminal, incomplete, duplicate, reordered,
expired, and corrected facts. Silence is a valid intentional result. Use
`createNarrationWorkerHandler` for the isolated artifact.

## Experience Suite composition

A Suite may combine several Practice Modes, coordination policies, narration,
overlays, Story Events, progression, and shared pure Domain Kits. The authoring
brief must declare all of them. Reuse pure code, schemas, and visual primitives,
but retain separate activity state and result contracts. A member adds one
release and receives the package-owned default modes without configuring rank-
affecting semantics.

## Domain Kit reuse

Use a checked Domain Kit when multiple packages need the same pure rule, JSON
Schema, deterministic fixture, token, or presentation helper. It is an ordinary
exact build dependency, never a member-facing install or runtime service.

1. Locate its tarball in `.chasing-mastery/toolchain/toolchain.json`, add that
   package-local `file:` path to `dependencies`, and reinstall with scripts
   disabled.
2. Run `.chasing-mastery/run.sh kit <package-name> . --json` on macOS/Linux or
   `.chasing-mastery/run.ps1 kit <package-name> . --json` on Windows.
3. Import only the pure exports needed by the package.
4. Add one `domainKits` entry to `chasing-mastery.package.json` with the returned
   identity, exact version, integrity, and the JavaScript artifact IDs that
   bundle it.
5. Let `npm test` and `npm run ready` prove the import graph. Never claim an
   artifact the bundle did not actually influence.

Do not add install scripts, dynamic loading, network calls, host SDKs, clocks,
storage, DOM authority, or transitive package dependencies to a Domain Kit.
Every `.cmpkg` remains complete when the kit or registry is unavailable.
