@cratis/pi 7.78.0 → 7.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package/corpus/agents/code-reviewer.md +3 -18
  2. package/package/corpus/agents/coordinator.md +1 -2
  3. package/package/corpus/agents/orchestrator.md +1 -2
  4. package/package/corpus/agents/performance-reviewer.md +3 -34
  5. package/package/corpus/agents/planner.md +2 -2
  6. package/package/corpus/agents/repository-investigation-reviewer.md +8 -1
  7. package/package/corpus/agents/security-reviewer.md +3 -37
  8. package/package/corpus/harnesses/copilot/instructions/review-reports.instructions.md +68 -0
  9. package/package/corpus/harnesses/pi/agents/code-reviewer.md +3 -18
  10. package/package/corpus/harnesses/pi/agents/coordinator.md +1 -2
  11. package/package/corpus/harnesses/pi/agents/orchestrator.md +1 -2
  12. package/package/corpus/harnesses/pi/agents/performance-reviewer.md +3 -34
  13. package/package/corpus/harnesses/pi/agents/planner.md +2 -2
  14. package/package/corpus/harnesses/pi/agents/repository-investigation-reviewer.md +8 -1
  15. package/package/corpus/harnesses/pi/agents/security-reviewer.md +3 -37
  16. package/package/corpus/product-sync.json +4 -4
  17. package/package/corpus/prompts/code-review.prompt.md +1 -0
  18. package/package/corpus/prompts/review-pr.prompt.md +8 -12
  19. package/package/corpus/prompts/review-skill.prompt.md +3 -3
  20. package/package/corpus/rules/general.md +1 -0
  21. package/package/corpus/rules/review-reports.md +67 -0
  22. package/package/corpus/skills/cratis-code-review/SKILL.md +6 -21
  23. package/package/corpus/skills/cratis-code-review/verification.json +10 -0
  24. package/package/corpus/skills/cratis-performance-review/SKILL.md +11 -13
  25. package/package/corpus/skills/cratis-performance-review/verification.json +12 -0
  26. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +40 -44
  27. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +8 -3
  28. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +26 -0
  29. package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +53 -7
  30. package/package/corpus/skills/cratis-screenplay-model-authoring/references/state-and-recovery.md +22 -0
  31. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +17 -1
  32. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  33. package/package/corpus/skills/cratis-security-review/SKILL.md +9 -12
  34. package/package/corpus/skills/cratis-security-review/verification.json +11 -0
  35. package/package.json +1 -1
@@ -161,21 +161,6 @@ When checking unused code, references, or naming, use semantic navigation if the
161
161
 
162
162
  ## Output format
163
163
 
164
- Start with a **summary**:
165
- > **Review result: ✅ Approved / ⚠️ Approved with comments / ❌ Changes requested**
166
-
167
- Then list issues grouped by file:
168
-
169
- ```
170
- ### <file path>
171
-
172
- **[BLOCKING]** … or **[SUGGESTION]** …
173
- > Line N: `problematic code`
174
- > Because: explanation
175
- > Fix:
176
- > ```
177
- > corrected code
178
- > ```
179
- ```
180
-
181
- End with a checklist of passed / failed items so the developer knows what was verified.
164
+ Read and use `.cratis/ai/rules/review-reports.md` when writing conclusions.
165
+ Apply the domain-specific classification in the Report section of
166
+ `.cratis/ai/skills/cratis-code-review/SKILL.md`.
@@ -143,8 +143,7 @@ For implementation, the applicable changed-lane gates must pass. Mark unrelated
143
143
  - [ ] `npx tsc -b` — zero TypeScript errors (if frontend present)
144
144
  - [ ] Public-facing changes (clients, SDKs, public APIs) include associated documentation updates
145
145
  - [ ] `Documentation/verify-markdown.sh` passes when documentation is added or changed
146
- - [ ] `code-reviewer` finds no blocking issues
147
- - [ ] `security-reviewer` finds no vulnerabilities
146
+ - [ ] Code and security reviews approve the scoped change; combine their reports using `.cratis/ai/rules/review-reports.md`, preserving each reviewer's findings and scope limits
148
147
  - [ ] PR description follows the pull request template and the release-note contract in `pull-requests.md`; test and review notes are in a PR comment
149
148
 
150
149
  ---
@@ -167,8 +167,7 @@ For implementation, the applicable changed-lane gates must pass. Mark unrelated
167
167
  - [ ] `npx tsc -b` — zero TypeScript errors (if frontend present)
168
168
  - [ ] Public-facing changes (clients, SDKs, public APIs) include associated documentation updates
169
169
  - [ ] `Documentation/verify-markdown.sh` passes when documentation is added or changed
170
- - [ ] `code-reviewer` finds no blocking issues
171
- - [ ] `security-reviewer` finds no vulnerabilities
170
+ - [ ] Code and security reviews approve the scoped change; combine their reports using `.cratis/ai/rules/review-reports.md`, preserving each reviewer's findings and scope limits
172
171
  - [ ] All documentation is complete and accurate (if required)
173
172
  - [ ] PR description follows the pull request template and the release-note contract in `pull-requests.md`; test and review notes are in a PR comment
174
173
 
@@ -71,39 +71,8 @@ Your responsibility is to identify performance problems in changed code before t
71
71
 
72
72
  ---
73
73
 
74
- ## Risk classification
75
-
76
- | Label | Meaning |
77
- | ------- | --------- |
78
- | 🔴 High | Will cause measurable degradation at moderate load — must fix before merge |
79
- | 🟡 Medium | Could degrade under load or at scale — should fix soon |
80
- | 🟢 Low | Minor inefficiency or style issue — fix when convenient |
81
-
82
- ---
83
-
84
74
  ## Output format
85
75
 
86
- Start with a **summary**:
87
- > **Performance Review: ✅ No issues / ⚠️ Minor findings / ❌ Blocking issues found**
88
-
89
- Group findings by category:
90
-
91
- ```
92
- ### MongoDB / Read Models
93
-
94
- 🟡 **Medium** — `<AppSourceRoot>/Projects/Listing/AllProjects.cs`
95
- > The query does not specify a sort order or index hint, which will result in a
96
- > collection scan once the `projects` collection grows.
97
- > Fix: Add `.SortBy(m => m.Name)` and ensure an index on `Name` exists in the
98
- > MongoDB collection initialization.
99
- ```
100
-
101
- End with a summary table:
102
-
103
- | Category | Status |
104
- | ---------- | -------- |
105
- | Chronicle / Event Sourcing | ✅ / ⚠️ / ❌ |
106
- | MongoDB / Read Models | ✅ / ⚠️ / ❌ |
107
- | ASP.NET Core / Commands & Queries | ✅ / ⚠️ / ❌ |
108
- | React / TypeScript | ✅ / ⚠️ / ❌ |
109
- | General .NET | ✅ / ⚠️ / ❌ |
76
+ Read and use `.cratis/ai/rules/review-reports.md` when writing conclusions.
77
+ Apply the domain-specific risk mapping in the Report section of
78
+ `.cratis/ai/skills/cratis-performance-review/SKILL.md`.
@@ -136,9 +136,9 @@ For an implemented application slice, require the applicable changed-lane gates
136
136
  - [ ] All TypeScript specs pass (`yarn test`) if applicable
137
137
  - [ ] Public-facing changes (clients, SDKs, public APIs) include associated documentation updates
138
138
  - [ ] `Documentation/verify-markdown.sh` passes when documentation is added or changed
139
- - [ ] Code review by `code-reviewer` finds no blocking issues
139
+ - [ ] Code review by `code-reviewer` approves the scoped change using `.cratis/ai/rules/review-reports.md`
140
140
  - [ ] In an opted-in repository: `.play` changes were reviewed by `screenplay-reviewer`, and no modeled business rule or model-owned behavior exists only in code (infrastructure, client, adapter, code-attachment/handler code and authorized gap-fill governed by the `.play` slice and specs are allowed)
141
- - [ ] Security review by `security-reviewer` finds no vulnerabilities
141
+ - [ ] Security review by `security-reviewer` approves the scoped change; combine the review reports using `.cratis/ai/rules/review-reports.md`, preserving each reviewer's findings and scope limits
142
142
  - [ ] PR description follows the pull request template and the release-note contract in `pull-requests.md`; test and review notes are in a PR comment
143
143
 
144
144
  ---
@@ -42,4 +42,11 @@ You independently review a completed Cratis repository investigation. Your resul
42
42
  7. Pre-existing failures are distinguished from failures caused by the investigated behavior.
43
43
  8. Failed, missing, or inconclusive evidence remains failed, blocked, or inconclusive.
44
44
 
45
- Return only the requested typed review envelope. Request a bounded correction when a correctable evidence gap exists; otherwise report the exact blocker.
45
+ ## Output format
46
+
47
+ Use `.cratis/ai/rules/review-reports.md` for conclusions, including its
48
+ typed-envelope mapping. Return only the requested typed review
49
+ envelope; preserve its schema and blocked or inconclusive states. A material
50
+ unsupported conclusion or inconsistent repository mode prevents acceptance;
51
+ a non-blocking recommendation is advisory. Request a bounded correction when
52
+ a correctable evidence gap exists; otherwise report the exact blocker.
@@ -79,42 +79,8 @@ Your responsibility is to perform a structured **security review** of all change
79
79
 
80
80
  ---
81
81
 
