@bendyline/gilde 0.1.17 → 0.1.19

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 (160) hide show
  1. package/README.md +11 -2
  2. package/authoring/chat-models/README.md +26 -0
  3. package/authoring/chat-models/btl4-35b-q4.json +142 -0
  4. package/authoring/chat-models/btl4-compact-iq2.json +142 -0
  5. package/authoring/chat-models/deepseek-r1-8b-q4.json +53 -0
  6. package/authoring/chat-models/deepseek-v4-flash-284b-mxfp4.json +110 -0
  7. package/authoring/chat-models/deepseek-v4-flash-284b-q2.json +110 -0
  8. package/authoring/chat-models/deepseek-v4-flash-284b-q2q4.json +111 -0
  9. package/authoring/chat-models/deepseek-v4-flash-284b-q4.json +113 -0
  10. package/authoring/chat-models/gemma4-12b-q4.json +190 -0
  11. package/authoring/chat-models/gemma4-12b-q8.json +164 -0
  12. package/authoring/chat-models/gemma4-26b-q4.json +90 -0
  13. package/authoring/chat-models/gemma4-31b-q4.json +81 -0
  14. package/authoring/chat-models/gemma4-e2b-q4.json +76 -0
  15. package/authoring/chat-models/gemma4-e4b-q4.json +71 -0
  16. package/authoring/chat-models/glm-5.2-754b-q2.json +60 -0
  17. package/authoring/chat-models/gpt-oss-120b-q4.json +48 -0
  18. package/authoring/chat-models/gpt-oss-20b-q4.json +47 -0
  19. package/authoring/chat-models/laguna-s-2.1-118b-q4.json +127 -0
  20. package/authoring/chat-models/laguna-s-2.1-118b-q6.json +121 -0
  21. package/authoring/chat-models/laguna-s-2.1-118b-q8.json +127 -0
  22. package/authoring/chat-models/lfm2.5-2.6b-q4.json +39 -0
  23. package/authoring/chat-models/llama3.2-3b-q4.json +42 -0
  24. package/authoring/chat-models/mistral-7b-q4.json +53 -0
  25. package/authoring/chat-models/mistral-medium-3.5-128b-q4.json +57 -0
  26. package/authoring/chat-models/muse-glimmer-30b-q4.json +126 -0
  27. package/authoring/chat-models/nemotron3-nano-30b-q4.json +49 -0
  28. package/authoring/chat-models/nemotron3-super-120b-q4.json +41 -0
  29. package/authoring/chat-models/ornith-35b-q4.json +145 -0
  30. package/authoring/chat-models/ornith-35b-q8.json +145 -0
  31. package/authoring/chat-models/ornith-9b-q4.json +146 -0
  32. package/authoring/chat-models/qwen3.5-122b-a10b-q4.json +172 -0
  33. package/authoring/chat-models/qwen3.5-2b-q4.json +70 -0
  34. package/authoring/chat-models/qwen3.5-4b-q4.json +61 -0
  35. package/authoring/chat-models/qwen3.5-9b-q4.json +61 -0
  36. package/authoring/chat-models/qwen3.6-27b-q4.json +66 -0
  37. package/authoring/chat-models/qwen3.6-27b-q8.json +153 -0
  38. package/authoring/chat-models/qwen3.6-35b-a3b-q4.json +154 -0
  39. package/authoring/chat-models/qwen3.6-35b-a3b-q8.json +154 -0
  40. package/authoring/chat-models/talkie-1930-13b-q4.json +74 -0
  41. package/authoring/chat-models/ternary-bonsai-27b-q2.json +144 -0
  42. package/authoring/gstack/LICENSE.gstack +21 -0
  43. package/authoring/gstack/README.md +50 -0
  44. package/authoring/gstack/evals/cso.json +152 -0
  45. package/authoring/gstack/evals/design-consultation.json +201 -0
  46. package/authoring/gstack/evals/document-generate.json +174 -0
  47. package/authoring/gstack/evals/investigate.json +153 -0
  48. package/authoring/gstack/evals/office-hours.json +141 -0
  49. package/authoring/gstack/evals/plan-ceo-review.json +135 -0
  50. package/authoring/gstack/evals/qa-only.json +376 -0
  51. package/authoring/gstack/evals/retro.json +191 -0
  52. package/authoring/gstack/evals/spec.json +162 -0
  53. package/authoring/gstack/overlays/cso.json +132 -0
  54. package/authoring/gstack/overlays/design-consultation.json +153 -0
  55. package/authoring/gstack/overlays/document-generate.json +124 -0
  56. package/authoring/gstack/overlays/investigate.json +128 -0
  57. package/authoring/gstack/overlays/office-hours.json +119 -0
  58. package/authoring/gstack/overlays/plan-ceo-review.json +128 -0
  59. package/authoring/gstack/overlays/qa-only.json +145 -0
  60. package/authoring/gstack/overlays/retro.json +132 -0
  61. package/authoring/gstack/overlays/spec.json +140 -0
  62. package/authoring/gstack/persona-drafts/cso.about.md +9 -0
  63. package/authoring/gstack/persona-drafts/design-consultation.about.md +9 -0
  64. package/authoring/gstack/persona-drafts/office-hours.about.md +9 -0
  65. package/authoring/gstack/persona-drafts/qa-only.about.md +5 -0
  66. package/authoring/gstack/persona-drafts/spec.about.md +26 -0
  67. package/authoring/gstack/snapshots/cso/SKILL.md +1285 -0
  68. package/authoring/gstack/snapshots/design-consultation/SKILL.md +1230 -0
  69. package/authoring/gstack/snapshots/document-generate/SKILL.md +1252 -0
  70. package/authoring/gstack/snapshots/investigate/SKILL.md +1074 -0
  71. package/authoring/gstack/snapshots/office-hours/SKILL.md +1697 -0
  72. package/authoring/gstack/snapshots/plan-ceo-review/SKILL.md +1476 -0
  73. package/authoring/gstack/snapshots/qa-only/SKILL.md +1256 -0
  74. package/authoring/gstack/snapshots/retro/SKILL.md +1812 -0
  75. package/authoring/gstack/snapshots/spec/SKILL.md +2359 -0
  76. package/authoring/gstack/wave.json +103 -0
  77. package/data/chat-models/gl/glm-5.2-754b-q2/manifest.json +65 -0
  78. package/data/chat-models/gl/glm-5.2-754b-q2/versions/1.0.0/manifest.json +18 -0
  79. package/data/chat-models/gp/gpt-oss-120b-q4/manifest.json +5 -5
  80. package/data/chat-models/gp/gpt-oss-120b-q4/versions/1.1.0/manifest.json +135 -0
  81. package/data/chat-models/index.json +1 -1
  82. package/data/chat-models/mu/muse-glimmer-30b-q4/manifest.json +135 -0
  83. package/data/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.0/manifest.json +20 -0
  84. package/data/connector-types/gi/github-releases/manifest.json +17 -0
  85. package/data/connector-types/gi/github-releases/versions/1.0.0/manifest.json +71 -0
  86. package/data/connector-types/index.json +1 -1
  87. package/data/craftbook-templates/br/branding-website/versions/1.1.0/craftbook.json +190 -0
  88. package/data/craftbook-templates/br/branding-website/versions/1.1.0/test.json +164 -0
  89. package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.0/craftbook.json +358 -0
  90. package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.0/test.json +376 -0
  91. package/data/craftbook-templates/ca/careful-mode/versions/1.1.0/craftbook.json +43 -0
  92. package/data/craftbook-templates/ca/careful-mode/versions/1.1.0/test.json +110 -0
  93. package/data/craftbook-templates/ca/careful-mode/versions/1.2.0/craftbook.json +43 -0
  94. package/data/craftbook-templates/ca/careful-mode/versions/1.2.0/test.json +110 -0
  95. package/data/craftbook-templates/co/content-deck/versions/1.1.0/craftbook.json +185 -0
  96. package/data/craftbook-templates/co/content-deck/versions/1.1.0/test.json +166 -0
  97. package/data/craftbook-templates/co/content-deck/versions/1.2.0/craftbook.json +185 -0
  98. package/data/craftbook-templates/co/content-deck/versions/1.2.0/test.json +169 -0
  99. package/data/craftbook-templates/co/corpus-email-digest/versions/1.1.0/craftbook.json +189 -0
  100. package/data/craftbook-templates/co/corpus-email-digest/versions/1.1.0/test.json +182 -0
  101. package/data/craftbook-templates/co/corpus-email-digest/versions/1.2.0/craftbook.json +189 -0
  102. package/data/craftbook-templates/co/corpus-email-digest/versions/1.2.0/test.json +187 -0
  103. package/data/craftbook-templates/de/design-system-consultation/versions/2.0.0/craftbook.json +385 -0
  104. package/data/craftbook-templates/de/design-system-consultation/versions/2.0.0/test.json +201 -0
  105. package/data/craftbook-templates/en/engineering-retrospective/versions/2.0.0/craftbook.json +353 -0
  106. package/data/craftbook-templates/en/engineering-retrospective/versions/2.0.0/test.json +191 -0
  107. package/data/craftbook-templates/ex/executive-level-review/versions/2.0.0/craftbook.json +347 -0
  108. package/data/craftbook-templates/ex/executive-level-review/versions/2.0.0/test.json +135 -0
  109. package/data/craftbook-templates/fr/freeze-scope/versions/1.2.0/craftbook.json +50 -0
  110. package/data/craftbook-templates/fr/freeze-scope/versions/1.2.0/test.json +131 -0
  111. package/data/craftbook-templates/fr/freeze-scope/versions/1.3.0/craftbook.json +50 -0
  112. package/data/craftbook-templates/fr/freeze-scope/versions/1.3.0/test.json +131 -0
  113. package/data/craftbook-templates/ht/html-arcade-game/versions/1.1.0/craftbook.json +197 -0
  114. package/data/craftbook-templates/ht/html-arcade-game/versions/1.1.0/test.json +173 -0
  115. package/data/craftbook-templates/ht/html-arcade-game/versions/1.2.0/craftbook.json +197 -0
  116. package/data/craftbook-templates/ht/html-arcade-game/versions/1.2.0/test.json +176 -0
  117. package/data/craftbook-templates/id/idea-office-hours/versions/2.0.0/craftbook.json +333 -0
  118. package/data/craftbook-templates/id/idea-office-hours/versions/2.0.0/test.json +141 -0
  119. package/data/craftbook-templates/im/image-set-index/versions/1.1.0/craftbook.json +163 -0
  120. package/data/craftbook-templates/im/image-set-index/versions/1.1.0/test.json +177 -0
  121. package/data/craftbook-templates/im/image-set-index/versions/1.2.0/craftbook.json +163 -0
  122. package/data/craftbook-templates/im/image-set-index/versions/1.2.0/test.json +180 -0
  123. package/data/craftbook-templates/index.json +1 -1
  124. package/data/craftbook-templates/pu/pull-request-review/manifest.json +5 -1
  125. package/data/craftbook-templates/pu/pull-request-review/versions/1.2.0/craftbook.json +159 -0
  126. package/data/craftbook-templates/pu/pull-request-review/versions/1.2.0/test.json +172 -0
  127. package/data/craftbook-templates/re/release-artifact-sanity-check/art.json +13 -0
  128. package/data/craftbook-templates/re/release-artifact-sanity-check/logo.webp +0 -0
  129. package/data/craftbook-templates/re/release-artifact-sanity-check/manifest.json +24 -0
  130. package/data/craftbook-templates/re/release-artifact-sanity-check/versions/1.0.0/craftbook.json +202 -0
  131. package/data/craftbook-templates/re/release-artifact-sanity-check/versions/1.0.0/test.json +138 -0
  132. package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.0/craftbook.json +348 -0
  133. package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.0/test.json +153 -0
  134. package/data/craftbook-templates/se/security-architecture-review/versions/2.0.0/craftbook.json +353 -0
  135. package/data/craftbook-templates/se/security-architecture-review/versions/2.0.0/test.json +152 -0
  136. package/data/craftbook-templates/sp/spec-authoring/versions/2.0.0/craftbook.json +391 -0
  137. package/data/craftbook-templates/sp/spec-authoring/versions/2.0.0/test.json +162 -0
  138. package/data/craftbook-templates/te/technical-documentation/versions/2.0.0/craftbook.json +343 -0
  139. package/data/craftbook-templates/te/technical-documentation/versions/2.0.0/test.json +174 -0
  140. package/data/craftbook-templates/tr/translate-content/versions/1.1.0/craftbook.json +84 -0
  141. package/data/craftbook-templates/tr/translate-content/versions/1.1.0/test.json +141 -0
  142. package/package.json +10 -4
  143. package/schemas/chat-model-identity.schema.json +44 -0
  144. package/schemas/chat-model-version.schema.json +3 -0
  145. package/schemas/connector-type-identity.schema.json +3 -0
  146. package/schemas/connector-type-version.schema.json +3 -0
  147. package/schemas/craftbook-doc.schema.json +3 -0
  148. package/schemas/craftbook-template-identity.schema.json +3 -0
  149. package/schemas/craftbook-template-version.schema.json +3 -0
  150. package/schemas/craftbook-test.schema.json +232 -3
  151. package/schemas/gezel-template-identity.schema.json +3 -0
  152. package/schemas/gezel-template-version.schema.json +3 -0
  153. package/schemas/image-model-identity.schema.json +3 -0
  154. package/schemas/image-model-version.schema.json +3 -0
  155. package/schemas/project-type-identity.schema.json +3 -0
  156. package/schemas/project-type-version.schema.json +3 -0
  157. package/schemas/toolset-identity.schema.json +3 -0
  158. package/schemas/toolset-version.schema.json +3 -0
  159. package/schemas/video-model-identity.schema.json +3 -0
  160. package/schemas/video-model-version.schema.json +3 -0
