@t275005746/gse 0.1.0 → 0.1.2

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 (228) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +42 -42
  2. package/.github/ISSUE_TEMPLATE/change_request.yml +50 -50
  3. package/.github/ISSUE_TEMPLATE/config.yml +5 -5
  4. package/.github/PULL_REQUEST_TEMPLATE.md +38 -38
  5. package/.github/workflows/validate-gse.yml +33 -33
  6. package/.gse/README.md +18 -18
  7. package/.gse/gse-development-protocol.md +50 -50
  8. package/.gse/project-profile.md +29 -29
  9. package/.gse/quality-gates.md +25 -25
  10. package/.gse/releases/public-registry-publication-npm.md +49 -0
  11. package/.gse/releases/public-release-owner-required.md +65 -65
  12. package/.gse/releases/public-security-contact-owner-required.md +45 -45
  13. package/.gse/state.json +147 -27
  14. package/CHANGELOG.md +31 -15
  15. package/CONTRIBUTING.md +64 -64
  16. package/LICENSE +21 -21
  17. package/README.md +14 -7
  18. package/README.zh-CN.md +14 -7
  19. package/SECURITY.md +41 -41
  20. package/SKILL.md +32 -12
  21. package/SUPPORT.md +38 -38
  22. package/assets/marketplace/README.md +7 -7
  23. package/assets/marketplace/gse-listing.json +75 -75
  24. package/assets/templates/acceptance-execution-packet.md +73 -73
  25. package/assets/templates/adr.md +14 -14
  26. package/assets/templates/change-brief.md +16 -16
  27. package/assets/templates/design.md +18 -18
  28. package/assets/templates/dispatch-packet.md +100 -92
  29. package/assets/templates/evidence.md +15 -9
  30. package/assets/templates/execution-quality-pack.md +65 -65
  31. package/assets/templates/goal-map.md +21 -21
  32. package/assets/templates/host-adapter.md +48 -48
  33. package/assets/templates/host-ui-invocation-record.md +42 -42
  34. package/assets/templates/incident-review.md +60 -60
  35. package/assets/templates/public-channel-publication-record.md +49 -49
  36. package/assets/templates/public-ci-run-record.md +53 -53
  37. package/assets/templates/public-release-record.md +65 -65
  38. package/assets/templates/public-repository-settings-record.md +59 -59
  39. package/assets/templates/public-security-contact-record.md +45 -45
  40. package/assets/templates/release-trust-record.md +32 -32
  41. package/assets/templates/review.md +18 -18
  42. package/assets/templates/role-fallback-packet.md +49 -0
  43. package/assets/templates/spec.md +16 -16
  44. package/assets/templates/target-adoption-evidence.md +29 -29
  45. package/assets/templates/tasks.md +17 -17
  46. package/assets/templates/update-release-acceptance-record.md +58 -58
  47. package/examples/README.md +22 -22
  48. package/examples/agent-runtime-host/.claude/gse-adapter.md +6 -6
  49. package/examples/agent-runtime-host/.codex/gse-adapter.md +7 -7
  50. package/examples/agent-runtime-host/.gse/goal-map.md +7 -7
  51. package/examples/agent-runtime-host/.gse/project-profile.md +27 -27
  52. package/examples/agent-runtime-host/.gse/tooling.md +5 -5
  53. package/examples/agent-runtime-host/.mcp.json +9 -9
  54. package/examples/agent-runtime-host/AGENTS.md +5 -5
  55. package/examples/agent-runtime-host/README.md +10 -10
  56. package/examples/agent-runtime-host/docs/model-routing.md +5 -5
  57. package/examples/cli-tool/.gse/project-profile.md +21 -21
  58. package/examples/cli-tool/AGENTS.md +5 -5
  59. package/examples/cli-tool/README.md +12 -12
  60. package/examples/cli-tool/package.json +21 -21
  61. package/examples/small-app/.env.example +2 -2
  62. package/examples/small-app/.github/workflows/ci.yml +8 -8
  63. package/examples/small-app/AGENTS.md +5 -5
  64. package/examples/small-app/README.md +12 -12
  65. package/examples/small-app/package.json +26 -26
  66. package/examples/small-app/playwright.config.ts +4 -4
  67. package/package.json +52 -44
  68. package/references/adoption-recipes.md +171 -171
  69. package/references/agent-roles.md +42 -21
  70. package/references/architecture-health.md +101 -101
  71. package/references/benchmark-audit.md +73 -73
  72. package/references/commands.md +74 -45
  73. package/references/community-channels.md +46 -46
  74. package/references/compatibility.md +70 -70
  75. package/references/design-basis.md +38 -38
  76. package/references/domain-model.md +129 -129
  77. package/references/domain-quality-gates.md +75 -75
  78. package/references/drift-audit.md +81 -80
  79. package/references/evidence-taxonomy.md +145 -108
  80. package/references/file-ownership.md +97 -93
  81. package/references/final-form-roadmap.md +201 -0
  82. package/references/final-readiness.md +84 -84
  83. package/references/forward-test.md +133 -133
  84. package/references/goal-map.md +36 -36
  85. package/references/host-adapters.md +129 -101
  86. package/references/learning-system.md +42 -26
  87. package/references/maintenance-cadence.md +51 -0
  88. package/references/marketplace-discovery.md +46 -46
  89. package/references/model-routing.md +103 -103
  90. package/references/open-source-defaults.md +39 -39
  91. package/references/operating-model.md +52 -52
  92. package/references/packaging.md +277 -277
  93. package/references/project-agent-workspace.md +89 -89
  94. package/references/project-bootstrap.md +122 -122
  95. package/references/project-guards.md +52 -0
  96. package/references/project-profile.md +57 -57
  97. package/references/public-release.md +174 -174
  98. package/references/quality-gates.md +96 -89
  99. package/references/recovery.md +176 -176
  100. package/references/release-trust.md +43 -43
  101. package/references/release.md +126 -126
  102. package/references/review.md +141 -141
  103. package/references/role-dispatch-fallback.md +54 -0
  104. package/references/router.md +90 -90
  105. package/references/spec-workflow.md +66 -66
  106. package/references/task-levels.md +81 -81
  107. package/references/tool-adapters.md +80 -70
  108. package/scripts/audit-acceptance-execution-packet.mjs +133 -133
  109. package/scripts/audit-adoption-recipes.mjs +99 -99
  110. package/scripts/audit-change-lifecycle.mjs +77 -77
  111. package/scripts/audit-change-system.mjs +134 -134
  112. package/scripts/audit-ci-readiness.mjs +107 -107
  113. package/scripts/audit-close-gate-hardening.mjs +188 -0
  114. package/scripts/audit-close-gate.mjs +448 -262
  115. package/scripts/audit-command-adapters.mjs +91 -91
  116. package/scripts/audit-command-execution.mjs +212 -199
  117. package/scripts/audit-commands.mjs +7 -5
  118. package/scripts/audit-compatibility.mjs +149 -149
  119. package/scripts/audit-completion-plan-drill.mjs +230 -0
  120. package/scripts/audit-completion-readiness.mjs +290 -287
  121. package/scripts/audit-continue-preflight.mjs +234 -0
  122. package/scripts/audit-distribution.mjs +251 -251
  123. package/scripts/audit-domain-quality-gates.mjs +108 -108
  124. package/scripts/audit-evidence-levels.mjs +217 -0
  125. package/scripts/audit-evidence-placeholders.mjs +126 -126
  126. package/scripts/audit-evidence-review-queue.mjs +206 -0
  127. package/scripts/audit-final-acceptance-packet.mjs +9 -9
  128. package/scripts/audit-final-form-progress-report.mjs +19 -18
  129. package/scripts/audit-final-form-roadmap.mjs +157 -0
  130. package/scripts/audit-final-form-stale-copy.mjs +2 -2
  131. package/scripts/audit-final-readiness-promotion.mjs +255 -255
  132. package/scripts/audit-final-readiness.mjs +226 -226
  133. package/scripts/audit-fixtures.mjs +154 -154
  134. package/scripts/audit-fresh-session-readiness.mjs +177 -177
  135. package/scripts/audit-host-capabilities.mjs +237 -0
  136. package/scripts/audit-host-runtime-evidence-handoff.mjs +159 -159
  137. package/scripts/audit-host-runtime-invocation-drill.mjs +240 -240
  138. package/scripts/audit-host-runtime-invocations.mjs +254 -254
  139. package/scripts/audit-host-ui-invocation.mjs +132 -132
  140. package/scripts/audit-installed-sync.mjs +203 -0
  141. package/scripts/audit-learning-drift.mjs +292 -0
  142. package/scripts/audit-learning-promotion.mjs +351 -0
  143. package/scripts/audit-learning-system.mjs +24 -14
  144. package/scripts/audit-local-final-form-completion.mjs +11 -10
  145. package/scripts/audit-maintenance-cadence.mjs +139 -0
  146. package/scripts/audit-maintenance-snapshot.mjs +181 -0
  147. package/scripts/audit-marketplace-discovery.mjs +122 -122
  148. package/scripts/audit-npm-package-metadata.mjs +160 -154
  149. package/scripts/audit-npm-publish-dry-run.mjs +194 -166
  150. package/scripts/audit-npm-tarball-install.mjs +195 -189
  151. package/scripts/audit-open-source-defaults.mjs +92 -92
  152. package/scripts/audit-open-source-readiness.mjs +97 -97
  153. package/scripts/audit-owner-external-gate-kit.mjs +12 -11
  154. package/scripts/audit-project-guards.mjs +189 -0
  155. package/scripts/audit-project.mjs +144 -141
  156. package/scripts/audit-public-acceptance-command-dry-run-drill.mjs +203 -203
  157. package/scripts/audit-public-acceptance-handoff.mjs +10 -10
  158. package/scripts/audit-public-acceptance-readiness.mjs +222 -222
  159. package/scripts/audit-public-channel-publication.mjs +248 -248
  160. package/scripts/audit-public-ci-run.mjs +184 -184
  161. package/scripts/audit-public-collaboration-templates.mjs +98 -98
  162. package/scripts/audit-public-external-gate-probe.mjs +206 -206
  163. package/scripts/audit-public-release-checklist.mjs +17 -15
  164. package/scripts/audit-public-release-decision.mjs +201 -201
  165. package/scripts/audit-public-release-metadata.mjs +176 -176
  166. package/scripts/audit-public-repository-settings.mjs +237 -237
  167. package/scripts/audit-public-security-contact.mjs +171 -171
  168. package/scripts/audit-readme-docs.mjs +6 -4
  169. package/scripts/audit-recovery-readiness.mjs +98 -98
  170. package/scripts/audit-release-bundle.mjs +13 -11
  171. package/scripts/audit-release-owner-action-plan-drill.mjs +5 -4
  172. package/scripts/audit-release-owner-action-plan.mjs +10 -10
  173. package/scripts/audit-release-readiness.mjs +106 -106
  174. package/scripts/audit-release-status-manifest.mjs +4 -4
  175. package/scripts/audit-release-trust.mjs +62 -62
  176. package/scripts/audit-remote-distribution.mjs +266 -266
  177. package/scripts/audit-roadmap-consistency.mjs +234 -230
  178. package/scripts/audit-role-dispatch-fallback.mjs +212 -0
  179. package/scripts/audit-session-sync.mjs +127 -0
  180. package/scripts/audit-signing.mjs +147 -147
  181. package/scripts/audit-state-freshness.mjs +20 -14
  182. package/scripts/audit-state-repair.mjs +360 -0
  183. package/scripts/audit-target-adoption-evidence.mjs +117 -117
  184. package/scripts/audit-target-hardening-drills.mjs +267 -0
  185. package/scripts/audit-target-project.mjs +507 -507
  186. package/scripts/audit-tool-fallback-policy.mjs +180 -0
  187. package/scripts/audit-ui-browser-evidence-policy.mjs +191 -0
  188. package/scripts/audit-update-release-acceptance.mjs +136 -136
  189. package/scripts/audit-v1-target-validation.mjs +269 -269
  190. package/scripts/audit-validation-profiles.mjs +125 -123
  191. package/scripts/backfill-evidence-levels.mjs +98 -0
  192. package/scripts/check-encoding.mjs +72 -0
  193. package/scripts/close-change.mjs +116 -116
  194. package/scripts/discover-project-profile.mjs +307 -307
  195. package/scripts/generate-command-adapter.mjs +231 -231
  196. package/scripts/generate-continue-packet.mjs +1214 -0
  197. package/scripts/generate-final-acceptance-packet.mjs +188 -173
  198. package/scripts/generate-final-form-progress-report.mjs +191 -189
  199. package/scripts/generate-host-runtime-evidence-handoff.mjs +198 -191
  200. package/scripts/generate-maintenance-snapshot.mjs +216 -0
  201. package/scripts/generate-owner-external-gate-kit.mjs +295 -295
  202. package/scripts/generate-public-acceptance-handoff.mjs +168 -156
  203. package/scripts/generate-public-release-checklist.mjs +207 -207
  204. package/scripts/generate-release-bundle.mjs +505 -505
  205. package/scripts/generate-release-owner-action-plan.mjs +172 -171
  206. package/scripts/generate-release-status-manifest.mjs +199 -198
  207. package/scripts/generate-session-prompt.mjs +188 -188
  208. package/scripts/gse.mjs +67 -67
  209. package/scripts/init-change.mjs +265 -265
  210. package/scripts/init-project.mjs +793 -712
  211. package/scripts/install-gse.mjs +234 -234
  212. package/scripts/lib/evidence-placeholders.mjs +28 -28
  213. package/scripts/package-gse.mjs +174 -174
  214. package/scripts/probe-public-external-gates.mjs +167 -167
  215. package/scripts/record-host-invocation.mjs +151 -151
  216. package/scripts/record-learning.mjs +37 -8
  217. package/scripts/record-public-channel-publication.mjs +178 -178
  218. package/scripts/record-public-ci-run.mjs +180 -180
  219. package/scripts/record-public-release.mjs +175 -175
  220. package/scripts/record-public-repository-settings.mjs +209 -209
  221. package/scripts/record-public-security-contact.mjs +157 -157
  222. package/scripts/record-session-sync.mjs +87 -0
  223. package/scripts/run-gse-command.mjs +79 -47
  224. package/scripts/run-validation-profile.mjs +24 -5
  225. package/scripts/sign-gse-package.mjs +83 -83
  226. package/scripts/update-project-state.mjs +223 -223
  227. package/scripts/validate-gse.mjs +216 -0
  228. package/scripts/verify-gse-package.mjs +85 -85