82
- ## Risk classification
83
-
84
- Assign each finding one of:
85
-
86
- | Label | Meaning |
87
- |-------|---------|
88
- | 🔴 Critical | Must be fixed before merge — exploitable without significant effort |
89
- | 🟡 Medium | Should be fixed soon — exploitable under specific conditions |
90
- | 🟢 Low | Improvement or defense-in-depth — fix when convenient |
91
-
92
- ---
93
-
94
82
  ## Output format
95
83
 
96
- Start with a **summary**:
97
- > **Security Review: ✅ No issues / ⚠️ Low-risk findings / ❌ Blocking issues found**
98
-
99
- Then list findings grouped by category:
100
-
101
- ```
102
- ### Input Validation & Injection
103
-
104
- 🔴 **Critical** — `Projects/Registration/RegisterProject.cs`
105
- > Line 14: `var path = Path.Combine(root, command.FileName);`
106
- > A path traversal attack is possible if `FileName` contains `../` sequences.
107
- > Fix: Validate that the resolved path stays within the expected root directory.
108
- ```
109
-
110
- End with a summary table:
111
-
112
- | Category | Status |
113
- |----------|--------|
114
- | Input Validation | ✅ / ⚠️ / ❌ |
115
- | Auth / Authz | ✅ / ⚠️ / ❌ |
116
- | Data Exposure | ✅ / ⚠️ / ❌ |
117
- | Secrets | ✅ / ⚠️ / ❌ |
118
- | Dependencies | ✅ / ⚠️ / ❌ |
119
- | Event Sourcing | ✅ / ⚠️ / ❌ |
120
- | Frontend | ✅ / ⚠️ / ❌ |
84
+ Read and use `.cratis/ai/rules/review-reports.md` when writing conclusions.
85
+ Apply the domain-specific risk mapping in the Report section of
86
+ `.cratis/ai/skills/cratis-security-review/SKILL.md`.
@@ -0,0 +1,68 @@
1
+ ---
2
+ applyTo: ".cratis/ai/skills/cratis-code-review/**,.cratis/ai/skills/cratis-security-review/**,.cratis/ai/skills/cratis-performance-review/**,.cratis/ai/agents/**,.cratis/ai/prompts/**"
3
+ paths:
4
+ - ".cratis/ai/skills/cratis-code-review/**"
5
+ - ".cratis/ai/skills/cratis-security-review/**"
6
+ - ".cratis/ai/skills/cratis-performance-review/**"
7
+ - ".cratis/ai/agents/**"
8
+ - ".cratis/ai/prompts/**"
9
+ ---
10
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
11
+
12
+ <!-- Copyright (c) Cratis. All rights reserved. -->
13
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
14
+
15
+ # Shared review reports
16
+
17
+ Use this report shape for code, security, performance, and repository-investigation
18
+ reviews. Domain-specific risk labels refine findings, not the report or verdict
19
+ vocabulary. Review the change within the declared scope, not unrelated existing debt.
20
+
21
+ ## Report shape
22
+
23
+ Keep these sections in order, writing `None` when a section has no entries:
24
+
25
+ - **Blockers** — findings that must be fixed before merge. Each names a file and
26
+ line or evidence reference, the problem, its concrete consequence, and a proposed
27
+ correction. A blocker names a consequence, not a rule number: "returns HTTP 500
28
+ instead of a validation error" explains harm; "violates rule 4" does not.
29
+ - **Suggestions** — non-blocking improvements, with their benefit and any relevant
30
+ conditions. Do not turn a preference or a hypothetical risk into a merge gate.
31
+ - **Dismissed (with reason)** — candidate findings considered and rejected, each
32
+ with the evidence or reasoning for dismissal so another reviewer need not raise
33
+ it again. Do not invent candidates to populate this section.
34
+ - **Verdict** — one of the values below, scoped to the evidence actually examined.
35
+
36
+ An empty Blockers section is a valid, complete review. Never manufacture a finding
37
+ to make a review look useful. Reserve **[BLOCKING]** exclusively for
38
+ must-fix-before-merge findings; suggestions and dismissed findings never carry it.
39
+
40
+ Every review includes a **Not examined:** line naming the paths, surfaces, checks,
41
+ and axes not examined, including anything that could not be reached. Name what was
42
+ not measured: code-shape inspection is not a benchmark, a build is not behavioral
43
+ proof, and an unexamined surface is not verified. State `None` only when the entire
44
+ declared scope was examined; otherwise give concrete limits and remaining checks.
45
+
46
+ ## Verdict vocabulary
47
+
48
+ | Verdict | Meaning |
49
+ | --- | --- |
50
+ | **Approved** | No blockers or suggestions within the examined scope; required review checks are complete. |
51
+ | **Approved with suggestions** | No blockers; non-blocking suggestions remain and required review checks are complete. |
52
+ | **Changes requested** | At least one blocker must be corrected before merge. |
53
+ | **Incomplete** | No confirmed blocker, but missing or inconclusive required evidence prevents approval. |
54
+
55
+ Skipped optional axes belong on the Not examined line and do not alone prevent a
56
+ scoped approval. Missing required evidence does. When blockers and evidence gaps
57
+ coexist, use Changes requested and record the gaps on the Not examined line; never
58
+ reinterpret a failed or blocked gate as passing.
59
+
60
+ When combining reviews, retain one report per reviewer with the shared sections
61
+ and scope line, then give one combined verdict. Any blocker means Changes requested;
62
+ otherwise any Incomplete review means Incomplete; otherwise any remaining suggestion
63
+ means Approved with suggestions; otherwise use Approved. Do not drop dismissals or
64
+ scope limits when combining reports.
65
+
66
+ When a workflow requires a typed review envelope, preserve its schema and express
67
+ these sections, verdict meanings, and scope limits through its existing fields.
68
+ Do not append a competing Markdown report or invent envelope fields.
@@ -158,21 +158,6 @@ When checking unused code, references, or naming, use semantic navigation if the
158
158
 
159
159
  ## Output format
160
160
 
161
- Start with a **summary**:
162
- > **Review result: ✅ Approved / ⚠️ Approved with comments / ❌ Changes requested**
163
-
164
- Then list issues grouped by file:
165
-
166
- ```
167
- ### <file path>
168
-
169
- **[BLOCKING]** … or **[SUGGESTION]** …
170
- > Line N: `problematic code`
171
- > Because: explanation
172
- > Fix:
173
- > ```
174
- > corrected code
175
- > ```
176
- ```
177
-
178
- End with a checklist of passed / failed items so the developer knows what was verified.
161
+ Read and use `.cratis/ai/rules/review-reports.md` when writing conclusions.
162
+ Apply the domain-specific classification in the Report section of
163
+ `.cratis/ai/skills/cratis-code-review/SKILL.md`.
@@ -139,8 +139,7 @@ For implementation, the applicable changed-lane gates must pass. Mark unrelated
139
139
  - [ ] `npx tsc -b` — zero TypeScript errors (if frontend present)
140
140
  - [ ] Public-facing changes (clients, SDKs, public APIs) include associated documentation updates
141
141
  - [ ] `Documentation/verify-markdown.sh` passes when documentation is added or changed
142
- - [ ] `code-reviewer` finds no blocking issues
143
- - [ ] `security-reviewer` finds no vulnerabilities
142
+ - [ ] Code and security reviews approve the scoped change; combine their reports using `.cratis/ai/rules/review-reports.md`, preserving each reviewer's findings and scope limits
144
143
  - [ ] PR description follows the pull request template and the release-note contract in `pull-requests.md`; test and review notes are in a PR comment
145
144
 
146
145
  ---
@@ -163,8 +163,7 @@ For implementation, the applicable changed-lane gates must pass. Mark unrelated
163
163
  - [ ] `npx tsc -b` — zero TypeScript errors (if frontend present)
164
164
  - [ ] Public-facing changes (clients, SDKs, public APIs) include associated documentation updates
165
165
  - [ ] `Documentation/verify-markdown.sh` passes when documentation is added or changed
166
- - [ ] `code-reviewer` finds no blocking issues
167
- - [ ] `security-reviewer` finds no vulnerabilities
166
+ - [ ] Code and security reviews approve the scoped change; combine their reports using `.cratis/ai/rules/review-reports.md`, preserving each reviewer's findings and scope limits
168
167
  - [ ] All documentation is complete and accurate (if required)
169
168
  - [ ] PR description follows the pull request template and the release-note contract in `pull-requests.md`; test and review notes are in a PR comment
170
169
 
@@ -68,39 +68,8 @@ Your responsibility is to identify performance problems in changed code before t
68
68
 
69
69
  ---
70
70
 
71
- ## Risk classification
72
-
73
- | Label | Meaning |
74
- | ------- | --------- |
75
- | 🔴 High | Will cause measurable degradation at moderate load — must fix before merge |
76
- | 🟡 Medium | Could degrade under load or at scale — should fix soon |
77
- | 🟢 Low | Minor inefficiency or style issue — fix when convenient |
78
-
79
- ---
80
-
81
71
  ## Output format
82
72
 
