Interoperability and extensions
Screenplay-family integrations move in two independent directions: authored source can be recovered into Screenplay, and Screenplay can be compiled and realized as target artifacts. Syntax-tree tools sit beside both directions when they only need to inspect or export the written language.
Choose the narrowest extension level that owns the decision you need to make. This keeps source-framework interpretation out of Screenplay, target realization out of Generation, and orchestration out of render planners.
Two-direction architecture
Section titled “Two-direction architecture”The two main directions are not inverses:
- A source adapter explains what authored source proves and reports what it cannot recover.
- A render planner makes explicit, versioned choices for one target and rejects semantics it cannot realize.
Recovering generated artifacts through a source adapter can provide a useful regression check, but it does not prove behavioral equivalence or a lossless round trip.
Level 1: syntax tools and exporters
Section titled “Level 1: syntax tools and exporters”Use ScreenplaySyntaxWalker when the integration consumes Screenplay syntax directly: documentation tools, linters, indexes, visualizers, format-aware exporters, and other tree analyses.
The type ships in the Cratis.Screenplay package under Cratis.Screenplay.Syntax. Its general and root entry points are:
| Member | Purpose |
|---|---|
public virtual void VisitNode(SyntaxNode node) | Observe every node before node-specific traversal |
public virtual void VisitApplication(ApplicationSyntax syntax) | Walk a complete application |
public virtual void VisitProjection(ProjectionSyntax syntax) | Walk a standalone projection |
public virtual void VisitSpecification(SpecificationSyntax syntax) | Walk a standalone specification |
public virtual void VisitCapture(CaptureSyntax syntax) | Walk a standalone capture |
Every concrete node kind also has a public virtual Visit... method. The walk is pre-order: VisitNode() runs before the node-specific method descends into children. An override that calls its base implementation continues into that subtree; an override that does not call base prunes it.
This is the compatibility-oriented extension point for syntax consumers. It is not the source-recovery contract and it is not the target-rendering contract. A generator that must make decisions from resolved semantic identity should consume the executable semantic model through a render planner instead of inferring meaning from syntax names.
See Visitors and traversal and Syntax tree compatibility for traversal and versioning details.
Level 2: source-to-Screenplay recovery
Section titled “Level 2: source-to-Screenplay recovery”Use IDotNetScreenplayAdapter when an integration recovers authored .NET source into Screenplay. The adapter interprets framework or library evidence in Roslyn compilations and contributes neutral facts, evidence, and diagnostics.
The contract ships in Cratis.Screenplay.Generation.DotNet under Cratis.Screenplay.Generation.DotNet:
| Member | Contract |
|---|---|
AdapterIdentity Identity { get; } | Stable adapter identity and version |
bool CanAnalyze(DotNetAnalysisContext context) | Whether the adapter recognizes evidence it can analyze |
AdapterContribution Analyze(DotNetAnalysisContext context, DotNetAdapterOptions options) | Neutral facts and diagnostics from one analysis |
The surrounding host owns workspace loading, the authoritative authored syntax trees, options, and explicit adapter selection. CanAnalyze() decides whether an already-selected adapter recognizes semantic evidence in that context. Analyze() returns one AdapterContribution; it does not construct syntax or print .play text.
Generation owns the framework-neutral pipeline after analysis. ScreenplayDefinitionGenerator.Generate(...) resolves all contributions together, lowers the resolved graph to Screenplay syntax, prints canonical source, and verifies that source with the Screenplay compiler.
Generation does not discover adapter packages automatically. A package, catalog entry, or implementation of the interface does not make an adapter active; a host must select and compose it.
For implementation details, source authority, evidence strength, deterministic identity, diagnostics, and verification, follow the canonical Generation source adapter guide.
Level 3: Screenplay-to-artifact rendering
Section titled “Level 3: Screenplay-to-artifact rendering”Use IArtifactRenderPlanner when an integration turns compiled Screenplay semantics into target artifacts. Raw .play input is compiled first; the planner receives an immutable executable semantic model and its capability-admitted execution plan.
The contract ships in Cratis.Stage.Contracts under Cratis.Stage.Contracts.Rendering. Its public operation is ArtifactRenderPlan Plan(ArtifactRenderRequest request).
ArtifactRenderRequest is a sealed record with this exact positional contract:
| Parameter | Type | Purpose |
|---|---|---|
Model | ExecutableSemanticModel | Immutable executable semantic model |
ExecutionPlan | SemanticExecutionPlan | Capability-admitted plan for that model |
Profile | ArtifactRenderProfile | Fully resolved target and renderer profile |
Scope | ArtifactRenderScope | Semantic scope to render |
A scope identifies the application, one module, one feature, or one slice. The fully resolved profile identifies the target, renderer, versions, and immutable inputs.
The planner owns target admission and realization. It returns a complete deterministic ArtifactRenderPlan with planned paths, bytes, hashes, and typed diagnostics. It must not write files, start processes, use the network, read the clock, or inspect ambient dependency state. Publication belongs to the caller after a successful plan.
A target must fail closed when it cannot realize reachable semantics. It must not emit guessed defaults, thinner behavior, placeholders, or to-do blocks.
For profiles, admission, deterministic planning, scope behavior, publication boundaries, and verification, follow the canonical Stage renderer target guide.
Ownership boundaries
Section titled “Ownership boundaries”| Owner | Semantic responsibility | Does not own |
|---|---|---|
| Screenplay | The language, syntax tree, compiler, printer, semantic identities, executable semantic model, and portable execution plan | Source-framework interpretation, target-specific realization, or CLI admission |
| Generation adapters | Interpretation of authored source into neutral facts, evidence, and diagnostics | Workspace authority, Screenplay language semantics, syntax printing, or target artifacts |
| Generation core | Deterministic resolution, lowering, canonical printing, and compiler verification across adapter contributions | Adapter discovery or framework-specific source interpretation |
| Stage renderers | Target capability admission and pure, deterministic artifact planning from the executable semantic model | Source recovery, file publication, process execution, or CLI command policy |
| CLI orchestration | Command-line selection, fully resolved profiles, planner invocation, diagnostics, staging, and publication | Screenplay semantics or target realization rules |
The source-recovery host and the rendering CLI are composition boundaries. They decide which trusted integrations to invoke; implementing an extension contract does not grant that trust.
Neutral extension catalog
Section titled “Neutral extension catalog”An extension catalog describes interoperability options. It is documentation, not a plugin loader, package-discovery mechanism, trust decision, compatibility guarantee, or CLI allowlist.
| Extension level | Public entry point | Input | Output | Activation model |
|---|---|---|---|---|
| Syntax consumer | ScreenplaySyntaxWalker | Screenplay syntax root or subtree | Consumer-defined analysis or export | The consuming tool constructs and invokes its walker |
| .NET source recovery | IDotNetScreenplayAdapter | DotNetAnalysisContext and DotNetAdapterOptions | AdapterContribution | A source host explicitly selects and composes adapters |
| Target rendering | IArtifactRenderPlanner | ArtifactRenderRequest | ArtifactRenderPlan | A caller explicitly constructs the planner and profile; a CLI may separately bundle a reviewed target |
Clearly labeled ecosystem examples include the Vogen source adapter in Screenplay Generation, the Critter Stack source adapter as a framework-specific integration, and the Cratis artifact render planner in Stage. Ecosystem-specific adapters and renderers are owned separately from the core extension contracts. Catalog membership documents an integration; it does not imply admission to or support by the Cratis CLI.
The Cratis CLI currently uses a static, reviewed renderer-target roster. A renderer appearing in this catalog, being installed beside a workspace, or implementing IArtifactRenderPlanner does not admit it to that roster. CLI support requires a separate orchestration change, explicit profile construction, publication wiring, and verification.