@t275005746/gse 0.1.0 → 0.1.1
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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +42 -42
- package/.github/ISSUE_TEMPLATE/change_request.yml +50 -50
- package/.github/ISSUE_TEMPLATE/config.yml +5 -5
- package/.github/PULL_REQUEST_TEMPLATE.md +38 -38
- package/.github/workflows/validate-gse.yml +33 -33
- package/.gse/README.md +18 -18
- package/.gse/gse-development-protocol.md +50 -50
- package/.gse/project-profile.md +29 -29
- package/.gse/quality-gates.md +25 -25
- package/.gse/releases/public-registry-publication-npm.md +49 -0
- package/.gse/releases/public-release-owner-required.md +65 -65
- package/.gse/releases/public-security-contact-owner-required.md +45 -45
- package/.gse/state.json +3 -4
- package/CHANGELOG.md +24 -24
- package/CONTRIBUTING.md +64 -64
- package/LICENSE +21 -21
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/SECURITY.md +41 -41
- package/SUPPORT.md +38 -38
- package/assets/marketplace/README.md +7 -7
- package/assets/marketplace/gse-listing.json +75 -75
- package/assets/templates/acceptance-execution-packet.md +73 -73
- package/assets/templates/adr.md +14 -14
- package/assets/templates/change-brief.md +16 -16
- package/assets/templates/design.md +18 -18
- package/assets/templates/dispatch-packet.md +104 -104
- package/assets/templates/evidence.md +14 -14
- package/assets/templates/execution-quality-pack.md +65 -65
- package/assets/templates/goal-map.md +21 -21
- package/assets/templates/host-adapter.md +48 -48
- package/assets/templates/host-ui-invocation-record.md +42 -42
- package/assets/templates/incident-review.md +60 -60
- package/assets/templates/public-channel-publication-record.md +49 -49
- package/assets/templates/public-ci-run-record.md +53 -53
- package/assets/templates/public-release-record.md +65 -65
- package/assets/templates/public-repository-settings-record.md +59 -59
- package/assets/templates/public-security-contact-record.md +45 -45
- package/assets/templates/release-trust-record.md +32 -32
- package/assets/templates/review.md +18 -18
- package/assets/templates/spec.md +16 -16
- package/assets/templates/target-adoption-evidence.md +29 -29
- package/assets/templates/tasks.md +17 -17
- package/assets/templates/update-release-acceptance-record.md +58 -58
- package/examples/README.md +22 -22
- package/examples/agent-runtime-host/.claude/gse-adapter.md +6 -6
- package/examples/agent-runtime-host/.codex/gse-adapter.md +7 -7
- package/examples/agent-runtime-host/.gse/goal-map.md +7 -7
- package/examples/agent-runtime-host/.gse/project-profile.md +27 -27
- package/examples/agent-runtime-host/.gse/tooling.md +5 -5
- package/examples/agent-runtime-host/.mcp.json +9 -9
- package/examples/agent-runtime-host/AGENTS.md +5 -5
- package/examples/agent-runtime-host/README.md +10 -10
- package/examples/agent-runtime-host/docs/model-routing.md +5 -5
- package/examples/cli-tool/.gse/project-profile.md +21 -21
- package/examples/cli-tool/AGENTS.md +5 -5
- package/examples/cli-tool/README.md +12 -12
- package/examples/cli-tool/package.json +21 -21
- package/examples/small-app/.env.example +2 -2
- package/examples/small-app/.github/workflows/ci.yml +8 -8
- package/examples/small-app/AGENTS.md +5 -5
- package/examples/small-app/README.md +12 -12
- package/examples/small-app/package.json +26 -26
- package/examples/small-app/playwright.config.ts +4 -4
- package/package.json +53 -53
- package/references/adoption-recipes.md +171 -171
- package/references/agent-roles.md +49 -49
- package/references/architecture-health.md +101 -101
- package/references/benchmark-audit.md +73 -73
- package/references/community-channels.md +46 -46
- package/references/compatibility.md +70 -70
- package/references/design-basis.md +38 -38
- package/references/domain-model.md +129 -129
- package/references/domain-quality-gates.md +75 -75
- package/references/drift-audit.md +81 -81
- package/references/evidence-taxonomy.md +123 -123
- package/references/file-ownership.md +107 -107
- package/references/final-readiness.md +84 -84
- package/references/forward-test.md +133 -133
- package/references/goal-map.md +36 -36
- package/references/host-adapters.md +119 -119
- package/references/learning-system.md +35 -35
- package/references/marketplace-discovery.md +46 -46
- package/references/model-routing.md +103 -103
- package/references/open-source-defaults.md +39 -39
- package/references/operating-model.md +52 -52
- package/references/packaging.md +277 -277
- package/references/project-agent-workspace.md +89 -89
- package/references/project-bootstrap.md +122 -122
- package/references/project-profile.md +57 -57
- package/references/public-release.md +174 -174
- package/references/quality-gates.md +100 -100
- package/references/recovery.md +176 -176
- package/references/release-trust.md +43 -43
- package/references/release.md +126 -126
- package/references/review.md +141 -141
- package/references/router.md +90 -90
- package/references/spec-workflow.md +66 -66
- package/references/task-levels.md +81 -81
- package/references/tool-adapters.md +73 -73
- package/scripts/audit-acceptance-execution-packet.mjs +133 -133
- package/scripts/audit-adoption-recipes.mjs +99 -99
- package/scripts/audit-change-lifecycle.mjs +77 -77
- package/scripts/audit-change-system.mjs +134 -134
- package/scripts/audit-ci-readiness.mjs +107 -107
- package/scripts/audit-close-gate.mjs +323 -323
- package/scripts/audit-command-adapters.mjs +91 -91
- package/scripts/audit-command-execution.mjs +210 -210
- package/scripts/audit-compatibility.mjs +149 -149
- package/scripts/audit-completion-readiness.mjs +292 -292
- package/scripts/audit-distribution.mjs +251 -251
- package/scripts/audit-domain-quality-gates.mjs +108 -108
- package/scripts/audit-evidence-placeholders.mjs +126 -126
- package/scripts/audit-final-readiness-promotion.mjs +255 -255
- package/scripts/audit-final-readiness.mjs +226 -226
- package/scripts/audit-fixtures.mjs +154 -154
- package/scripts/audit-fresh-session-readiness.mjs +177 -177
- package/scripts/audit-host-runtime-evidence-handoff.mjs +159 -159
- package/scripts/audit-host-runtime-invocation-drill.mjs +240 -240
- package/scripts/audit-host-runtime-invocations.mjs +254 -254
- package/scripts/audit-host-ui-invocation.mjs +132 -132
- package/scripts/audit-marketplace-discovery.mjs +122 -122
- package/scripts/audit-npm-package-metadata.mjs +155 -155
- package/scripts/audit-npm-publish-dry-run.mjs +191 -169
- package/scripts/audit-npm-tarball-install.mjs +191 -191
- package/scripts/audit-open-source-defaults.mjs +92 -92
- package/scripts/audit-open-source-readiness.mjs +97 -97
- package/scripts/audit-project.mjs +138 -138
- package/scripts/audit-public-acceptance-command-dry-run-drill.mjs +203 -203
- package/scripts/audit-public-acceptance-readiness.mjs +224 -224
- package/scripts/audit-public-channel-publication.mjs +248 -248
- package/scripts/audit-public-ci-run.mjs +184 -184
- package/scripts/audit-public-collaboration-templates.mjs +98 -98
- package/scripts/audit-public-external-gate-probe.mjs +206 -206
- package/scripts/audit-public-release-decision.mjs +201 -201
- package/scripts/audit-public-release-metadata.mjs +176 -176
- package/scripts/audit-public-repository-settings.mjs +237 -237
- package/scripts/audit-public-security-contact.mjs +171 -171
- package/scripts/audit-readme-docs.mjs +6 -4
- package/scripts/audit-recovery-readiness.mjs +98 -98
- package/scripts/audit-release-readiness.mjs +106 -106
- package/scripts/audit-release-trust.mjs +62 -62
- package/scripts/audit-remote-distribution.mjs +266 -266
- package/scripts/audit-roadmap-consistency.mjs +235 -235
- package/scripts/audit-signing.mjs +147 -147
- package/scripts/audit-state-freshness.mjs +14 -9
- package/scripts/audit-target-adoption-evidence.mjs +117 -117
- package/scripts/audit-target-project.mjs +507 -507
- package/scripts/audit-update-release-acceptance.mjs +136 -136
- package/scripts/audit-v1-target-validation.mjs +269 -269
- package/scripts/audit-validation-profiles.mjs +125 -125
- package/scripts/close-change.mjs +116 -116
- package/scripts/discover-project-profile.mjs +307 -307
- package/scripts/generate-command-adapter.mjs +231 -231
- package/scripts/generate-final-acceptance-packet.mjs +181 -181
- package/scripts/generate-final-form-progress-report.mjs +205 -205
- package/scripts/generate-host-runtime-evidence-handoff.mjs +206 -206
- package/scripts/generate-owner-external-gate-kit.mjs +295 -295
- package/scripts/generate-public-acceptance-handoff.mjs +168 -168
- package/scripts/generate-public-release-checklist.mjs +207 -207
- package/scripts/generate-release-bundle.mjs +505 -505
- package/scripts/generate-release-owner-action-plan.mjs +172 -172
- package/scripts/generate-release-status-manifest.mjs +200 -200
- package/scripts/generate-session-prompt.mjs +188 -188
- package/scripts/gse.mjs +67 -67
- package/scripts/init-change.mjs +265 -265
- package/scripts/init-project.mjs +785 -785
- package/scripts/install-gse.mjs +234 -234
- package/scripts/lib/evidence-placeholders.mjs +28 -28
- package/scripts/package-gse.mjs +174 -174
- package/scripts/probe-public-external-gates.mjs +167 -167
- package/scripts/record-host-invocation.mjs +151 -151
- package/scripts/record-public-channel-publication.mjs +178 -178
- package/scripts/record-public-ci-run.mjs +180 -180
- package/scripts/record-public-release.mjs +175 -175
- package/scripts/record-public-repository-settings.mjs +209 -209
- package/scripts/record-public-security-contact.mjs +157 -157
- package/scripts/sign-gse-package.mjs +83 -83
- package/scripts/update-project-state.mjs +223 -223
- package/scripts/verify-gse-package.mjs +85 -85
|
@@ -1,97 +1,97 @@
|
|
|
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 contributing = read('CONTRIBUTING.md')
|
|
30
|
-
const security = read('SECURITY.md')
|
|
31
|
-
const support = read('SUPPORT.md')
|
|
32
|
-
const readme = read('README.md')
|
|
33
|
-
const readmeZh = read('README.zh-CN.md')
|
|
34
|
-
const communityChannels = read('references/community-channels.md')
|
|
35
|
-
const publicRelease = read('references/public-release.md')
|
|
36
|
-
const packaging = read('references/packaging.md')
|
|
37
|
-
const validate = read('scripts/validate-gse.mjs')
|
|
38
|
-
const changelog = read('CHANGELOG.md')
|
|
39
|
-
const ciWorkflow = read('.github/workflows/validate-gse.yml')
|
|
40
|
-
const prTemplate = read('.github/PULL_REQUEST_TEMPLATE.md')
|
|
41
|
-
|
|
42
|
-
const checks = [
|
|
43
|
-
check('OS01', 'contributing guide exists', exists('CONTRIBUTING.md') && contributing.includes('Validation') && contributing.includes('Evidence') && contributing.includes('Do not claim support'), 'CONTRIBUTING.md'),
|
|
44
|
-
check('OS02', 'security policy exists without fake public contact', exists('SECURITY.md') && security.includes('Until a public security contact is chosen') && security.includes('release trust') && security.includes('No public vulnerability disclosure address has been owner-approved yet'), 'SECURITY.md'),
|
|
45
|
-
check('OS03', 'support guide exists with first diagnostic commands and community entry', exists('SUPPORT.md') && support.includes('validate-gse.mjs') && support.includes('audit-target-project.mjs') && support.includes('GateHub (`https://gatehub.top/`)'), 'SUPPORT.md'),
|
|
46
|
-
check('OS04', 'open-source readiness keeps license owner-gated', publicRelease.includes('GSE must not choose a license by guessing') && changelog.includes('Open-source license selection remains an owner decision'), 'references/public-release.md, CHANGELOG.md'),
|
|
47
|
-
check('OS05', 'package boundary includes open-source docs', packaging.includes('CONTRIBUTING.md') && packaging.includes('SECURITY.md') && packaging.includes('SUPPORT.md'), 'references/packaging.md'),
|
|
48
|
-
check('OS06', 'validator includes open-source readiness audit', validate.includes('audit-open-source-readiness.mjs'), 'scripts/validate-gse.mjs'),
|
|
49
|
-
check('OS07', 'public repository CI workflow is present and audited', ciWorkflow.includes('node scripts/validate-gse.mjs --root . --skip-skill-validator --json') && validate.includes('audit-ci-readiness.mjs'), '.github/workflows/validate-gse.yml, scripts/validate-gse.mjs'),
|
|
50
|
-
check('OS08', 'public collaboration templates require GSE evidence fields', prTemplate.includes('## Outcome') && prTemplate.includes('## Evidence') && validate.includes('audit-public-collaboration-templates.mjs'), '.github/PULL_REQUEST_TEMPLATE.md, scripts/validate-gse.mjs'),
|
|
51
|
-
check('OS09', 'community support channel is documented with release boundaries', exists('references/community-channels.md') && readme.includes('GateHub ([gatehub.top](https://gatehub.top/))') && readmeZh.includes('GateHub([gatehub.top](https://gatehub.top/))') && support.includes('GateHub (`https://gatehub.top/`)') && publicRelease.includes('references/community-channels.md') && communityChannels.includes('Do not describe GateHub as') && communityChannels.includes('vulnerability disclosure channel'), 'README.md, README.zh-CN.md, SUPPORT.md, references/community-channels.md, references/public-release.md'),
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
const passed = checks.filter((item) => item.status === 'passed').length
|
|
55
|
-
const failed = checks.length - passed
|
|
56
|
-
const report = {
|
|
57
|
-
root,
|
|
58
|
-
generatedAt: new Date().toISOString(),
|
|
59
|
-
summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
|
|
60
|
-
workflows: { openSourceReadiness: failed === 0 ? 'verified' : 'failed' },
|
|
61
|
-
limits: [
|
|
62
|
-
'This audit verifies repository collaboration, security, and support documents.',
|
|
63
|
-
'It does not choose a license, create a public security address, publish to GitHub, or approve a marketplace listing.',
|
|
64
|
-
],
|
|
65
|
-
checks,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function renderMarkdown(data) {
|
|
69
|
-
const lines = []
|
|
70
|
-
lines.push('# GSE Open Source Readiness Audit')
|
|
71
|
-
lines.push('')
|
|
72
|
-
lines.push('Generated: ' + data.generatedAt)
|
|
73
|
-
lines.push('Root: ' + data.root)
|
|
74
|
-
lines.push('')
|
|
75
|
-
lines.push('## Summary')
|
|
76
|
-
lines.push('')
|
|
77
|
-
lines.push('- Status: ' + data.summary.status)
|
|
78
|
-
lines.push('- Checks: ' + data.summary.passed + '/' + data.summary.total)
|
|
79
|
-
lines.push('- Open source readiness: ' + data.workflows.openSourceReadiness)
|
|
80
|
-
lines.push('')
|
|
81
|
-
lines.push('## Checks')
|
|
82
|
-
lines.push('')
|
|
83
|
-
for (const item of data.checks) {
|
|
84
|
-
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
85
|
-
lines.push('- ' + marker + ' ' + item.id + ' ' + item.label + ': ' + item.evidence)
|
|
86
|
-
}
|
|
87
|
-
lines.push('')
|
|
88
|
-
lines.push('## Limits')
|
|
89
|
-
lines.push('')
|
|
90
|
-
for (const item of data.limits) lines.push('- ' + item)
|
|
91
|
-
return lines.join('\n') + '\n'
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
95
|
-
else console.log(renderMarkdown(report))
|
|
96
|
-
|
|
97
|
-
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 contributing = read('CONTRIBUTING.md')
|
|
30
|
+
const security = read('SECURITY.md')
|
|
31
|
+
const support = read('SUPPORT.md')
|
|
32
|
+
const readme = read('README.md')
|
|
33
|
+
const readmeZh = read('README.zh-CN.md')
|
|
34
|
+
const communityChannels = read('references/community-channels.md')
|
|
35
|
+
const publicRelease = read('references/public-release.md')
|
|
36
|
+
const packaging = read('references/packaging.md')
|
|
37
|
+
const validate = read('scripts/validate-gse.mjs')
|
|
38
|
+
const changelog = read('CHANGELOG.md')
|
|
39
|
+
const ciWorkflow = read('.github/workflows/validate-gse.yml')
|
|
40
|
+
const prTemplate = read('.github/PULL_REQUEST_TEMPLATE.md')
|
|
41
|
+
|
|
42
|
+
const checks = [
|
|
43
|
+
check('OS01', 'contributing guide exists', exists('CONTRIBUTING.md') && contributing.includes('Validation') && contributing.includes('Evidence') && contributing.includes('Do not claim support'), 'CONTRIBUTING.md'),
|
|
44
|
+
check('OS02', 'security policy exists without fake public contact', exists('SECURITY.md') && security.includes('Until a public security contact is chosen') && security.includes('release trust') && security.includes('No public vulnerability disclosure address has been owner-approved yet'), 'SECURITY.md'),
|
|
45
|
+
check('OS03', 'support guide exists with first diagnostic commands and community entry', exists('SUPPORT.md') && support.includes('validate-gse.mjs') && support.includes('audit-target-project.mjs') && support.includes('GateHub (`https://gatehub.top/`)'), 'SUPPORT.md'),
|
|
46
|
+
check('OS04', 'open-source readiness keeps license owner-gated', publicRelease.includes('GSE must not choose a license by guessing') && changelog.includes('Open-source license selection remains an owner decision'), 'references/public-release.md, CHANGELOG.md'),
|
|
47
|
+
check('OS05', 'package boundary includes open-source docs', packaging.includes('CONTRIBUTING.md') && packaging.includes('SECURITY.md') && packaging.includes('SUPPORT.md'), 'references/packaging.md'),
|
|
48
|
+
check('OS06', 'validator includes open-source readiness audit', validate.includes('audit-open-source-readiness.mjs'), 'scripts/validate-gse.mjs'),
|
|
49
|
+
check('OS07', 'public repository CI workflow is present and audited', ciWorkflow.includes('node scripts/validate-gse.mjs --root . --skip-skill-validator --json') && validate.includes('audit-ci-readiness.mjs'), '.github/workflows/validate-gse.yml, scripts/validate-gse.mjs'),
|
|
50
|
+
check('OS08', 'public collaboration templates require GSE evidence fields', prTemplate.includes('## Outcome') && prTemplate.includes('## Evidence') && validate.includes('audit-public-collaboration-templates.mjs'), '.github/PULL_REQUEST_TEMPLATE.md, scripts/validate-gse.mjs'),
|
|
51
|
+
check('OS09', 'community support channel is documented with release boundaries', exists('references/community-channels.md') && readme.includes('GateHub ([gatehub.top](https://gatehub.top/))') && readmeZh.includes('GateHub([gatehub.top](https://gatehub.top/))') && support.includes('GateHub (`https://gatehub.top/`)') && publicRelease.includes('references/community-channels.md') && communityChannels.includes('Do not describe GateHub as') && communityChannels.includes('vulnerability disclosure channel'), 'README.md, README.zh-CN.md, SUPPORT.md, references/community-channels.md, references/public-release.md'),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
const passed = checks.filter((item) => item.status === 'passed').length
|
|
55
|
+
const failed = checks.length - passed
|
|
56
|
+
const report = {
|
|
57
|
+
root,
|
|
58
|
+
generatedAt: new Date().toISOString(),
|
|
59
|
+
summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
|
|
60
|
+
workflows: { openSourceReadiness: failed === 0 ? 'verified' : 'failed' },
|
|
61
|
+
limits: [
|
|
62
|
+
'This audit verifies repository collaboration, security, and support documents.',
|
|
63
|
+
'It does not choose a license, create a public security address, publish to GitHub, or approve a marketplace listing.',
|
|
64
|
+
],
|
|
65
|
+
checks,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function renderMarkdown(data) {
|
|
69
|
+
const lines = []
|
|
70
|
+
lines.push('# GSE Open Source Readiness Audit')
|
|
71
|
+
lines.push('')
|
|
72
|
+
lines.push('Generated: ' + data.generatedAt)
|
|
73
|
+
lines.push('Root: ' + data.root)
|
|
74
|
+
lines.push('')
|
|
75
|
+
lines.push('## Summary')
|
|
76
|
+
lines.push('')
|
|
77
|
+
lines.push('- Status: ' + data.summary.status)
|
|
78
|
+
lines.push('- Checks: ' + data.summary.passed + '/' + data.summary.total)
|
|
79
|
+
lines.push('- Open source readiness: ' + data.workflows.openSourceReadiness)
|
|
80
|
+
lines.push('')
|
|
81
|
+
lines.push('## Checks')
|
|
82
|
+
lines.push('')
|
|
83
|
+
for (const item of data.checks) {
|
|
84
|
+
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
85
|
+
lines.push('- ' + marker + ' ' + item.id + ' ' + item.label + ': ' + item.evidence)
|
|
86
|
+
}
|
|
87
|
+
lines.push('')
|
|
88
|
+
lines.push('## Limits')
|
|
89
|
+
lines.push('')
|
|
90
|
+
for (const item of data.limits) lines.push('- ' + item)
|
|
91
|
+
return lines.join('\n') + '\n'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
95
|
+
else console.log(renderMarkdown(report))
|
|
96
|
+
|
|
97
|
+
if (failed > 0) process.exit(1)
|
|
@@ -15,28 +15,28 @@ function readArg(name, fallback = null) {
|
|
|
15
15
|
const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
|
|
16
16
|
const jsonOnly = args.includes('--json')
|
|
17
17
|
const keepTemp = args.includes('--keep-temp')
|
|
18
|
-
const tempRootArg = readArg('--temp-root', null)
|
|
18
|
+
const tempRootArg = readArg('--temp-root', null)
|
|
19
19
|
const baseTemp = tempRootArg ? path.resolve(tempRootArg) : fs.mkdtempSync(path.join(os.tmpdir(), 'gse-project-audit-'))
|
|
20
20
|
const initScript = path.join(root, 'scripts', 'init-project.mjs')
|
|
21
21
|
|
|
22
|
-
const commonFiles = [
|
|
23
|
-
'.gse/README.md',
|
|
24
|
-
'.gse/state.json',
|
|
25
|
-
'.gse/project-profile.md',
|
|
26
|
-
'.gse/goal-map.md',
|
|
27
|
-
'.gse/quality-gates.md',
|
|
28
|
-
'.gse/tooling.md',
|
|
29
|
-
'.gse/learnings.md',
|
|
30
|
-
'.gse/evidence/index.jsonl',
|
|
31
|
-
'.gse/goals/README.md',
|
|
32
|
-
'.gse/templates/change-brief.md',
|
|
33
|
-
'.gse/templates/spec.md',
|
|
34
|
-
'.gse/templates/design.md',
|
|
35
|
-
'.gse/templates/tasks.md',
|
|
36
|
-
'.gse/templates/evidence.md',
|
|
37
|
-
'.gse/templates/review.md',
|
|
38
|
-
'.gse/templates/execution-quality-pack.md',
|
|
39
|
-
]
|
|
22
|
+
const commonFiles = [
|
|
23
|
+
'.gse/README.md',
|
|
24
|
+
'.gse/state.json',
|
|
25
|
+
'.gse/project-profile.md',
|
|
26
|
+
'.gse/goal-map.md',
|
|
27
|
+
'.gse/quality-gates.md',
|
|
28
|
+
'.gse/tooling.md',
|
|
29
|
+
'.gse/learnings.md',
|
|
30
|
+
'.gse/evidence/index.jsonl',
|
|
31
|
+
'.gse/goals/README.md',
|
|
32
|
+
'.gse/templates/change-brief.md',
|
|
33
|
+
'.gse/templates/spec.md',
|
|
34
|
+
'.gse/templates/design.md',
|
|
35
|
+
'.gse/templates/tasks.md',
|
|
36
|
+
'.gse/templates/evidence.md',
|
|
37
|
+
'.gse/templates/review.md',
|
|
38
|
+
'.gse/templates/execution-quality-pack.md',
|
|
39
|
+
]
|
|
40
40
|
|
|
41
41
|
const standardFiles = [
|
|
42
42
|
'.gse/agent-workspace.md',
|
|
@@ -55,23 +55,23 @@ const enterpriseFiles = [
|
|
|
55
55
|
'.gse/audit.md',
|
|
56
56
|
]
|
|
57
57
|
|
|
58
|
-
const modeExpectations = {
|
|
58
|
+
const modeExpectations = {
|
|
59
59
|
lite: {
|
|
60
60
|
files: commonFiles,
|
|
61
|
-
dirs: ['.gse/changes', '.gse/evidence', '.gse/templates', '.gse/goals'],
|
|
61
|
+
dirs: ['.gse/changes', '.gse/evidence', '.gse/templates', '.gse/goals'],
|
|
62
62
|
},
|
|
63
63
|
standard: {
|
|
64
64
|
files: [...commonFiles, ...standardFiles],
|
|
65
|
-
dirs: ['.gse/changes', '.gse/evidence', '.gse/templates', '.gse/goals', '.gse/agents', '.gse/skills', '.gse/lsp'],
|
|
65
|
+
dirs: ['.gse/changes', '.gse/evidence', '.gse/templates', '.gse/goals', '.gse/agents', '.gse/skills', '.gse/lsp'],
|
|
66
66
|
},
|
|
67
67
|
enterprise: {
|
|
68
68
|
files: [...commonFiles, ...standardFiles, ...enterpriseFiles],
|
|
69
69
|
dirs: [
|
|
70
70
|
'.gse/changes',
|
|
71
71
|
'.gse/evidence',
|
|
72
|
-
'.gse/templates',
|
|
73
|
-
'.gse/goals',
|
|
74
|
-
'.gse/agents',
|
|
72
|
+
'.gse/templates',
|
|
73
|
+
'.gse/goals',
|
|
74
|
+
'.gse/agents',
|
|
75
75
|
'.gse/skills',
|
|
76
76
|
'.gse/lsp',
|
|
77
77
|
'.gse/hooks',
|
|
@@ -79,45 +79,45 @@ const modeExpectations = {
|
|
|
79
79
|
'.gse/plugins',
|
|
80
80
|
],
|
|
81
81
|
},
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const autoExpectations = [
|
|
85
|
-
{
|
|
86
|
-
name: 'empty-project',
|
|
87
|
-
expectedMode: 'lite',
|
|
88
|
-
setup(target) {
|
|
89
|
-
fs.mkdirSync(target, { recursive: true })
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: 'standard-app',
|
|
94
|
-
expectedMode: 'standard',
|
|
95
|
-
setup(target) {
|
|
96
|
-
fs.mkdirSync(target, { recursive: true })
|
|
97
|
-
fs.writeFileSync(path.join(target, 'README.md'), '# Standard App\n', 'utf8')
|
|
98
|
-
fs.writeFileSync(
|
|
99
|
-
path.join(target, 'package.json'),
|
|
100
|
-
JSON.stringify({ scripts: { test: 'vitest run', build: 'vite build' }, devDependencies: { typescript: '^5.0.0', vitest: '^2.0.0' } }, null, 2),
|
|
101
|
-
'utf8',
|
|
102
|
-
)
|
|
103
|
-
fs.writeFileSync(path.join(target, 'tsconfig.json'), '{}\n', 'utf8')
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
name: 'enterprise-agent-runtime',
|
|
108
|
-
expectedMode: 'enterprise',
|
|
109
|
-
setup(target) {
|
|
110
|
-
fs.mkdirSync(path.join(target, '.claude'), { recursive: true })
|
|
111
|
-
fs.mkdirSync(path.join(target, '.codex'), { recursive: true })
|
|
112
|
-
fs.writeFileSync(path.join(target, '.mcp.json'), '{}\n', 'utf8')
|
|
113
|
-
fs.writeFileSync(
|
|
114
|
-
path.join(target, 'package.json'),
|
|
115
|
-
JSON.stringify({ scripts: { test: 'vitest run', release: 'node release.mjs' } }, null, 2),
|
|
116
|
-
'utf8',
|
|
117
|
-
)
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const autoExpectations = [
|
|
85
|
+
{
|
|
86
|
+
name: 'empty-project',
|
|
87
|
+
expectedMode: 'lite',
|
|
88
|
+
setup(target) {
|
|
89
|
+
fs.mkdirSync(target, { recursive: true })
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'standard-app',
|
|
94
|
+
expectedMode: 'standard',
|
|
95
|
+
setup(target) {
|
|
96
|
+
fs.mkdirSync(target, { recursive: true })
|
|
97
|
+
fs.writeFileSync(path.join(target, 'README.md'), '# Standard App\n', 'utf8')
|
|
98
|
+
fs.writeFileSync(
|
|
99
|
+
path.join(target, 'package.json'),
|
|
100
|
+
JSON.stringify({ scripts: { test: 'vitest run', build: 'vite build' }, devDependencies: { typescript: '^5.0.0', vitest: '^2.0.0' } }, null, 2),
|
|
101
|
+
'utf8',
|
|
102
|
+
)
|
|
103
|
+
fs.writeFileSync(path.join(target, 'tsconfig.json'), '{}\n', 'utf8')
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'enterprise-agent-runtime',
|
|
108
|
+
expectedMode: 'enterprise',
|
|
109
|
+
setup(target) {
|
|
110
|
+
fs.mkdirSync(path.join(target, '.claude'), { recursive: true })
|
|
111
|
+
fs.mkdirSync(path.join(target, '.codex'), { recursive: true })
|
|
112
|
+
fs.writeFileSync(path.join(target, '.mcp.json'), '{}\n', 'utf8')
|
|
113
|
+
fs.writeFileSync(
|
|
114
|
+
path.join(target, 'package.json'),
|
|
115
|
+
JSON.stringify({ scripts: { test: 'vitest run', release: 'node release.mjs' } }, null, 2),
|
|
116
|
+
'utf8',
|
|
117
|
+
)
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
]
|
|
121
121
|
|
|
122
122
|
function runNode(script, runArgs) {
|
|
123
123
|
return spawnSync(process.execPath, [script, ...runArgs], {
|
|
@@ -169,7 +169,7 @@ function compareSignatures(before, after) {
|
|
|
169
169
|
return changed
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
function auditMode(mode, tempRoot) {
|
|
172
|
+
function auditMode(mode, tempRoot) {
|
|
173
173
|
const target = path.join(tempRoot, mode)
|
|
174
174
|
fs.mkdirSync(target, { recursive: true })
|
|
175
175
|
const expectation = modeExpectations[mode]
|
|
@@ -205,45 +205,45 @@ function auditMode(mode, tempRoot) {
|
|
|
205
205
|
dirChecks,
|
|
206
206
|
changedOnRerun,
|
|
207
207
|
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function auditAuto(item, tempRoot) {
|
|
211
|
-
const target = path.join(tempRoot, 'auto-' + item.name)
|
|
212
|
-
fs.rmSync(target, { recursive: true, force: true })
|
|
213
|
-
item.setup(target)
|
|
214
|
-
const run = runNode(initScript, ['--target', target, '--mode', 'auto'])
|
|
215
|
-
const model = readJsonFromRun(run)
|
|
216
|
-
const expectation = modeExpectations[item.expectedMode]
|
|
217
|
-
const fileChecks = expectation.files.map((relativePath) => ({ relativePath, status: fileStatus(target, relativePath) }))
|
|
218
|
-
const dirChecks = expectation.dirs.map((relativePath) => ({ relativePath, status: dirStatus(target, relativePath) }))
|
|
219
|
-
const ok =
|
|
220
|
-
run.status === 0 &&
|
|
221
|
-
model?.requestedMode === 'auto' &&
|
|
222
|
-
model?.mode === item.expectedMode &&
|
|
223
|
-
Array.isArray(model?.selectionReasons) &&
|
|
224
|
-
model.selectionReasons.length > 0 &&
|
|
225
|
-
fileChecks.every((check) => check.status === 'present') &&
|
|
226
|
-
dirChecks.every((check) => check.status === 'present') &&
|
|
227
|
-
(item.expectedMode !== 'enterprise' || (fileStatus(target, '.codex/gse-adapter.md') === 'present' && fileStatus(target, '.claude/gse-adapter.md') === 'present'))
|
|
228
|
-
return {
|
|
229
|
-
name: item.name,
|
|
230
|
-
target,
|
|
231
|
-
expectedMode: item.expectedMode,
|
|
232
|
-
detectedMode: model?.mode ?? null,
|
|
233
|
-
selectionReasons: model?.selectionReasons ?? [],
|
|
234
|
-
status: ok ? 'passed' : 'failed',
|
|
235
|
-
run: { status: run.status, stderr: run.stderr.trim() },
|
|
236
|
-
fileChecks,
|
|
237
|
-
dirChecks,
|
|
238
|
-
hostAdapterChecks:
|
|
239
|
-
item.expectedMode === 'enterprise'
|
|
240
|
-
? [
|
|
241
|
-
{ relativePath: '.codex/gse-adapter.md', status: fileStatus(target, '.codex/gse-adapter.md') },
|
|
242
|
-
{ relativePath: '.claude/gse-adapter.md', status: fileStatus(target, '.claude/gse-adapter.md') },
|
|
243
|
-
]
|
|
244
|
-
: [],
|
|
245
|
-
}
|
|
246
|
-
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function auditAuto(item, tempRoot) {
|
|
211
|
+
const target = path.join(tempRoot, 'auto-' + item.name)
|
|
212
|
+
fs.rmSync(target, { recursive: true, force: true })
|
|
213
|
+
item.setup(target)
|
|
214
|
+
const run = runNode(initScript, ['--target', target, '--mode', 'auto'])
|
|
215
|
+
const model = readJsonFromRun(run)
|
|
216
|
+
const expectation = modeExpectations[item.expectedMode]
|
|
217
|
+
const fileChecks = expectation.files.map((relativePath) => ({ relativePath, status: fileStatus(target, relativePath) }))
|
|
218
|
+
const dirChecks = expectation.dirs.map((relativePath) => ({ relativePath, status: dirStatus(target, relativePath) }))
|
|
219
|
+
const ok =
|
|
220
|
+
run.status === 0 &&
|
|
221
|
+
model?.requestedMode === 'auto' &&
|
|
222
|
+
model?.mode === item.expectedMode &&
|
|
223
|
+
Array.isArray(model?.selectionReasons) &&
|
|
224
|
+
model.selectionReasons.length > 0 &&
|
|
225
|
+
fileChecks.every((check) => check.status === 'present') &&
|
|
226
|
+
dirChecks.every((check) => check.status === 'present') &&
|
|
227
|
+
(item.expectedMode !== 'enterprise' || (fileStatus(target, '.codex/gse-adapter.md') === 'present' && fileStatus(target, '.claude/gse-adapter.md') === 'present'))
|
|
228
|
+
return {
|
|
229
|
+
name: item.name,
|
|
230
|
+
target,
|
|
231
|
+
expectedMode: item.expectedMode,
|
|
232
|
+
detectedMode: model?.mode ?? null,
|
|
233
|
+
selectionReasons: model?.selectionReasons ?? [],
|
|
234
|
+
status: ok ? 'passed' : 'failed',
|
|
235
|
+
run: { status: run.status, stderr: run.stderr.trim() },
|
|
236
|
+
fileChecks,
|
|
237
|
+
dirChecks,
|
|
238
|
+
hostAdapterChecks:
|
|
239
|
+
item.expectedMode === 'enterprise'
|
|
240
|
+
? [
|
|
241
|
+
{ relativePath: '.codex/gse-adapter.md', status: fileStatus(target, '.codex/gse-adapter.md') },
|
|
242
|
+
{ relativePath: '.claude/gse-adapter.md', status: fileStatus(target, '.claude/gse-adapter.md') },
|
|
243
|
+
]
|
|
244
|
+
: [],
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
247
|
|
|
248
248
|
function renderMarkdown(data) {
|
|
249
249
|
const lines = []
|
|
@@ -255,29 +255,29 @@ function renderMarkdown(data) {
|
|
|
255
255
|
lines.push('')
|
|
256
256
|
lines.push('## Summary')
|
|
257
257
|
lines.push('')
|
|
258
|
-
lines.push('- Status: ' + data.summary.status)
|
|
259
|
-
lines.push('- Modes: ' + data.summary.passed + '/' + data.summary.total)
|
|
260
|
-
lines.push('- Bootstrap scaffold: ' + data.workflows.bootstrapScaffold)
|
|
261
|
-
lines.push('- Rerun safety: ' + data.workflows.rerunSafety)
|
|
262
|
-
lines.push('- Auto mode selection: ' + data.workflows.autoModeSelection)
|
|
263
|
-
lines.push('')
|
|
264
|
-
lines.push('## Modes')
|
|
258
|
+
lines.push('- Status: ' + data.summary.status)
|
|
259
|
+
lines.push('- Modes: ' + data.summary.passed + '/' + data.summary.total)
|
|
260
|
+
lines.push('- Bootstrap scaffold: ' + data.workflows.bootstrapScaffold)
|
|
261
|
+
lines.push('- Rerun safety: ' + data.workflows.rerunSafety)
|
|
262
|
+
lines.push('- Auto mode selection: ' + data.workflows.autoModeSelection)
|
|
263
|
+
lines.push('')
|
|
264
|
+
lines.push('## Modes')
|
|
265
265
|
lines.push('')
|
|
266
266
|
for (const item of data.modes) {
|
|
267
267
|
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
268
268
|
lines.push('- ' + marker + ' ' + item.mode + ': files ' + item.fileChecks.filter((check) => check.status === 'present').length + '/' + item.fileChecks.length + ', dirs ' + item.dirChecks.filter((check) => check.status === 'present').length + '/' + item.dirChecks.length + ', skipped on rerun ' + item.secondRun.skippedCount + '/' + item.secondRun.expectedSkips)
|
|
269
|
-
if (item.changedOnRerun.length) lines.push(' - Changed on rerun: ' + item.changedOnRerun.join(', '))
|
|
270
|
-
}
|
|
271
|
-
lines.push('')
|
|
272
|
-
lines.push('## Auto Mode')
|
|
273
|
-
lines.push('')
|
|
274
|
-
for (const item of data.autoModes) {
|
|
275
|
-
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
276
|
-
const hostAdapters = item.hostAdapterChecks?.length ? ', host adapters ' + item.hostAdapterChecks.filter((check) => check.status === 'present').length + '/' + item.hostAdapterChecks.length : ''
|
|
277
|
-
lines.push('- ' + marker + ' ' + item.name + ': expected ' + item.expectedMode + ', detected ' + item.detectedMode + ', reasons ' + item.selectionReasons.join(', ') + hostAdapters)
|
|
278
|
-
}
|
|
279
|
-
lines.push('')
|
|
280
|
-
lines.push('## Limits')
|
|
269
|
+
if (item.changedOnRerun.length) lines.push(' - Changed on rerun: ' + item.changedOnRerun.join(', '))
|
|
270
|
+
}
|
|
271
|
+
lines.push('')
|
|
272
|
+
lines.push('## Auto Mode')
|
|
273
|
+
lines.push('')
|
|
274
|
+
for (const item of data.autoModes) {
|
|
275
|
+
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
276
|
+
const hostAdapters = item.hostAdapterChecks?.length ? ', host adapters ' + item.hostAdapterChecks.filter((check) => check.status === 'present').length + '/' + item.hostAdapterChecks.length : ''
|
|
277
|
+
lines.push('- ' + marker + ' ' + item.name + ': expected ' + item.expectedMode + ', detected ' + item.detectedMode + ', reasons ' + item.selectionReasons.join(', ') + hostAdapters)
|
|
278
|
+
}
|
|
279
|
+
lines.push('')
|
|
280
|
+
lines.push('## Limits')
|
|
281
281
|
lines.push('')
|
|
282
282
|
for (const item of data.limits) lines.push('- ' + item)
|
|
283
283
|
return lines.join('\n') + '\n'
|
|
@@ -291,29 +291,29 @@ if (!fs.existsSync(initScript)) {
|
|
|
291
291
|
fs.rmSync(baseTemp, { recursive: true, force: true })
|
|
292
292
|
fs.mkdirSync(baseTemp, { recursive: true })
|
|
293
293
|
|
|
294
|
-
const modes = Object.keys(modeExpectations).map((mode) => auditMode(mode, baseTemp))
|
|
295
|
-
const autoModes = autoExpectations.map((item) => auditAuto(item, baseTemp))
|
|
296
|
-
const passed = modes.filter((item) => item.status === 'passed').length
|
|
297
|
-
const autoPassed = autoModes.filter((item) => item.status === 'passed').length
|
|
298
|
-
const failed = modes.length - passed + (autoModes.length - autoPassed)
|
|
299
|
-
const report = {
|
|
294
|
+
const modes = Object.keys(modeExpectations).map((mode) => auditMode(mode, baseTemp))
|
|
295
|
+
const autoModes = autoExpectations.map((item) => auditAuto(item, baseTemp))
|
|
296
|
+
const passed = modes.filter((item) => item.status === 'passed').length
|
|
297
|
+
const autoPassed = autoModes.filter((item) => item.status === 'passed').length
|
|
298
|
+
const failed = modes.length - passed + (autoModes.length - autoPassed)
|
|
299
|
+
const report = {
|
|
300
300
|
root,
|
|
301
301
|
generatedAt: new Date().toISOString(),
|
|
302
302
|
tempRoot: baseTemp,
|
|
303
|
-
summary: { passed: passed + autoPassed, failed, total: modes.length + autoModes.length, status: failed === 0 ? 'passed' : 'failed' },
|
|
304
|
-
workflows: {
|
|
305
|
-
bootstrapScaffold: modes.every((item) => item.fileChecks.every((check) => check.status === 'present') && item.dirChecks.every((check) => check.status === 'present')) ? 'verified' : 'failed',
|
|
306
|
-
rerunSafety: modes.every((item) => item.changedOnRerun.length === 0 && item.secondRun.skippedCount === item.secondRun.expectedSkips) ? 'verified' : 'failed',
|
|
307
|
-
autoModeSelection: autoModes.every((item) => item.status === 'passed') ? 'verified' : 'failed',
|
|
308
|
-
},
|
|
303
|
+
summary: { passed: passed + autoPassed, failed, total: modes.length + autoModes.length, status: failed === 0 ? 'passed' : 'failed' },
|
|
304
|
+
workflows: {
|
|
305
|
+
bootstrapScaffold: modes.every((item) => item.fileChecks.every((check) => check.status === 'present') && item.dirChecks.every((check) => check.status === 'present')) ? 'verified' : 'failed',
|
|
306
|
+
rerunSafety: modes.every((item) => item.changedOnRerun.length === 0 && item.secondRun.skippedCount === item.secondRun.expectedSkips) ? 'verified' : 'failed',
|
|
307
|
+
autoModeSelection: autoModes.every((item) => item.status === 'passed') ? 'verified' : 'failed',
|
|
308
|
+
},
|
|
309
309
|
limits: [
|
|
310
310
|
'Project audit uses temporary directories and generated scaffolds, not arbitrary real repositories.',
|
|
311
311
|
'Project audit verifies init-project scaffold and rerun safety, not tool installation, CI, package install, or fresh-session acceptance.',
|
|
312
312
|
'Use discover-project-profile and focused project checks separately for real existing repo adoption.',
|
|
313
313
|
],
|
|
314
|
-
modes,
|
|
315
|
-
autoModes,
|
|
316
|
-
}
|
|
314
|
+
modes,
|
|
315
|
+
autoModes,
|
|
316
|
+
}
|
|
317
317
|
|
|
318
318
|
if (!keepTemp) fs.rmSync(baseTemp, { recursive: true, force: true })
|
|
319
319
|
|