83
- Start with a **summary**:
84
- > **Performance Review: ✅ No issues / ⚠️ Minor findings / ❌ Blocking issues found**
85
-
86
- Group findings by category:
87
-
88
- ```
89
- ### MongoDB / Read Models
90
-
91
- 🟡 **Medium** — `<AppSourceRoot>/Projects/Listing/AllProjects.cs`
92
- > The query does not specify a sort order or index hint, which will result in a
93
- > collection scan once the `projects` collection grows.
94
- > Fix: Add `.SortBy(m => m.Name)` and ensure an index on `Name` exists in the
95
- > MongoDB collection initialization.
96
- ```
97
-
98
- End with a summary table:
99
-
100
- | Category | Status |
101
- | ---------- | -------- |
102
- | Chronicle / Event Sourcing | ✅ / ⚠️ / ❌ |
103
- | MongoDB / Read Models | ✅ / ⚠️ / ❌ |
104
- | ASP.NET Core / Commands & Queries | ✅ / ⚠️ / ❌ |
105
- | React / TypeScript | ✅ / ⚠️ / ❌ |
106
- | General .NET | ✅ / ⚠️ / ❌ |
73
+ Read and use `.cratis/ai/rules/review-reports.md` when writing conclusions.
74
+ Apply the domain-specific risk mapping in the Report section of
75
+ `.cratis/ai/skills/cratis-performance-review/SKILL.md`.
@@ -132,9 +132,9 @@ For an implemented application slice, require the applicable changed-lane gates
132
132
  - [ ] All TypeScript specs pass (`yarn test`) if applicable
133
133
  - [ ] Public-facing changes (clients, SDKs, public APIs) include associated documentation updates
134
134
  - [ ] `Documentation/verify-markdown.sh` passes when documentation is added or changed
135
- - [ ] Code review by `code-reviewer` finds no blocking issues
135
+ - [ ] Code review by `code-reviewer` approves the scoped change using `.cratis/ai/rules/review-reports.md`
136
136
  - [ ] In an opted-in repository: `.play` changes were reviewed by `screenplay-reviewer`, and no modeled business rule or model-owned behavior exists only in code (infrastructure, client, adapter, code-attachment/handler code and authorized gap-fill governed by the `.play` slice and specs are allowed)
137
- - [ ] Security review by `security-reviewer` finds no vulnerabilities
137
+ - [ ] Security review by `security-reviewer` approves the scoped change; combine the review reports using `.cratis/ai/rules/review-reports.md`, preserving each reviewer's findings and scope limits
138
138
  - [ ] PR description follows the pull request template and the release-note contract in `pull-requests.md`; test and review notes are in a PR comment
139
139
 
140
140
  ---
@@ -40,4 +40,11 @@ You independently review a completed Cratis repository investigation. Your resul
40
40
  7. Pre-existing failures are distinguished from failures caused by the investigated behavior.
41
41
  8. Failed, missing, or inconclusive evidence remains failed, blocked, or inconclusive.
42
42
 
43
- Return only the requested typed review envelope. Request a bounded correction when a correctable evidence gap exists; otherwise report the exact blocker.
43
+ ## Output format
44
+
45
+ Use `.cratis/ai/rules/review-reports.md` for conclusions, including its
46
+ typed-envelope mapping. Return only the requested typed review
47
+ envelope; preserve its schema and blocked or inconclusive states. A material
48
+ unsupported conclusion or inconsistent repository mode prevents acceptance;
49
+ a non-blocking recommendation is advisory. Request a bounded correction when
50
+ a correctable evidence gap exists; otherwise report the exact blocker.
@@ -76,42 +76,8 @@ Your responsibility is to perform a structured **security review** of all change
76
76
 
77
77
  ---
78
78
 
79
- ## Risk classification
80
-
81
- Assign each finding one of:
82
-
83
- | Label | Meaning |
84
- |-------|---------|
85
- | 🔴 Critical | Must be fixed before merge — exploitable without significant effort |
86
- | 🟡 Medium | Should be fixed soon — exploitable under specific conditions |
87
- | 🟢 Low | Improvement or defense-in-depth — fix when convenient |
88
-
89
- ---
90
-
91
79
  ## Output format
92
80
 
93
- Start with a **summary**:
94
- > **Security Review: ✅ No issues / ⚠️ Low-risk findings / ❌ Blocking issues found**
95
-
96
- Then list findings grouped by category:
97
-
98
- ```
99
- ### Input Validation & Injection
100
-
101
- 🔴 **Critical** — `Projects/Registration/RegisterProject.cs`
102
- > Line 14: `var path = Path.Combine(root, command.FileName);`
103
- > A path traversal attack is possible if `FileName` contains `../` sequences.
104
- > Fix: Validate that the resolved path stays within the expected root directory.
105
- ```
106
-
107
- End with a summary table:
108
-
109
- | Category | Status |
110
- |----------|--------|
111
- | Input Validation | ✅ / ⚠️ / ❌ |
112
- | Auth / Authz | ✅ / ⚠️ / ❌ |
113
- | Data Exposure | ✅ / ⚠️ / ❌ |
114
- | Secrets | ✅ / ⚠️ / ❌ |
115
- | Dependencies | ✅ / ⚠️ / ❌ |
116
- | Event Sourcing | ✅ / ⚠️ / ❌ |
117
- | Frontend | ✅ / ⚠️ / ❌ |
81
+ Read and use `.cratis/ai/rules/review-reports.md` when writing conclusions.
82
+ Apply the domain-specific risk mapping in the Report section of
83
+ `.cratis/ai/skills/cratis-security-review/SKILL.md`.
@@ -171,9 +171,9 @@
171
171
  }
172
172
  ],
173
173
  "synced": {
174
- "version": "4.212.4",
175
- "date": "2026-10-17",
176
- "by": "Cratis/AI#772"
174
+ "version": "4.213.0",
175
+ "date": "2026-10-18",
176
+ "by": "Cratis/AI#771"
177
177
  },
178
178
  "covers": {
179
179
  "skills": [
@@ -201,7 +201,7 @@
201
201
  ],
202
202
  "rules": []
203
203
  },
