@macedon-technologies/batman 1.17.2 → 1.18.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 (50) hide show
  1. package/.jsii +205 -26
  2. package/.swamp.yaml +6 -0
  3. package/API.md +164 -1
  4. package/CLAUDE.md +44 -0
  5. package/architecture-rules/README.md +42 -0
  6. package/architecture-rules/check.ts +162 -0
  7. package/architecture-rules/rules.json +3 -0
  8. package/architecture-rules/tsconfig.json +14 -0
  9. package/attestation/manifest.ts +40 -0
  10. package/attestation/tsconfig.json +13 -0
  11. package/attestation/verify.ts +142 -0
  12. package/build-tools/scan-generated-workflows.ts +18 -11
  13. package/lib/Application.js +6 -1
  14. package/lib/BatmanProject.js +8 -2
  15. package/lib/BootcampProject.js +8 -2
  16. package/lib/CodeOwnersFile.js +1 -1
  17. package/lib/ProductionDeployWorkflow.js +1 -1
  18. package/lib/ProjenWorkflowHardening.d.ts +18 -0
  19. package/lib/ProjenWorkflowHardening.js +59 -0
  20. package/lib/SoftwareFactoryArchitectureRules.d.ts +10 -0
  21. package/lib/SoftwareFactoryArchitectureRules.js +245 -0
  22. package/lib/SoftwareFactoryAttestation.d.ts +18 -0
  23. package/lib/SoftwareFactoryAttestation.js +221 -0
  24. package/lib/SoftwareFactoryFiles.d.ts +45 -0
  25. package/lib/SoftwareFactoryFiles.js +102 -0
  26. package/lib/SoftwareFactoryModels.d.ts +25 -0
  27. package/lib/SoftwareFactoryModels.js +306 -0
  28. package/lib/SoftwareFactoryOpenSpecGates.d.ts +8 -0
  29. package/lib/SoftwareFactoryOpenSpecGates.js +75 -0
  30. package/lib/SoftwareFactoryWorkflows.d.ts +28 -0
  31. package/lib/SoftwareFactoryWorkflows.js +326 -0
  32. package/lib/StagingDeployWorkflow.js +1 -1
  33. package/lib/WorkflowActionVersions.d.ts +31 -1
  34. package/lib/WorkflowActionVersions.js +5 -1
  35. package/lib/WorkflowAutoDiscover.js +1 -1
  36. package/lib/index.d.ts +1 -0
  37. package/lib/index.js +2 -1
  38. package/lib/utils.js +29 -1
  39. package/models/@goodcraft/github/platform-common-pr.yaml +10 -0
  40. package/models/@swamp/software-factory/platform-common-factory.yaml +240 -0
  41. package/models/@webframp/github/platform-common-issues.yaml +8 -0
  42. package/models/command/shell/platform-common-shell-architecture.yaml +8 -0
  43. package/models/command/shell/platform-common-shell-manifest.yaml +8 -0
  44. package/models/command/shell/platform-common-shell.yaml +8 -0
  45. package/openspec-gates/check-tasks-complete.ts +44 -0
  46. package/openspec-gates/tsconfig.json +13 -0
  47. package/package.json +6 -1
  48. package/workflows/workflow-openspec-plan-verify.yaml +51 -0
  49. package/workflows/workflow-openspec-tasks-verify.yaml +51 -0
  50. package/workflows/workflow-pre-pr-verify.yaml +118 -0
