cratis-screenplay-model-authoring · git:20261017.2d3233b · 2026-10-17 · sha256 191361fbbfb6a109

cratis-screenplay-model-authoring git:20261017.2d3233bA

Immutable. This exact content never changes and is served at /api/v1/blob/191361fbbfb6a109.

---
name: cratis-screenplay-model-authoring
description: Author, inspect, refactor and verify a Cratis Screenplay .play model through its typed AST and MCP workspace tools. Use for creating or changing model elements, navigating large split models, reviewing references/specifications, revision-checked screen/UI authoring proposals, or distinguishing source validity from executable/runtime readiness. Do not use for rendering a model into an application or hand-written Arc/Chronicle code.
license: MIT
---

# Author a Screenplay model through its AST

Read [preferred syntax](../cratis-screenplay-toolchain/references/preferred-syntax.md) when writing or reviewing `.play`.

Prefer the Screenplay MCP tools to text/regex edits: the compiler owns declaration,
reference, hierarchy and source evidence for the declarative document set.

Screenplay remains experimental. **Valid source is not necessarily executable.**
It does not generate or run an application; Stage owns rendering/runtime admission.
When selecting construct syntax or distinguishing source validity from execution, read the [language reference](references/language-reference.md) for constructs,
the executable profile and a complete compiled model.

For screens: discover UI schemas, propose/apply with revisions, then pass the
same model root or workspace export to all checks. Workflow:
`references/screen-authoring-workflow.md`; syntax/support:
`cratis-screenplay-ui-composition`.

Record open modeling questions as `question` notes in committed
`.screenplay/notes.json`, not chat or `description` text. Never put secrets or
personal data in notes. Read [model notes](references/model-notes.md) when
listing, recording or resolving questions: `list-model-notes`,
`propose-model-notes`, `read-proposal view=notes`, refs and orphan review.
Prefer dotted split-model targets; inspect `substitutions`, also for reanchor,
and disclose broader owners. The reference covers typed `parts` targets from
`open-workspace.applicationIdentity`.

## Choosing a strategy

Read [shop strategies and entropy](references/choosing-generation.md) before
editing concept generation or `generated identifier`.

## When not to