204
- "notes": "Cratis/AI#772: standalone Screenplay 4.212.4 pinned; regenerated compiler contract is byte-identical to the v4.212.4 release asset. Source-checked joined-event automap/no automap overrides and level fallback in executable binding; PLAY0380 covers only all inside children/nested. No new render/runtime probe. Prior: Cratis/AI#769: standalone Screenplay 4.212.3 pinned; regenerated compiler contract is byte-identical to the v4.212.3 release asset. Source-checked both compilers and projection documentation for PLAY0801 DuplicateEventInProjectionScope: shared from/removal/clear set, separate join set, fresh sets per children/nested/variant level, and no two-row update through repeated from blocks with different keys. No new render/runtime probe. Prior: Cratis/AI#768: standalone Screenplay 4.212.2 pinned; regenerated compiler contract is byte-identical to the v4.212.2 release asset (unchanged from the previous contract). Source-checked v4.212.0 split-model dotted note targets, open-workspace applicationIdentity and complete add/reanchor substitutions; unbound container identities are not claimed. v4.212.1 aligns PLAY0535 collection fields, optional parameters and single-result identity inference. v4.212.2 counts read-only query denials for SPEC004, not SPEC006. No new render/runtime probe. Prior: Cratis/AI#762 and #761: source-checked v4.210.0 and v4.211.0 contracts for PLAY0800 CommandHandlerRequiresAttachment (required typed subject, permanent code-attachment requirement, other PLAY0268 families unchanged), independent reference remove/add batches, located same-text ambiguity conflicts and string MCP conflict/move-report document fields. v4.211.1 mapping changes inspected but excluded from this guidance update at the user's request; no typed PLAY0273 property/type arguments are claimed. Standalone Screenplay 4.211.1 and its compiler contract pinned; the contract is a byte-identical copy of the v4.211.1 release asset. No new render/runtime probe. Prior: Standalone 4.205.0 and byte-identical compiler contract pinned. Cratis/AI#746: Uuid ==/!= in command require and produces when (ESM v28): same-concept rule, bare Uuid against a concept, canonical literals, protected read paths in require only; PLAY0268 (different concepts, ordering, Uuid validation and concept rules, read paths in produces when) and PLAY0273 (non-canonical literal) checked against the 4.205.0 compiler, v28 selection read from the MCP executable-model view; Stage admits exact v1-v21 and v23-v26 pairs so v28 is refused STAGE-ESM-016, not probed against a Stage image; CLI 3.74.0 renders through v26. Prior: Standalone 4.204.0 and byte-identical compiler contract pinned. Cratis/AI#702 and #691: PLAY0690 reducer identity (Screenplay 4.170.0, native compiler only) and the screenplay.json validation gate (Screenplay 4.165.0; cratis screenplay validate reads it from CLI 3.65.0) are taught and probed against the 4.204.0 compiler. Cratis/AI#743: flat composite read-model keys (ESM v27): untyped projection key blocks on root from and remove with, equality-filter lists, single-instance by blocks and per-part fixtures, with PLAY0661/PLAY0662/PLAY0268 refusals checked against the 4.204.0 compiler; Stage origin/main still refuses v27 with STAGE-ESM-016 (stage-rendering.md); Stage v4.135.0 v26 admission (Host and executor run date comparisons; renderer STAGE-ESM-046) was source-checked for this sync; no render or runtime probe. Prior: Standalone 4.201.0 and byte-identical compiler contract pinned. Cratis/AI#733: the ui profile root template, shell options, appearance and new screens default (PLAY0788-PLAY0799, quick fix for the legacy layout line, ui-profiles MCP tool, 44 tools). Cratis/AI#735: chronological Date/DateTime ordering in command conditions and command/property literal validation (ESM v26), UTC tick precision and pre-rule offset validation; then matching remains ordinal. Source-checked Screenplay v4.199.0 commands, diagnostics, interoperability and specifications documentation plus decision 0087. Stage v4.127.1 still refuses v26 with STAGE-ESM-016 (stage-rendering.md and SemanticVersionFeatures.Supports); no render/runtime probe. Cratis/AI#576: prior mechanical compiler catch-up. Language batch #717/#722/#723/#724/#720/#728/#734 teaches atomic reaction batches (v22), described payload handlers (v23), portable linear matching, ordinal text rules (v24), protected command reads (v25), diagnostic arguments and event-source invokes mappings. Facts read at Screenplay v4.198.0 and introducing tags; Stage v4.127.0 admits exact v1-v21 and v23-v25 pairs but refuses v22/v26 and mixed pairs (STAGE-ESM-016), protected reads (044), atomic mode (043) and described handlers (STAGE-IMPL-002), even Stub mode. Stage text rules execute/render; no new renderer/runtime probe or Stage pin uplift. Cratis/AI#706: application navigation regions (module inherit, extend or override), toolbar slice buttons, blueprint template references and sample data packs in cratis-screenplay-ui-composition (references/application-shell.md), with the canonical shell vector and the rejection codes PLAY0710-PLAY0722 and PLAY0740-PLAY0765. Examples moved to the executable-state rules since 4.164: translator reactions in an Automation slice beside the Translate slice (PLAY0694) and the first record of a capture key appended with `when added`. Earlier: Standalone 4.164.0 and byte-identical compiler contract pinned. Cratis/AI#663: one origin per capture (PLAY0687). #668: executable no-event/redelivery v17. #684: concept query-argument validation in every version and query-error assertions v18. #681: executable refusal branches and refusal values v19. #666: proposal summary/severity counts and exact structural source proposals. Generated-concept rules select v20 with PLAY0688/0689 proofs and derived-matches repair; generated secrets and preview strategies remain refused. Release-baseline from-esm admission reads storedName. Standalone binding is not renderer admission: Stage 4.103.0 admits v1-v17 and v19; CLI 3.62.0 bundles Screenplay 4.159.0 / Stage 4.99.0 and renders through v16. Prior evidence remains unless superseded; no new renderer, Docker or browser probe."
204
+ "notes": "Cratis/AI#771: standalone Screenplay 4.213.0 pinned; regenerated compiler contract is byte-identical to the v4.213.0 release asset and unchanged from 4.212.4. Reviewed the full v4.212.4-v4.213.0 delta against tagged decision 0093 and MCP reference: pre-binding container identities and stable binding/migration continuity, own-slice member substitutions, containerIdentities completeness/ambiguity/collision refusals, retained ambiguous notes, explicit semanticRenames/retirements, binding fixes through MCP, exact reopen exception, notes/identity rollback and exact-ID re-add anchoring. No grammar, binder, ESM or diagnostic-code changes; no new render/runtime probe. Prior: Cratis/AI#772: standalone Screenplay 4.212.4 pinned; regenerated compiler contract is byte-identical to the v4.212.4 release asset. Source-checked joined-event automap/no automap overrides and level fallback in executable binding; PLAY0380 covers only all inside children/nested. No new render/runtime probe. Prior: Cratis/AI#769: standalone Screenplay 4.212.3 pinned; regenerated compiler contract is byte-identical to the v4.212.3 release asset. Source-checked both compilers and projection documentation for PLAY0801 DuplicateEventInProjectionScope: shared from/removal/clear set, separate join set, fresh sets per children/nested/variant level, and no two-row update through repeated from blocks with different keys. No new render/runtime probe. Prior: Cratis/AI#768: standalone Screenplay 4.212.2 pinned; regenerated compiler contract is byte-identical to the v4.212.2 release asset (unchanged from the previous contract). Source-checked v4.212.0 split-model dotted note targets, open-workspace applicationIdentity and complete add/reanchor substitutions; unbound container identities are not claimed. v4.212.1 aligns PLAY0535 collection fields, optional parameters and single-result identity inference. v4.212.2 counts read-only query denials for SPEC004, not SPEC006. No new render/runtime probe. Prior: Cratis/AI#762 and #761: source-checked v4.210.0 and v4.211.0 contracts for PLAY0800 CommandHandlerRequiresAttachment (required typed subject, permanent code-attachment requirement, other PLAY0268 families unchanged), independent reference remove/add batches, located same-text ambiguity conflicts and string MCP conflict/move-report document fields. v4.211.1 mapping changes inspected but excluded from this guidance update at the user's request; no typed PLAY0273 property/type arguments are claimed. Standalone Screenplay 4.211.1 and its compiler contract pinned; the contract is a byte-identical copy of the v4.211.1 release asset. No new render/runtime probe. Prior: Standalone 4.205.0 and byte-identical compiler contract pinned. Cratis/AI#746: Uuid ==/!= in command require and produces when (ESM v28): same-concept rule, bare Uuid against a concept, canonical literals, protected read paths in require only; PLAY0268 (different concepts, ordering, Uuid validation and concept rules, read paths in produces when) and PLAY0273 (non-canonical literal) checked against the 4.205.0 compiler, v28 selection read from the MCP executable-model view; Stage admits exact v1-v21 and v23-v26 pairs so v28 is refused STAGE-ESM-016, not probed against a Stage image; CLI 3.74.0 renders through v26. Prior: Standalone 4.204.0 and byte-identical compiler contract pinned. Cratis/AI#702 and #691: PLAY0690 reducer identity (Screenplay 4.170.0, native compiler only) and the screenplay.json validation gate (Screenplay 4.165.0; cratis screenplay validate reads it from CLI 3.65.0) are taught and probed against the 4.204.0 compiler. Cratis/AI#743: flat composite read-model keys (ESM v27): untyped projection key blocks on root from and remove with, equality-filter lists, single-instance by blocks and per-part fixtures, with PLAY0661/PLAY0662/PLAY0268 refusals checked against the 4.204.0 compiler; Stage origin/main still refuses v27 with STAGE-ESM-016 (stage-rendering.md); Stage v4.135.0 v26 admission (Host and executor run date comparisons; renderer STAGE-ESM-046) was source-checked for this sync; no render or runtime probe. Prior: Standalone 4.201.0 and byte-identical compiler contract pinned. Cratis/AI#733: the ui profile root template, shell options, appearance and new screens default (PLAY0788-PLAY0799, quick fix for the legacy layout line, ui-profiles MCP tool, 44 tools). Cratis/AI#735: chronological Date/DateTime ordering in command conditions and command/property literal validation (ESM v26), UTC tick precision and pre-rule offset validation; then matching remains ordinal. Source-checked Screenplay v4.199.0 commands, diagnostics, interoperability and specifications documentation plus decision 0087. Stage v4.127.1 still refuses v26 with STAGE-ESM-016 (stage-rendering.md and SemanticVersionFeatures.Supports); no render/runtime probe. Cratis/AI#576: prior mechanical compiler catch-up. Language batch #717/#722/#723/#724/#720/#728/#734 teaches atomic reaction batches (v22), described payload handlers (v23), portable linear matching, ordinal text rules (v24), protected command reads (v25), diagnostic arguments and event-source invokes mappings. Facts read at Screenplay v4.198.0 and introducing tags; Stage v4.127.0 admits exact v1-v21 and v23-v25 pairs but refuses v22/v26 and mixed pairs (STAGE-ESM-016), protected reads (044), atomic mode (043) and described handlers (STAGE-IMPL-002), even Stub mode. Stage text rules execute/render; no new renderer/runtime probe or Stage pin uplift. Cratis/AI#706: application navigation regions (module inherit, extend or override), toolbar slice buttons, blueprint template references and sample data packs in cratis-screenplay-ui-composition (references/application-shell.md), with the canonical shell vector and the rejection codes PLAY0710-PLAY0722 and PLAY0740-PLAY0765. Examples moved to the executable-state rules since 4.164: translator reactions in an Automation slice beside the Translate slice (PLAY0694) and the first record of a capture key appended with `when added`. Earlier: Standalone 4.164.0 and byte-identical compiler contract pinned. Cratis/AI#663: one origin per capture (PLAY0687). #668: executable no-event/redelivery v17. #684: concept query-argument validation in every version and query-error assertions v18. #681: executable refusal branches and refusal values v19. #666: proposal summary/severity counts and exact structural source proposals. Generated-concept rules select v20 with PLAY0688/0689 proofs and derived-matches repair; generated secrets and preview strategies remain refused. Release-baseline from-esm admission reads storedName. Standalone binding is not renderer admission: Stage 4.103.0 admits v1-v17 and v19; CLI 3.62.0 bundles Screenplay 4.159.0 / Stage 4.99.0 and renders through v16. Prior evidence remains unless superseded; no new renderer, Docker or browser probe."
205
205
  },