@@ -4,9 +4,13 @@
4
4
  "id": "pull-request-review",
5
5
  "role": "maintenance-review",
6
6
  "name": "Pull Request Review",
7
- "description": "Staff-engineer-style PR review. Loads PR context, walks a per-file diff, applies a safety/quality checklist, and posts a structured summary. Requires a GitHub-connected project on a feature branch.",
7
+ "description": "Staff-engineer-style PR review. Defaults to the open pull request for the project's checked-out branch, walks its per-file diff, applies a safety/quality checklist, and posts a structured summary. Requires a GitHub-connected project on a feature branch.",
8
8
  "tags": [
9
9
  "review",
10
+ "pull-request",
11
+ "pr-review",
12
+ "code-review",
13
+ "github",
10
14
  "recommended"
11
15
  ],
12
16
  "maintainer": {
@@ -0,0 +1,159 @@
1
+ {
2
+ "id": "pull-request-review",
3
+ "name": "Pull Request Review",
4
+ "description": "Review the open GitHub pull request for the project's checked-out branch and deliver a gated, evidence-based report. This is the PR-aware companion to Code Review: it resolves the current branch's PR by default, reads PR metadata, comments, files, and diff through the GitHub toolset, and writes `pr-review.md` without modifying source or posting back to GitHub. Three steps:\n\n1. **Scope the PR** — select an explicit PR number or the unique current-branch match and record the review surface\n2. **Review and report** — walk every changed file, cite concrete `path:line` evidence, and write a severity-ranked report\n3. **Deliver the verdict** — summarize approve vs request-changes in task notes\n\nIf the current branch has no unique open PR, the reviewer asks instead of silently choosing another branch's PR.",
5
+ "basedOn": {
6
+ "name": "Gezel Code Review",
7
+ "url": "https://github.com/bendyline/gezel"
8
+ },
9
+ "entryStepId": "scope",
10
+ "triggers": [
11
+ "review this pr",
12
+ "review the current pr",
13
+ "review this pull request",
14
+ "pr review",
15
+ "review the github pull request"
16
+ ],
17
+ "requirements": [
18
+ {
19
+ "kind": "github"
20
+ },
21
+ {
22
+ "kind": "non-main-branch"
23
+ }
24
+ ],
25
+ "toolsets": [
26
+ {
27
+ "toolsetId": "github",
28
+ "optional": true,
29
+ "autoAllow": true,
30
+ "reason": "read pull-request metadata, comments, changed files, and the unified diff"
31
+ }
32
+ ],
33
+ "paramSchema": {
34
+ "type": "object",
35
+ "properties": {
36
+ "number": {
37
+ "type": "number",
38
+ "title": "Pull request number",
39
+ "description": "Optional PR number. Leave blank to use the open PR whose head matches the project's checked-out branch."
40
+ },
41
+ "focus": {
42
+ "type": "string",
43
+ "title": "Review focus",
44
+ "description": "Optional area to emphasize, e.g. security, performance, or tests."
45
+ },
46
+ "intensity": {
47
+ "type": "string",
48
+ "title": "Intensity",
49
+ "enum": [
50
+ "low",
51
+ "medium",
52
+ "high"
53
+ ],
54
+ "default": "medium",
55
+ "squisq": {
56
+ "control": "segmented"
57
+ },
58
+ "description": "How deep to go on the diff walk."
59
+ }
60
+ }
61
+ },
62
+ "steps": [
63
+ {
64
+ "id": "scope",
65
+ "name": "Scope the pull request",
66
+ "description": "Resolve an explicit PR or the unique open PR for the checked-out branch, then record its metadata, changed files, existing review context, and review themes.",
67
+ "prompt": "**You are reviewing a pull request, not authoring it. Never modify project source in this craftbook.**\n\n**Your first tool call this turn:** `github_pr_list({})`. It lists open PRs for this project, puts PRs whose head matches the checked-out branch first, and marks a unique one `Current branch match — default`.\n\nSelect the PR with this precedence:\n\n1. If the invocation parameters or user message supply a PR number, use it.\n2. Otherwise use the unique `Current branch match — default`.\n3. If multiple PRs match the current branch, or no PR matches and more than one PR is open, call `ask_user_question` with the concrete choices. Never take an unrelated first result.\n4. If no PR is open, write a task note explaining that and stop.\n\nFor the selected number, call `github_pr_view`, `github_pr_files`, and `github_pr_comments`. Read the title/body, head and base branches, file list, additions/deletions, and any feedback already raised so you do not duplicate it. Then write ONE task note beginning `## Scope — PR #<number>` and include: title, URL, head → base, draft state, changed-file list, existing-review themes, and 3–6 review themes weighted by the requested focus and intensity. End by calling `advance_task_step`.",
68
+ "suggestedRole": "reviewer",
69
+ "gate": {
70
+ "at": "completion",
71
+ "scripts": [
72
+ {
73
+ "name": "checkTaskNoteContains",
74
+ "scope": "standard",
75
+ "inputs": {
76
+ "pattern": "##\\s*Scope\\s*[—-]\\s*PR\\s*#\\d+"
77
+ }
78
+ }
79
+ ],
80
+ "onReject": "scope",
81
+ "maxAttempts": 3
82
+ },
83
+ "next": "report"
84
+ },
85
+ {
86
+ "id": "report",
87
+ "name": "Review and write the report",
88
+ "description": "Walk the full PR diff and every changed file, then write a gated report with concrete citations and a verdict. The report is local; this recipe never posts to GitHub automatically.",
89
+ "prompt": "Use the PR number selected in the Scope note. Call `github_pr_diff` for the complete unified diff and `github_pr_files` for the per-file patches. Walk every changed file and review for correctness, security, data-loss risk, error handling, concurrency, compatibility, tests, and clarity — weighted by the requested focus and intensity. Use `read_file` only when you need surrounding workspace context. Do not repeat an existing PR comment unless the issue still needs action and you explicitly say it was already raised.\n\nCite every finding as `path:line` using a changed path and a line from the new side of the diff. Do not invent files, behavior, or line numbers. Any critical or major finding requires `request-changes`; otherwise use `approve`.\n\nWrite `pr-review.md` in ONE `write_file` call using exactly this skeleton:\n\n```\n# Pull Request Review — PR #<number>: <title>\n\n## Summary\n<2–6 sentences: what changes, overall risk, and whether existing comments cover any issue. Say \"No findings.\" when there are none.>\n\n## Findings\n| # | Severity | File | Line | Finding | Recommendation |\n|---|----------|------|------|---------|----------------|\n<one row per finding; severities: critical, major, minor, nit. Keep the header when there are no findings.>\n\n## Verdict\nVerdict: approve\n<or> Verdict: request-changes\n<one sentence of rationale>\n```\n\nDo not modify source and do not call `github_pr_comment`; the user asked for a review report, not an automatic public side effect. If the gate rejects, fix exactly the named gap and rewrite the whole report. Then call `advance_task_step`.",
90
+ "suggestedRole": "reviewer",
91
+ "advanceWhen": {
92
+ "file": "pr-review.md",
93
+ "minBytes": 500
94
+ },
95
+ "gate": {
96
+ "at": "completion",
97
+ "checks": [
98
+ {
99
+ "kind": "minBytes",
100
+ "file": "pr-review.md",
101
+ "bytes": 500
102
+ },
103
+ {
104
+ "kind": "contains",
105
+ "file": "pr-review.md",
106
+ "pattern": "#\\s+Pull Request Review\\s+[—-]\\s+PR\\s+#\\d+",
107
+ "label": "PR-numbered title"
108
+ },
109
+ {
110
+ "kind": "contains",
111
+ "file": "pr-review.md",
112
+ "pattern": "##\\s+Summary",
113
+ "label": "Summary section"
114
+ },
115
+ {
116
+ "kind": "contains",
117
+ "file": "pr-review.md",
118
+ "pattern": "##\\s+Findings",
119
+ "label": "Findings section"
120
+ },
121
+ {
122
+ "kind": "contains",
123
+ "file": "pr-review.md",
124
+ "pattern": "\\|\\s*Severity\\s*\\|",
125
+ "label": "findings table header"
126
+ },
127
+ {
128
+ "kind": "contains",
129
+ "file": "pr-review.md",
130
+ "pattern": "Verdict:\\s*(approve|request-changes)",
131
+ "label": "verdict line"
132
+ },
133
+ {
134
+ "kind": "tableShape",
135
+ "file": "pr-review.md",
136
+ "requiredColumns": [
137
+ "Severity",
138
+ "File",
139
+ "Finding"
140
+ ]
141
+ }
142
+ ],
143
+ "onReject": "report",
144
+ "maxAttempts": 4
145
+ },
146
+ "next": "done"
147
+ },
148
+ {
149
+ "id": "done",
150
+ "name": "Deliver the verdict",
151
+ "description": "The report passed its gates. Summarize the verdict and point the user to the local report.",
152
+ "prompt": "Read `pr-review.md`, then write one final task note with `write_task_note`: `PR #<number> — Verdict: <approve|request-changes> — N findings (a critical, b major, c minor, d nit)` plus a one-paragraph summary. Tell the user the full local review is at `pr-review.md` and was not posted to GitHub. Then call `advance_task_step` to complete the task.",
153
+ "suggestedRole": "reviewer",
154
+ "terminal": true
155
+ }
156
+ ],
157
+ "version": "1.2.0",
158
+ "releasedAt": "2026-08-10T00:00:00Z"
159
+ }
@@ -0,0 +1,172 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "title": "Current-branch pull request review",
4
+ "objective": "Verify that Pull Request Review selects the PR marked as the checked-out branch default, inspects its GitHub metadata and diff through a deterministic MCP fixture, and writes a cited request-changes report without posting to GitHub.",
5
+ "tags": [
6
+ "external",
7
+ "mcp",
8
+ "pull-request"
9
+ ],
10
+ "prompt": "Run the Pull Request Review craftbook for the current checked-out branch. The fake GitHub toolset is local and deterministic; do not use real network or credentials. Review the PR marked as the current-branch default, not unrelated PR #41. Write the complete local review to pr-review.md and do not post a GitHub comment.",
11
+ "setup": {
12
+ "projectName": "Current Branch PR Review Eval",
13
+ "about": "A local fixture project whose checked-out branch is codex/pr-review. GitHub operations are supplied by the fake github MCP toolset.",
14
+ "missionObjectives": "Review the open PR for codex/pr-review, cite concrete changed-file lines, identify the insecure fallback credential, and deliver pr-review.md without public side effects.",
15
+ "files": [
16
+ {
17
+ "path": "src/auth.ts",
18
+ "content": "export function isAdmin(token: string): boolean {\n const expected = process.env.ADMIN_API_KEY || 'dev-admin-key';\n return token === expected;\n}\n"
19
+ },
20
+ {
21
+ "path": "source/eval-context.md",
22
+ "content": "# Eval context\n\nThe checked-out branch is `codex/pr-review`. PR #52 is the only open pull request whose head matches that branch. PR #41 is unrelated and must not be reviewed.\n"
23
+ }
24
+ ],
25
+ "worker": {
26
+ "name": "Rina",
27
+ "role": "Reviewer",
28
+ "description": "A careful code reviewer who grounds findings in changed lines."
29
+ }
30
+ },
31
+ "mocks": [
32
+ {
33
+ "kind": "mcp",
34
+ "id": "github",
35
+ "toolsetId": "github",
36
+ "description": "Fake GitHub PR tools with two open PRs; PR #52 is the unique current-branch match and PR #41 is unrelated.",
37
+ "tools": [
38
+ {
39
+ "name": "github_pr_list",
40
+ "description": "List open PRs, prioritizing and marking the checked-out branch match.",
41
+ "resultTemplate": "#52 — Add admin API-key authentication (alex, codex/pr-review → main)\n https://github.example.test/acme/widget/pull/52\n Current branch match — default: codex/pr-review\n\n#41 — Refactor invoice export (sam, feature/invoice-export → main)\n https://github.example.test/acme/widget/pull/41"
42
+ },
43
+ {
44
+ "name": "github_pr_view",
45
+ "description": "Fetch PR metadata for a selected number.",
46
+ "resultTemplate": "#52 — Add admin API-key authentication\nAuthor: alex\nBranches: codex/pr-review → main\nState: OPEN\nChanges: +4 −0 across 1 file(s)\nURL: https://github.example.test/acme/widget/pull/52\n\nAdds an API-key check for admin routes."
47
+ },
48
+ {
49
+ "name": "github_pr_files",
50
+ "description": "List changed files and patches for a selected PR.",
51
+ "resultTemplate": "src/auth.ts — added (+4 −0)\n```diff\n@@ -0,0 +1,4 @@\n+export function isAdmin(token: string): boolean {\n+ const expected = process.env.ADMIN_API_KEY || 'dev-admin-key';\n+ return token === expected;\n+}\n```"
52
+ },
53
+ {
54
+ "name": "github_pr_diff",
55
+ "description": "Fetch the full unified diff for a selected PR.",
56
+ "resultTemplate": "diff --git a/src/auth.ts b/src/auth.ts\nnew file mode 100644\n--- /dev/null\n+++ b/src/auth.ts\n@@ -0,0 +1,4 @@\n+export function isAdmin(token: string): boolean {\n+ const expected = process.env.ADMIN_API_KEY || 'dev-admin-key';\n+ return token === expected;\n+}\n"
57
+ },
58
+ {
59
+ "name": "github_pr_comments",
60
+ "description": "List existing PR comments.",
61
+ "resultTemplate": "No comments on this PR."
62
+ },
63
+ {
64
+ "name": "github_pr_comment",
65
+ "description": "Post a PR comment. Present only so the eval can prove the review recipe does not call it.",
66
+ "resultTemplate": {
67
+ "id": 9001,
68
+ "url": "https://github.example.test/acme/widget/pull/52#comment-9001"
69
+ }
70
+ }
71
+ ]
72
+ }
73
+ ],
74
+ "success": {
75
+ "summary": "pr-review.md reviews PR #52 (the unique current-branch match), cites src/auth.ts, flags the hard-coded fallback credential, requests changes, and never calls the GitHub comment tool.",
76
+ "deliverables": [
77
+ {
78
+ "path": "pr-review.md",
79
+ "kind": "markdown-report",
80
+ "minBytes": 500,
81
+ "checks": [
82
+ {
83
+ "kind": "contains",
84
+ "file": "pr-review.md",
85
+ "pattern": "#\\s+Pull Request Review\\s+[—-]\\s+PR\\s+#52",
86
+ "flags": "i"
87
+ },
88
+ {
89
+ "kind": "contains",
90
+ "file": "pr-review.md",
91
+ "pattern": "src/auth\\.ts(?::|\\s*\\|\\s*)[23]",
92
+ "flags": "i"
93
+ },
94
+ {
95
+ "kind": "contains",
96
+ "file": "pr-review.md",
97
+ "pattern": "dev-admin-key|fallback credential|hard-coded credential|hardcoded credential",
98
+ "flags": "i"
99
+ },
100
+ {
101
+ "kind": "contains",
102
+ "file": "pr-review.md",
103
+ "pattern": "Verdict:\\s*request-changes",
104
+ "flags": "i"
105
+ },
106
+ {
107
+ "kind": "notContains",
108
+ "file": "pr-review.md",
109
+ "pattern": "PR\\s*#41|invoice export",
110
+ "flags": "i"
111
+ }
112
+ ]
113
+ }
114
+ ],
115
+ "mocks": [
116
+ {
117
+ "service": "github",
118
+ "requiredTools": [
119
+ "github_pr_list",
120
+ "github_pr_view",
121
+ "github_pr_files",
122
+ "github_pr_diff"
123
+ ],
124
+ "toolCalls": {
125
+ "github_pr_comment": {
126
+ "minCalls": 0,
127
+ "maxCalls": 0
128
+ }
129
+ }
130
+ }
131
+ ]
132
+ },
133
+ "rubric": {
134
+ "artifact": {
135
+ "path": "pr-review.md",
136
+ "kind": "markdown"
137
+ },
138
+ "axes": [
139
+ {
140
+ "name": "selection",
141
+ "description": "The report is explicitly about PR #52, the current-branch default, and contains no analysis of unrelated PR #41."
142
+ },
143
+ {
144
+ "name": "grounding",
145
+ "description": "Every finding is grounded in the supplied diff with a concrete src/auth.ts line citation."
146
+ },
147
+ {
148
+ "name": "severity",
149
+ "description": "The insecure fallback credential receives a proportionate severity and forces request-changes."
150
+ },
151
+ {
152
+ "name": "side-effects",
153
+ "description": "The review remains local and does not post a GitHub comment."
154
+ }
155
+ ]
156
+ },
157
+ "qualityFocus": [
158
+ "current-branch PR selection",
159
+ "diff-grounded findings",
160
+ "safe local-only delivery"
161
+ ],
162
+ "extensions": {
163
+ "legacySimulators": [
164
+ {
165
+ "id": "pull-request-review-github-mcp",
166
+ "kind": "mcp",
167
+ "status": "implemented",
168
+ "description": "Deterministic fake GitHub PR toolset with a unique current-branch match, an unrelated open PR, changed-file patches, and a forbidden comment side effect."
169
+ }
170
+ ]
171
+ }
172
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "promptVersion": "workshop-mark-1910-v2",
4
+ "periodCue": "circa-1910-subtle",
5
+ "family": "inspect-verify",
6
+ "accents": [
7
+ "ochre",
8
+ "sage",
9
+ "muted indigo"
10
+ ],
11
+ "sourceSummary": "Inspect release parcels, ledgers, seals, and package contents for integrity and provenance.",
12
+ "styleReference": "release-readiness-review-1910"
13
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "kind": "craftbook-template",
4
+ "id": "release-artifact-sanity-check",
5
+ "role": "maintenance-review",
6
+ "name": "Release Artifact Sanity Check",
7
+ "description": "Sanity-check a folder of release artifacts without executing them: inventory every package, verify hashes and signatures against trusted evidence, safely inspect every file inside archives and application bundles, scan for suspicious or secret-bearing content, and produce an evidence-backed ship or no-ship report. Use this for release artifact verification, installer signing checks, package integrity audits, supply-chain inspection, or a pre-publish binary review.",
8
+ "tags": [
9
+ "gallery",
10
+ "release",
11
+ "artifacts",
12
+ "integrity",
13
+ "signing",
14
+ "security",
15
+ "supply-chain"
16
+ ],
17
+ "maintainer": {
18
+ "name": "Gezel"
19
+ },
20
+ "logo": "logo.webp",
21
+ "license": "MIT",
22
+ "yankedVersions": [],
23
+ "workflow": "build-loop"
24
+ }
@@ -0,0 +1,202 @@
1
+ {
2
+ "id": "release-artifact-sanity-check",
3
+ "name": "Release Artifact Sanity Check",
4
+ "description": "Sanity-check a folder of release artifacts without executing them: inventory every package, verify hashes and signatures against trusted evidence, safely inspect every file inside archives and application bundles, scan for suspicious or secret-bearing content, and produce an evidence-backed ship or no-ship report.\n\nThis craftbook treats release artifacts as hostile input. It never executes an installer, application, script, postinstall hook, or extracted binary. It stages any extraction under a disposable workspace directory, rejects path traversal and escaping symlinks, bounds recursive expansion, and reports any item it could not inspect as NOT VERIFIED rather than silently passing it. The result is a file-level inventory plus a go/no-go report whose claims are tied to commands, hashes, signer identities, and exact paths.",
5
+ "entryStepId": "inventory",
6
+ "triggers": [
7
+ "sanity check release artifacts",
8
+ "audit release packages",
9
+ "verify installer signatures",
10
+ "inspect app bundles",
11
+ "check release artifact integrity",
12
+ "scan a release folder"
13
+ ],
14
+ "toolsets": [
15
+ {
16
+ "toolsetId": "builtin.security-intel",
17
+ "autoAllow": true,
18
+ "reason": "reuse local secret, dependency, malware, and vulnerability scanner evidence when available"
19
+ },
20
+ {
21
+ "toolsetId": "builtin.code-intel",
22
+ "autoAllow": true,
23
+ "reason": "search safely extracted text and package manifests without executing bundled code"
24
+ }
25
+ ],
26
+ "steps": [
27
+ {
28
+ "id": "inventory",
29
+ "name": "Inventory the release set",
30
+ "description": "identify every release record, artifact, checksum, signature, and package boundary",
31
+ "prompt": "Treat the entire input folder as hostile and do not execute anything in it. Locate the requested release folder; if it came from the GitHub Releases connector, use the release Markdown records, frontmatter, asset tables, and sibling `attachments/` directories to associate bytes with releases. Enumerate every top-level artifact, checksum manifest, detached signature, certificate/provenance file, and release-notes record. Record exact relative path, byte size, file type identified from magic bytes (not extension alone), release/tag association, and the expected digest/signature evidence available. Define the inspection boundary and a safe staging directory outside the source corpus. Before extraction, list archive entries and flag absolute paths, `..` traversal, device files, escaping links, duplicate paths, case collisions, excessive nesting, or expansion bombs. Never follow a symlink outside the staging root. Write the complete inventory, counts, tool availability, inspection limits, and acceptance checklist to `notes/release-artifact-inventory.md` and task notes. Any artifact omitted by a configured size/name filter must be listed as NOT PRESENT and prevents a full-set pass.",
32
+ "suggestedRole": "developer",
33
+ "advanceWhen": {
34
+ "file": "notes/release-artifact-inventory.md",
35
+ "minBytes": 1,
36
+ "sniff": "nonempty"
37
+ },
38
+ "gate": {
39
+ "at": "completion",
40
+ "checks": [
41
+ {
42
+ "kind": "minBytes",
43
+ "file": "notes/release-artifact-inventory.md",
44
+ "bytes": 500
45
+ },
46
+ {
47
+ "kind": "sniff",
48
+ "file": "notes/release-artifact-inventory.md",
49
+ "sniff": "nonempty"
50
+ }
51
+ ],
52
+ "onReject": "inventory",
53
+ "maxAttempts": 3
54
+ },
55
+ "next": "verify"
56
+ },
57
+ {
58
+ "id": "verify",
59
+ "name": "Verify integrity and signing",
60
+ "description": "hash every artifact and validate signatures against a trusted identity",
61
+ "prompt": "Without executing any artifact, compute SHA-256 for every top-level asset and compare it independently against: GitHub's supplied `sha256:` digest when present, checked-in checksum manifests, detached signature payloads, and any release provenance/attestation. A hash written beside the same untrusted artifact is evidence of consistency, not authenticity; name the trust root. Verify signatures with the platform-appropriate verifier when installed (for example `codesign`/`spctl`/`pkgutil` on macOS, `Get-AuthenticodeSignature` or `signtool` on Windows, and `gpgv`, `cosign verify-blob`, `rpm --checksig`, or package-native verification on Linux). Capture the exact command, exit status, signer subject/team/key identity, timestamp/notarization status, certificate chain or trusted key source, and whether the signed object covers the bytes being shipped. Do not call an artifact signed merely because a signature file exists. Use PASS / FAIL / NOT VERIFIED for every artifact and evidence type. A mismatch, invalid signature, unsigned required executable, untrusted key, unavailable verifier, or missing expected artifact is not a pass. Write results to `notes/release-artifact-verification.md` and task notes.",
62
+ "suggestedRole": "reviewer",
63
+ "advanceWhen": {
64
+ "file": "notes/release-artifact-verification.md",
65
+ "minBytes": 1,
66
+ "sniff": "nonempty"
67
+ },
68
+ "gate": {
69
+ "at": "completion",
70
+ "checks": [
71
+ {
72
+ "kind": "minBytes",
73
+ "file": "notes/release-artifact-verification.md",
74
+ "bytes": 600
75
+ }
76
+ ],
77
+ "scripts": [
78
+ {
79
+ "name": "checkContains",
80
+ "scope": "standard",
81
+ "inputs": {
82
+ "file": "notes/release-artifact-verification.md",
83
+ "pattern": "PASS|FAIL|NOT VERIFIED",
84
+ "flags": "i"
85
+ }
86
+ }
87
+ ],
88
+ "onReject": "verify",
89
+ "maxAttempts": 3
90
+ },
91
+ "next": "inspect"
92
+ },
93
+ {
94
+ "id": "inspect",
95
+ "name": "Inspect every package member",
96
+ "description": "safely unpack app packages and scan every contained file",
97
+ "prompt": "Work only in the disposable staging directory; never mutate the source corpus and never execute package contents. Safely expand each supported container recursively, including ZIP/TAR archives, DMG/PKG and `.app` bundles where host tooling permits, MSI/EXE packages where a non-executing extractor is available, AppImage/deb/rpm packages, and nested archives. Inventory EVERY regular file and symlink with relative path, magic-byte type, size, SHA-256, executable bit, signing coverage, and parent package. Inspect manifests, entitlements, permissions, dynamic libraries, launch agents/services, updater helpers, install scripts as text, bundled runtimes/dependencies, debug symbols, universal architectures, and unexpected executables. Scan extracted text and metadata for secrets, private keys, credentials, unsafe URLs, suspicious persistence, world-writable paths, and provenance drift; reuse `security_scan`/local malware scanners when available, recording tool name/version/result. Never run an installer, binary, macro, or script and disable postinstall hooks. If a format/tool/limit prevents inspecting even one member, name the exact gap and mark the package coverage INCOMPLETE / NOT VERIFIED. Write the file-count reconciliation, findings, and evidence to `notes/release-package-inspection.md` and task notes.",
98
+ "suggestedRole": "developer",
99
+ "advanceWhen": {
100
+ "file": "notes/release-package-inspection.md",
101
+ "minBytes": 1,
102
+ "sniff": "nonempty"
103
+ },
104
+ "gate": {
105
+ "at": "completion",
106
+ "checks": [
107
+ {
108
+ "kind": "minBytes",
109
+ "file": "notes/release-package-inspection.md",
110
+ "bytes": 700
111
+ }
112
+ ],
113
+ "scripts": [
114
+ {
115
+ "name": "checkContains",
116
+ "scope": "standard",
117
+ "inputs": {
118
+ "file": "notes/release-package-inspection.md",
119
+ "pattern": "file|path|SHA-256|coverage",
120
+ "flags": "i"
121
+ }
122
+ }
123
+ ],
124
+ "onReject": "inspect",
125
+ "maxAttempts": 3
126
+ },
127
+ "next": "report"
128
+ },
129
+ {
130
+ "id": "report",
131
+ "name": "Write the artifact sanity report",
132
+ "description": "state a ship decision with complete evidence and blockers",
133
+ "prompt": "Write `release-artifact-sanity-report.md`. Put one decision at the top: PASS / NO-GO / PASS-WITH-CONDITIONS, with the deciding evidence. Include: scope and release/tag; coverage summary with top-level and contained-file counts reconciled; an artifact matrix with expected/computed digest, integrity result, signature result, signer/trust root, package-inspection coverage, and evidence path/command; findings ranked by severity with exact package/member paths; unsupported or uninspected items; and blockers with concrete remediation/rebuild/re-sign/re-upload actions. Distinguish verified authenticity from checksum consistency and signature presence. A digest mismatch, invalid/untrusted/required-but-missing signature, escaping archive member, secret-bearing shipped file, uninspected package member, or unavailable mandatory verifier prevents an unconditional PASS. Do not minimize an issue because another platform's package passed. Include enough detail for another reviewer to reproduce each claim without running the artifacts. Record the report path, decision, artifact count, contained-file count, and blocker count in task notes.",
134
+ "suggestedRole": "reviewer",
135
+ "advanceWhen": {
136
+ "file": "release-artifact-sanity-report.md",
137
+ "minBytes": 1,
138
+ "sniff": "nonempty"
139
+ },
140
+ "gate": {
141
+ "at": "completion",
142
+ "checks": [
143
+ {
144
+ "kind": "minBytes",
145
+ "file": "release-artifact-sanity-report.md",
146
+ "bytes": 2000
147
+ }
148
+ ],
149
+ "scripts": [
150
+ {
151
+ "name": "checkContains",
152
+ "scope": "standard",
153
+ "inputs": {
154
+ "file": "release-artifact-sanity-report.md",
155
+ "pattern": "PASS|NO-GO|PASS-WITH-CONDITIONS",
156
+ "flags": "i"
157
+ }
158
+ },
159
+ {
160
+ "name": "checkContains",
161
+ "scope": "standard",
162
+ "inputs": {
163
+ "file": "release-artifact-sanity-report.md",
164
+ "pattern": "integrity|digest|SHA-256",
165
+ "flags": "i"
166
+ }
167
+ },
168
+ {
169
+ "name": "checkContains",
170
+ "scope": "standard",
171
+ "inputs": {
172
+ "file": "release-artifact-sanity-report.md",
173
+ "pattern": "signature|signer|notar",
174
+ "flags": "i"
175
+ }
176
+ }
177
+ ],
178
+ "onReject": "report",
179
+ "maxAttempts": 4
180
+ },
181
+ "next": "evaluate"
182
+ },
183
+ {
184
+ "id": "evaluate",
185
+ "name": "Evaluate",
186
+ "description": "grade coverage and evidence; pass only when every acceptance criterion is met",
187
+ "prompt": "Open `release-artifact-sanity-report.md` and the three evidence notes. Grade EACH criterion PASS/FAIL with one-line evidence: (1) every top-level release artifact is inventoried and its SHA-256 computed; (2) expected digests are compared and mismatches are blockers; (3) every required signature is cryptographically verified against a named trusted identity, with presence-only and unavailable checks marked NOT VERIFIED; (4) every supported package is safely expanded without executing content; (5) contained-file counts reconcile and every member has a path/type/hash/security disposition; (6) traversal, escaping links, expansion limits, secrets, persistence, entitlements, permissions, libraries, and nested executables are addressed; (7) all inspection gaps are explicit and prevent an unconditional pass; (8) the final decision follows from the evidence. Then route explicitly: if every criterion passes, call `advance_task_step({ ref, stepId: \"evaluate\", next: \"finish\" })`. If any criterion fails, write the exact gap to task notes and call `advance_task_step({ ref, stepId: \"evaluate\", next: \"report\" })`. Never route to finish with a silent omission or unsupported package. After three unproductive loops, stop with DONE_WITH_CONCERNS for user review.",
188
+ "suggestedRole": "reviewer",
189
+ "next": "report"
190
+ },
191
+ {
192
+ "id": "finish",
193
+ "name": "Finish",
194
+ "description": "stamp the decision and hand off the evidence-backed report",
195
+ "prompt": "All acceptance criteria passed. Write a concise DONE summary to task notes: the release/tag and folder reviewed, report path, decision, top-level artifact count, contained-file count, blocker count, and any conditions or NOT VERIFIED items. Remind the user that the audit did not execute any artifact. Then report DONE.",
196
+ "suggestedRole": "reviewer",
197
+ "terminal": true
198
+ }
199
+ ],
200
+ "version": "1.0.0",
201
+ "releasedAt": "2026-08-09T00:00:00Z"
202
+ }