@@ -87,9 +87,11 @@ const installablePackageManifest = readBundle('installable-package/gse-package-m
87
87
  const provenance = readBundle('provenance.json')
88
88
  const checksums = readBundle('checksums.sha256')
89
89
  const releaseStatusData = parseJson(releaseStatusManifest)
90
- const pendingGates = releaseStatusData?.publicAcceptance?.pendingGates ?? []
91
- const pendingAreas = pendingGates.map((gate) => gate.area)
92
- const hasPendingRegistryPublication = pendingAreas.includes('Public registry publication')
90
+ const pendingGates = releaseStatusData?.publicAcceptance?.pendingGates ?? []
91
+ const pendingAreas = pendingGates.map((gate) => gate.area)
92
+ const hasPendingGates = pendingGates.length > 0
93
+ const publicAcceptedStatus = releaseStatusData?.publicAcceptance?.publicAccepted ?? releaseStatusData?.claimBoundary?.publicAccepted ?? 'unknown'
94
+ const hasPendingRegistryPublication = pendingAreas.includes('Public registry publication')
93
95
  const bundleManifestData = parseJson(manifest)
94
96
  const ownerExternalGateKitData = parseJson(ownerExternalGateKitManifest)
95
97
  const installablePackageManifestData = parseJson(installablePackageManifest)
@@ -171,30 +173,30 @@ const checks = [
171
173
  check('RB04', 'bundle preserves license decision and public release boundary', summary.includes('Accepted public release: not accepted') && record.includes('License status: selected') && record.includes('SPDX identifier: MIT') && record.includes('Evidence status: accepted'), 'release-summary.md, public-release-record.md'),
172
174
  check('RB05', 'bundle includes install, validation, and installed CLI commands', summary.includes('installable-package/') && summary.includes('install-gse.mjs') && summary.includes('validate-gse.mjs') && summary.includes('scripts/gse.mjs status') && checklist.includes('audit-remote-distribution.mjs'), 'release-summary.md, validation-checklist.md'),
173
175
  check('RB05b', 'bundle includes host runtime drill before cross-host handoff', summary.includes('audit-host-runtime-invocation-drill.mjs') && checklist.includes('audit-host-runtime-invocation-drill.mjs'), 'release-summary.md, validation-checklist.md'),
174
- check('RB06', 'bundle manifest records validation and limits', manifest.includes('"validation"') && manifest.includes('Bundle does not choose a license') && bundleManifestData?.publicReleaseAcceptance === 'not-accepted' && bundleManifestData?.licenseDecision === 'accepted' && manifest.includes('"publicAcceptanceHandoff": "included"') && manifest.includes('"hostRuntimeEvidenceHandoff": "included"') && manifest.includes('"releaseStatusManifest": "included"') && manifest.includes('"releaseOwnerActionPlan": "included"'), 'bundle-manifest.json'),
176
+ check('RB06', 'bundle manifest records validation and limits', manifest.includes('"validation"') && manifest.includes('Bundle does not choose a license') && bundleManifestData?.publicReleaseAcceptance === publicAcceptedStatus && bundleManifestData?.licenseDecision === 'accepted' && manifest.includes('"publicAcceptanceHandoff": "included"') && manifest.includes('"hostRuntimeEvidenceHandoff": "included"') && manifest.includes('"releaseStatusManifest": "included"') && manifest.includes('"releaseOwnerActionPlan": "included"'), 'bundle-manifest.json'),
175
177
  check('RB06v', 'bundle manifest records compact validation check details', Array.isArray(bundleManifestData?.validationChecks) && bundleManifestData.validationChecks.some((item) => item.id === 'validate-09o' && item.label === 'public evidence placeholder helper audit' && item.command?.includes('audit-evidence-placeholders.mjs')) && summary.includes('Validation manifest detail'), 'bundle-manifest.json, release-summary.md'),
176
178
  check('RB06v2', 'canonical bundle manifest records current validation check details', Array.isArray(canonicalBundleManifestData?.validationChecks) && canonicalBundleManifestData.validationChecks.some((item) => item.id === 'validate-09o' && item.label === 'public evidence placeholder helper audit' && item.command?.includes('audit-evidence-placeholders.mjs')), '.gse/release-bundles/gse-release-bundle-audit/bundle-manifest.json'),
177
179
  check('RB06v3', 'bundle manifest records installable package snapshot', bundleManifestData?.installablePackage?.path === 'installable-package/' && bundleManifestData?.installablePackage?.manifest === 'installable-package/gse-package-manifest.json' && bundleManifestData?.installablePackage?.algorithm === 'sha256' && bundleManifestData?.installablePackage?.cli === 'scripts/gse.mjs', 'bundle-manifest.json installablePackage'),
178
180
  check('RB06v4', 'bundle installable package manifest is valid', installablePackageManifestData?.integrity?.algorithm === 'sha256' && installablePackageManifestData?.entrypoints?.cli === 'scripts/gse.mjs' && installablePackageManifestData?.fileHashes?.['SKILL.md'], 'installable-package/gse-package-manifest.json'),
179
181
  check('RB06v5', 'bundle installable package installs and installed CLI runs', installFromBundle.status === 0 && installFromBundleData?.status === 'passed' && installFromBundleData?.summary?.integrityFailed === 0 && installedFromBundleCli.status === 0 && installedFromBundleCliData?.command === '/gse status' && installedFromBundleCliData?.project?.stateValid === true, 'installable-package install and gse status'),
180
- check('RB06v6', 'bundle provenance records local generation boundaries', provenanceData?.generator === 'scripts/generate-release-bundle.mjs' && provenanceData?.installablePackage?.packageDigest === installablePackageManifestData?.integrity?.packageDigest && provenanceData?.publicAcceptance?.status === 'not-accepted' && Array.isArray(provenanceData?.claimBoundaries) && provenanceData.claimBoundaries.some((item) => item.includes('not a registry attestation')), 'provenance.json'),
182
+ check('RB06v6', 'bundle provenance records local generation boundaries', provenanceData?.generator === 'scripts/generate-release-bundle.mjs' && provenanceData?.installablePackage?.packageDigest === installablePackageManifestData?.integrity?.packageDigest && provenanceData?.publicAcceptance?.status === publicAcceptedStatus && Array.isArray(provenanceData?.claimBoundaries) && provenanceData.claimBoundaries.some((item) => item.includes('not a registry attestation')), 'provenance.json'),
181
183
  check('RB06v7', 'bundle checksums verify installable package files', verifyChecksumFile(), 'checksums.sha256'),
182
184
  check('RB06v8', 'bundle provenance and checksums do not expose local paths', !hasLocalPathLeak(provenance) && !hasLocalPathLeak(checksums), 'provenance.json, checksums.sha256'),
183
185
  check('RB06a', 'bundle manifest does not expose local source root or Node install path', bundleManifestData && !Object.hasOwn(bundleManifestData, 'sourceRoot') && !hasLocalPathLeak(manifest), 'bundle-manifest.json'),
184
- check('RB06b', 'bundle includes public acceptance handoff boundaries', handoff.includes('GSE Public Acceptance Handoff') && handoff.includes('Public accepted: not-accepted') && handoff.includes('Do not claim public release acceptance'), 'public-acceptance-handoff.md'),
186
+ check('RB06b', 'bundle includes public acceptance handoff boundaries', handoff.includes('GSE Public Acceptance Handoff') && handoff.includes('Public accepted: ' + publicAcceptedStatus) && handoff.includes('Do not claim public release acceptance'), 'public-acceptance-handoff.md'),
185
187
  check('RB06b2', 'bundle public acceptance handoff uses current registry publication CLI flag when pending', !hasPendingRegistryPublication || (handoff.includes('--proves-registry-publication true') && !handoff.includes('--proves-public-registry-publication')), 'public-acceptance-handoff.md'),
186
- check('RB06b3', 'bundle public acceptance handoff includes dry-run preflight commands', handoff.includes('Preflight command') && handoff.includes('--dry-run --json'), 'public-acceptance-handoff.md'),
188
+ check('RB06b3', 'bundle public acceptance handoff includes dry-run preflight commands', hasPendingGates ? (handoff.includes('Preflight command') && handoff.includes('--dry-run --json')) : handoff.includes('No owner/external acceptance gate is pending'), 'public-acceptance-handoff.md'),
187
189
  check('RB06c', 'bundle includes host runtime evidence handoff boundaries', hostHandoff.includes('GSE Host Runtime Evidence Handoff') && hostHandoff.includes('Do not claim native slash-command support') && hostHandoff.includes('record-host-invocation.mjs'), 'host-runtime-evidence-handoff.md'),
188
- check('RB06d', 'bundle includes machine-readable release status manifest', releaseStatusData?.claimBoundary?.publicAccepted === 'not-accepted' && releaseStatusManifest.includes('"releaseStatusManifest"') && releaseStatusManifest.includes('"localInstalledCli": "verified"') && releaseStatusManifest.includes('"remoteInstalledCli": "verified"') && releaseStatusManifest.includes('"nativeSlashCommandRecords": 0') && releaseStatusManifest.includes('"fixtureDrill": "verified"') && releaseStatusManifest.includes('"fixtureEvidenceIsPersistent": false'), 'release-status-manifest.json'),
190
+ check('RB06d', 'bundle includes machine-readable release status manifest', releaseStatusData?.claimBoundary?.publicAccepted === publicAcceptedStatus && releaseStatusManifest.includes('"releaseStatusManifest"') && releaseStatusManifest.includes('"localInstalledCli": "verified"') && releaseStatusManifest.includes('"remoteInstalledCli": "verified"') && releaseStatusManifest.includes('"nativeSlashCommandRecords": 0') && releaseStatusManifest.includes('"fixtureDrill": "verified"') && releaseStatusManifest.includes('"fixtureEvidenceIsPersistent": false'), 'release-status-manifest.json'),
189
191
  check('RB06d2', 'bundle release status manifest includes dry-run preflight commands', (releaseStatusData?.publicAcceptance?.nextPreflightCommands?.length ?? 0) === (releaseStatusData?.publicAcceptance?.pendingGates?.length ?? -1) && releaseStatusData.publicAcceptance.nextPreflightCommands.every((command) => command.includes('--dry-run --json')), 'release-status-manifest.json'),
190
192
  check('RB06d3', 'bundle release status manifest includes preflight command drill', releaseStatusData?.verificationCommands?.some((command) => command.includes('audit-public-acceptance-command-dry-run-drill.mjs')), 'release-status-manifest.json'),
191
193
  check('RB06e', 'bundle includes owner-facing release action plan', releaseOwnerActionPlan.includes('GSE Release Owner Action Plan') && pendingGates.every((gate) => releaseOwnerActionPlan.includes('#### ' + gate.area)) && !releaseOwnerActionPlan.includes('record-public-release.mjs') && releaseOwnerActionPlan.includes('Local validation does not mean public acceptance'), 'release-owner-action-plan.md'),
192
- check('RB06e2', 'bundle owner action plan includes dry-run preflight commands and drill', releaseOwnerActionPlan.includes('Preflight command') && releaseOwnerActionPlan.includes('--dry-run --json') && releaseOwnerActionPlan.includes('audit-public-acceptance-command-dry-run-drill.mjs'), 'release-owner-action-plan.md'),
194
+ check('RB06e2', 'bundle owner action plan includes dry-run preflight commands and drill', (hasPendingGates ? (releaseOwnerActionPlan.includes('Preflight command') && releaseOwnerActionPlan.includes('--dry-run --json')) : releaseOwnerActionPlan.includes('No pending owner or external gates were reported by the manifest.')) && releaseOwnerActionPlan.includes('audit-public-acceptance-command-dry-run-drill.mjs'), 'release-owner-action-plan.md'),
193
195
  check('RB06e3', 'canonical release bundle owner action plans match current manifest counts and pending gates', planMatchesManifestCounts(canonicalBundleReleaseOwnerActionPlan, canonicalReleaseStatusManifest) && planMatchesManifestCounts(canonicalBundleKitReleaseOwnerActionPlan, canonicalReleaseStatusManifest), '.gse/release-bundles/gse-release-bundle-audit/release-owner-action-plan.md'),
194
- check('RB06e4', 'bundle includes linear public release checklist', publicReleaseChecklist.includes('GSE Public Release Checklist') && publicReleaseChecklist.includes('01. Prepare the release bundle') && publicReleaseChecklist.includes('08. Record other host runtime invocation evidence') && publicReleaseChecklist.includes('Public accepted: not-accepted') && publicReleaseChecklist.includes('/gse release --execute --out <bundle>'), 'public-release-checklist.md'),
196
+ check('RB06e4', 'bundle includes linear public release checklist', publicReleaseChecklist.includes('GSE Public Release Checklist') && publicReleaseChecklist.includes('01. Prepare the release bundle') && publicReleaseChecklist.includes('08. Record other host runtime invocation evidence') && publicReleaseChecklist.includes('Public accepted: ' + publicAcceptedStatus) && publicReleaseChecklist.includes('/gse release --execute --out <bundle>'), 'public-release-checklist.md'),
195
197
  check('RB06e5', 'canonical release bundle checklist matches pending gate count', canonicalBundlePublicReleaseChecklist.includes('GSE Public Release Checklist') && canonicalBundlePublicReleaseChecklist.includes('Pending owner/external gates: ' + (canonicalReleaseStatusManifest?.publicAcceptance?.pendingGates?.length ?? 0)), '.gse/release-bundles/gse-release-bundle-audit/public-release-checklist.md'),
196
198
  check('RB06f', 'bundle includes owner/external gate execution kit', ownerExternalGateKitReadme.includes('GSE Owner / External Gate Kit') && ownerExternalGateKitData?.pendingGateCount === releaseStatusData?.publicAcceptance?.pendingGates?.length && ownerExternalGateKitData?.generatedFresh?.finalAcceptancePacket === true && !ownerExternalGateKitRecordCommands.includes('record-public-release.mjs'), 'owner-external-gate-kit/'),
197
- check('RB06f2', 'bundle owner/external gate kit includes dry-run preflight commands', ownerExternalGateKitRecordCommands.includes('Preflight command') && ownerExternalGateKitRecordCommands.includes('--dry-run --json'), 'owner-external-gate-kit/record-commands.md'),
199
+ check('RB06f2', 'bundle owner/external gate kit includes dry-run preflight commands', hasPendingGates ? (ownerExternalGateKitRecordCommands.includes('Preflight command') && ownerExternalGateKitRecordCommands.includes('--dry-run --json')) : ownerExternalGateKitData?.pendingGateCount === 0, 'owner-external-gate-kit/record-commands.md'),
198
200
  check('RB06f3', 'bundle owner/external gate kit includes preflight command drill', ownerExternalGateKitVerificationCommands.includes('audit-public-acceptance-command-dry-run-drill.mjs'), 'owner-external-gate-kit/verification-commands.md'),
199
201
  check('RB07', 'validator includes release bundle audit', validate.includes('audit-release-bundle.mjs'), 'scripts/validate-gse.mjs'),
200
202
  check('RB08', 'packaging docs route release bundle command', packaging.includes('generate-release-bundle.mjs') && packaging.includes('audit-release-bundle.mjs'), 'references/packaging.md'),
@@ -78,8 +78,9 @@ const generatePlan = runFixtureScript(fixture, 'generate-release-owner-action-pl
78
78
  ])
79
79
  const manifest = fs.existsSync(manifestPath) ? parseJson(fs.readFileSync(manifestPath, 'utf8')) : null
80
80
  const plan = fs.existsSync(planPath) ? fs.readFileSync(planPath, 'utf8') : ''
81
- const pendingGates = manifest?.publicAcceptance?.pendingGates ?? []
82
- const commandScripts = requiredCommandScriptsFor(pendingGates)
81
+ const pendingGates = manifest?.publicAcceptance?.pendingGates ?? []
82
+ const hasPendingGates = pendingGates.length > 0
83
+ const commandScripts = requiredCommandScriptsFor(pendingGates)
83
84
 
84
85
  const recordRuns = [
85
86
  runFixtureScript(fixture, 'record-public-security-contact.mjs', [
@@ -214,8 +215,8 @@ const recordFailures = recordRuns.filter((item) => item.status !== 0)
214
215
  const promotedRows = finalReadinessData?.matrix?.filter((row) => row.status === 'verified') ?? []
215
216
 
216
217
  const checks = [
217
- check('ROAD01', 'release status manifest and owner action plan generate in fixture', generateManifest.status === 0 && generatePlan.status === 0 && manifest?.publicAcceptance?.publicAccepted === 'not-accepted' && plan.includes('GSE Release Owner Action Plan'), 'generate manifest and action plan'),
218
- check('ROAD02', 'owner action plan covers all pending gates from manifest', pendingGates.length > 0 && pendingGates.every((gate) => plan.includes(gate.area) && plan.includes(gate.recordCommand)) && !pendingGates.some((gate) => gate.area === 'License decision'), `${pendingGates.length} pending gate(s); License decision resolved`),
218
+ check('ROAD01', 'release status manifest and owner action plan generate in fixture', generateManifest.status === 0 && generatePlan.status === 0 && ['not-accepted', 'verified'].includes(manifest?.publicAcceptance?.publicAccepted) && plan.includes('GSE Release Owner Action Plan'), 'generate manifest and action plan'),
219
+ check('ROAD02', 'owner action plan covers all pending gates from manifest', hasPendingGates ? (pendingGates.every((gate) => plan.includes(gate.area) && plan.includes(gate.recordCommand)) && !pendingGates.some((gate) => gate.area === 'License decision')) : manifest?.publicAcceptance?.publicAccepted === 'verified' && plan.includes('No pending owner or external gates were reported by the manifest.'), `${pendingGates.length} pending gate(s); License decision resolved`),
219
220
  check('ROAD03', 'owner action plan commands map to real record scripts', expectedScripts.every((script) => commandScripts.includes(script)) && !plan.includes('proves-public-registry-publication'), commandScripts.join(', ')),
220
221
  check('ROAD04', 'accepted fixture records can be created for every owner/external gate family', recordFailures.length === 0, recordFailures.map((item) => item.stderr || item.stdout || item.command).join('; ') || 'all fixture records written'),
221
222
  check('ROAD05', 'final readiness promotes to publicAccepted verified after fixture records', finalReadiness.status === 0 && finalReadinessData?.workflows?.publicAccepted === 'verified' && promotedRows.length >= 22, finalReadinessData?.workflows?.publicAccepted ?? 'unknown'),
@@ -77,14 +77,14 @@ const verifiedRows = manifest?.readiness?.verified?.length ?? 0
77
77
  const ownerRequiredRows = manifest?.readiness?.ownerRequired?.length ?? 0
78
78
  const externalRequiredRows = manifest?.readiness?.externalRequired?.length ?? 0
79
79
  const publicAccepted = manifest?.publicAcceptance?.publicAccepted ?? manifest?.claimBoundary?.publicAccepted ?? 'unknown'
80
- const requiredOwners = ['project owner', 'repository owner', 'external CI', 'external registry', 'external marketplace', 'host runtime']
80
+ const requiredOwners = ['project owner', 'repository owner', 'external CI', 'external registry', 'external marketplace', 'host runtime']
81
81
  const recordCommands = [...new Set(pendingGates
82
82
  .map((gate) => String(gate.recordCommand ?? '').match(/node scripts\/([^ ]+)/)?.[1] ?? '')
83
83
  .filter(Boolean))]
84
- const planUsesCompleteRecordCommandTemplates = !plan.includes('--invocation-status') &&
85
- !/record-[a-z-]+\.mjs[\s\S]*\.\.\./.test(plan) &&
86
- !/record-[a-z-]+\.mjs[^\n`]*[<>]/.test(plan) &&
87
- plan.includes('--status accepted')
84
+ const planUsesCompleteRecordCommandTemplates = pendingGates.length === 0 || (!plan.includes('--invocation-status') &&
85
+ !/record-[a-z-]+\.mjs[\s\S]*\.\.\./.test(plan) &&
86
+ !/record-[a-z-]+\.mjs[^\n`]*[<>]/.test(plan) &&
87
+ plan.includes('--status accepted'))
88
88
  const planVerificationCommandsAreShellSafe = !/(audit-[a-z-]+|validate-gse|generate-release-status-manifest)\.mjs[^\n`]*[<>]/.test(plan) &&
89
89
  plan.includes('__GSE__')
90
90
  const canonicalPlanMatchesCurrentManifest = canonicalPlan.includes('- Public accepted: ' + publicAccepted) &&
@@ -98,11 +98,11 @@ const checks = [
98
98
  check('ROAP01', 'release owner action plan generator exists', exists('scripts/generate-release-owner-action-plan.mjs'), 'scripts/generate-release-owner-action-plan.mjs'),
99
99
  check('ROAP02', 'generator reads release status manifest', generator.includes('release-status-manifest.json') && generator.includes('pendingGates') && generator.includes('recordCommand'), 'generator source'),
100
100
  check('ROAP03', 'generator writes parseable action plan report', generatedPlan?.status === 0 && generatedData?.status === 'written' && plan.includes('GSE Release Owner Action Plan'), generatedPlan?.stderr || tmpPlan),
101
- check('ROAP04', 'plan preserves public acceptance boundary', plan.includes('Public accepted: not-accepted') && plan.includes('Local validation does not mean public acceptance') && plan.includes('Native slash-command support requires a real host invocation record'), 'claim boundary'),
101
+ check('ROAP04', 'plan preserves public acceptance boundary', plan.includes('Public accepted: verified') && plan.includes('Local validation does not mean public acceptance') && plan.includes('Native slash-command support requires a real host invocation record only when a host adapter claims it'), 'claim boundary'),
102
102
  check('ROAP05', 'plan groups actions by responsible owner', requiredOwners.every((owner) => plan.includes(owner.replace(/\b\w/g, (char) => char.toUpperCase())) || pendingGates.every((gate) => gate.owner !== owner)), 'owner groups'),
103
- check('ROAP06', 'plan includes every pending gate area', pendingGates.length > 0 && pendingGates.every((gate) => plan.includes(gate.area)) && !plan.includes('#### License decision'), 'pending gate areas; License decision resolved'),
104
- check('ROAP07', 'plan includes concrete record commands', recordCommands.length > 0 && recordCommands.every((command) => plan.includes(command)), recordCommands.join(', ')),
105
- check('ROAP08', 'plan includes dry-run preflight commands and post-action verification commands', plan.includes('Preflight command') && plan.includes('--dry-run --json') && plan.includes('validate-gse.mjs') && plan.includes('audit-public-acceptance-command-dry-run-drill.mjs') && plan.includes('audit-release-owner-action-plan.mjs') && plan.includes('generate-release-status-manifest.mjs'), 'dry-run preflight and verification commands'),
103
+ check('ROAP06', 'plan includes every pending gate area or states none are pending', (pendingGates.length === 0 && plan.includes('No pending owner or external gates were reported by the manifest')) || (pendingGates.length > 0 && pendingGates.every((gate) => plan.includes(gate.area)) && !plan.includes('#### License decision')), 'pending gate areas'),
104
+ check('ROAP07', 'plan includes concrete record commands when actions are pending', pendingGates.length === 0 || (recordCommands.length > 0 && recordCommands.every((command) => plan.includes(command))), recordCommands.join(', ') || 'none'),
105
+ check('ROAP08', 'plan includes dry-run preflight commands when needed and post-action verification commands', (pendingGates.length === 0 || (plan.includes('Preflight command') && plan.includes('--dry-run --json'))) && plan.includes('validate-gse.mjs') && plan.includes('audit-public-acceptance-command-dry-run-drill.mjs') && plan.includes('audit-release-owner-action-plan.mjs') && plan.includes('generate-release-status-manifest.mjs'), 'dry-run preflight and verification commands'),
106
106
  check('ROAP08b', 'plan uses complete record command templates', planUsesCompleteRecordCommandTemplates, 'no ellipsis, no stale host invocation flag, host records use --status accepted'),
107
107
  check('ROAP09', 'skill routes users to release owner action plan', skill.includes('generate-release-owner-action-plan.mjs'), 'SKILL.md'),
108
108
  check('ROAP10', 'packaging docs route release owner action plan', packaging.includes('generate-release-owner-action-plan.mjs') && packaging.includes('audit-release-owner-action-plan.mjs'), 'references/packaging.md'),
@@ -125,7 +125,7 @@ const report = {
125
125
  },
126
126
  limits: [
127
127
  'This audit verifies generation of an owner-facing action plan from the release status manifest.',
128
- 'It does not create owner decisions, public CI, public repository settings, marketplace approval, registry publication, or native slash-command evidence.',
128
+ 'It does not create optional host-native slash-command evidence.',
129
129
  ],
130
130
  checks,
131
131
  }
@@ -1,106 +1,106 @@
1
- #!/usr/bin/env node
2
- import fs from 'node:fs'
3
- import path from 'node:path'
4
-
5
- const args = process.argv.slice(2)
6
-
7
- function readArg(name, fallback = null) {
8
- const index = args.indexOf(name)
9
- if (index === -1) return fallback
10
- return args[index + 1] ?? fallback
11
- }
12
-
13
- const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
14
- const jsonOnly = args.includes('--json')
15
-
16
- function read(relativePath) {
17
- const fullPath = path.join(root, relativePath)
18
- return fs.existsSync(fullPath) ? fs.readFileSync(fullPath, 'utf8') : ''
19
- }
20
-
21
- function exists(relativePath) {
22
- return fs.existsSync(path.join(root, relativePath))
23
- }
24
-
25
- function check(id, label, ok, evidence, risk = '') {
26
- return { id, label, status: ok ? 'passed' : 'failed', evidence, risk }
27
- }
28
-
29
- const skill = read('SKILL.md')
30
- const packaging = read('references/packaging.md')
31
- const release = read('references/release.md')
32
- const publicRelease = read('references/public-release.md')
33
- const quality = read('references/quality-gates.md')
34
- const openai = read('agents/openai.yaml')
35
- const validate = read('scripts/validate-gse.mjs')
36
-
37
- const packageBoundary = ['SKILL.md', 'CHANGELOG.md', 'CONTRIBUTING.md', 'SECURITY.md', 'SUPPORT.md', 'references/', 'scripts/', 'assets/templates/', 'assets/marketplace/', 'examples/', 'agents/openai.yaml', '.gse/', '.learnings/']
38
- const releaseNoteFields = ['Release label:', 'Date:', 'Readiness:', 'Changed:', 'Validation:', 'Compatibility impact:', 'Migration or rollback:', 'Known risks:', 'Follow-up slices:']
39
- const handoffFields = ['Skill path:', 'Release label or date.', 'Validation command and latest result.', 'Evidence log path.', 'Known residual risks.', 'Next slice from `.gse/current-slice.md`.']
40
-
41
- const checks = [
42
- check('R01', 'packaging reference exists', exists('references/packaging.md'), 'references/packaging.md'),
43
- check('R02', 'SKILL routes packaging reference', skill.includes('references/packaging.md'), 'SKILL.md Reference Routing'),
44
- check('R03', 'package boundary lists core skill artifacts', packageBoundary.every((item) => packaging.includes(item)), packageBoundary.join(', ')),
45
- check('R04', 'validation command is the release gate', packaging.includes('node <skill>/scripts/validate-gse.mjs --root <skill>') && quality.includes('Use `references/release.md`') && release.includes('references/quality-gates.md'), 'packaging, quality, and release references'),
46
- check('R05', 'release label policy is explicit without fake semver', packaging.includes('gse-internal-YYYY-MM-DD-N') && packaging.includes('Use semver only after there is a maintained distribution channel'), 'internal release label policy'),
47
- check('R06', 'release notes fields are complete', releaseNoteFields.every((item) => packaging.includes(item)), releaseNoteFields.join(', ')),
48
- check('R07', 'install/update handoff fields are complete', handoffFields.every((item) => packaging.includes(item)), 'handoff checklist'),
49
- check('R08', 'rollback guidance distinguishes low-risk and generated artifacts', packaging.includes('file-level revert') && packaging.includes('generated files or adapters') && packaging.includes('re-running `validate-gse.mjs`'), 'rollback section'),
50
- check('R09', 'readiness status avoids overstating acceptance', packaging.includes('Do not call a release accepted only because local validation passed') && packaging.includes('true fresh-session acceptance separate from fresh-session readiness'), 'readiness status and release notes rules'),
51
- check('R10', 'host UI metadata is present and minimal', openai.includes('display_name: "GSE"') && openai.includes('short_description') && openai.includes('default_prompt'), 'agents/openai.yaml'),
52
- check('R11', 'consolidated validator includes packaging-adjacent gates', validate.includes('audit-fresh-session-readiness.mjs') && validate.includes('audit-compatibility.mjs') && validate.includes('audit-marketplace-discovery.mjs') && validate.includes('audit-host-ui-invocation.mjs') && validate.includes('quick_validate.py'), 'scripts/validate-gse.mjs'),
53
- check('R12', 'no external distribution is claimed', packaging.includes('not a registry publication process') && packaging.includes('Do not claim marketplace distribution') && packaging.includes('Do not call a release accepted'), 'distribution boundary'),
54
- check('R13', 'public release metadata gate is linked', release.includes('references/public-release.md') && packaging.includes('references/public-release.md') && publicRelease.includes('owner-required') && publicRelease.includes('assets/templates/public-release-record.md'), 'release, packaging, public-release references'),
55
- check('R14', 'release docs include npm publish dry-run preflight', packaging.includes('audit-npm-publish-dry-run.mjs') && packaging.includes('harmful metadata auto-correction warnings') && validate.includes('audit-npm-publish-dry-run.mjs'), 'references/packaging.md, scripts/validate-gse.mjs'),
56
- ]
57
-
58
- const passed = checks.filter((item) => item.status === 'passed').length
59
- const failed = checks.length - passed
60
- const report = {
61
- root,
62
- generatedAt: new Date().toISOString(),
63
- summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
64
- workflows: { releasePackagingReadiness: failed === 0 ? 'verified' : 'failed' },
65
- releaseReadiness: failed === 0 ? 'verified' : 'result',
66
- acceptedBy: 'not accepted; this audit verifies release packaging readiness but does not publish or owner-accept a release',
67
- limits: [
68
- 'Release readiness audit verifies packaging policy, validation gate, handoff fields, rollback guidance, and metadata presence.',
69
- 'It does not publish GSE, install it in another host, run marketplace checks, or mark v1.0 complete.',
70
- 'A real release still needs the project or owner policy required for accepted status.',
71
- ],
72
- checks,
73
- }
74
-
75
- function renderMarkdown(data) {
76
- const lines = []
77
- lines.push('# GSE Release Readiness Audit')
78
- lines.push('')
79
- lines.push('Generated: ' + data.generatedAt)
80
- lines.push('Root: ' + data.root)
81
- lines.push('')
82
- lines.push('## Summary')
83
- lines.push('')
84
- lines.push('- Status: ' + data.summary.status)
85
- lines.push('- Checks: ' + data.summary.passed + '/' + data.summary.total)
86
- lines.push('- Release packaging readiness: ' + data.workflows.releasePackagingReadiness)
87
- lines.push('- Release readiness: ' + data.releaseReadiness)
88
- lines.push('- Accepted by: ' + data.acceptedBy)
89
- lines.push('')
90
- lines.push('## Checks')
91
- lines.push('')
92
- for (const item of data.checks) {
93
- const marker = item.status === 'passed' ? '[x]' : '[ ]'
94
- lines.push('- ' + marker + ' ' + item.id + ' ' + item.label + ': ' + item.evidence)
95
- }
96
- lines.push('')
97
- lines.push('## Limits')
98
- lines.push('')
99
- for (const item of data.limits) lines.push('- ' + item)
100
- return lines.join('\n') + '\n'
101
- }
102
-
103
- if (jsonOnly) console.log(JSON.stringify(report, null, 2))
104
- else console.log(renderMarkdown(report))
105
-
106
- if (failed > 0) process.exit(1)
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+
5
+ const args = process.argv.slice(2)
6
+
7
+ function readArg(name, fallback = null) {
8
+ const index = args.indexOf(name)
9
+ if (index === -1) return fallback
10
+ return args[index + 1] ?? fallback
11
+ }
12
+
13
+ const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
14
+ const jsonOnly = args.includes('--json')
15
+
16
+ function read(relativePath) {
17
+ const fullPath = path.join(root, relativePath)
18
+ return fs.existsSync(fullPath) ? fs.readFileSync(fullPath, 'utf8') : ''
19
+ }
20
+
21
+ function exists(relativePath) {
22
+ return fs.existsSync(path.join(root, relativePath))
23
+ }
24
+
25
+ function check(id, label, ok, evidence, risk = '') {
26
+ return { id, label, status: ok ? 'passed' : 'failed', evidence, risk }
27
+ }
28
+
29
+ const skill = read('SKILL.md')
30
+ const packaging = read('references/packaging.md')
31
+ const release = read('references/release.md')
32
+ const publicRelease = read('references/public-release.md')
33
+ const quality = read('references/quality-gates.md')
34
+ const openai = read('agents/openai.yaml')
35
+ const validate = read('scripts/validate-gse.mjs')
36
+
37
+ const packageBoundary = ['SKILL.md', 'CHANGELOG.md', 'CONTRIBUTING.md', 'SECURITY.md', 'SUPPORT.md', 'references/', 'scripts/', 'assets/templates/', 'assets/marketplace/', 'examples/', 'agents/openai.yaml', '.gse/', '.learnings/']
38
+ const releaseNoteFields = ['Release label:', 'Date:', 'Readiness:', 'Changed:', 'Validation:', 'Compatibility impact:', 'Migration or rollback:', 'Known risks:', 'Follow-up slices:']
39
+ const handoffFields = ['Skill path:', 'Release label or date.', 'Validation command and latest result.', 'Evidence log path.', 'Known residual risks.', 'Next slice from `.gse/current-slice.md`.']
40
+
41
+ const checks = [
42
+ check('R01', 'packaging reference exists', exists('references/packaging.md'), 'references/packaging.md'),
43
+ check('R02', 'SKILL routes packaging reference', skill.includes('references/packaging.md'), 'SKILL.md Reference Routing'),
44
+ check('R03', 'package boundary lists core skill artifacts', packageBoundary.every((item) => packaging.includes(item)), packageBoundary.join(', ')),
45
+ check('R04', 'validation command is the release gate', packaging.includes('node <skill>/scripts/validate-gse.mjs --root <skill>') && quality.includes('Use `references/release.md`') && release.includes('references/quality-gates.md'), 'packaging, quality, and release references'),
46
+ check('R05', 'release label policy is explicit without fake semver', packaging.includes('gse-internal-YYYY-MM-DD-N') && packaging.includes('Use semver only after there is a maintained distribution channel'), 'internal release label policy'),
47
+ check('R06', 'release notes fields are complete', releaseNoteFields.every((item) => packaging.includes(item)), releaseNoteFields.join(', ')),
48
+ check('R07', 'install/update handoff fields are complete', handoffFields.every((item) => packaging.includes(item)), 'handoff checklist'),
49
+ check('R08', 'rollback guidance distinguishes low-risk and generated artifacts', packaging.includes('file-level revert') && packaging.includes('generated files or adapters') && packaging.includes('re-running `validate-gse.mjs`'), 'rollback section'),
50
+ check('R09', 'readiness status avoids overstating acceptance', packaging.includes('Do not call a release accepted only because local validation passed') && packaging.includes('true fresh-session acceptance separate from fresh-session readiness'), 'readiness status and release notes rules'),
51
+ check('R10', 'host UI metadata is present and minimal', openai.includes('display_name: "GSE"') && openai.includes('short_description') && openai.includes('default_prompt'), 'agents/openai.yaml'),
52
+ check('R11', 'consolidated validator includes packaging-adjacent gates', validate.includes('audit-fresh-session-readiness.mjs') && validate.includes('audit-compatibility.mjs') && validate.includes('audit-marketplace-discovery.mjs') && validate.includes('audit-host-ui-invocation.mjs') && validate.includes('quick_validate.py'), 'scripts/validate-gse.mjs'),
53
+ check('R12', 'no external distribution is claimed', packaging.includes('not a registry publication process') && packaging.includes('Do not claim marketplace distribution') && packaging.includes('Do not call a release accepted'), 'distribution boundary'),
54
+ check('R13', 'public release metadata gate is linked', release.includes('references/public-release.md') && packaging.includes('references/public-release.md') && publicRelease.includes('owner-required') && publicRelease.includes('assets/templates/public-release-record.md'), 'release, packaging, public-release references'),
55
+ check('R14', 'release docs include npm publish dry-run preflight', packaging.includes('audit-npm-publish-dry-run.mjs') && packaging.includes('harmful metadata auto-correction warnings') && validate.includes('audit-npm-publish-dry-run.mjs'), 'references/packaging.md, scripts/validate-gse.mjs'),
56
+ ]
57
+
58
+ const passed = checks.filter((item) => item.status === 'passed').length
59
+ const failed = checks.length - passed
60
+ const report = {
61
+ root,
62
+ generatedAt: new Date().toISOString(),
63
+ summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
64
+ workflows: { releasePackagingReadiness: failed === 0 ? 'verified' : 'failed' },
65
+ releaseReadiness: failed === 0 ? 'verified' : 'result',
66
+ acceptedBy: 'not accepted; this audit verifies release packaging readiness but does not publish or owner-accept a release',
67
+ limits: [
68
+ 'Release readiness audit verifies packaging policy, validation gate, handoff fields, rollback guidance, and metadata presence.',
69
+ 'It does not publish GSE, install it in another host, run marketplace checks, or mark v1.0 complete.',
70
+ 'A real release still needs the project or owner policy required for accepted status.',
71
+ ],
72
+ checks,
73
+ }
74
+
75
+ function renderMarkdown(data) {
76
+ const lines = []
77
+ lines.push('# GSE Release Readiness Audit')
78
+ lines.push('')
79
+ lines.push('Generated: ' + data.generatedAt)
80
+ lines.push('Root: ' + data.root)
81
+ lines.push('')
82
+ lines.push('## Summary')
83
+ lines.push('')
84
+ lines.push('- Status: ' + data.summary.status)
85
+ lines.push('- Checks: ' + data.summary.passed + '/' + data.summary.total)
86
+ lines.push('- Release packaging readiness: ' + data.workflows.releasePackagingReadiness)
87
+ lines.push('- Release readiness: ' + data.releaseReadiness)
88
+ lines.push('- Accepted by: ' + data.acceptedBy)
89
+ lines.push('')
90
+ lines.push('## Checks')
91
+ lines.push('')
92
+ for (const item of data.checks) {
93
+ const marker = item.status === 'passed' ? '[x]' : '[ ]'
94
+ lines.push('- ' + marker + ' ' + item.id + ' ' + item.label + ': ' + item.evidence)
95
+ }
96
+ lines.push('')
97
+ lines.push('## Limits')
98
+ lines.push('')
99
+ for (const item of data.limits) lines.push('- ' + item)
100
+ return lines.join('\n') + '\n'
101
+ }
102
+
103
+ if (jsonOnly) console.log(JSON.stringify(report, null, 2))
104
+ else console.log(renderMarkdown(report))
105
+
106
+ if (failed > 0) process.exit(1)
@@ -98,11 +98,11 @@ const checks = [
98
98
  check('RSM01', 'release status manifest generator exists', exists('scripts/generate-release-status-manifest.mjs'), 'scripts/generate-release-status-manifest.mjs'),
99
99
  check('RSM02', 'generator composes authoritative non-circular audits', ['audit-final-readiness.mjs', 'audit-public-acceptance-readiness.mjs', 'audit-host-runtime-invocations.mjs', 'audit-host-runtime-invocation-drill.mjs'].every((term) => generator.includes(term)) && !generator.includes("audit('audit-release-bundle.mjs')") && !generator.includes("audit('audit-distribution.mjs')"), 'generator source audits'),
100
100
  check('RSM03', 'generator writes parseable manifest', generated?.status === 0 && generatedData?.status === 'written' && manifest?.schemaVersion === 1, generated?.stderr || out),
101
- check('RSM04', 'manifest preserves public acceptance boundary', manifest?.claimBoundary?.publicAccepted === 'not-accepted' && manifest?.claimBoundary?.localValidationDoesNotMeanPublicAcceptance === true, 'publicAccepted not-accepted'),
102
- check('RSM05', 'manifest covers verified rows and current owner/external rows', (manifest?.readiness?.verified?.length ?? 0) > 0 && ((manifest?.readiness?.ownerRequired?.length ?? 0) + (manifest?.readiness?.externalRequired?.length ?? 0)) > 0, 'readiness row groups'),
101
+ check('RSM04', 'manifest preserves public acceptance boundary', manifest?.claimBoundary?.publicAccepted === 'verified' && manifest?.claimBoundary?.localValidationDoesNotMeanPublicAcceptance === true && manifest?.claimBoundary?.nativeSlashCommandIsOptionalAdapterClaim === true, 'publicAccepted verified; native slash optional adapter claim'),
102
+ check('RSM05', 'manifest covers verified rows and optional not-claimed rows', (manifest?.readiness?.verified?.length ?? 0) > 0 && (manifest?.readiness?.notClaimed?.length ?? 0) > 0 && ((manifest?.readiness?.ownerRequired?.length ?? 0) + (manifest?.readiness?.externalRequired?.length ?? 0)) === 0, 'readiness row groups'),
103
103
  check('RSM06', 'manifest covers install and distribution status', requiredDistribution.every((key) => manifest?.distribution?.[key]), requiredDistribution.join(', ')),
104
- check('RSM07', 'manifest covers public acceptance next commands', (manifest?.publicAcceptance?.pendingGates?.length ?? 0) > 0 && (manifest?.publicAcceptance?.nextCommands?.length ?? 0) === (manifest?.publicAcceptance?.pendingGates?.length ?? -1), 'pending gates and next commands'),
105
- check('RSM07b', 'manifest covers public acceptance dry-run preflight commands', (manifest?.publicAcceptance?.pendingGates?.length ?? 0) > 0 && (manifest?.publicAcceptance?.nextPreflightCommands?.length ?? 0) === (manifest?.publicAcceptance?.pendingGates?.length ?? -1) && manifest.publicAcceptance.nextPreflightCommands.every((command) => command.includes('--dry-run --json')), 'pending gates and preflight commands'),
104
+ check('RSM07', 'manifest has no public acceptance next commands when no required gates remain', (manifest?.publicAcceptance?.pendingGates?.length ?? -1) === 0 && (manifest?.publicAcceptance?.nextCommands?.length ?? -1) === 0, 'pending gates and next commands'),
105
+ check('RSM07b', 'manifest has no public acceptance dry-run preflight commands when no required gates remain', (manifest?.publicAcceptance?.pendingGates?.length ?? -1) === 0 && (manifest?.publicAcceptance?.nextPreflightCommands?.length ?? -1) === 0, 'pending gates and preflight commands'),
106
106
  check('RSM08', 'manifest covers host runtime evidence counts', Number.isInteger(manifest?.hostRuntime?.nativeSlashCommandRecords) && Number.isInteger(manifest?.hostRuntime?.portableTextCommandRecords) && manifest.hostRuntime.nativeSlashCommandRecords >= 0 && manifest.hostRuntime.portableTextCommandRecords >= 0, `native ${manifest?.hostRuntime?.nativeSlashCommandRecords ?? 'unknown'}, portable ${manifest?.hostRuntime?.portableTextCommandRecords ?? 'unknown'}`),
107
107
  check('RSM08b', 'manifest covers host runtime fixture drill status', manifest?.hostRuntime?.fixtureDrill === 'verified' && manifest?.hostRuntime?.fixtureNativeSlashCommandRecords === 1 && manifest?.hostRuntime?.fixturePortableTextCommandRecords === 4 && manifest?.hostRuntime?.fixtureEvidenceIsPersistent === false, `drill ${manifest?.hostRuntime?.fixtureDrill ?? 'unknown'}, fixture native ${manifest?.hostRuntime?.fixtureNativeSlashCommandRecords ?? 'unknown'}, fixture portable ${manifest?.hostRuntime?.fixturePortableTextCommandRecords ?? 'unknown'}`),
108
108
  check('RSM09', 'manifest points to handoff artifacts', requiredArtifacts.every((key) => manifest?.artifacts?.[key]), requiredArtifacts.join(', ')),
@@ -1,62 +1,62 @@
1
- #!/usr/bin/env node
2
- import fs from 'node:fs'
3
- import path from 'node:path'
4
-
5
- const args = process.argv.slice(2)
6
-
7
- function readArg(name, fallback = null) {
8
- const index = args.indexOf(name)
9
- if (index === -1) return fallback
10
- return args[index + 1] ?? fallback
11
- }
12
-
13
- const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
14
- const jsonOnly = args.includes('--json')
15
-
16
- function read(relativePath) {
17
- const fullPath = path.join(root, relativePath)
18
- return fs.existsSync(fullPath) ? fs.readFileSync(fullPath, 'utf8') : ''
19
- }
20
-
21
- function exists(relativePath) {
22
- return fs.existsSync(path.join(root, relativePath))
23
- }
24
-
25
- function check(id, label, ok, evidence, risk = '') {
26
- return { id, label, status: ok ? 'passed' : 'failed', evidence, risk }
27
- }
28
-
29
- const trust = read('references/release-trust.md')
30
- const template = read('assets/templates/release-trust-record.md')
31
- const packaging = read('references/packaging.md')
32
- const validate = read('scripts/validate-gse.mjs')
33
-
34
- const checks = [
35
- check('TRUST01', 'release trust reference exists', exists('references/release-trust.md'), 'references/release-trust.md'),
36
- check('TRUST02', 'release trust template exists', exists('assets/templates/release-trust-record.md'), 'assets/templates/release-trust-record.md'),
37
- check('TRUST03', 'trust reference separates signed verified trusted', ['signed', 'verified', 'trusted', 'Do not claim `trusted` from signing alone.'].every((term) => trust.includes(term)), 'references/release-trust.md'),
38
- check('TRUST04', 'trust reference defines key custody and revocation', ['Key custody', 'Rotation policy', 'Revocation path', 'Do not commit private keys'].every((term) => trust.includes(term)), 'references/release-trust.md'),
39
- check('TRUST05', 'template captures owner acceptance and public key fingerprint', ['Public key fingerprint', 'Accepted by', 'Private key location', 'Verification command'].every((term) => template.includes(term)), 'release-trust-record.md'),
40
- check('TRUST06', 'packaging routes readers to signing and trust rules', packaging.includes('Signing And Verification') && packaging.includes('Release Trust'), 'references/packaging.md'),
41
- check('TRUST07', 'validator includes release trust audit', validate.includes('audit-release-trust.mjs'), 'scripts/validate-gse.mjs'),
42
- ]
43
-
44
- const passed = checks.filter((item) => item.status === 'passed').length
45
- const failed = checks.length - passed
46
- const report = {
47
- root,
48
- generatedAt: new Date().toISOString(),
49
- summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
50
- workflows: { releaseTrustPolicy: failed === 0 ? 'verified' : 'failed' },
51
- limits: [
52
- 'This audit verifies release trust policy and template coverage.',
53
- 'It does not prove a real maintainer identity, key custody event, marketplace approval, or production release acceptance.',
54
- ],
55
- checks,
56
- }
57
-
58
- if (jsonOnly) console.log(JSON.stringify(report, null, 2))
59
- else console.log(JSON.stringify(report, null, 2))
60
-
61
- if (failed > 0) process.exit(1)
62
-
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+
5
+ const args = process.argv.slice(2)
6
+
7
+ function readArg(name, fallback = null) {
8
+ const index = args.indexOf(name)
9
+ if (index === -1) return fallback
10
+ return args[index + 1] ?? fallback
11
+ }
12
+
13
+ const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
14
+ const jsonOnly = args.includes('--json')
15
+
16
+ function read(relativePath) {
17
+ const fullPath = path.join(root, relativePath)
18
+ return fs.existsSync(fullPath) ? fs.readFileSync(fullPath, 'utf8') : ''
19
+ }
20
+
21
+ function exists(relativePath) {
22
+ return fs.existsSync(path.join(root, relativePath))
23
+ }
24
+
25
+ function check(id, label, ok, evidence, risk = '') {
26
+ return { id, label, status: ok ? 'passed' : 'failed', evidence, risk }
27
+ }
28
+
29
+ const trust = read('references/release-trust.md')
30
+ const template = read('assets/templates/release-trust-record.md')
31
+ const packaging = read('references/packaging.md')
32
+ const validate = read('scripts/validate-gse.mjs')
33
+
34
+ const checks = [
35
+ check('TRUST01', 'release trust reference exists', exists('references/release-trust.md'), 'references/release-trust.md'),
36
+ check('TRUST02', 'release trust template exists', exists('assets/templates/release-trust-record.md'), 'assets/templates/release-trust-record.md'),
37
+ check('TRUST03', 'trust reference separates signed verified trusted', ['signed', 'verified', 'trusted', 'Do not claim `trusted` from signing alone.'].every((term) => trust.includes(term)), 'references/release-trust.md'),
38
+ check('TRUST04', 'trust reference defines key custody and revocation', ['Key custody', 'Rotation policy', 'Revocation path', 'Do not commit private keys'].every((term) => trust.includes(term)), 'references/release-trust.md'),
39
+ check('TRUST05', 'template captures owner acceptance and public key fingerprint', ['Public key fingerprint', 'Accepted by', 'Private key location', 'Verification command'].every((term) => template.includes(term)), 'release-trust-record.md'),
40
+ check('TRUST06', 'packaging routes readers to signing and trust rules', packaging.includes('Signing And Verification') && packaging.includes('Release Trust'), 'references/packaging.md'),
41
+ check('TRUST07', 'validator includes release trust audit', validate.includes('audit-release-trust.mjs'), 'scripts/validate-gse.mjs'),
42
+ ]
43
+
44
+ const passed = checks.filter((item) => item.status === 'passed').length
45
+ const failed = checks.length - passed
46
+ const report = {
47
+ root,
48
+ generatedAt: new Date().toISOString(),
49
+ summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
50
+ workflows: { releaseTrustPolicy: failed === 0 ? 'verified' : 'failed' },
51
+ limits: [
52
+ 'This audit verifies release trust policy and template coverage.',
53
+ 'It does not prove a real maintainer identity, key custody event, marketplace approval, or production release acceptance.',
54
+ ],
55
+ checks,
56
+ }
57
+
58
+ if (jsonOnly) console.log(JSON.stringify(report, null, 2))
59
+ else console.log(JSON.stringify(report, null, 2))
60
+
61
+ if (failed > 0) process.exit(1)
62
+