206
206
  {
207
207
  "id": "scene",
@@ -7,3 +7,4 @@ description: Review a proposed change for correctness, maintainability, and secu
7
7
 
8
8
  Review the proposed change for correctness, maintainability, and security.
9
9
  Focus on actionable findings and minimize false positives.
10
+ Read and use `.cratis/ai/rules/review-reports.md` when writing the report.
@@ -21,15 +21,11 @@ Produce a structured review of a pull request against all Cratis standards.
21
21
 
22
22
  ## Output
23
23
 
24
- ```
25
- ## Pull Request Review — #<number>
26
- ### Summary — <2–3 sentences>
27
- ### Architecture & Quality — ✅ / ⚠️ / ❌ <findings>
28
- ### Security — ✅ / ⚠️ / ❌ <findings>
29
- ### Spec Coverage — ✅ / ⚠️ / ❌
30
- ### Documentation — ✅ / ⚠️ / ❌
31
- ### Overall — ✅ Approved / ⚠️ Approved with comments / ❌ Changes requested
32
- **Blocking** (violates a MUST): 1. … **Suggestions**: 1. …
33
- ```
34
-
35
- Be specific — file, line, and corrected code for every blocking issue.
24
+ Read and use `.cratis/ai/rules/review-reports.md` before writing the report.
25
+ Open with the PR number and a short summary. Keep one report per reviewer using
26
+ the shared Blockers / Suggestions / Dismissed (with reason) / Verdict sections
27
+ and Not examined line. Include specification-coverage and documentation checks
28
+ in the relevant reviewer's scope, with any missing evidence made explicit.
29
+
30
+ End with one **Combined verdict** using the shared aggregation rule, preserving
31
+ each reviewer's findings, dismissals, and scope limits.
@@ -9,6 +9,6 @@ Read [authoring-skills.md](../rules/authoring-skills.md), then apply its section
9
9
  checklist to the requested skill folder under `.cratis/ai/skills/`. Check routing
10
10
  against neighboring skills and workflow correctness against the owning product.
11
11
 
12
- Report blocking findings separately from suggestions, with the file and concrete
13
- consequence. Name any evaluation runs or verification not performed. Return findings
14
- first, then proposed edits; do not edit during the review.
12
+ Read and use `.cratis/ai/rules/review-reports.md` when writing the report.
13
+ Name any evaluation runs or verification not performed on the scope line.
14
+ Include proposed edits with the findings; do not edit during the review.
@@ -161,6 +161,7 @@ A claim is only as good as the signal behind it — a build result, a test run,
161
161
  | Reviewing or explaining a `.play` model | the **cratis-screenplay-model-review** skill |
162
162
  | Turning an existing system into a model | the **cratis-screenplay-legacy-extraction** skill |
163
163
  | Rendering or gap-filling an accepted model | the **cratis-screenplay-render-and-gap-fill** skill, then **cratis-stage-rendering-and-sandbox** for renderer facts |
164
+ | Code, security, performance and repository-investigation review reports | `review-reports.md` |
164
165
  | Authoring or reviewing skills, rules, agents or prompts | `authoring-skills.md` |
165
166
  | Step-by-step recipes | `.cratis/ai/skills/` |
166
167
 
@@ -0,0 +1,67 @@
1
+ ---
2
+ applyTo: ".cratis/ai/skills/cratis-code-review/**,.cratis/ai/skills/cratis-security-review/**,.cratis/ai/skills/cratis-performance-review/**,.cratis/ai/agents/**,.cratis/ai/prompts/**"
3
+ paths:
4
+ - ".cratis/ai/skills/cratis-code-review/**"
5
+ - ".cratis/ai/skills/cratis-security-review/**"
6
+ - ".cratis/ai/skills/cratis-performance-review/**"
7
+ - ".cratis/ai/agents/**"
8
+ - ".cratis/ai/prompts/**"
9
+ ---
10
+
11
+ <!-- Copyright (c) Cratis. All rights reserved. -->
12
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
13
+
14
+ # Shared review reports
15
+
16
+ Use this report shape for code, security, performance, and repository-investigation
17
+ reviews. Domain-specific risk labels refine findings, not the report or verdict
18
+ vocabulary. Review the change within the declared scope, not unrelated existing debt.
19
+
20
+ ## Report shape
21
+
22
+ Keep these sections in order, writing `None` when a section has no entries:
23
+
24
+ - **Blockers** — findings that must be fixed before merge. Each names a file and
25
+ line or evidence reference, the problem, its concrete consequence, and a proposed
26
+ correction. A blocker names a consequence, not a rule number: "returns HTTP 500
27
+ instead of a validation error" explains harm; "violates rule 4" does not.
28
+ - **Suggestions** — non-blocking improvements, with their benefit and any relevant
29
+ conditions. Do not turn a preference or a hypothetical risk into a merge gate.
30
+ - **Dismissed (with reason)** — candidate findings considered and rejected, each
31
+ with the evidence or reasoning for dismissal so another reviewer need not raise
32
+ it again. Do not invent candidates to populate this section.
33
+ - **Verdict** — one of the values below, scoped to the evidence actually examined.
34
+
35
+ An empty Blockers section is a valid, complete review. Never manufacture a finding
36
+ to make a review look useful. Reserve **[BLOCKING]** exclusively for
37
+ must-fix-before-merge findings; suggestions and dismissed findings never carry it.
38
+
39
+ Every review includes a **Not examined:** line naming the paths, surfaces, checks,
40
+ and axes not examined, including anything that could not be reached. Name what was
41
+ not measured: code-shape inspection is not a benchmark, a build is not behavioral
42
+ proof, and an unexamined surface is not verified. State `None` only when the entire
43
+ declared scope was examined; otherwise give concrete limits and remaining checks.
44
+
45
+ ## Verdict vocabulary
46
+
47
+ | Verdict | Meaning |
48
+ | --- | --- |
49
+ | **Approved** | No blockers or suggestions within the examined scope; required review checks are complete. |
50
+ | **Approved with suggestions** | No blockers; non-blocking suggestions remain and required review checks are complete. |
51
+ | **Changes requested** | At least one blocker must be corrected before merge. |
52
+ | **Incomplete** | No confirmed blocker, but missing or inconclusive required evidence prevents approval. |
53
+
54
+ Skipped optional axes belong on the Not examined line and do not alone prevent a
55
+ scoped approval. Missing required evidence does. When blockers and evidence gaps
56
+ coexist, use Changes requested and record the gaps on the Not examined line; never
57
+ reinterpret a failed or blocked gate as passing.
58
+
59
+ When combining reviews, retain one report per reviewer with the shared sections
60
+ and scope line, then give one combined verdict. Any blocker means Changes requested;
61
+ otherwise any Incomplete review means Incomplete; otherwise any remaining suggestion
62
+ means Approved with suggestions; otherwise use Approved. Do not drop dismissals or
63
+ scope limits when combining reports.
64
+
65
+ When a workflow requires a typed review envelope, preserve its schema and express
66
+ these sections, verdict meanings, and scope limits through its existing fields.
67
+ Do not append a competing Markdown report or invent envelope fields.
@@ -169,28 +169,13 @@ degradations a reviewer can see without measuring:
169
169
 
170
170
  ## Step 7 — Report
171
171
 
172
- Open with one line:
172
+ Read and use `.cratis/ai/rules/review-reports.md` when writing the report.
173
173
 
174
- > **Review result: Approved / Approved with comments / Changes requested**
175
-
176
- Then, per file:
177
-
178
- ```
179
- ### <file path>
180
-
181
- **[BLOCKING]** Line N: `problematic code`
182
- Because: <the consequence, not the rule number>
183
- Fix:
184
- <corrected code>
185
- ```
186
-
187
- Close with what passed and what must change. Two rules make the report usable:
188
-
189
- - **A blocking finding names a consequence.** "Violates the style guide" is not
190
- a reason. "Throws on a recoverable path, so the caller sees a 500 instead of a
191
- validation error" is.
192
- - **Say what you did not review.** A report listing only findings reads as if
193
- everything was checked. Name the files, the paths, and the axes you skipped.
174
+ Correctness regressions, broken contracts, and missing specification coverage
175
+ that leaves changed behavior unverified belong in Blockers when they require
176
+ correction before merge. Style preferences and maintainability improvements
177
+ without such a consequence belong in Suggestions. Apply the shared verdict
178
+ vocabulary to those findings.
194
179
 
195
180
  ## What breaks
196
181
 
@@ -0,0 +1,10 @@
1
+ {
2
+ "skill": "cratis-code-review",
3
+ "input": "Report a code review with no blockers and one non-blocking maintainability suggestion.",
4
+ "fixtures": [],
5
+ "assertions": [
6
+ { "kind": "skill-contains", "value": ".cratis/ai/rules/review-reports.md" },
7
+ { "kind": "skill-contains", "value": "Correctness regressions, broken contracts" },
8
+ { "kind": "skill-contains", "value": "Style preferences and maintainability improvements" }
9
+ ]
10
+ }
@@ -121,25 +121,23 @@ behavior this file does not already state.
121
121
 
122
122
  ## Step 6 — Report
123
123
 
124
- Open with one line:
124
+ Read and use `.cratis/ai/rules/review-reports.md` when writing the report.
125
+ Keep the performance risk label on each finding:
125
126
 
126
- > **Performance review: No issues / Minor findings / Blocking issues found**
127
-
128
- Group findings by the section that produced them, and classify each:
129
-
130
- | Risk | Meaning |
127
+ | Risk | Shared classification |
131
128
  | --- | --- |
132
- | **High** | Measurable degradation at moderate load — fix before merge |
133
- | **Medium** | Degrades under load or as data grows |
134
- | **Low** | Minor inefficiency |
129
+ | **High** | Blockers: degradation at moderate load requiring correction before merge |
130
+ | **Medium** | Suggestions: degradation under load or as data grows |
131
+ | **Low** | Suggestions: minor inefficiency |
135
132
 
136
- Close with a per-section summary table.
133
+ Use the shared verdict vocabulary, not a separate performance verdict. If a
134
+ scale-dependent degradation must be corrected before merge, classify it as High
135
+ and state the relevant scale rather than leaving a blocker under Medium.
137
136
 
138
137
  **Say what the finding costs and at what scale.** "This is slow" is not
139
138
  actionable; "this scans the whole collection on every page load, so it is fine
140
- at hundreds of rows and not at tens of thousands" is. And **name what you did
141
- not measure** — a review of code shape is not a benchmark, and reporting it as
142
- one overstates the evidence.
139
+ at hundreds of rows and not at tens of thousands" is. Distinguish measured cost
140
+ from code-shape inference; use the shared scope line to name unmeasured behavior.
143
141
 
144
142
  ## What breaks
145
143
 
@@ -0,0 +1,12 @@
1
+ {
2
+ "skill": "cratis-performance-review",
3
+ "input": "Report performance risks from code inspection without presenting unmeasured cost as a benchmark.",
4
+ "fixtures": [],
5
+ "assertions": [
6
+ { "kind": "skill-contains", "value": ".cratis/ai/rules/review-reports.md" },
7
+ { "kind": "skill-contains", "value": "**High** | Blockers:" },
8
+ { "kind": "skill-contains", "value": "**Medium** | Suggestions:" },
9
+ { "kind": "skill-contains", "value": "**Low** | Suggestions:" },
10
+ { "kind": "skill-contains", "value": "Distinguish measured cost" }
11
+ ]
12
+ }
@@ -11,24 +11,23 @@ Read [preferred syntax](../cratis-screenplay-toolchain/references/preferred-synt
11
11
  Prefer the Screenplay MCP tools to text/regex edits: the compiler owns declaration,
12
12
  reference, hierarchy and source evidence for the declarative document set.
13
13
 
14
- Screenplay remains experimental. **Valid source is not necessarily executable.**
15
- It does not generate or run an application; Stage owns rendering/runtime admission.
16
- When selecting construct syntax or distinguishing source validity from execution, read the [language reference](references/language-reference.md) for constructs,
17
- the executable profile and a complete compiled model.
14
+ **Valid source is not necessarily executable.** Stage owns rendering/runtime
15
+ admission. Read the [language reference](references/language-reference.md) for
16
+ construct syntax, source-versus-execution states and a complete compiled model.
18
17
 
19
- For screens: discover UI schemas, propose/apply with revisions, then pass the
20
- same model root or workspace export to all checks. Workflow:
21
- `references/screen-authoring-workflow.md`; syntax/support:
22
- `cratis-screenplay-ui-composition`.
18
+ For screens, read `references/screen-authoring-workflow.md`; use the
19
+ same model root or workspace export for all checks. Syntax: `cratis-screenplay-ui-composition`.
23
20
 
24
21
  Record open modeling questions as `question` notes in committed
25
22
  `.screenplay/notes.json`, not chat or `description` text. Never put secrets or
26
23
  personal data in notes. Read [model notes](references/model-notes.md) when
27
24
  listing, recording or resolving questions: `list-model-notes`,
28
25
  `propose-model-notes`, `read-proposal view=notes`, refs and orphan review.
29
- Prefer dotted split-model targets; inspect `substitutions`, also for reanchor,
30
- and disclose broader owners. The reference covers typed `parts` targets from
31
- `open-workspace.applicationIdentity`.
26
+ Application, Module, Feature and Slice notes anchor before binding; members
27
+ still need binding and otherwise substitute their own slice. Inspect
28
+ `containerIdentities` in `open-workspace` / `workspace-state` for missing or
29
+ ambiguous identities; fix parse/placement errors first. Read the notes reference
30
+ for refusals, `ambiguous: true`, typed targets and every `substitutions` entry.
32
31
 
33
32
  ## Choosing a strategy
34
33
 
@@ -61,8 +60,8 @@ explanatory Markdown belongs in repository documentation.
61
60
  is owned by the Cratis CLI, which preserves other servers and user configuration.
62
61
 
63
62
  The CLI-bundled MCP can be older than the standalone tool: discover schemas.
64
- Read [MCP loop](references/mcp-loop.md) for launch options. Use the supported
65
- channel, not another global tool, Docker or copied managed configuration.
63
+ Read [MCP loop](references/mcp-loop.md) for supported launch channels; do not
64
+ substitute a global tool, Docker or copied managed configuration.
66
65
 
67
66
  If MCP is unavailable, report it; regex edits are not compiler-validated AST
68
67
  editing. Existing standalone `screenplay mcp` users may retain that entry point.
@@ -93,9 +92,8 @@ editing. Existing standalone `screenplay mcp` users may retain that entry point.
93
92
  outlet declarations that provide context. A component binding with no traced
94
93
  data source is not a shortcut; fix the model source.
95
94
 
96
- Keep reads scoped to the relevant module, feature, slice or document. Do not
97
- request a whole merged AST when a bounded declaration/property query answers the
98
- question. Size-limit refusals require narrower reads, not truncation.
95
+ Scope reads to the relevant container/document, not the whole merged AST.
96
+ Size-limit refusals require narrower reads, not truncation.
99
97
 
100
98
  ## Application modes and described handler intent
101
99
 
@@ -111,11 +109,10 @@ Read [comparison sources](references/mcp-tools.md#semantic-revision-comparison)
111
109
 
112
110
  ## Make one coherent proposal
113
111
 
114
- **One edit strategy.** Discover what the server offers. Prefer typed,
115
- identity-preserving operations (`propose-rename`, `propose-repair`,
116
- `propose-extract-inline-event`, `propose-ast`). A bounded text edit is fine only for
117
- edits that leave catalog addresses unchanged (descriptions, rule and expression bodies, mappings
118
- between existing members), never a way around an MCP refusal. When `.screenplay/identities.json`
112
+ **One edit strategy.** Prefer discovered identity-preserving operations
113
+ (`propose-rename`, `propose-repair`, `propose-extract-inline-event`, `propose-ast`).
114
+ Bounded text edits must leave catalog addresses unchanged (descriptions, rule
115
+ bodies, existing-member mappings), never a way around an MCP refusal. When `.screenplay/identities.json`
119
116
  exists, adding, removing or renaming a declaration, command or read-model property, query,
120
117
  query argument or specification goes through MCP, and an `id` pin is not enough for a rename or move. A request naming
121
118
  a rename, move or removal is the approval: do not ask again at `apply`. Without MCP, text-rename
@@ -131,9 +128,10 @@ Others send an edit request ([MCP loop](references/mcp-loop.md)).
131
128
  identity state. `read-workspace` locates document identities.
132
129
  2. `read-ast` returns original occurrence handles and existing semantic IDs.
133
130
  Query `syntax-schema` for exact node members before constructing typed input.
134
- 3. Prefer `propose-rename` for supported logical renames: it coordinates fragments,
135
- repairs proven references and preserves assigned identities. Never substitute
136
- global string replacement for an explicit refusal.
131
+ 3. Prefer `propose-rename` and `propose-move`: they carry identities and notes
132
+ even on unbound models. Manual `propose-ast` / `propose-source` renames need
133
+ `semanticRenames`; removal needs retirement and reports `orphanedNotes`.
134
+ Never substitute global string replacement for an explicit refusal.
137
135
  4. Prefer `propose-property` for property add/rename/remove, not hand-composed
138
136
  `propose-ast` batches. Inspect the chain and never guess past a refusal:
139
137
  [property links](references/property-links.md). Otherwise use `propose-source`
@@ -152,20 +150,17 @@ Others send an edit request ([MCP loop](references/mcp-loop.md)).
152
150
  identity-state change through `workspace-state`. Review `orphanedNotes` on
153
151
  source proposals; reanchor or resolve affected questions before applying
154
152
  ([notes and orphan impact](references/model-notes.md#source-proposals-can-orphan-notes)).
155
- 7. Run `run-specifications` with `proposalId` before applying. Record V4 separately: PLAY0285
156
- (impossible `then`) unbinds the whole model. Paging and read-only candidate semantics:
157
- [MCP tool guide](references/mcp-tools.md#run-reference-specifications).
158
-
159
- Requires Screenplay 4.145.0 or later (`screenplay --version`) for `proposalId`; earlier servers run only the current workspace.
153
+ 7. Run `run-specifications` with `proposalId` before applying; record V4 separately.
154
+ PLAY0285 unbinds the whole model. Read the [MCP tool guide](references/mcp-tools.md#run-reference-specifications)
155
+ for candidate paging and the required version.
160
156
  8. `apply` only the reviewed server-produced proposal within the user's requested
161
157
  change. The proposal ID and before revisions are required; stale state rejects.
162
- When the user already requested apply, do it after checks without asking again;
163
- otherwise show the proposal and ask once.
158
+ Apply after checks if requested; otherwise show the proposal and ask once.
164
159
  9. When the host draws views, `visualize-model` shows the board. It follows the files
165
160
  on disk while open, so after an apply do not re-request it; just say what changed.
166
161
 
167
- Handles are revision-bound occurrences, not durable IDs. Modules/features can
168
- span fragments; one header edit may not change all. After apply, fetch fresh handles/revisions.
162
+ Handles are revision-bound, not durable IDs. Modules/features span fragments;
163
+ after apply fetch fresh handles/revisions.
169
164
 
170
165
  On refusal, use `failureKind`, never message text ([failures/limits](references/mcp-loop.md#failures-use-failurekind-never-message-text)).
171
166
  After revision/disk/identity drift, reopen and re-propose. For `ApplyOutcomeUnknown`
@@ -188,6 +183,8 @@ Use `recommend-layout` for options and review an `expand-layout` proposal; layou
188
183
 
189
184
  ## Preserve state and recover explicitly
190
185
 
186
+ Fix binding errors through MCP proposals, not outside MCP: reopening after an
187
+ external fix can require reconciliation of a persisted partial catalog.
191
188
  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.
192
189
 
193
190
  ## Code attachments
@@ -199,8 +196,8 @@ are not behavioral evidence.
199
196
 
200
197
  ## Verify and report honestly
201
198
 
202
- - Require zero source errors and investigate every warning.
203
- - Confirm reference safety, identity continuity and exact intended source changes.
199
+ - Require zero source errors; investigate warnings, reference safety, identity
200
+ continuity and exact intended changes.
204
201
  - Report which of the four states you checked: **parsed**, **bound**,
205
202
  **reference-executed**, **target-executed**. When distinguishing source validity from execution, read the
206
203
  [language reference](references/language-reference.md#source-validity-is-not-execution);
@@ -209,9 +206,8 @@ are not behavioral evidence.
209
206
  clean run is not a bound or executable result.
210
207
  - 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.
211
208
 
212
- - Distinguish authoring acceptance from `executableReady`; unsupported backend
213
- capabilities are not a reason to drop source constructs or invent stubs.
214
- - If execution is intended, validate with the owning downstream runtime as well.
209
+ - Unsupported capabilities never justify dropping constructs or inventing stubs.
210
+ Validate intended execution with the owning downstream runtime.
215
211
  - Model rejection cases as specifications; assertion presence is not execution.
216
212
  - Check installed `tools/list`/schemas rather than assuming a remembered tool count.
217
213
 
@@ -221,9 +217,9 @@ The ordinary CLI remains useful for whole-folder validation:
221
217
  cratis screenplay validate <model-folder> --warnings-as-errors
222
218
  ```
223
219
 
224
- Record screen MCP transcripts in `.ai-work/`; render/runtime checks must use the
225
- same source, never an app that silently drops authored UI. Use the Screenplay-owned canonical
226
- corpus fixture path instead of copying available `.play` fixtures here.
220
+ Keep screen transcripts in `.ai-work/`; check the same source, never an app that
221
+ silently drops authored UI. Use the Screenplay-owned canonical
222
+ corpus fixture path instead of copying fixtures here.
227
223
 
228
224
  Never invent syntax or capabilities.
229
225
 
@@ -235,10 +231,10 @@ Never invent syntax or capabilities.
235
231
  | Commands, events, validation and concurrency | `cratis-screenplay-command-surface` |
236
232
  | Projections and reducers | `cratis-screenplay-projections` |
237
233
  | Read models, queries and screens | `cratis-screenplay-read-surface` |
238
- | Layouts, forms, contributions, navigation regions, slice buttons, template references, sample data, component bindings, toolbars, outlets, themes and localization | `cratis-screenplay-ui-composition` |
234
+ | UI composition, bindings, navigation and themes | `cratis-screenplay-ui-composition` |
239
235
  | Captures, reactions and triggers | `cratis-screenplay-captures-and-reactions` |
240
236
  | Behavioral examples and assertions | `cratis-screenplay-specifications` |
241
237
  | Rendering/running an admitted model | `cratis-stage-rendering-and-sandbox` |
242
- | Lifecycle, verdicts V1 to V5 and the model-first decision | `cratis-screenplay-modeling-lifecycle` |
243
- | Compiler, CLI and MCP versions, diagnostics, capability tables | `cratis-screenplay-toolchain` |
238
+ | Lifecycle and model-first decision | `cratis-screenplay-modeling-lifecycle` |
239
+ | Compiler, CLI, MCP and diagnostics | `cratis-screenplay-toolchain` |
244
240
  | Event-model diagrams rather than .play source | `cratis-event-model-diagram` |
@@ -281,9 +281,14 @@ Requires Screenplay 4.89.0 or later (`screenplay --version`) for `identityMigrat
281
281
 
282
282
  ## Identity state (`.screenplay/identities.json`)
283
283
 
284
- - `apply` persists identities with the `.play` changes (probed: the file survives
285
- restarts without `export-workspace`). `open-workspace` and read-only commands
286
- never create it. Commit both.
284
+ - `apply` persists identities with source or notes-only changes; they survive
285
+ restarts without `export-workspace`. `open-workspace` and read-only commands
286
+ never create the file. Commit identity state with the model and notes.
287
+ - Containers anchor before binding when all documents parse and place; inspect
288
+ `containerIdentities` in `open-workspace` / `workspace-state`. Fix binding
289
+ through MCP proposals, not external edits after persisting a partial catalog.
290
+ Read [state and recovery](state-and-recovery.md) for the exact unbound reopen
291
+ exception and [model notes](model-notes.md) for targeting refusal reasons.
287
292
  - A model only ever edited as text has **no persisted identities** until the first
288
293
  `apply`. Whether a first apply is the intended initialization is not documented
289
294
  beyond "after the first apply, keep `.screenplay/identities.json`"; ask before
@@ -127,6 +127,32 @@ A folder is one application; a file selects only itself and its imports.
127
127
 
128
128
  ## Whole-source authoring
129
129
 
130
+ Application notes already anchor before binding; Module, Feature and Slice
131
+ identities materialize from the authoring hierarchy when every document parses
132
+ and places. Binding keeps those IDs. Read `containerIdentities` in
133
+ `open-workspace` / `workspace-state`: `complete`, `containers` (`address`,
134
+ `reason`, `assigned`) and `documents` (`path`, `reason`). Reasons are `ambiguous`,
135
+ `idCollision`, `incomplete`, `unparsed` and `unplaced`; incomplete documents stop
136
+ all new assignments, not just their own. Fix parse/placement errors first.
137
+ Notes tools refuse unavailable targets and descendants with the same reasons in
138
+ all forms. Existing notes on ambiguous containers remain resolved with
139
+ `ambiguous: true`; inspect them unfiltered or by existing `semanticId`.
140
+ Unidentified members still need binding and substitute their own slice in
141
+ `substitutions`, never silently promote to a feature/module. Details:
142
+ [model notes](model-notes.md#anchors-and-independent-state).
143
+
144
+ Requires Screenplay 4.213.0 (`screenplay --version`) for pre-binding container
145
+ identities and reporting; upgrade older servers before relying on direct
146
+ container anchoring.
147
+
148
+ `propose-rename` and `propose-move` preserve assigned container identities and
149
+ notes on unbound models, including before first binding. Manual `propose-ast` /
150
+ `propose-source` renames need `semanticRenames`, removals need
151
+ `retiredSemanticAddresses` and report `orphanedNotes`. Fix binding errors through
152
+ MCP proposals so reopening does not require reconciliation after an external fix.
153
+ Opening computes identities in memory only; even notes-only `apply` can persist
154
+ them with notes under the same rollback journal.
155
+
130
156
  `propose-source` takes `expectedRevision`, `expectedCatalogRevision`, explicit
131
157
  `formatting` and `documents`. Default `validation: "Authoring"` accepts syntax-only
132
158
  models; `"Executable"` requires binding and never falls back. Default
@@ -63,11 +63,38 @@ a Module (replace the Application key with that response's value):
63
63
  }
64
64
  ```
65
65
 
66
- A typed address needs an existing catalog identity; it refuses when none exists.
67
- Use the construct's current source handle instead. A target without an identity
68
- lands on the nearest identified slice, feature, module or application. On an
69
- unbound model, even a Slice can lack an identity and fall back to Application;
70
- opening the workspace does not guarantee container identities.
66
+ Application notes anchor as `{ application: true }` before binding. Modules,
67
+ nested Features and Slices gain deterministic catalog identities from the
68
+ authoring hierarchy before the model binds, provided every document parses and
69
+ places. Dotted, typed and source-handle targets anchor directly to those
70
+ containers without substitution. Binding preserves their existing IDs and
71
+ origins; never calculate an ID client-side.
72
+
73
+ Commands, events, read models, projections, queries, specifications, reactions,
74
+ captures and properties still need a bound model for their own identities. Until
75
+ then, their notes land on their own slice, not the feature or module, and are
76
+ reported in `substitutions`. Name the intended member in the text.
77
+
78
+ Requires Screenplay 4.213.0 (`screenplay --version`) for pre-binding container
79
+ identities and identity-problem reporting. Older servers can broaden container
80
+ notes to an identified ancestor; upgrade before relying on direct anchoring.
81
+
82
+ Inspect `containerIdentities` from `open-workspace` and `workspace-state` when
83
+ identities are missing. It contains `complete`, `containers` entries with
84
+ `address`, `reason`, `assigned`, and `documents` entries with `path`, `reason`.
85
+ Container reasons are `ambiguous`, `idCollision` or `incomplete`; document reasons
86
+ are `unparsed` or `unplaced`. Fix parse and import-placement errors first:
87
+ **no new identities are assigned anywhere** until every document parses and
88
+ places, even in otherwise valid documents. Existing assignments are retained.
89
+ Unavailable containers and descendants refuse new note targeting with the same
90
+ reason in every form, including semantic-ID anchors; do not bypass a refusal by
91
+ requesting a broader owner. Repeated Module/Feature fragments count as one logical
92
+ declaration; duplicate Slices do not.
93
+
94
+ A container duplicated outside MCP keeps its identity and notes. Existing notes
95
+ on it or its descendants stay resolved with `ambiguous: true`, not orphaned.
96
+ Read them unfiltered or by their existing `semanticId`; new targeting on the
97
+ ambiguous container or its descendants is refused.
71
98
 
72
99
  Always inspect `substitutions` for both `add` and `reanchor`, even when reanchor
73
100
  leaves the note unchanged. Each entry has the requested `target`, resolved
@@ -82,8 +109,12 @@ reporting. Older servers can refuse split targets, omit that field or silently
82
109
  broaden the anchor; use a catalog address/current handle and inspect the notes
83
110
  review's actual anchor, or upgrade before relying on these responses.
84
111
 
85
- Notes do not change source, workspace/catalog/semantic revisions, executable
86
- model bytes or compiler verdicts. Their own `notesRevision` is `nrev1:` plus the
112
+ Notes do not change source, executable model bytes or compiler verdicts.
113
+ Opening or proposing an unbound workspace can materialize container assignments
114
+ in memory and advance its catalog revision. Opening never writes them; a
115
+ notes-only `apply` can persist them in `.screenplay/identities.json` under the
116
+ same journal as the sidecar. Rollback restores both the notes and exact earlier
117
+ identity state. Notes retain an independent revision; their `notesRevision` is `nrev1:` plus the
87
118
  lowercase SHA-256 of canonical bytes; `nrev1:absent` is not an empty document.
88
119
  The file header uses `schema: "cratis.screenplay.notes"`, `schemaVersion: 1` and
89
120
  `applicationIdentity` in the catalog's representation. The server writes stable
@@ -205,12 +236,27 @@ stops being adequate.
205
236
 
206
237
  ## Source proposals can orphan notes
207
238
 
239
+ Prefer `propose-rename` and `propose-move`: identities and notes follow containers
240
+ on unbound models as on bound ones, including before their first binding. A
241
+ manual `propose-ast` or `propose-source` rename needs explicit `semanticRenames`;
242
+ removal needs `retiredSemanticAddresses`. Retirement is not a substitute for a
243
+ rename when continuity is intended.
244
+
245
+ Fix binding errors through MCP proposals. After a partial catalog is persisted,
246
+ fixing binding outside MCP can add bound identities on reopen and require
247
+ reconciliation; never discard state to bypass it.
248
+
208
249
  Review `orphanedNotes` IDs and `notes` status/reason/count on source, AST, rename,
209
250
  move and property proposals and their reviews. Retirement leaves a computed
210
251
  orphan with null current address and `orphanReason: "unknown"`; notes are never
211
252
  silently deleted. `orphanedNotes: null` with unreadable notes means unknown
212
253
  impact, not `[]`.
213
254
 
255
+ Re-adding a retired address recreates its deterministic identity only when source
256
+ is complete and unambiguous. Orphaned notes resolve again only for their exact
257
+ former ID. An identity previously carried there by rename or assigned externally
258
+ may differ; explicitly reanchor those notes.
259
+
214
260
  Before applying a source proposal, review each affected question: reanchor to a
215
261
  surviving element, or resolve with evidence and deliberately decide whether to
216
262
  retain its orphaned history. Resolution alone does not restore an anchor. Remove
@@ -10,6 +10,28 @@ Commit `.screenplay/identities.json` with the model. Only `apply` writes it;
10
10
  overwrite conflicting identity state, silently mint IDs on restart, or text-rename
11
11
  identity-affecting declarations in a model that has it.
12
12
 
13
+ An unbound workspace materializes collision-free deterministic Module, Feature
14
+ and Slice identities in memory when every document parses and places. Application
15
+ notes already anchor before binding. Opening never writes state; `apply`,
16
+ including a notes-only apply, persists these assignments. Binding preserves their
17
+ IDs and origins, and rename/move proposals carry identities and notes before
18
+ first binding. Read `containerIdentities` from `open-workspace` / `workspace-state`
19
+ and the [notes guidance](model-notes.md#anchors-and-independent-state) for
20
+ ambiguity, collision and incomplete-source refusals.
21
+
22
+ Reopening persisted unbound state admits only deterministic container additions:
23
+ every document must parse and place; every previous assignment must still be
24
+ present in source; earlier IDs, origins, event revisions, document mappings and
25
+ application metadata must be unchanged. Other drift still requires reconciliation.
26
+ A supplied `workspaceJson` cannot replace different persisted identity authority.
27
+ Fix binding errors through MCP proposals: an external fix after a partial catalog
28
+ was persisted can add bound identities on reopen and require reconciliation.
29
+ Never delete state to bypass that refusal.
30
+
31
+ A notes apply journals the sidecar and any new container identities together;
32
+ rollback restores exact earlier identity bytes as well as notes, including an
33
+ earlier catalog without those containers.
34
+
13
35
  Default root discovery preserves ancestor identity state and journals. Inspect
14
36
  `rootBindingConflict` in `open-workspace`/`workspace-state` when several state roots
15
37
  compete; do not delete state or mint replacement identities. To recover a competing
@@ -40,7 +40,23 @@
40
40
  { "kind": "skill-contains", "value": "`applicationIdentity` returned by `open-workspace`", "file": "references/model-notes.md" },
41
41
  { "kind": "skill-contains", "value": "Repeated Module/Feature headers", "file": "references/model-notes.md" },
42
42
  { "kind": "skill-contains", "value": "Always inspect `substitutions` for both `add` and `reanchor`", "file": "references/model-notes.md" },
43
- { "kind": "skill-contains", "value": "even a Slice can lack an identity", "file": "references/model-notes.md" },
43
+ { "kind": "skill-contains", "value": "before the model binds", "file": "references/model-notes.md" },
44
+ { "kind": "skill-contains", "value": "Application, Module, Feature and Slice notes anchor before binding" },
45
+ { "kind": "skill-contains", "value": "Binding preserves their existing IDs and", "file": "references/model-notes.md" },
46
+ { "kind": "skill-contains", "value": "their notes land on their own slice, not the feature or module", "file": "references/model-notes.md" },
47
+ { "kind": "skill-contains", "value": "`containerIdentities`", "file": "references/mcp-tools.md" },
48
+ { "kind": "skill-contains", "value": "`ambiguous`, `idCollision` or `incomplete`", "file": "references/model-notes.md" },
49
+ { "kind": "skill-contains", "value": "`unparsed` or `unplaced`", "file": "references/model-notes.md" },
50
+ { "kind": "skill-contains", "value": "**no new identities are assigned anywhere**", "file": "references/model-notes.md" },
51
+ { "kind": "skill-contains", "value": "reason in every form, including semantic-ID anchors", "file": "references/model-notes.md" },
52
+ { "kind": "skill-contains", "value": "stay resolved with `ambiguous: true`, not orphaned", "file": "references/model-notes.md" },
53
+ { "kind": "skill-contains", "value": "notes on unbound models, including before first binding", "file": "references/mcp-tools.md" },
54
+ { "kind": "skill-contains", "value": "`semanticRenames`", "file": "references/model-notes.md" },
55
+ { "kind": "skill-contains", "value": "`retiredSemanticAddresses`", "file": "references/model-notes.md" },
56
+ { "kind": "skill-contains", "value": "Fix binding errors through MCP proposals", "file": "references/model-notes.md" },
57
+ { "kind": "skill-contains", "value": "rollback restores exact earlier identity bytes as well as notes", "file": "references/state-and-recovery.md" },
58
+ { "kind": "skill-contains", "value": "Orphaned notes resolve again only for their exact", "file": "references/model-notes.md" },
59
+ { "kind": "skill-contains", "value": "Requires Screenplay 4.213.0", "file": "references/model-notes.md" },
44
60
  { "kind": "skill-contains", "value": "older servers miss the read-only denial for SPEC004 and count it for SPEC006", "file": "references/mcp-tools.md" },
45
61
  { "kind": "skill-contains", "value": "`anchor`", "file": "references/model-notes.md" },
46
62
  { "kind": "skill-contains", "value": "`scope`", "file": "references/model-notes.md" },
@@ -129,21 +129,18 @@ command's properties as well as grepping them.
129
129
 
130
130
  ## Step 7 — Report
131
131
 
132
- Open with one line:
132
+ Read and use `.cratis/ai/rules/review-reports.md` when writing the report.
133
+ Keep the security risk label on each finding:
133
134
 
134
- > **Security review: No issues / Low-risk findings / Blocking issues found**
135
-
136
- Group findings by the section that produced them, and classify each:
137
-
138
- | Risk | Meaning |
135
+ | Risk | Shared classification |
139
136
  | --- | --- |
140
- | **Critical** | Must be fixed before merge |
141
- | **Medium** | Should be fixed soon; state what makes it not-critical |
142
- | **Low** | Fix when convenient |
137
+ | **Critical** | Blockers: exploitable exposure requiring correction before merge |
138
+ | **Medium** | Suggestions: conditional exposure; state what makes it non-critical |
139
+ | **Low** | Suggestions: defense-in-depth improvement |
143
140
 
144
- Close with a per-section summary table, and **name what you did not review** —
145
- the paths, the surfaces, and the axes out of scope. A security report listing
146
- only findings reads as a clean bill of health for everything it never opened.
141
+ Use the shared verdict vocabulary, not a separate security verdict. If a
142
+ conditional exposure must be corrected before merge, classify it as Critical
143
+ and explain the exploit conditions rather than leaving a blocker under Medium.
147
144
 
148
145
  ## What breaks
149
146
 
@@ -0,0 +1,11 @@
1
+ {
2
+ "skill": "cratis-security-review",
3
+ "input": "Report security risks using the shared report and distinguish conditional exposure from a merge blocker.",
4
+ "fixtures": [],
5
+ "assertions": [
6
+ { "kind": "skill-contains", "value": ".cratis/ai/rules/review-reports.md" },
7
+ { "kind": "skill-contains", "value": "**Critical** | Blockers:" },
8
+ { "kind": "skill-contains", "value": "**Medium** | Suggestions:" },
9
+ { "kind": "skill-contains", "value": "**Low** | Suggestions:" }
10
+ ]
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/pi",
3
- "version": "7.78.0",
3
+ "version": "7.80.0",
4
4
  "description": "Configuration-aware Cratis AI integration for Pi",
5
5
  "type": "module",
6
6
  "files": [