@@ -0,0 +1,240 @@
1
+ type: '@swamp/software-factory'
2
+ typeVersion: 2026.06.24.1
3
+ id: 7e207e5d-7067-4286-9a84-ca8330a26f53
4
+ name: platform-common-factory
5
+ version: 1
6
+ tags: {}
7
+ reports:
8
+ require:
9
+ - name: "@swamp/software-factory/work-item-summary"
10
+ methods: [summary]
11
+ globalArguments:
12
+ stages:
13
+ - id: intake
14
+ initial: true
15
+ description: >-
16
+ Fetch the GitHub issue for this work item (workItem is the bare
17
+ issue number) and record its context.
18
+ work:
19
+ mode: interactive
20
+ systemPrompt: >-
21
+ Fetch the GitHub issue numbered ${{ self.workItem }} for
22
+ macedon-technologies/platform-common using the platform-common-issues model
23
+ (list_issues, then swamp data query filtered by number — see the
24
+ platform-common-issues data), and record the issue-context artifact.
25
+ artifacts:
26
+ - name: issue-context
27
+ schema:
28
+ type: object
29
+ required: [number, title, url]
30
+ properties:
31
+ number: { type: integer }
32
+ title: { type: string, minLength: 1 }
33
+ body: { type: string }
34
+ url: { type: string, minLength: 1 }
35
+ labels: { type: array, items: { type: string } }
36
+ transitions:
37
+ - name: submit
38
+ to: planning
39
+ gates:
40
+ - type: artifact-exists
41
+ config: { artifact: issue-context }
42
+
43
+ - id: planning
44
+ description: >-
45
+ Turn the issue into a real OpenSpec change (proposal, design,
46
+ specs, tasks) — OpenSpec's task list is the plan, not a
47
+ freeform artifact.
48
+ work:
49
+ mode: interactive
50
+ systemPrompt: >-
51
+ Using the recorded issue-context artifact, use the
52
+ openspec-propose skill to create a complete OpenSpec change
53
+ (proposal.md, design.md, specs with deltas, tasks.md) for this
54
+ work item under openspec/changes/<changeSlug>/ — do not write a
55
+ freeform plan instead of this. Then record the plan artifact
56
+ with the change's slug and a one-line summary.
57
+ artifacts:
58
+ - name: plan
59
+ schema:
60
+ type: object
61
+ required: [changeSlug, summary]
62
+ properties:
63
+ changeSlug: { type: string, minLength: 1 }
64
+ summary: { type: string, minLength: 1 }
65
+ transitions:
66
+ - name: submit
67
+ to: openspec-plan-verify
68
+ gates:
69
+ - type: artifact-exists
70
+ config: { artifact: plan }
71
+
72
+ - id: openspec-plan-verify
73
+ description: >-
74
+ Verify the OpenSpec change is real and well-formed (not just an
75
+ artifact claiming one exists) before implementation starts.
76
+ work:
77
+ mode: workflow
78
+ workflow:
79
+ name: openspec-plan-verify
80
+ inputs:
81
+ changeSlug: '${{ data.latest(self.name, "artifact-plan").payload.changeSlug }}'
82
+ resultEvidence: plan-verify-run
83
+ transitions:
84
+ - name: pass
85
+ to: implementing
86
+ gates:
87
+ - type: workflow-succeeded
88
+ config: { workflow: openspec-plan-verify }
89
+ - name: fail
90
+ to: planning
91
+ gates:
92
+ - type: evidence-recorded
93
+ config: { name: plan-verify-run, requireField: { status: failed } }
94
+
95
+ - id: implementing
96
+ description: Implement the OpenSpec change's tasks on a branch.
97
+ work:
98
+ mode: interactive
99
+ systemPrompt: >-
100
+ Use the openspec-apply-change skill against the change recorded
101
+ in the plan artifact's changeSlug — work through its tasks.md
102
+ one task at a time, checking each off (`- [ ]` -> `- [x]`) as
103
+ you complete it, until every task is done. Commit the work on a
104
+ feature branch. Record the change-summary artifact and the
105
+ change-request evidence (branch name and head commit sha — no
106
+ PR yet, that happens after pre-PR verification passes).
107
+ artifacts:
108
+ - name: change-summary
109
+ schema:
110
+ type: object
111
+ required: [summary, headSha]
112
+ properties:
113
+ summary: { type: string, minLength: 1 }
114
+ headSha: { type: string, minLength: 7 }
115
+ evidence:
116
+ - name: change-request
117
+ schema:
118
+ type: object
119
+ required: [branch, headSha]
120
+ properties:
121
+ branch: { type: string, minLength: 1 }
122
+ headSha: { type: string, minLength: 7 }
123
+ url: { type: string }
124
+ transitions:
125
+ - name: submit
126
+ to: openspec-tasks-verify
127
+ gates:
128
+ - type: artifact-exists
129
+ config: { artifact: change-summary }
130
+ - type: evidence-recorded
131
+ config: { name: change-request }
132
+
133
+ - id: openspec-tasks-verify
134
+ description: >-
135
+ Verify every task in the OpenSpec change is actually checked off
136
+ before pre-PR verification runs.
137
+ work:
138
+ mode: workflow
139
+ workflow:
140
+ name: openspec-tasks-verify
141
+ inputs:
142
+ changeSlug: '${{ data.latest(self.name, "artifact-plan").payload.changeSlug }}'
143
+ resultEvidence: tasks-verify-run
144
+ transitions:
145
+ - name: pass
146
+ to: pre-pr-verify
147
+ gates:
148
+ - type: workflow-succeeded
149
+ config: { workflow: openspec-tasks-verify }
150
+ - name: fail
151
+ to: implementing
152
+ gates:
153
+ - type: evidence-recorded
154
+ config: { name: tasks-verify-run, requireField: { status: failed } }
155
+
156
+ - id: pre-pr-verify
157
+ description: >-
158
+ Pre-PR verification: build/synth/test/lint plus the architecture
159
+ rule registry, run before the PR is opened rather than relying on
160
+ CI after the fact.
161
+ work:
162
+ mode: workflow
163
+ workflow:
164
+ name: pre-pr-verify
165
+ inputs:
166
+ commit: '${{ data.latest(self.name, "evidence-change-request").payload.headSha }}'
167
+ branch: '${{ data.latest(self.name, "evidence-change-request").payload.branch }}'
168
+ resultEvidence: verify-run
169
+ transitions:
170
+ - name: pass
171
+ to: open-pr
172
+ gates:
173
+ - type: workflow-succeeded
174
+ config: { workflow: pre-pr-verify }
175
+ - name: fail
176
+ to: implementing
177
+ gates:
178
+ - type: evidence-recorded
179
+ config: { name: verify-run, requireField: { status: failed } }
180
+
181
+ - id: open-pr
182
+ description: Open the pull request now that pre-PR verification has passed.
183
+ work:
184
+ mode: interactive
185
+ systemPrompt: >-
186
+ Before opening the PR, fetch the real pre-pr-verify attestation
187
+ with `swamp data get --workflow pre-pr-verify
188
+ report-swamp-verification-attestation --json` and include its
189
+ `content` verbatim (as a markdown block, e.g. under a "Pre-PR
190
+ verification" heading) in the PR body — never just assert in
191
+ prose that checks passed. Also fetch this same run's manifest step
192
+ output (`swamp data query 'modelName == "platform-common-shell-manifest" &&
193
+ name == "result"' --select attributes.stdout --json`, take the
194
+ latest) and append it to the PR body as
195
+ `<!-- attestation-manifest {"commit": "<headSha>", "status":
196
+ "succeeded", ...the manifest step's JSON, spread in...} -->` — an
197
+ HTML comment so it's invisible when rendered but still present in
198
+ the raw body text verify-attestation.yml reads via the GitHub API.
199
+ Also fetch the plan artifact's changeSlug and include an explicit
200
+ "OpenSpec change" line in the PR body naming it and its path
201
+ (`openspec/changes/<changeSlug>/`) — every PR the factory opens
202
+ must call out which OpenSpec change(s) drove the session, not
203
+ just imply it. If planning cycled through more than one change
204
+ (a rework loop produced a new changeSlug), list every distinct
205
+ changeSlug recorded across the run's plan artifact versions, not
206
+ only the latest. Then call platform-common-pr's openPr method
207
+ (repo=macedon-technologies/platform-common, head=<the branch recorded in
208
+ change-request evidence>, base=main, dryRun=false), with
209
+ title/body referencing the intake stage's issue number, the
210
+ OpenSpec change(s), the attestation block, and the manifest
211
+ comment, then record the pr-opened evidence with the returned PR
212
+ url and number.
213
+ evidence:
214
+ - name: pr-opened
215
+ schema:
216
+ type: object
217
+ required: [url, number]
218
+ properties:
219
+ url: { type: string, minLength: 1 }
220
+ number: { type: integer }
221
+ transitions:
222
+ - name: submit
223
+ to: done
224
+ gates:
225
+ - type: evidence-recorded
226
+ config: { name: pr-opened }
227
+
228
+ - id: done
229
+ terminal: true
230
+
231
+ - id: aborted
232
+ terminal: true
233
+
234
+ globalTransitions:
235
+ - name: abort
236
+ to: aborted
237
+ gates:
238
+ - type: human-approval
239
+ config: { id: abort-confirmation }
240
+ methods: {}
@@ -0,0 +1,8 @@
1
+ type: '@webframp/github'
2
+ typeVersion: 2026.08.28.1
3
+ id: e2014176-817c-4d45-9ca6-67646b1a9500
4
+ name: platform-common-issues
5
+ version: 1
6
+ tags: {}
7
+ globalArguments: {}
8
+ methods: {}
@@ -0,0 +1,8 @@
1
+ type: command/shell
2
+ typeVersion: 2026.02.09.1
3
+ id: a8146f72-fe38-466c-9216-ea1ecefff400
4
+ name: platform-common-shell-architecture
5
+ version: 1
6
+ tags: {}
7
+ globalArguments: {}
8
+ methods: {}
@@ -0,0 +1,8 @@
1
+ type: command/shell
2
+ typeVersion: 2026.02.09.1
3
+ id: a17cfd88-712b-4fe6-a146-4a1c3a9b4ca5
4
+ name: platform-common-shell-manifest
5
+ version: 1
6
+ tags: {}
7
+ globalArguments: {}
8
+ methods: {}
@@ -0,0 +1,8 @@
1
+ type: command/shell
2
+ typeVersion: 2026.02.09.1
3
+ id: 656d013d-0cf3-4a99-87c9-fa89fc323cd0
4
+ name: platform-common-shell
5
+ version: 1
6
+ tags: {}
7
+ globalArguments: {}
8
+ methods: {}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Gate: fails unless every task in the named OpenSpec change's tasks.md is
3
+ * checked off. `openspec validate`/`openspec status` don't check this (an
4
+ * in-progress change is a normal, valid state) — this is the deterministic
5
+ * check the pre-pr pipeline needs before letting implementation proceed.
6
+ */
7
+ import { execFileSync } from 'node:child_process';
8
+
9
+ interface OpenSpecChangeSummary {
10
+ name: string;
11
+ completedTasks: number;
12
+ totalTasks: number;
13
+ status: string;
14
+ }
15
+
16
+ function main(): number {
17
+ // pnpm's `-- <args>` forwarding (and projen's receiveArgs) can pass a
18
+ // literal "--" through as an argv token ahead of the real argument.
19
+ const slug = process.argv.slice(2).find((arg) => arg !== '--');
20
+ if (!slug) {
21
+ console.error('Usage: check-tasks-complete <change-slug>');
22
+ return 1;
23
+ }
24
+
25
+ const raw = execFileSync('openspec', ['list', '--json'], { encoding: 'utf8' });
26
+ const { changes } = JSON.parse(raw) as { changes: OpenSpecChangeSummary[] };
27
+ const change = changes.find((c) => c.name === slug);
28
+
29
+ if (!change) {
30
+ console.error(`OpenSpec change "${slug}" not found (openspec list --json)`);
31
+ return 1;
32
+ }
33
+ if (change.status !== 'complete') {
34
+ console.error(
35
+ `OpenSpec change "${slug}" has incomplete tasks: ${change.completedTasks}/${change.totalTasks}`,
36
+ );
37
+ return 1;
38
+ }
39
+
40
+ console.log(`OpenSpec change "${slug}": all ${change.totalTasks} tasks complete`);
41
+ return 0;
42
+ }
43
+
44
+ process.exit(main());
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "rootDir": "."
6
+ },
7
+ "include": [
8
+ "*.ts"
9
+ ],
10
+ "exclude": [
11
+ "node_modules"
12
+ ]
13
+ }
package/package.json CHANGED
@@ -49,7 +49,7 @@
49
49
  "main": "lib/index.js",
