@t275005746/gse 0.1.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 (207) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +42 -0
  2. package/.github/ISSUE_TEMPLATE/change_request.yml +50 -0
  3. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. package/.github/PULL_REQUEST_TEMPLATE.md +38 -0
  5. package/.github/workflows/validate-gse.yml +33 -0
  6. package/.gse/README.md +18 -0
  7. package/.gse/gse-development-protocol.md +50 -0
  8. package/.gse/project-profile.md +29 -0
  9. package/.gse/quality-gates.md +25 -0
  10. package/.gse/releases/public-channel-publication-pending.md +49 -0
  11. package/.gse/releases/public-ci-run-pending.md +53 -0
  12. package/.gse/releases/public-release-owner-required.md +65 -0
  13. package/.gse/releases/public-repository-settings-owner-required.md +59 -0
  14. package/.gse/releases/public-security-contact-owner-required.md +45 -0
  15. package/.gse/state.json +27 -0
  16. package/CHANGELOG.md +24 -0
  17. package/CONTRIBUTING.md +64 -0
  18. package/LICENSE +21 -0
  19. package/README.md +236 -0
  20. package/README.zh-CN.md +236 -0
  21. package/SECURITY.md +41 -0
  22. package/SKILL.md +148 -0
  23. package/SUPPORT.md +38 -0
  24. package/agents/openai.yaml +4 -0
  25. package/assets/marketplace/README.md +7 -0
  26. package/assets/marketplace/gse-listing.json +75 -0
  27. package/assets/templates/acceptance-execution-packet.md +73 -0
  28. package/assets/templates/adr.md +14 -0
  29. package/assets/templates/change-brief.md +16 -0
  30. package/assets/templates/design.md +18 -0
  31. package/assets/templates/dispatch-packet.md +104 -0
  32. package/assets/templates/evidence.md +14 -0
  33. package/assets/templates/execution-quality-pack.md +65 -0
  34. package/assets/templates/goal-map.md +21 -0
  35. package/assets/templates/host-adapter.md +48 -0
  36. package/assets/templates/host-ui-invocation-record.md +42 -0
  37. package/assets/templates/incident-review.md +60 -0
  38. package/assets/templates/public-channel-publication-record.md +49 -0
  39. package/assets/templates/public-ci-run-record.md +53 -0
  40. package/assets/templates/public-release-record.md +65 -0
  41. package/assets/templates/public-repository-settings-record.md +59 -0
  42. package/assets/templates/public-security-contact-record.md +45 -0
  43. package/assets/templates/release-trust-record.md +32 -0
  44. package/assets/templates/review.md +18 -0
  45. package/assets/templates/spec.md +16 -0
  46. package/assets/templates/target-adoption-evidence.md +29 -0
  47. package/assets/templates/tasks.md +17 -0
  48. package/assets/templates/update-release-acceptance-record.md +58 -0
  49. package/examples/README.md +22 -0
  50. package/examples/agent-runtime-host/.claude/gse-adapter.md +6 -0
  51. package/examples/agent-runtime-host/.codex/gse-adapter.md +7 -0
  52. package/examples/agent-runtime-host/.gse/goal-map.md +7 -0
  53. package/examples/agent-runtime-host/.gse/project-profile.md +27 -0
  54. package/examples/agent-runtime-host/.gse/tooling.md +5 -0
  55. package/examples/agent-runtime-host/.mcp.json +9 -0
  56. package/examples/agent-runtime-host/AGENTS.md +5 -0
  57. package/examples/agent-runtime-host/README.md +10 -0
  58. package/examples/agent-runtime-host/docs/model-routing.md +5 -0
  59. package/examples/cli-tool/.gse/project-profile.md +21 -0
  60. package/examples/cli-tool/AGENTS.md +5 -0
  61. package/examples/cli-tool/README.md +12 -0
  62. package/examples/cli-tool/package.json +21 -0
  63. package/examples/small-app/.env.example +2 -0
  64. package/examples/small-app/.github/workflows/ci.yml +8 -0
  65. package/examples/small-app/AGENTS.md +5 -0
  66. package/examples/small-app/README.md +12 -0
  67. package/examples/small-app/package.json +26 -0
  68. package/examples/small-app/playwright.config.ts +4 -0
  69. package/package.json +53 -0
  70. package/references/adoption-recipes.md +171 -0
  71. package/references/agent-roles.md +49 -0
  72. package/references/architecture-health.md +101 -0
  73. package/references/benchmark-audit.md +73 -0
  74. package/references/commands.md +295 -0
  75. package/references/community-channels.md +46 -0
  76. package/references/compatibility.md +70 -0
  77. package/references/design-basis.md +38 -0
  78. package/references/domain-model.md +129 -0
  79. package/references/domain-quality-gates.md +75 -0
  80. package/references/drift-audit.md +81 -0
  81. package/references/evidence-taxonomy.md +123 -0
  82. package/references/file-ownership.md +107 -0
  83. package/references/final-readiness.md +84 -0
  84. package/references/forward-test.md +133 -0
  85. package/references/goal-map.md +36 -0
  86. package/references/host-adapters.md +119 -0
  87. package/references/learning-system.md +35 -0
  88. package/references/marketplace-discovery.md +46 -0
  89. package/references/model-routing.md +103 -0
  90. package/references/open-source-defaults.md +39 -0
  91. package/references/operating-model.md +52 -0
  92. package/references/packaging.md +277 -0
  93. package/references/project-agent-workspace.md +89 -0
  94. package/references/project-bootstrap.md +122 -0
  95. package/references/project-profile.md +57 -0
  96. package/references/public-release.md +174 -0
  97. package/references/quality-gates.md +100 -0
  98. package/references/recovery.md +176 -0
  99. package/references/release-trust.md +43 -0
  100. package/references/release.md +126 -0
  101. package/references/review.md +141 -0
  102. package/references/router.md +90 -0
  103. package/references/spec-workflow.md +66 -0
  104. package/references/task-levels.md +81 -0
  105. package/references/tool-adapters.md +73 -0
  106. package/scripts/audit-acceptance-execution-packet.mjs +133 -0
  107. package/scripts/audit-adoption-recipes.mjs +99 -0
  108. package/scripts/audit-adoption.mjs +154 -0
  109. package/scripts/audit-change-lifecycle.mjs +77 -0
  110. package/scripts/audit-change-system.mjs +134 -0
  111. package/scripts/audit-ci-readiness.mjs +107 -0
  112. package/scripts/audit-close-gate.mjs +323 -0
  113. package/scripts/audit-command-adapters.mjs +91 -0
  114. package/scripts/audit-command-execution.mjs +210 -0
  115. package/scripts/audit-commands.mjs +117 -0
  116. package/scripts/audit-compatibility.mjs +149 -0
  117. package/scripts/audit-completion-readiness.mjs +292 -0
  118. package/scripts/audit-distribution.mjs +251 -0
  119. package/scripts/audit-domain-quality-gates.mjs +108 -0
  120. package/scripts/audit-evidence-placeholders.mjs +126 -0
  121. package/scripts/audit-final-acceptance-packet.mjs +148 -0
  122. package/scripts/audit-final-form-progress-report.mjs +161 -0
  123. package/scripts/audit-final-form-stale-copy.mjs +221 -0
  124. package/scripts/audit-final-readiness-promotion.mjs +255 -0
  125. package/scripts/audit-final-readiness.mjs +226 -0
  126. package/scripts/audit-fixtures.mjs +154 -0
  127. package/scripts/audit-fresh-session-readiness.mjs +177 -0
  128. package/scripts/audit-gse.mjs +275 -0
  129. package/scripts/audit-host-adapters.mjs +119 -0
  130. package/scripts/audit-host-runtime-evidence-handoff.mjs +159 -0
  131. package/scripts/audit-host-runtime-invocation-drill.mjs +240 -0
  132. package/scripts/audit-host-runtime-invocations.mjs +254 -0
  133. package/scripts/audit-host-ui-invocation.mjs +132 -0
  134. package/scripts/audit-learning-system.mjs +103 -0
  135. package/scripts/audit-local-final-form-completion.mjs +131 -0
  136. package/scripts/audit-marketplace-discovery.mjs +122 -0
  137. package/scripts/audit-npm-package-metadata.mjs +155 -0
  138. package/scripts/audit-npm-publish-dry-run.mjs +169 -0
  139. package/scripts/audit-npm-tarball-install.mjs +191 -0
  140. package/scripts/audit-open-source-defaults.mjs +92 -0
  141. package/scripts/audit-open-source-readiness.mjs +97 -0
  142. package/scripts/audit-owner-external-gate-kit.mjs +218 -0
  143. package/scripts/audit-project.mjs +323 -0
  144. package/scripts/audit-public-acceptance-command-dry-run-drill.mjs +203 -0
  145. package/scripts/audit-public-acceptance-handoff.mjs +142 -0
  146. package/scripts/audit-public-acceptance-readiness.mjs +224 -0
  147. package/scripts/audit-public-channel-publication.mjs +248 -0
  148. package/scripts/audit-public-ci-run.mjs +184 -0
  149. package/scripts/audit-public-collaboration-templates.mjs +98 -0
  150. package/scripts/audit-public-external-gate-probe.mjs +206 -0
  151. package/scripts/audit-public-release-checklist.mjs +133 -0
  152. package/scripts/audit-public-release-decision.mjs +201 -0
  153. package/scripts/audit-public-release-metadata.mjs +176 -0
  154. package/scripts/audit-public-repository-settings.mjs +237 -0
  155. package/scripts/audit-public-security-contact.mjs +171 -0
  156. package/scripts/audit-readme-docs.mjs +185 -0
  157. package/scripts/audit-recovery-readiness.mjs +98 -0
  158. package/scripts/audit-release-bundle.mjs +251 -0
  159. package/scripts/audit-release-owner-action-plan-drill.mjs +277 -0
  160. package/scripts/audit-release-owner-action-plan.mjs +164 -0
  161. package/scripts/audit-release-readiness.mjs +106 -0
  162. package/scripts/audit-release-status-manifest.mjs +165 -0
  163. package/scripts/audit-release-trust.mjs +62 -0
  164. package/scripts/audit-remote-distribution.mjs +266 -0
  165. package/scripts/audit-roadmap-consistency.mjs +235 -0
  166. package/scripts/audit-signing.mjs +147 -0
  167. package/scripts/audit-state-freshness.mjs +113 -0
  168. package/scripts/audit-target-adoption-evidence.mjs +117 -0
  169. package/scripts/audit-target-project.mjs +507 -0
  170. package/scripts/audit-update-release-acceptance.mjs +136 -0
  171. package/scripts/audit-v1-target-validation.mjs +269 -0
  172. package/scripts/audit-validation-profiles.mjs +125 -0
  173. package/scripts/close-change.mjs +116 -0
  174. package/scripts/discover-project-profile.mjs +307 -0
  175. package/scripts/forward-test-gse.mjs +146 -0
  176. package/scripts/generate-command-adapter.mjs +231 -0
  177. package/scripts/generate-final-acceptance-packet.mjs +181 -0
  178. package/scripts/generate-final-form-progress-report.mjs +205 -0
  179. package/scripts/generate-host-adapter.mjs +73 -0
  180. package/scripts/generate-host-runtime-evidence-handoff.mjs +206 -0
  181. package/scripts/generate-owner-external-gate-kit.mjs +295 -0
  182. package/scripts/generate-public-acceptance-handoff.mjs +168 -0
  183. package/scripts/generate-public-release-checklist.mjs +207 -0
  184. package/scripts/generate-release-bundle.mjs +505 -0
  185. package/scripts/generate-release-owner-action-plan.mjs +172 -0
  186. package/scripts/generate-release-status-manifest.mjs +200 -0
  187. package/scripts/generate-session-prompt.mjs +188 -0
  188. package/scripts/gse.mjs +67 -0
  189. package/scripts/init-change.mjs +265 -0
  190. package/scripts/init-project.mjs +785 -0
  191. package/scripts/install-gse.mjs +234 -0
  192. package/scripts/lib/evidence-placeholders.mjs +28 -0
  193. package/scripts/package-gse.mjs +174 -0
  194. package/scripts/probe-public-external-gates.mjs +167 -0
  195. package/scripts/record-host-invocation.mjs +151 -0
  196. package/scripts/record-learning.mjs +137 -0
  197. package/scripts/record-public-channel-publication.mjs +178 -0
  198. package/scripts/record-public-ci-run.mjs +180 -0
  199. package/scripts/record-public-release.mjs +175 -0
  200. package/scripts/record-public-repository-settings.mjs +209 -0
  201. package/scripts/record-public-security-contact.mjs +157 -0
  202. package/scripts/run-gse-command.mjs +538 -0
  203. package/scripts/run-validation-profile.mjs +146 -0
  204. package/scripts/sign-gse-package.mjs +83 -0
  205. package/scripts/update-project-state.mjs +223 -0
  206. package/scripts/validate-gse.mjs +1168 -0
  207. package/scripts/verify-gse-package.mjs +85 -0
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import { spawnSync } from 'node:child_process'
5
+
6
+ const args = process.argv.slice(2)
7
+
8
+ function readArg(name, fallback = null) {
9
+ const index = args.indexOf(name)
10
+ if (index === -1) return fallback
11
+ return args[index + 1] ?? fallback
12
+ }
13
+
14
+ const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
15
+ const displayRoot = readArg('--display-root', '<gse-root>')
16
+ const out = path.resolve(readArg('--out', path.join(root, '.gse', 'acceptance', 'final-acceptance-packet.md')))
17
+ const jsonOnly = args.includes('--json')
18
+ const dryRun = args.includes('--dry-run')
19
+ const force = args.includes('--force')
20
+
21
+ function runAudit() {
22
+ const result = spawnSync(process.execPath, [path.join(root, 'scripts', 'audit-final-readiness.mjs'), '--root', root, '--json'], {
23
+ cwd: root,
24
+ encoding: 'utf8',
25
+ windowsHide: true,
26
+ })
27
+ if (result.status !== 0) {
28
+ return {
29
+ ok: false,
30
+ error: 'audit-final-readiness failed',
31
+ stdout: result.stdout?.trim() ?? '',
32
+ stderr: result.stderr?.trim() ?? '',
33
+ }
34
+ }
35
+ try {
36
+ return { ok: true, data: JSON.parse(result.stdout) }
37
+ } catch (error) {
38
+ return { ok: false, error: 'audit-final-readiness did not return valid JSON', detail: error.message }
39
+ }
40
+ }
41
+
42
+ function runPublicDoctor() {
43
+ const result = spawnSync(process.execPath, [path.join(root, 'scripts', 'audit-public-acceptance-readiness.mjs'), '--root', root, '--json'], {
44
+ cwd: root,
45
+ encoding: 'utf8',
46
+ windowsHide: true,
47
+ })
48
+ if (result.status !== 0) return { ok: false, gates: new Map() }
49
+ try {
50
+ const data = JSON.parse(result.stdout)
51
+ return {
52
+ ok: true,
53
+ gates: new Map((data.pendingGates ?? []).map((gate) => [gate.area, gate])),
54
+ }
55
+ } catch {
56
+ return { ok: false, gates: new Map() }
57
+ }
58
+ }
59
+
60
+ function actionFor(row, publicGate) {
61
+ if (publicGate?.recordCommand) {
62
+ const parts = [
63
+ 'Attach the real owner/external evidence, then run `' + publicGate.recordCommand + '`.',
64
+ ]
65
+ if (publicGate.preflightCommand) parts.push('Preflight with `' + publicGate.preflightCommand + '`.')
66
+ return parts.join(' ')
67
+ }
68
+ if (row.area === 'License decision') {
69
+ return 'Run `node scripts/record-public-release.mjs --root __GSE__ --license-status selected --spdx __SPDX_ID__ --license-file __LICENSE_FILE__ --approved-by __OWNER__ --decision-date __YYYY_MM_DD__ --evidence-status accepted` after the owner chooses a license, or record `--license-status not-public` with owner approval.'
70
+ }
71
+ if (row.area === 'Public security contact') {
72
+ return 'Update `SECURITY.md` with an owner-approved vulnerability disclosure path before public release acceptance.'
73
+ }
74
+ if (row.area === 'Public registry publication') {
75
+ return 'Publish only through the chosen public channel, then record the package URL, version, digest, date, and verification command in release evidence.'
76
+ }
77
+ if (row.area === 'Marketplace approval') {
78
+ return 'Submit the marketplace/catalog listing, wait for real approval or publication evidence, then attach the listing URL and review status.'
79
+ }
80
+ if (row.area === 'Native slash command') {
81
+ return 'Use the host runtime to invoke a real native slash command and record it with `scripts/record-host-invocation.mjs` using native slash-command evidence.'
82
+ }
83
+ if (row.area === 'Other host runtime invocation') {
84
+ return 'Run GSE in each claimed host, record invocation evidence with `scripts/record-host-invocation.mjs`, then re-run host runtime audits.'
85
+ }
86
+ return 'Provide explicit owner or external evidence, then re-run final readiness and close gate audits.'
87
+ }
88
+
89
+ function renderPacket(audit) {
90
+ const publicDoctor = runPublicDoctor()
91
+ const matrix = audit.matrix ?? []
92
+ const verified = matrix.filter((row) => row.status === 'verified')
93
+ const pending = matrix.filter((row) => row.status !== 'verified')
94
+ const lines = []
95
+ lines.push('# GSE Final Acceptance Packet')
96
+ lines.push('')
97
+ lines.push('Generated: ' + new Date().toISOString())
98
+ lines.push('Root: ' + displayRoot)
99
+ lines.push('')
100
+ lines.push('## Purpose')
101
+ lines.push('')
102
+ lines.push('Turn the final-readiness matrix into an executable owner/external acceptance checklist. This packet is not acceptance by itself; it is the handoff plan for the evidence that cannot be produced locally.')
103
+ lines.push('')
104
+ lines.push('## Current Claim Boundary')
105
+ lines.push('')
106
+ lines.push('- Local readiness: ' + (audit.workflows?.finalReadinessMatrix ?? 'unknown'))
107
+ lines.push('- Public accepted: ' + (audit.workflows?.publicAccepted ?? 'unknown'))
108
+ lines.push('- Verified rows: ' + verified.length)
109
+ lines.push('- Pending owner/external rows: ' + pending.length)
110
+ lines.push('')
111
+ lines.push('## Verified Local Capabilities')
112
+ lines.push('')
113
+ for (const row of verified) lines.push('- ' + row.area + ': verified; evidence: ' + row.evidence)
114
+ lines.push('')
115
+ lines.push('## Pending Acceptance Gates')
116
+ lines.push('')
117
+ for (const row of pending) {
118
+ lines.push('### ' + row.area)
119
+ lines.push('')
120
+ lines.push('- Status: ' + row.status)
121
+ lines.push('- Current evidence: ' + row.evidence)
122
+ lines.push('- Required action: ' + actionFor(row, publicDoctor.gates.get(row.area)))
123
+ lines.push('- Acceptance rule: do not mark accepted until the evidence is real, dated, and re-audited.')
124
+ lines.push('')
125
+ }
126
+ lines.push('## Re-Verification Commands')
127
+ lines.push('')
128
+ lines.push('```bash')
129
+ lines.push('node scripts/audit-final-readiness.mjs --root __GSE__ --json')
130
+ lines.push('node scripts/audit-public-acceptance-readiness.mjs --root __GSE__ --json')
131
+ lines.push('node scripts/audit-public-release-decision.mjs --root __GSE__ --json')
132
+ lines.push('node scripts/audit-host-runtime-invocations.mjs --root __GSE__ --json')
133
+ lines.push('node scripts/validate-gse.mjs --root __GSE__ --json')
134
+ lines.push('node scripts/audit-close-gate.mjs --target __GSE__ --json')
135
+ lines.push('```')
136
+ lines.push('')
137
+ lines.push('## Anti-Overclaim Rules')
138
+ lines.push('')
139
+ lines.push('- Do not claim public release acceptance until public security contact, repository settings, CI, publication, marketplace, and host-runtime evidence are accepted.')
140
+ lines.push('- Do not claim marketplace availability until an actual marketplace or catalog record exists.')
141
+ lines.push('- Do not claim native slash-command support from portable text-command routing.')
142
+ lines.push('- Do not claim support for a host until that host has its own runtime invocation record.')
143
+ lines.push('- Keep owner-required and external-required gates visible in status reports until they are re-audited as verified.')
144
+ lines.push('')
145
+ lines.push('## Next Action')
146
+ lines.push('')
147
+ lines.push('Run the public acceptance doctor, collect the owner-required decisions first, then record public channel and host-runtime evidence as those external systems become available.')
148
+ return lines.join('\n') + '\n'
149
+ }
150
+
151
+ const audit = runAudit()
152
+ if (!audit.ok) {
153
+ console.error(JSON.stringify({ status: 'failed', ...audit }, null, 2))
154
+ process.exit(1)
155
+ }
156
+
157
+ const packet = renderPacket(audit.data)
158
+ if (!dryRun) {
159
+ if (fs.existsSync(out) && !force) {
160
+ console.error(JSON.stringify({ status: 'failed', reason: 'output exists; pass --force to overwrite', out }, null, 2))
161
+ process.exit(1)
162
+ }
163
+ fs.mkdirSync(path.dirname(out), { recursive: true })
164
+ fs.writeFileSync(out, packet, 'utf8')
165
+ }
166
+
167
+ const report = {
168
+ status: 'ready',
169
+ root,
170
+ out,
171
+ dryRun,
172
+ written: dryRun ? 0 : 1,
173
+ summary: {
174
+ verifiedRows: audit.data.matrix.filter((row) => row.status === 'verified').length,
175
+ pendingRows: audit.data.matrix.filter((row) => row.status !== 'verified').length,
176
+ publicAccepted: audit.data.workflows?.publicAccepted ?? 'unknown',
177
+ },
178
+ }
179
+
180
+ if (jsonOnly) console.log(JSON.stringify(report, null, 2))
181
+ else console.log(packet)
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import { spawnSync } from 'node:child_process'
5
+
6
+ const args = process.argv.slice(2)
7
+
8
+ function readArg(name, fallback = null) {
9
+ const index = args.indexOf(name)
10
+ if (index === -1) return fallback
11
+ return args[index + 1] ?? fallback
12
+ }
13
+
14
+ const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
15
+ const out = path.resolve(readArg('--out', path.join(root, '.gse', 'acceptance', 'final-form-progress-report.md')))
16
+ const jsonOut = path.resolve(readArg('--json-out', path.join(root, '.gse', 'acceptance', 'final-form-progress-report.json')))
17
+ const displayRoot = readArg('--display-root', '<gse-root>')
18
+ const force = args.includes('--force')
19
+ const dryRun = args.includes('--dry-run')
20
+ const jsonOnly = args.includes('--json')
21
+
22
+ function run(command, commandArgs) {
23
+ const result = spawnSync(command, commandArgs, {
24
+ cwd: root,
25
+ encoding: 'utf8',
26
+ windowsHide: true,
27
+ })
28
+ return {
29
+ status: result.status ?? 1,
30
+ stdout: (result.stdout ?? '').trim(),
31
+ stderr: (result.stderr ?? '').trim(),
32
+ command: [command, ...commandArgs].join(' '),
33
+ }
34
+ }
35
+
36
+ function parseJson(text) {
37
+ try {
38
+ return JSON.parse(text)
39
+ } catch {
40
+ return null
41
+ }
42
+ }
43
+
44
+ function countBy(rows, status) {
45
+ return rows.filter((row) => row.status === status).length
46
+ }
47
+
48
+ function percent(numerator, denominator) {
49
+ if (!denominator) return 0
50
+ return Math.round((numerator / denominator) * 100)
51
+ }
52
+
53
+ const finalReadiness = run(process.execPath, [path.join(root, 'scripts', 'audit-final-readiness.mjs'), '--root', root, '--json'])
54
+ const publicAcceptance = run(process.execPath, [path.join(root, 'scripts', 'audit-public-acceptance-readiness.mjs'), '--root', root, '--json'])
55
+ const publicAcceptanceCommandDryRunDrill = run(process.execPath, [path.join(root, 'scripts', 'audit-public-acceptance-command-dry-run-drill.mjs'), '--root', root, '--json'])
56
+ const hostRuntime = run(process.execPath, [path.join(root, 'scripts', 'audit-host-runtime-invocations.mjs'), '--root', root, '--json'])
57
+
58
+ const finalReadinessData = parseJson(finalReadiness.stdout)
59
+ const publicAcceptanceData = parseJson(publicAcceptance.stdout)
60
+ const hostRuntimeData = parseJson(hostRuntime.stdout)
61
+
62
+ const matrix = finalReadinessData?.matrix ?? []
63
+ const verifiedRows = countBy(matrix, 'verified')
64
+ const ownerRequiredRows = countBy(matrix, 'owner-required')
65
+ const externalRequiredRows = countBy(matrix, 'external-required')
66
+ const acceptedRows = countBy(matrix, 'accepted')
67
+ const totalRows = matrix.length
68
+ const localReadyRows = verifiedRows + acceptedRows
69
+ const publicAccepted = finalReadinessData?.workflows?.publicAccepted ?? 'unknown'
70
+ const pendingGates = publicAcceptanceData?.pendingGates ?? matrix.filter((row) => row.status !== 'verified')
71
+ const licenseDecisionVerified = matrix.some((row) => row.area === 'License decision' && (row.status === 'verified' || row.status === 'accepted'))
72
+ const cannotClaim = [
73
+ ...(licenseDecisionVerified ? [] : ['owner-selected license acceptance unless accepted owner evidence exists']),
74
+ 'public security contact acceptance unless accepted owner evidence exists',
75
+ 'public repository settings unless real repository evidence exists',
76
+ 'public CI unless a real successful public CI run is recorded',
77
+ 'registry or marketplace publication unless real publication evidence exists',
78
+ 'native slash-command support unless real host runtime evidence exists',
79
+ ]
80
+
81
+ const localRows = totalRows - ownerRequiredRows - externalRequiredRows
82
+ const localEngineeringScore = percent(localReadyRows, localRows)
83
+ const finalFormScore = publicAccepted === 'verified' ? 100 : percent(localReadyRows, totalRows)
84
+ const status = publicAccepted === 'verified' ? 'accepted' : 'verified-with-external-blockers'
85
+
86
+ const report = {
87
+ schemaVersion: 1,
88
+ generatedAt: new Date().toISOString(),
89
+ root: displayRoot,
90
+ status,
91
+ scores: {
92
+ localEngineeringReadiness: localEngineeringScore,
93
+ fullFinalFormReadiness: finalFormScore,
94
+ scoringBasis: 'local engineering excludes owner-required and external-required rows; full final-form counts every readiness row',
95
+ },
96
+ readiness: {
97
+ totalRows,
98
+ localRows,
99
+ verifiedRows,
100
+ acceptedRows,
101
+ ownerRequiredRows,
102
+ externalRequiredRows,
103
+ publicAccepted,
104
+ pendingGateCount: pendingGates.length,
105
+ },
106
+ blockers: pendingGates.map((gate) => ({
107
+ area: gate.area,
108
+ status: gate.status,
109
+ owner: gate.owner ?? (gate.status === 'owner-required' ? 'project owner' : 'external system or host'),
110
+ evidence: gate.currentEvidence ?? gate.evidence ?? '',
111
+ recordCommand: gate.recordCommand ?? null,
112
+ preflightCommand: gate.preflightCommand ?? null,
113
+ requiredEvidence: gate.requiredEvidence ?? 'Record accepted owner/external evidence and re-run final readiness.',
114
+ })),
115
+ verifiedCapabilities: matrix.filter((row) => row.status === 'verified' || row.status === 'accepted').map((row) => ({
116
+ area: row.area,
117
+ status: row.status,
118
+ evidence: row.evidence,
119
+ })),
120
+ commandEvidence: {
121
+ finalReadiness: { status: finalReadiness.status, command: 'node scripts/audit-final-readiness.mjs --root __GSE__ --json' },
122
+ publicAcceptance: { status: publicAcceptance.status, command: 'node scripts/audit-public-acceptance-readiness.mjs --root __GSE__ --json' },
123
+ publicAcceptanceCommandDryRunDrill: { status: publicAcceptanceCommandDryRunDrill.status, command: 'node scripts/audit-public-acceptance-command-dry-run-drill.mjs --root __GSE__ --json' },
124
+ hostRuntime: { status: hostRuntime.status, command: 'node scripts/audit-host-runtime-invocations.mjs --root __GSE__ --json' },
125
+ },
126
+ hostRuntime: {
127
+ nativeSlashCommandRecords: hostRuntimeData?.inventory?.nativeSlashCommandRecords ?? 0,
128
+ portableTextCommandRecords: hostRuntimeData?.inventory?.portableTextCommandRecords ?? 0,
129
+ totalRecords: hostRuntimeData?.inventory?.totalRecords ?? 0,
130
+ },
131
+ claimBoundary: {
132
+ mayClaimLocalEngineeringReadiness: finalReadiness.status === 0,
133
+ mayClaimPublicAcceptedFinalForm: publicAccepted === 'verified' && pendingGates.length === 0,
134
+ cannotClaim,
135
+ },
136
+ }
137
+
138
+ function renderMarkdown(data) {
139
+ const lines = []
140
+ lines.push('# GSE Final-Form Progress Report')
141
+ lines.push('')
142
+ lines.push('Generated: ' + data.generatedAt)
143
+ lines.push('Root: ' + data.root)
144
+ lines.push('')
145
+ lines.push('## Summary')
146
+ lines.push('')
147
+ lines.push('- Status: ' + data.status)
148
+ lines.push('- Local engineering readiness: ' + data.scores.localEngineeringReadiness + '%')
149
+ lines.push('- Full final-form readiness: ' + data.scores.fullFinalFormReadiness + '%')
150
+ lines.push('- Scoring basis: ' + data.scores.scoringBasis)
151
+ lines.push('- Public accepted: ' + data.readiness.publicAccepted)
152
+ lines.push('- Matrix rows: ' + data.readiness.verifiedRows + ' verified, ' + data.readiness.ownerRequiredRows + ' owner-required, ' + data.readiness.externalRequiredRows + ' external-required, ' + data.readiness.totalRows + ' total')
153
+ lines.push('- Local rows: ' + data.readiness.localRows)
154
+ lines.push('')
155
+ lines.push('## Remaining Blockers')
156
+ lines.push('')
157
+ if (data.blockers.length === 0) {
158
+ lines.push('- None reported by final readiness. Re-run close gate and release audits before claiming completion.')
159
+ } else {
160
+ for (const blocker of data.blockers) {
161
+ lines.push('- ' + blocker.area + ': ' + blocker.status)
162
+ lines.push(' - Owner: ' + blocker.owner)
163
+ lines.push(' - Evidence now: ' + blocker.evidence)
164
+ lines.push(' - Required evidence: ' + blocker.requiredEvidence)
165
+ if (blocker.preflightCommand) lines.push(' - Preflight command: `' + blocker.preflightCommand + '`')
166
+ if (blocker.recordCommand) lines.push(' - Record command: `' + blocker.recordCommand + '`')
167
+ }
168
+ }
169
+ lines.push('')
170
+ lines.push('## Verified Capabilities')
171
+ lines.push('')
172
+ for (const item of data.verifiedCapabilities) {
173
+ lines.push('- ' + item.area + ': ' + item.status + ' (' + item.evidence + ')')
174
+ }
175
+ lines.push('')
176
+ lines.push('## Claim Boundary')
177
+ lines.push('')
178
+ lines.push('- May claim local engineering readiness: ' + data.claimBoundary.mayClaimLocalEngineeringReadiness)
179
+ lines.push('- May claim public accepted final form: ' + data.claimBoundary.mayClaimPublicAcceptedFinalForm)
180
+ for (const item of data.claimBoundary.cannotClaim) lines.push('- Cannot claim ' + item)
181
+ lines.push('')
182
+ lines.push('## Verification Commands')
183
+ lines.push('')
184
+ for (const item of Object.values(data.commandEvidence)) {
185
+ lines.push('- `' + item.command + '`')
186
+ }
187
+ return lines.join('\n') + '\n'
188
+ }
189
+
190
+ if (!dryRun) {
191
+ for (const target of [out, jsonOut]) {
192
+ if (fs.existsSync(target) && !force) {
193
+ throw new Error(`Refusing to overwrite ${target}; pass --force`)
194
+ }
195
+ fs.mkdirSync(path.dirname(target), { recursive: true })
196
+ }
197
+ fs.writeFileSync(out, renderMarkdown(report), 'utf8')
198
+ fs.writeFileSync(jsonOut, JSON.stringify(report, null, 2) + '\n', 'utf8')
199
+ }
200
+
201
+ if (jsonOnly) {
202
+ console.log(JSON.stringify({ status: dryRun ? 'ready' : 'written', out, jsonOut, summary: report.readiness, scores: report.scores }, null, 2))
203
+ } else {
204
+ console.log(renderMarkdown(report))
205
+ }
@@ -0,0 +1,73 @@
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 target = path.resolve(readArg('--target', process.cwd()))
14
+ const hostArg = readArg('--host', 'all')
15
+ const force = args.includes('--force')
16
+ const jsonOnly = args.includes('--json')
17
+
18
+ const hostConfigs = {
19
+ codex: {
20
+ title: 'Codex Adapter',
21
+ path: path.join('.codex', 'gse-adapter.md'),
22
+ bullets: [
23
+ 'Read `.gse/project-profile.md` before using host-specific tools.',
24
+ 'Mark subagent, MCP, browser, and LSP capabilities as verified only after current-session evidence.',
25
+ 'Use `references/compatibility.md` and `references/drift-audit.md` when adapter claims and current tools disagree.',
26
+ ],
27
+ },
28
+ claude: {
29
+ title: 'Claude Code Adapter',
30
+ path: path.join('.claude', 'gse-adapter.md'),
31
+ bullets: [
32
+ 'Commands and agents should point back to `.gse/` for goals, evidence, quality gates, and learning rules.',
33
+ 'Do not copy the goal map, quality gates, or evidence log into this folder.',
34
+ 'Use `references/compatibility.md` and `references/drift-audit.md` when adapter claims and current tools disagree.',
35
+ ],
36
+ },
37
+ }
38
+
39
+ function render(config) {
40
+ return [
41
+ '# ' + config.title,
42
+ '',
43
+ 'Source of truth: `.gse/`.',
44
+ '',
45
+ ...config.bullets.map((item) => '- ' + item),
46
+ '',
47
+ 'Capability status vocabulary: `verified`, `documented`, `unknown`, `unavailable`.',
48
+ '',
49
+ ].join('\n')
50
+ }
51
+
52
+ function writeAdapter(host) {
53
+ const config = hostConfigs[host]
54
+ if (!config) return { host, status: 'invalid', path: null }
55
+ const fullPath = path.join(target, config.path)
56
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true })
57
+ if (!force && fs.existsSync(fullPath)) return { host, status: 'skipped', path: fullPath, relativePath: config.path }
58
+ fs.writeFileSync(fullPath, render(config).replace(/\n/g, '\r\n'), 'utf8')
59
+ return { host, status: 'written', path: fullPath, relativePath: config.path }
60
+ }
61
+
62
+ const hosts = hostArg === 'all' ? Object.keys(hostConfigs) : hostArg.split(',').map((item) => item.trim()).filter(Boolean)
63
+ const invalid = hosts.filter((host) => !hostConfigs[host])
64
+ if (invalid.length) {
65
+ console.error('Invalid --host value: ' + invalid.join(', ') + '. Expected codex, claude, or all.')
66
+ process.exit(1)
67
+ }
68
+
69
+ const results = hosts.map(writeAdapter)
70
+ const report = { target, force, hosts, results }
71
+
72
+ if (jsonOnly) console.log(JSON.stringify(report, null, 2))
73
+ else console.log(JSON.stringify(report, null, 2))
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import { spawnSync } from 'node:child_process'
5
+
6
+ const args = process.argv.slice(2)
7
+
8
+ function readArg(name, fallback = null) {
9
+ const index = args.indexOf(name)
10
+ if (index === -1) return fallback
11
+ return args[index + 1] ?? fallback
12
+ }
13
+
14
+ function hasArg(name) {
15
+ return args.includes(name)
16
+ }
17
+
18
+ const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
19
+ const out = path.resolve(readArg('--out', path.join(root, '.gse', 'acceptance', 'host-runtime-evidence-handoff.md')))
20
+ const displayRoot = readArg('--display-root', '<gse-root>')
21
+ const jsonOnly = hasArg('--json')
22
+ const dryRun = hasArg('--dry-run')
23
+ const force = hasArg('--force')
24
+
25
+ function read(relativePath) {
26
+ const fullPath = path.join(root, relativePath)
27
+ return fs.existsSync(fullPath) ? fs.readFileSync(fullPath, 'utf8').replace(/^\uFEFF/, '') : ''
28
+ }
29
+
30
+ function run(command, commandArgs) {
31
+ const result = spawnSync(command, commandArgs, {
32
+ cwd: root,
33
+ encoding: 'utf8',
34
+ windowsHide: true,
35
+ })
36
+ return {
37
+ status: result.status ?? 1,
38
+ stdout: (result.stdout ?? '').trim(),
39
+ stderr: (result.stderr ?? '').trim(),
40
+ command: [command, ...commandArgs].join(' '),
41
+ }
42
+ }
43
+
44
+ function parseJson(text) {
45
+ try {
46
+ return JSON.parse(text)
47
+ } catch {
48
+ return null
49
+ }
50
+ }
51
+
52
+ function runHostAudit() {
53
+ const result = run(process.execPath, [path.join(root, 'scripts', 'audit-host-runtime-invocations.mjs'), '--root', root, '--json'])
54
+ if (result.status !== 0) {
55
+ return { ok: false, error: 'host runtime invocation audit failed', result }
56
+ }
57
+ const data = parseJson(result.stdout)
58
+ if (!data) return { ok: false, error: 'host runtime invocation audit returned invalid JSON', result }
59
+ return { ok: true, data, command: result.command }
60
+ }
61
+
62
+ function hostRowsFromCompatibility() {
63
+ const text = read('references/compatibility.md')
64
+ const rows = []
65
+ let inHostMatrix = false
66
+ for (const line of text.split(/\r?\n/)) {
67
+ if (line.trim() === '## Host Matrix') {
68
+ inHostMatrix = true
69
+ continue
70
+ }
71
+ if (inHostMatrix && line.startsWith('## ')) break
72
+ if (!inHostMatrix) continue
73
+ if (!line.startsWith('| ')) continue
74
+ if (line.includes('---') || line.includes('Host family')) continue
75
+ const cells = line.split('|').map((item) => item.trim()).filter(Boolean)
76
+ if (cells.length < 6) continue
77
+ rows.push({
78
+ hostFamily: cells[0],
79
+ adapterLocation: cells[1],
80
+ sourcePointer: cells[2],
81
+ currentStatus: cells[3].replace(/`/g, ''),
82
+ evidence: cells[4],
83
+ fallback: cells[5],
84
+ })
85
+ }
86
+ return rows
87
+ }
88
+
89
+ function commandFor(hostFamily) {
90
+ const safeHost = hostFamily.replace(/\|/g, '').replace(/\s+/g, ' ').trim()
91
+ return [
92
+ 'node __GSE__/scripts/record-host-invocation.mjs',
93
+ '--root __PROJECT_OR_GSE__',
94
+ `--host "${safeHost}"`,
95
+ '--host-version "__VERSION_OR_UNKNOWN__"',
96
+ '--project "__PROJECT_NAME__"',
97
+ '--adapter-path "__HOST_ADAPTER_OR_POINTER__"',
98
+ '--invocation-method "__NATIVE_SLASH_COMMAND_OR_PORTABLE_TEXT_COMMAND_OR_HOST_UI_COMMAND_OR_RUNTIME_BRIDGE__"',
99
+ '--command "/gse continue"',
100
+ '--status verified',
101
+ '--evidence-owner "__PERSON_OR_AGENT__"',
102
+ '--evidence "__THREAD_ID_TRANSCRIPT_SCREENSHOT_TERMINAL_OUTPUT_OR_HOST_LOG__"',
103
+ '--portable-text-command true|false',
104
+ '--native-slash-command true|false',
105
+ '--generated-pointer true|false',
106
+ '--owner-acceptance-required false',
107
+ '--out __PROJECT_OR_GSE__/.gse/evidence/host-invocations/__DATE__-__HOST__-gse.md',
108
+ ].join(' ')
109
+ }
110
+
111
+ function renderHandoff(audit, hostRows) {
112
+ const inventory = audit.inventory ?? {}
113
+ const lines = []
114
+ lines.push('# GSE Host Runtime Evidence Handoff')
115
+ lines.push('')
116
+ lines.push('Generated: ' + new Date().toISOString())
117
+ lines.push('Root: ' + displayRoot)
118
+ lines.push('')
119
+ lines.push('## Purpose')
120
+ lines.push('')
121
+ lines.push('Turn cross-host support into auditable runtime evidence. Generated adapters, docs, or command pointers are useful setup, but they are not proof that a host actually invoked GSE.')
122
+ lines.push('')
123
+ lines.push('## Current Runtime Evidence')
124
+ lines.push('')
125
+ lines.push('- Host runtime invocation records: ' + (inventory.records ?? 0))
126
+ lines.push('- Verified or accepted records: ' + (inventory.closeableRecords ?? 0))
127
+ lines.push('- Hosts with records: ' + (inventory.hosts?.length ? inventory.hosts.join(', ') : 'none'))
128
+ lines.push('- Native slash-command records: ' + (inventory.nativeSlashCommandRecords ?? 0))
129
+ lines.push('- Portable text-command records: ' + (inventory.portableTextCommandRecords ?? 0))
130
+ lines.push('- Audit command: `node scripts/audit-host-runtime-invocations.mjs --root __GSE_OR_PROJECT__ --json`')
131
+ lines.push('')
132
+ lines.push('## Host Evidence Plan')
133
+ lines.push('')
134
+ for (const host of hostRows) {
135
+ lines.push('### ' + host.hostFamily)
136
+ lines.push('')
137
+ lines.push('- Adapter location: ' + host.adapterLocation)
138
+ lines.push('- Current matrix status: ' + host.currentStatus)
139
+ lines.push('- Existing evidence: ' + host.evidence)
140
+ lines.push('- Fallback: ' + host.fallback)
141
+ lines.push('- Required runtime proof: a persistent record under `.gse/evidence/host-invocations/` produced by `record-host-invocation.mjs` or manually matching the same fields.')
142
+ lines.push('- Record command:')
143
+ lines.push('')
144
+ lines.push('```bash')
145
+ lines.push(commandFor(host.hostFamily))
146
+ lines.push('```')
147
+ lines.push('')
148
+ }
149
+ lines.push('## Verification')
150
+ lines.push('')
151
+ lines.push('Run these commands after adding host evidence:')
152
+ lines.push('')
153
+ lines.push('```bash')
154
+ lines.push('node scripts/audit-host-runtime-invocations.mjs --root __GSE_OR_PROJECT__ --json')
155
+ lines.push('node scripts/audit-final-readiness.mjs --root __GSE_OR_PROJECT__ --json')
156
+ lines.push('node scripts/validate-gse.mjs --root __GSE_OR_PROJECT__ --json')
157
+ lines.push('```')
158
+ lines.push('')
159
+ lines.push('## Anti-Overclaim')
160
+ lines.push('')
161
+ lines.push('- Do not claim native slash-command support from generated pointers or portable text-command records.')
162
+ lines.push('- Do not claim a host is supported without a host runtime invocation record for that host.')
163
+ lines.push('- Do not mark a host record accepted when `owner-acceptance-required` is true.')
164
+ lines.push('- Keep host capability status separate from portable `.gse/` workflow status.')
165
+ lines.push('- Treat subagents, MCP, LSP, browser tools, hooks, and plugins as host/session-specific until current evidence proves them.')
166
+ lines.push('')
167
+ lines.push('## Next Action')
168
+ lines.push('')
169
+ lines.push('Record real invocation evidence for Claude Code-style, Hermes/AION-style, WorkBuddy/other IDE agents, and any host-native slash-command mechanism that becomes available.')
170
+ return lines.join('\n') + '\n'
171
+ }
172
+
173
+ const audit = runHostAudit()
174
+ if (!audit.ok) {
175
+ console.error(JSON.stringify({ status: 'failed', root, out, error: audit.error, auditResult: audit.result }, null, 2))
176
+ process.exit(1)
177
+ }
178
+
179
+ const hostRows = hostRowsFromCompatibility()
180
+ const handoff = renderHandoff(audit.data, hostRows)
181
+
182
+ if (!dryRun) {
183
+ if (fs.existsSync(out) && !force) {
184
+ console.error(JSON.stringify({ status: 'exists', root, out, error: 'output exists; pass --force to overwrite' }, null, 2))
185
+ process.exit(1)
186
+ }
187
+ fs.mkdirSync(path.dirname(out), { recursive: true })
188
+ fs.writeFileSync(out, handoff, 'utf8')
189
+ }
190
+
191
+ const report = {
192
+ status: dryRun ? 'ready' : 'written',
193
+ root,
194
+ out,
195
+ dryRun,
196
+ hostAuditCommand: audit.command,
197
+ summary: {
198
+ hostFamilies: hostRows.length,
199
+ records: audit.data.inventory?.records ?? 0,
200
+ nativeSlashCommandRecords: audit.data.inventory?.nativeSlashCommandRecords ?? 0,
201
+ portableTextCommandRecords: audit.data.inventory?.portableTextCommandRecords ?? 0,
202
+ },
203
+ }
204
+
205
+ if (jsonOnly) console.log(JSON.stringify(report, null, 2))
206
+ else console.log(handoff)