For generation proofs/PLAY0688 repairs, read [generation details](references/mcp-tools.md#concept-generation):
use `rules[]`, not parsed diagnostics (Requires Screenplay 4.173.0,
`screenplay --version`; older servers omit proofs).

## Locate and connect

Use the declared `screenplay` MCP server (for example `open-workspace`).

Never ask the user which folder to use before trying `open-workspace` without
arguments; do not invent a root. Read [MCP loop](references/mcp-loop.md) when connecting or switching roots;
it owns fallback discovery, fixed-root limits and the initialization protocol.
Discover `tools/list` schemas.

Look first for the project's existing `.play` files: their folder is the model.
New models go in `Source/` or `src/`, else root `Screenplay/`, never `.cratis/`
(configuration/shared corpus only). The source is the single flow model;
explanatory Markdown belongs in repository documentation.

`cratis ai install` manages `.cratis/ai/`, never model files. Select the
`cratis/screenplay` profile in the project's AI configuration. The corpus-owned
`mcp-servers.json` declares the Screenplay server; supported client registration
is owned by the Cratis CLI, which preserves other servers and user configuration.

The CLI-bundled MCP can be older than the standalone tool: discover schemas.
Read [MCP loop](references/mcp-loop.md) for launch options. Use the supported
channel, not another global tool, Docker or copied managed configuration.

If MCP is unavailable, report it; regex edits are not compiler-validated AST
editing. Existing standalone `screenplay mcp` users may retain that entry point.

## Understand before editing

1. Start with `describe-application` counts and paged logical children. A folder
   of `.play` files is one application, not independent files.
2. Use `search-declarations`, `declaration-details`, `find-references` and
   `dependencies` to locate the owning declaration and affected references.
   Before a property change, read [property links](references/property-links.md):
   `kind: "Property"`, `Owner.member` / `Owner.generationN.member`, direct mappings.
   `complete: false` is incomplete evidence, never a successful empty list.
   Edit through MCP proposals, not hand-edited text; [generation](references/mcp-tools.md#concept-generation).
3. Read diagnostics and coverage limitations. Identify subjects by code and typed
   `arguments`, never by parsing message text. Read [diagnostic arguments](../cratis-screenplay-toolchain/references/diagnostic-arguments.md)
   for kinds, PLAY0524 step paths/indices, unknown fields and older responses. Use `dependency-graph` for container
   edges, declared-dependency coverage, cycles and advisory order; the board's
   dependency-map toggle exposes this evidence visually. Unknown or ambiguous
   bindings are not an empty, successful dependency graph.
4. Use `find-fixtures` for value occurrences (including example/override origins
   and event routes) and `find-assertion-gaps` for authored assertion gaps. Neither
   executes specifications; use `run-specifications` for that. `diagnostics` accepts `scope` and opt-in `checks`;
   skipped completeness checks are not passes. Details: `references/mcp-tools.md`.
5. Echo `sourceRevision` on subsequent pages. Restart the query after drift;
   never combine pages from different snapshots.
6. For screens, also discover the template, form, toolbar, package/icon and
   outlet declarations that provide context. A component binding with no traced
   data source is not a shortcut; fix the model source.

Keep reads scoped to the relevant module, feature, slice or document. Do not
request a whole merged AST when a bounded declaration/property query answers the
question. Size-limit refusals require narrower reads, not truncation.

## Application modes and described handler intent

Start new models with `reaction batches atomic`; preserve it through proposals.
Read [language admission](../cratis-screenplay-toolchain/references/language-admission.md)
for atomic/protected modes and Stage refusals. Read [intent inventories](references/mcp-tools.md#dependencies-and-intent-inventories)
for handler views: `executableReady` means binding, not an implemented body.

## Compare models

Compare with `main` through `semantic-diff` worktree `path`, not two exports.
Read [comparison sources](references/mcp-tools.md#semantic-revision-comparison) for paging.

## Make one coherent proposal

**One edit strategy.** Discover what the server offers. Prefer typed,
identity-preserving operations (`propose-rename`, `propose-repair`,
`propose-extract-inline-event`, `propose-ast`). A bounded text edit is fine only for
edits that leave catalog addresses unchanged (descriptions, rule and expression bodies, mappings
between existing members), never a way around an MCP refusal. When `.screenplay/identities.json`
exists, adding, removing or renaming a declaration, command or read-model property, query,
query argument or specification goes through MCP, and an `id` pin is not enough for a rename or move. A request naming
a rename, move or removal is the approval: do not ask again at `apply`. Without MCP, text-rename
with `id "<Old>"` pins and an identity note; only with `identities.json` and no MCP, return the
request to the owning session, saying first it is NOT done.
Proposals are connection-local (16 cap); only the owner proposes/applies.
Others send an edit request ([MCP loop](references/mcp-loop.md)).

- Apply is not crash-atomic across files: it journals its inverse first. The model
  root must be trusted and exclusively writable during effects.

1. `open-workspace` obtains workspace/catalog revisions and restores root-local
   identity state. `read-workspace` locates document identities.
2. `read-ast` returns original occurrence handles and existing semantic IDs.
   Query `syntax-schema` for exact node members before constructing typed input.
3. Prefer `propose-rename` for supported logical renames: it coordinates fragments,
   repairs proven references and preserves assigned identities. Never substitute
   global string replacement for an explicit refusal.
4. Prefer `propose-property` for property add/rename/remove, not hand-composed
   `propose-ast` batches. Inspect the chain and never guess past a refusal:
   [property links](references/property-links.md). Otherwise use `propose-source`
   (whole text) or `propose-ast` (typed edits); `propose` is executable-only.
   Default hand-written source to `PreserveExactSource` (Requires Screenplay 4.158.0,
   `screenplay --version`); read `references/mcp-loop.md` when choosing formatting.
5. Keep reference policy `Safe`. Use `Draft` only for deliberately requested
   unresolved model debt and report that debt; it does not waive structural,
   identity or binding-protection checks. Batch independent reference removals/additions;
   unmatched same-text pairs refuse as ambiguous. Preserve moves with `propose-move`
   or semantic migrations. String `conflicts[].document`/`path` locate refusals:
   [reference continuity and version gate](references/mcp-loop.md#reference-continuity-and-located-conflicts).
6. Report `summary`, inspect severity errors/codes rather than counts
   (Requires Screenplay 4.156.0, `screenplay --version`); read `references/mcp-loop.md`
   when reviewing PLAY0288, comment loss or introduced executable errors. Inspect `read-proposal` before/after bytes and diagnostics, including the
   identity-state change through `workspace-state`. Review `orphanedNotes` on
   source proposals; reanchor or resolve affected questions before applying
   ([notes and orphan impact](references/model-notes.md#source-proposals-can-orphan-notes)).
7. Run `run-specifications` with `proposalId` before applying. Record V4 separately: PLAY0285
   (impossible `then`) unbinds the whole model. Paging and read-only candidate semantics:
   [MCP tool guide](references/mcp-tools.md#run-reference-specifications).

   Requires Screenplay 4.145.0 or later (`screenplay --version`) for `proposalId`; earlier servers run only the current workspace.
8. `apply` only the reviewed server-produced proposal within the user's requested
   change. The proposal ID and before revisions are required; stale state rejects.
   When the user already requested apply, do it after checks without asking again;
   otherwise show the proposal and ask once.
9. When the host draws views, `visualize-model` shows the board. It follows the files
   on disk while open, so after an apply do not re-request it; just say what changed.

Handles are revision-bound occurrences, not durable IDs. Modules/features can
span fragments; one header edit may not change all. After apply, fetch fresh handles/revisions.

On refusal, use `failureKind`, never message text ([failures/limits](references/mcp-loop.md#failures-use-failurekind-never-message-text)).
After revision/disk/identity drift, reopen and re-propose. For `ApplyOutcomeUnknown`
or EOF during `apply`, **never retry apply**: reconnect, inspect `workspace-state`
and ask. Never delete `.screenplay/pending.json`. Limits reject, never truncate.

Choose formatting and disclose dropped comments before apply:
[formatting/limits](references/mcp-loop.md#formatting-and-limits) covers
`PreserveTrivia`, canonical consent and byte preservation.

`identityMigrationIssues`: read the [MCP loop](references/mcp-loop.md).

## Repair or extract before rewriting

Read `read-workspace` with `view: "repairs"` at the same revision as diagnostics and pass the repair to `propose-repair`; use `propose-extract-inline-event` before adding generations. `PLAY0469` changes the event contract, so ask about stored contracts first. No automatic generation-evolution repair ships. `PLAY0479`: migrate optionality spelling with `PreserveTrivia`. `eventNeverPersisted: true` cannot unfreeze admitted revisions. Differing event pins carry `storedName` in ESM v16, shared by all generations and unique (PLAY0472). Read [references/repairs.md](references/repairs.md) when fixing `PLAY0166`, `PLAY0478`, `PLAY0516` or `PLAY0683`, or admitting a [release baseline](references/release-baseline.md).

## Choose a readable layout

Use `recommend-layout` for options and review an `expand-layout` proposal; layout is not application semantics. Use one file per module when modules are simple. Use one file per slice when a large model needs isolated diffs. Each level above the slices is a barrel file. Read [references/layout.md](references/layout.md) when splitting files or writing import barrels.

## Preserve state and recover explicitly

Commit `.screenplay/identities.json` with the model; only `apply` writes it. Never delete or overwrite identity state, mint IDs on restart, or text-rename identity-affecting declarations. A pending journal blocks normal work: inspect `workspace-state` and use `recover-workspace` only for the identified interrupted operation. Only `apply` / `recover-workspace` write source/catalog. `readiness.authoringAccepted` says the source is valid Screenplay; `executableReady` is separate. Read [references/state-and-recovery.md](references/state-and-recovery.md) for root conflicts, journals and readiness.

## Code attachments

Screenplay never compiles/runs opaque code attachments or `file` constraints;
a screen's `file` realizes UI instead. Read [MCP code attachments](references/mcp-tools.md#code-attachments)
for paths, PLAY0430–PLAY0434 and implementation-requirements views; hashes/maps
are not behavioral evidence.

## Verify and report honestly

- Require zero source errors and investigate every warning.
- Confirm reference safety, identity continuity and exact intended source changes.
- Report which of the four states you checked: **parsed**, **bound**,
  **reference-executed**, **target-executed**. When distinguishing source validity from execution, read the
  [language reference](references/language-reference.md#source-validity-is-not-execution);
  it defines them and maps them onto V1 to V5. `screenplay --warnaserror` checks
  syntax plus the consistency rules (`PLAY0282`-`PLAY0294`) but never binds, so a
  clean run is not a bound or executable result.
- Never drop or stub source contracts to bind; the bundled compiler and renderer can be older than the standalone tool. Read [references/language-reference.md](references/language-reference.md) for the ESM version at which each construct binds.

- Distinguish authoring acceptance from `executableReady`; unsupported backend
  capabilities are not a reason to drop source constructs or invent stubs.
- If execution is intended, validate with the owning downstream runtime as well.
- Model rejection cases as specifications; assertion presence is not execution.
- Check installed `tools/list`/schemas rather than assuming a remembered tool count.

The ordinary CLI remains useful for whole-folder validation:

```shell
cratis screenplay validate <model-folder> --warnings-as-errors
```

Record screen MCP transcripts in `.ai-work/`; render/runtime checks must use the
same source, never an app that silently drops authored UI. Use the Screenplay-owned canonical
corpus fixture path instead of copying available `.play` fixtures here.

Never invent syntax or capabilities.

## Route near misses

| Need | Skill |
| --- | --- |
| Discovering the domain and event-modeling method | `cratis-screenplay-event-modeling` |
| Commands, events, validation and concurrency | `cratis-screenplay-command-surface` |
| Projections and reducers | `cratis-screenplay-projections` |
| Read models, queries and screens | `cratis-screenplay-read-surface` |
| Layouts, forms, contributions, navigation regions, slice buttons, template references, sample data, component bindings, toolbars, outlets, themes and localization | `cratis-screenplay-ui-composition` |
| Captures, reactions and triggers | `cratis-screenplay-captures-and-reactions` |
| Behavioral examples and assertions | `cratis-screenplay-specifications` |
| Rendering/running an admitted model | `cratis-stage-rendering-and-sandbox` |
| Lifecycle, verdicts V1 to V5 and the model-first decision | `cratis-screenplay-modeling-lifecycle` |
| Compiler, CLI and MCP versions, diagnostics, capability tables | `cratis-screenplay-toolchain` |
| Event-model diagrams rather than .play source | `cratis-event-model-diagram` |