50
50
  "license": "Apache-2.0",
51
51
  "stability": "stable",
52
- "version": "1.17.2",
52
+ "version": "1.18.0",
53
53
  "jest": {
54
54
  "coverageProvider": "v8",
55
55
  "testMatch": [
@@ -104,6 +104,8 @@
104
104
  },
105
105
  "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"pnpm exec projen\".",
106
106
  "scripts": {
107
+ "attestation:manifest": "projen attestation:manifest",
108
+ "attestation:verify": "projen attestation:verify",
107
109
  "build": "projen build",
108
110
  "bump": "projen bump",
109
111
  "bump:releasable-commits": "projen bump:releasable-commits",
@@ -114,6 +116,7 @@
114
116
  "docgen": "projen docgen",
115
117
  "eject": "projen eject",
116
118
  "eslint": "projen eslint",
119
+ "openspec:check-tasks-complete": "projen openspec:check-tasks-complete",
117
120
  "package": "projen package",
118
121
  "package-all": "projen package-all",
119
122
  "package:js": "projen package:js",
@@ -121,10 +124,12 @@
121
124
  "post-upgrade": "projen post-upgrade",
122
125
  "pre-compile": "projen pre-compile",
123
126
  "release": "projen release",
127
+ "swamp:bootstrap": "projen swamp:bootstrap",
124
128
  "test": "projen test",
125
129
  "test:watch": "projen test:watch",
126
130
  "unbump": "projen unbump",
127
131
  "upgrade": "projen upgrade",
132
+ "validate:architecture": "projen validate:architecture",
128
133
  "watch": "projen watch",
129
134
  "zizmor": "projen zizmor",
130
135
  "projen": "projen"
@@ -0,0 +1,51 @@
1
+ id: 9876c89c-de05-4c3c-9595-cbc7622f5391
2
+ name: openspec-plan-verify
3
+ description: >-
4
+ Fails unless the named OpenSpec change is well-formed (proposal, design,
5
+ specs with deltas, tasks all present) via `openspec validate`. Gates the
6
+ factory's planning stage: a request can't proceed to implementation until
7
+ it's a real OpenSpec change, not just prose in a swamp artifact.
8
+ tags: {}
9
+ inputs:
10
+ type: object
11
+ required: [changeSlug]
12
+ properties:
13
+ changeSlug:
14
+ type: string
15
+ description: The openspec change name (openspec/changes/<changeSlug>/).
16
+ jobs:
17
+ - name: verify
18
+ description: Validate the OpenSpec change is complete and well-formed
19
+ steps:
20
+ - name: validate
21
+ description: openspec validate <changeSlug> --type change
22
+ task:
23
+ type: model_method
24
+ modelIdOrName: platform-common-shell
25
+ methodName: execute
26
+ inputs:
27
+ run: 'openspec validate ${{ inputs.changeSlug }} --type change'
28
+ dependsOn: []
29
+ weight: 0
30
+ allowFailure: false
31
+ - name: assert-valid
32
+ description: openspec validate must exit 0
33
+ task:
34
+ type: assert
35
+ expr: >-
36
+ data.query('modelName == "platform-common-shell" && name == "result" &&
37
+ workflowRunId == "' + run.id + '"')[0].attributes.exitCode == 0
38
+ message: >-
39
+ OpenSpec change is not valid/complete (missing proposal, design,
40
+ specs with deltas, or tasks) — see the platform-common-shell result data
41
+ for openspec's own remediation output
42
+ severity: high
43
+ dependsOn:
44
+ - step: validate
45
+ condition:
46
+ type: succeeded
47
+ weight: 0
48
+ allowFailure: false
49
+ dependsOn: []
50
+ weight: 0
51
+ version: 1
@@ -0,0 +1,51 @@
1
+ id: 57139fa5-bcae-4338-90c0-1f4d2fa05398
2
+ name: openspec-tasks-verify
3
+ description: >-
4
+ Fails unless every task in the named OpenSpec change's tasks.md is checked
5
+ off (openspec-gates/check-tasks-complete.ts, via `pnpm run
6
+ openspec:check-tasks-complete`). Gates the factory's implementing stage:
7
+ work isn't done until the change's own task list says it's done, not just
8
+ because an artifact was recorded.
9
+ tags: {}
10
+ inputs:
11
+ type: object
12
+ required: [changeSlug]
13
+ properties:
14
+ changeSlug:
15
+ type: string
16
+ description: The openspec change name (openspec/changes/<changeSlug>/).
17
+ jobs:
18
+ - name: verify
19
+ description: Check every task in the change's tasks.md is complete
20
+ steps:
21
+ - name: check-tasks
22
+ description: pnpm run openspec:check-tasks-complete -- <changeSlug>
23
+ task:
24
+ type: model_method
25
+ modelIdOrName: platform-common-shell
26
+ methodName: execute
27
+ inputs:
28
+ run: 'pnpm run openspec:check-tasks-complete -- ${{ inputs.changeSlug }}'
29
+ dependsOn: []
30
+ weight: 0
31
+ allowFailure: false
32
+ - name: assert-tasks-complete
33
+ description: openspec:check-tasks-complete must exit 0
34
+ task:
35
+ type: assert
36
+ expr: >-
37
+ data.query('modelName == "platform-common-shell" && name == "result" &&
38
+ workflowRunId == "' + run.id + '"')[0].attributes.exitCode == 0
39
+ message: >-
40
+ OpenSpec change has incomplete tasks — see the platform-common-shell
41
+ result data for the completedTasks/totalTasks breakdown
42
+ severity: high
43
+ dependsOn:
44
+ - step: check-tasks
45
+ condition:
46
+ type: succeeded
47
+ weight: 0
48
+ allowFailure: false
49
+ dependsOn: []
50
+ weight: 0
51
+ version: 1
@@ -0,0 +1,118 @@
1
+ id: a3b4b6f9-cb73-460a-8a5a-c464250c7d03
2
+ name: pre-pr-verify
3
+ description: >-
4
+ Pre-PR verification: run the same checks CI would run, before the factory
5
+ opens a PR rather than after — build/synth/test/lint (pnpm build) and the
6
+ architecture rule registry (pnpm validate:architecture). Both must pass.
7
+ tags: {}
8
+ inputs:
9
+ type: object
10
+ properties:
11
+ commit:
12
+ type: string
13
+ description: >-
14
+ The commit sha being verified. Read by the built-in
15
+ @swamp/verification-attestation report's subject.commit — pass the
16
+ real HEAD sha or the attestation renders "unknown".
17
+ branch:
18
+ type: string
19
+ description: Same as commit, but for @swamp/verification-attestation's subject.branch.
20
+ jobs:
21
+ - name: verify
22
+ description: Build/test/lint plus architecture-rule checks, gating PR creation
23
+ steps:
24
+ - name: build
25
+ description: compile -> cdk synth -> jest -> eslint (existing projen build task)
26
+ task:
27
+ type: model_method
28
+ modelIdOrName: platform-common-shell
29
+ methodName: execute
30
+ inputs:
31
+ run: pnpm build
32
+ dependsOn: []
33
+ weight: 0
34
+ allowFailure: false
35
+ - name: assert-build
36
+ description: pnpm build must exit 0
37
+ task:
38
+ type: assert
39
+ expr: >-
40
+ data.query('modelName == "platform-common-shell" && name == "result" &&
41
+ workflowRunId == "' + run.id + '"')[0].attributes.exitCode == 0
42
+ message: >-
43
+ pnpm build failed (compile/synth/test/lint) — see the platform-common-shell
44
+ result data for stdout/stderr
45
+ severity: high
46
+ dependsOn:
47
+ - step: build
48
+ condition:
49
+ type: succeeded
50
+ weight: 0
51
+ allowFailure: false
52
+ - name: architecture
53
+ description: run the architecture rule registry (architecture-rules/rules.json)
54
+ task:
55
+ type: model_method
56
+ modelIdOrName: platform-common-shell-architecture
57
+ methodName: execute
58
+ inputs:
59
+ run: pnpm run validate:architecture
60
+ dependsOn:
61
+ - step: assert-build
62
+ condition:
63
+ type: succeeded
64
+ weight: 0
65
+ allowFailure: false
66
+ - name: assert-architecture
67
+ description: architecture rule registry must exit 0 (no enabled-rule violations)
68
+ task:
69
+ type: assert
70
+ expr: >-
71
+ data.query('modelName == "platform-common-shell-architecture" && name == "result" &&
72
+ workflowRunId == "' + run.id + '"')[0].attributes.exitCode == 0
73
+ message: >-
74
+ architecture rule violation(s) found — see the platform-common-shell result
75
+ data for details
76
+ severity: high
77
+ dependsOn:
78
+ - step: architecture
79
+ condition:
80
+ type: succeeded
81
+ weight: 0
82
+ allowFailure: false
83
+ - name: manifest
84
+ description: >-
85
+ compute the attestation-manifest checksums (attestation/manifest.ts)
86
+ that verify-attestation.yml re-checks at merge time
87
+ task:
88
+ type: model_method
89
+ modelIdOrName: platform-common-shell-manifest
90
+ methodName: execute
91
+ inputs:
92
+ run: pnpm run attestation:manifest
93
+ dependsOn:
94
+ - step: assert-architecture
95
+ condition:
96
+ type: succeeded
97
+ weight: 0
98
+ allowFailure: false
99
+ - name: assert-manifest
100
+ description: attestation:manifest must exit 0
101
+ task:
102
+ type: assert
103
+ expr: >-
104
+ data.query('modelName == "platform-common-shell-manifest" && name == "result" &&
105
+ workflowRunId == "' + run.id + '"')[0].attributes.exitCode == 0
106
+ message: >-
107
+ failed to compute the attestation manifest — see the
108
+ platform-common-shell-manifest result data for stdout/stderr
109
+ severity: high
110
+ dependsOn:
111
+ - step: manifest
112
+ condition:
113
+ type: succeeded
114
+ weight: 0
115
+ allowFailure: false
116
+ dependsOn: []
117
+ weight: 0
118
+ version: 1