@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.
- 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 +147 -27
- package/CHANGELOG.md +31 -15
- package/CONTRIBUTING.md +64 -64
- package/LICENSE +21 -21
- package/README.md +14 -7
- package/README.zh-CN.md +14 -7
- package/SECURITY.md +41 -41
- package/SKILL.md +32 -12
- 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 +100 -92
- package/assets/templates/evidence.md +15 -9
- 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/role-fallback-packet.md +49 -0
- 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 +52 -44
- package/references/adoption-recipes.md +171 -171
- package/references/agent-roles.md +42 -21
- package/references/architecture-health.md +101 -101
- package/references/benchmark-audit.md +73 -73
- package/references/commands.md +74 -45
- 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 -80
- package/references/evidence-taxonomy.md +145 -108
- package/references/file-ownership.md +97 -93
- package/references/final-form-roadmap.md +201 -0
- 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 +129 -101
- package/references/learning-system.md +42 -26
- package/references/maintenance-cadence.md +51 -0
- 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-guards.md +52 -0
- package/references/project-profile.md +57 -57
- package/references/public-release.md +174 -174
- package/references/quality-gates.md +96 -89
- 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/role-dispatch-fallback.md +54 -0
- 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 +80 -70
- 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-hardening.mjs +188 -0
- package/scripts/audit-close-gate.mjs +448 -262
- package/scripts/audit-command-adapters.mjs +91 -91
- package/scripts/audit-command-execution.mjs +212 -199
- package/scripts/audit-commands.mjs +7 -5
- package/scripts/audit-compatibility.mjs +149 -149
- package/scripts/audit-completion-plan-drill.mjs +230 -0
- package/scripts/audit-completion-readiness.mjs +290 -287
- package/scripts/audit-continue-preflight.mjs +234 -0
- package/scripts/audit-distribution.mjs +251 -251
- package/scripts/audit-domain-quality-gates.mjs +108 -108
- package/scripts/audit-evidence-levels.mjs +217 -0
- package/scripts/audit-evidence-placeholders.mjs +126 -126
- package/scripts/audit-evidence-review-queue.mjs +206 -0
- package/scripts/audit-final-acceptance-packet.mjs +9 -9
- package/scripts/audit-final-form-progress-report.mjs +19 -18
- package/scripts/audit-final-form-roadmap.mjs +157 -0
- package/scripts/audit-final-form-stale-copy.mjs +2 -2
- 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-capabilities.mjs +237 -0
- 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-installed-sync.mjs +203 -0
- package/scripts/audit-learning-drift.mjs +292 -0
- package/scripts/audit-learning-promotion.mjs +351 -0
- package/scripts/audit-learning-system.mjs +24 -14
- package/scripts/audit-local-final-form-completion.mjs +11 -10
- package/scripts/audit-maintenance-cadence.mjs +139 -0
- package/scripts/audit-maintenance-snapshot.mjs +181 -0
- package/scripts/audit-marketplace-discovery.mjs +122 -122
- package/scripts/audit-npm-package-metadata.mjs +160 -154
- package/scripts/audit-npm-publish-dry-run.mjs +194 -166
- package/scripts/audit-npm-tarball-install.mjs +195 -189
- package/scripts/audit-open-source-defaults.mjs +92 -92
- package/scripts/audit-open-source-readiness.mjs +97 -97
- package/scripts/audit-owner-external-gate-kit.mjs +12 -11
- package/scripts/audit-project-guards.mjs +189 -0
- package/scripts/audit-project.mjs +144 -141
- package/scripts/audit-public-acceptance-command-dry-run-drill.mjs +203 -203
- package/scripts/audit-public-acceptance-handoff.mjs +10 -10
- package/scripts/audit-public-acceptance-readiness.mjs +222 -222
- 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-checklist.mjs +17 -15
- 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-bundle.mjs +13 -11
- package/scripts/audit-release-owner-action-plan-drill.mjs +5 -4
- package/scripts/audit-release-owner-action-plan.mjs +10 -10
- package/scripts/audit-release-readiness.mjs +106 -106
- package/scripts/audit-release-status-manifest.mjs +4 -4
- package/scripts/audit-release-trust.mjs +62 -62
- package/scripts/audit-remote-distribution.mjs +266 -266
- package/scripts/audit-roadmap-consistency.mjs +234 -230
- package/scripts/audit-role-dispatch-fallback.mjs +212 -0
- package/scripts/audit-session-sync.mjs +127 -0
- package/scripts/audit-signing.mjs +147 -147
- package/scripts/audit-state-freshness.mjs +20 -14
- package/scripts/audit-state-repair.mjs +360 -0
- package/scripts/audit-target-adoption-evidence.mjs +117 -117
- package/scripts/audit-target-hardening-drills.mjs +267 -0
- package/scripts/audit-target-project.mjs +507 -507
- package/scripts/audit-tool-fallback-policy.mjs +180 -0
- package/scripts/audit-ui-browser-evidence-policy.mjs +191 -0
- 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 -123
- package/scripts/backfill-evidence-levels.mjs +98 -0
- package/scripts/check-encoding.mjs +72 -0
- 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-continue-packet.mjs +1214 -0
- package/scripts/generate-final-acceptance-packet.mjs +188 -173
- package/scripts/generate-final-form-progress-report.mjs +191 -189
- package/scripts/generate-host-runtime-evidence-handoff.mjs +198 -191
- package/scripts/generate-maintenance-snapshot.mjs +216 -0
- package/scripts/generate-owner-external-gate-kit.mjs +295 -295
- package/scripts/generate-public-acceptance-handoff.mjs +168 -156
- 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 -171
- package/scripts/generate-release-status-manifest.mjs +199 -198
- 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 +793 -712
- 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-learning.mjs +37 -8
- 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/record-session-sync.mjs +87 -0
- package/scripts/run-gse-command.mjs +79 -47
- package/scripts/run-validation-profile.mjs +24 -5
- package/scripts/sign-gse-package.mjs +83 -83
- package/scripts/update-project-state.mjs +223 -223
- package/scripts/validate-gse.mjs +216 -0
- package/scripts/verify-gse-package.mjs +85 -85
|
@@ -1,108 +1,108 @@
|
|
|
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 domain = read('references/domain-quality-gates.md')
|
|
30
|
-
const quality = read('references/quality-gates.md')
|
|
31
|
-
const review = read('references/review.md')
|
|
32
|
-
const architecture = read('references/architecture-health.md')
|
|
33
|
-
const skill = read('SKILL.md')
|
|
34
|
-
|
|
35
|
-
const domains = [
|
|
36
|
-
'Security/privacy',
|
|
37
|
-
'Performance/cost',
|
|
38
|
-
'Accessibility',
|
|
39
|
-
'Resilience/recovery',
|
|
40
|
-
'UI/browser',
|
|
41
|
-
'API/state',
|
|
42
|
-
'Data/migration',
|
|
43
|
-
'Model/tool routing',
|
|
44
|
-
'Release/operations',
|
|
45
|
-
]
|
|
46
|
-
const evidenceTerms = ['File inspection', 'Focused tests', 'API smokes', 'Browser smokes', 'Architecture/review scans']
|
|
47
|
-
const outputFields = ['Domain gates selected:', 'Why selected:', 'Evidence run:', 'Evidence status:', 'Unverified tools:', 'Residual risk:', 'Next action:']
|
|
48
|
-
const scaleTerms = ['Lite', 'Standard', 'Enterprise']
|
|
49
|
-
|
|
50
|
-
const checks = [
|
|
51
|
-
check('DQ01', 'domain quality gates reference exists', exists('references/domain-quality-gates.md'), 'references/domain-quality-gates.md'),
|
|
52
|
-
check('DQ02', 'SKILL routes domain quality gates', skill.includes('references/domain-quality-gates.md'), 'SKILL.md Reference Routing'),
|
|
53
|
-
check('DQ03', 'quality-gates routes to domain gates', quality.includes('references/domain-quality-gates.md') && quality.includes('## Domain Gates'), 'references/quality-gates.md'),
|
|
54
|
-
check('DQ04', 'review protocol routes to domain gates', review.includes('references/domain-quality-gates.md'), 'references/review.md'),
|
|
55
|
-
check('DQ05', 'all required domains are represented', domains.every((item) => domain.includes(item)), domains.join(', ')),
|
|
56
|
-
check('DQ06', 'scale adaptation is explicit', scaleTerms.every((item) => domain.includes(item)) && domain.includes('Lite work should not inherit every gate by default'), 'Lite, Standard, Enterprise'),
|
|
57
|
-
check('DQ07', 'evidence taxonomy routing is explicit', domain.includes('references/evidence-taxonomy.md') && domain.includes('result') && domain.includes('verified') && domain.includes('accepted'), 'evidence taxonomy labels'),
|
|
58
|
-
check('DQ08', 'tool execution is not faked', domain.includes('Do not claim scan, benchmark, browser, accessibility, security, or resilience results unless') && domain.includes('actually executed'), 'tool execution claim rule'),
|
|
59
|
-
check('DQ09', 'minimum evidence mapping covers major evidence modes', evidenceTerms.every((item) => domain.includes(item)), evidenceTerms.join(', ')),
|
|
60
|
-
check('DQ10', 'output format includes selected gates and residual risk', outputFields.every((item) => domain.includes(item)), outputFields.join(', ')),
|
|
61
|
-
check('DQ11', 'architecture health covers performance and resilience risk', architecture.includes('Performance And Resilience') && architecture.includes('migration') && architecture.includes('release'), 'references/architecture-health.md'),
|
|
62
|
-
check('DQ12', 'quality gates remain risk-based instead of mandatory for every task', domain.includes('Pick only the gates that match the changed behavior and project risk') && quality.includes('Do not force all gates onto Lite tasks'), 'risk-based gate language'),
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
const passed = checks.filter((item) => item.status === 'passed').length
|
|
66
|
-
const failed = checks.length - passed
|
|
67
|
-
const report = {
|
|
68
|
-
root,
|
|
69
|
-
generatedAt: new Date().toISOString(),
|
|
70
|
-
summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
|
|
71
|
-
workflows: { domainQualityGates: failed === 0 ? 'verified' : 'failed' },
|
|
72
|
-
limits: [
|
|
73
|
-
'Domain quality gate audit verifies reusable guidance and routing; it does not run project-specific security scans, benchmarks, accessibility tools, browser tests, or API smokes.',
|
|
74
|
-
'Projects must still execute the selected gates with their own commands, tools, owners, and evidence.',
|
|
75
|
-
],
|
|
76
|
-
checks,
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function renderMarkdown(data) {
|
|
80
|
-
const lines = []
|
|
81
|
-
lines.push('# GSE Domain Quality Gate Audit')
|
|
82
|
-
lines.push('')
|
|
83
|
-
lines.push('Generated: ' + data.generatedAt)
|
|
84
|
-
lines.push('Root: ' + data.root)
|
|
85
|
-
lines.push('')
|
|
86
|
-
lines.push('## Summary')
|
|
87
|
-
lines.push('')
|
|
88
|
-
lines.push('- Status: ' + data.summary.status)
|
|
89
|
-
lines.push('- Checks: ' + data.summary.passed + '/' + data.summary.total)
|
|
90
|
-
lines.push('- Domain quality gates: ' + data.workflows.domainQualityGates)
|
|
91
|
-
lines.push('')
|
|
92
|
-
lines.push('## Checks')
|
|
93
|
-
lines.push('')
|
|
94
|
-
for (const item of data.checks) {
|
|
95
|
-
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
96
|
-
lines.push('- ' + marker + ' ' + item.id + ' ' + item.label + ': ' + item.evidence)
|
|
97
|
-
}
|
|
98
|
-
lines.push('')
|
|
99
|
-
lines.push('## Limits')
|
|
100
|
-
lines.push('')
|
|
101
|
-
for (const item of data.limits) lines.push('- ' + item)
|
|
102
|
-
return lines.join('\n') + '\n'
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
106
|
-
else console.log(renderMarkdown(report))
|
|
107
|
-
|
|
108
|
-
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 domain = read('references/domain-quality-gates.md')
|
|
30
|
+
const quality = read('references/quality-gates.md')
|
|
31
|
+
const review = read('references/review.md')
|
|
32
|
+
const architecture = read('references/architecture-health.md')
|
|
33
|
+
const skill = read('SKILL.md')
|
|
34
|
+
|
|
35
|
+
const domains = [
|
|
36
|
+
'Security/privacy',
|
|
37
|
+
'Performance/cost',
|
|
38
|
+
'Accessibility',
|
|
39
|
+
'Resilience/recovery',
|
|
40
|
+
'UI/browser',
|
|
41
|
+
'API/state',
|
|
42
|
+
'Data/migration',
|
|
43
|
+
'Model/tool routing',
|
|
44
|
+
'Release/operations',
|
|
45
|
+
]
|
|
46
|
+
const evidenceTerms = ['File inspection', 'Focused tests', 'API smokes', 'Browser smokes', 'Architecture/review scans']
|
|
47
|
+
const outputFields = ['Domain gates selected:', 'Why selected:', 'Evidence run:', 'Evidence status:', 'Unverified tools:', 'Residual risk:', 'Next action:']
|
|
48
|
+
const scaleTerms = ['Lite', 'Standard', 'Enterprise']
|
|
49
|
+
|
|
50
|
+
const checks = [
|
|
51
|
+
check('DQ01', 'domain quality gates reference exists', exists('references/domain-quality-gates.md'), 'references/domain-quality-gates.md'),
|
|
52
|
+
check('DQ02', 'SKILL routes domain quality gates', skill.includes('references/domain-quality-gates.md'), 'SKILL.md Reference Routing'),
|
|
53
|
+
check('DQ03', 'quality-gates routes to domain gates', quality.includes('references/domain-quality-gates.md') && quality.includes('## Domain Gates'), 'references/quality-gates.md'),
|
|
54
|
+
check('DQ04', 'review protocol routes to domain gates', review.includes('references/domain-quality-gates.md'), 'references/review.md'),
|
|
55
|
+
check('DQ05', 'all required domains are represented', domains.every((item) => domain.includes(item)), domains.join(', ')),
|
|
56
|
+
check('DQ06', 'scale adaptation is explicit', scaleTerms.every((item) => domain.includes(item)) && domain.includes('Lite work should not inherit every gate by default'), 'Lite, Standard, Enterprise'),
|
|
57
|
+
check('DQ07', 'evidence taxonomy routing is explicit', domain.includes('references/evidence-taxonomy.md') && domain.includes('result') && domain.includes('verified') && domain.includes('accepted'), 'evidence taxonomy labels'),
|
|
58
|
+
check('DQ08', 'tool execution is not faked', domain.includes('Do not claim scan, benchmark, browser, accessibility, security, or resilience results unless') && domain.includes('actually executed'), 'tool execution claim rule'),
|
|
59
|
+
check('DQ09', 'minimum evidence mapping covers major evidence modes', evidenceTerms.every((item) => domain.includes(item)), evidenceTerms.join(', ')),
|
|
60
|
+
check('DQ10', 'output format includes selected gates and residual risk', outputFields.every((item) => domain.includes(item)), outputFields.join(', ')),
|
|
61
|
+
check('DQ11', 'architecture health covers performance and resilience risk', architecture.includes('Performance And Resilience') && architecture.includes('migration') && architecture.includes('release'), 'references/architecture-health.md'),
|
|
62
|
+
check('DQ12', 'quality gates remain risk-based instead of mandatory for every task', domain.includes('Pick only the gates that match the changed behavior and project risk') && quality.includes('Do not force all gates onto Lite tasks'), 'risk-based gate language'),
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
const passed = checks.filter((item) => item.status === 'passed').length
|
|
66
|
+
const failed = checks.length - passed
|
|
67
|
+
const report = {
|
|
68
|
+
root,
|
|
69
|
+
generatedAt: new Date().toISOString(),
|
|
70
|
+
summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
|
|
71
|
+
workflows: { domainQualityGates: failed === 0 ? 'verified' : 'failed' },
|
|
72
|
+
limits: [
|
|
73
|
+
'Domain quality gate audit verifies reusable guidance and routing; it does not run project-specific security scans, benchmarks, accessibility tools, browser tests, or API smokes.',
|
|
74
|
+
'Projects must still execute the selected gates with their own commands, tools, owners, and evidence.',
|
|
75
|
+
],
|
|
76
|
+
checks,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function renderMarkdown(data) {
|
|
80
|
+
const lines = []
|
|
81
|
+
lines.push('# GSE Domain Quality Gate Audit')
|
|
82
|
+
lines.push('')
|
|
83
|
+
lines.push('Generated: ' + data.generatedAt)
|
|
84
|
+
lines.push('Root: ' + data.root)
|
|
85
|
+
lines.push('')
|
|
86
|
+
lines.push('## Summary')
|
|
87
|
+
lines.push('')
|
|
88
|
+
lines.push('- Status: ' + data.summary.status)
|
|
89
|
+
lines.push('- Checks: ' + data.summary.passed + '/' + data.summary.total)
|
|
90
|
+
lines.push('- Domain quality gates: ' + data.workflows.domainQualityGates)
|
|
91
|
+
lines.push('')
|
|
92
|
+
lines.push('## Checks')
|
|
93
|
+
lines.push('')
|
|
94
|
+
for (const item of data.checks) {
|
|
95
|
+
const marker = item.status === 'passed' ? '[x]' : '[ ]'
|
|
96
|
+
lines.push('- ' + marker + ' ' + item.id + ' ' + item.label + ': ' + item.evidence)
|
|
97
|
+
}
|
|
98
|
+
lines.push('')
|
|
99
|
+
lines.push('## Limits')
|
|
100
|
+
lines.push('')
|
|
101
|
+
for (const item of data.limits) lines.push('- ' + item)
|
|
102
|
+
return lines.join('\n') + '\n'
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
106
|
+
else console.log(renderMarkdown(report))
|
|
107
|
+
|
|
108
|
+
if (failed > 0) process.exit(1)
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import os from 'node:os'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
|
|
7
|
+
const args = process.argv.slice(2)
|
|
8
|
+
|
|
9
|
+
function readArg(name, fallback = null) {
|
|
10
|
+
const index = args.indexOf(name)
|
|
11
|
+
if (index === -1) return fallback
|
|
12
|
+
return args[index + 1] ?? fallback
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const root = path.resolve(readArg('--root', path.join(import.meta.dirname, '..')))
|
|
16
|
+
const targetArg = readArg('--target')
|
|
17
|
+
const jsonOnly = args.includes('--json')
|
|
18
|
+
|
|
19
|
+
export const evidenceLevels = [
|
|
20
|
+
'result',
|
|
21
|
+
'verified-unit',
|
|
22
|
+
'verified-component',
|
|
23
|
+
'verified-api',
|
|
24
|
+
'verified-browser',
|
|
25
|
+
'verified-ci',
|
|
26
|
+
'accepted-owner',
|
|
27
|
+
'accepted-release',
|
|
28
|
+
'external-required',
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
const levelRank = new Map([
|
|
32
|
+
['result', 0],
|
|
33
|
+
['verified-unit', 1],
|
|
34
|
+
['verified-component', 2],
|
|
35
|
+
['verified-api', 2],
|
|
36
|
+
['verified-browser', 3],
|
|
37
|
+
['verified-ci', 3],
|
|
38
|
+
['accepted-owner', 4],
|
|
39
|
+
['accepted-release', 4],
|
|
40
|
+
['external-required', 0],
|
|
41
|
+
])
|
|
42
|
+
|
|
43
|
+
function readText(filePath) {
|
|
44
|
+
return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, '') : ''
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readJsonl(filePath) {
|
|
48
|
+
if (!fs.existsSync(filePath)) return { exists: false, ok: false, records: [], error: 'missing' }
|
|
49
|
+
const lines = readText(filePath)
|
|
50
|
+
.split(/\r?\n/)
|
|
51
|
+
.map((line) => line.trim())
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
const records = []
|
|
54
|
+
for (const [index, line] of lines.entries()) {
|
|
55
|
+
try {
|
|
56
|
+
records.push(JSON.parse(line))
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return { exists: true, ok: false, records, error: `line ${index + 1}: ${error.message}` }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { exists: true, ok: true, records, error: '' }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function analyzeEvidenceLevels(records) {
|
|
65
|
+
const allowed = new Set(evidenceLevels)
|
|
66
|
+
const recordsWithLevel = records.filter((record) => typeof record.evidenceLevel === 'string' && record.evidenceLevel)
|
|
67
|
+
const missingLevel = records.filter((record) => !record.evidenceLevel).map((record) => record.summary || record.recordType || '(unknown)')
|
|
68
|
+
const invalidLevel = records
|
|
69
|
+
.filter((record) => record.evidenceLevel && !allowed.has(record.evidenceLevel))
|
|
70
|
+
.map((record) => ({ summary: record.summary || record.recordType || '(unknown)', evidenceLevel: record.evidenceLevel }))
|
|
71
|
+
const downgraded = records
|
|
72
|
+
.filter((record) => record.evidenceLevel && record.requiredEvidenceLevel && allowed.has(record.evidenceLevel) && allowed.has(record.requiredEvidenceLevel))
|
|
73
|
+
.filter((record) => (levelRank.get(record.evidenceLevel) ?? 0) < (levelRank.get(record.requiredEvidenceLevel) ?? 0))
|
|
74
|
+
.map((record) => ({
|
|
75
|
+
summary: record.summary || record.recordType || '(unknown)',
|
|
76
|
+
evidenceLevel: record.evidenceLevel,
|
|
77
|
+
requiredEvidenceLevel: record.requiredEvidenceLevel,
|
|
78
|
+
}))
|
|
79
|
+
return {
|
|
80
|
+
allowed: evidenceLevels,
|
|
81
|
+
records: records.length,
|
|
82
|
+
recordsWithLevel: recordsWithLevel.length,
|
|
83
|
+
missingLevel,
|
|
84
|
+
invalidLevel,
|
|
85
|
+
downgraded,
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function check(id, label, ok, evidence, risk = '') {
|
|
90
|
+
return { id, label, status: ok ? 'passed' : 'failed', evidence, risk }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function createFixture() {
|
|
94
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gse-evidence-levels-'))
|
|
95
|
+
fs.mkdirSync(path.join(dir, '.gse', 'evidence'), { recursive: true })
|
|
96
|
+
const records = [
|
|
97
|
+
{
|
|
98
|
+
date: '2026-07-08',
|
|
99
|
+
recordType: 'slice',
|
|
100
|
+
status: 'verified',
|
|
101
|
+
evidenceLevel: 'verified-component',
|
|
102
|
+
requiredEvidenceLevel: 'verified-browser',
|
|
103
|
+
summary: 'UI component proof is downgraded from required browser proof.',
|
|
104
|
+
evidenceFile: '.gse/evidence/2026-07-08.md',
|
|
105
|
+
commands: ['pnpm test component'],
|
|
106
|
+
nextAction: 'Run browser smoke before release.',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
date: '2026-07-08',
|
|
110
|
+
recordType: 'slice',
|
|
111
|
+
status: 'verified',
|
|
112
|
+
evidenceLevel: 'verified-browser',
|
|
113
|
+
requiredEvidenceLevel: 'verified-browser',
|
|
114
|
+
summary: 'Browser proof satisfies UI requirement.',
|
|
115
|
+
evidenceFile: '.gse/evidence/2026-07-08.md',
|
|
116
|
+
commands: ['pnpm smoke browser'],
|
|
117
|
+
nextAction: 'Close slice.',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
date: '2026-07-08',
|
|
121
|
+
recordType: 'release',
|
|
122
|
+
status: 'result',
|
|
123
|
+
evidenceLevel: 'external-required',
|
|
124
|
+
requiredEvidenceLevel: 'accepted-release',
|
|
125
|
+
summary: 'Release evidence still needs owner or external acceptance.',
|
|
126
|
+
evidenceFile: '.gse/evidence/2026-07-08.md',
|
|
127
|
+
commands: ['gse owner-actions'],
|
|
128
|
+
nextAction: 'Collect external gate.',
|
|
129
|
+
},
|
|
130
|
+
]
|
|
131
|
+
fs.writeFileSync(path.join(dir, '.gse', 'evidence', 'index.jsonl'), records.map((record) => JSON.stringify(record)).join('\n') + '\n', 'utf8')
|
|
132
|
+
fs.writeFileSync(path.join(dir, '.gse', 'evidence', '2026-07-08.md'), '# Evidence\n', 'utf8')
|
|
133
|
+
return dir
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function audit(target) {
|
|
137
|
+
const resolvedTarget = path.resolve(target)
|
|
138
|
+
const taxonomy = readText(path.join(root, 'references', 'evidence-taxonomy.md'))
|
|
139
|
+
const qualityGates = readText(path.join(root, 'references', 'quality-gates.md'))
|
|
140
|
+
const closeGate = readText(path.join(root, 'scripts', 'audit-close-gate.mjs'))
|
|
141
|
+
const continuePacket = readText(path.join(root, 'scripts', 'generate-continue-packet.mjs'))
|
|
142
|
+
const validationProfile = readText(path.join(root, 'scripts', 'run-validation-profile.mjs'))
|
|
143
|
+
const validator = readText(path.join(root, 'scripts', 'validate-gse.mjs'))
|
|
144
|
+
const evidenceIndex = readJsonl(path.join(resolvedTarget, '.gse', 'evidence', 'index.jsonl'))
|
|
145
|
+
const analysis = analyzeEvidenceLevels(evidenceIndex.records)
|
|
146
|
+
const fixtureRecords = [
|
|
147
|
+
{
|
|
148
|
+
status: 'verified',
|
|
149
|
+
evidenceLevel: 'verified-component',
|
|
150
|
+
requiredEvidenceLevel: 'verified-browser',
|
|
151
|
+
summary: 'fixture component downgrade',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
status: 'verified',
|
|
155
|
+
evidenceLevel: 'verified-browser',
|
|
156
|
+
requiredEvidenceLevel: 'verified-browser',
|
|
157
|
+
summary: 'fixture browser proof',
|
|
158
|
+
},
|
|
159
|
+
]
|
|
160
|
+
const fixtureAnalysis = analyzeEvidenceLevels(fixtureRecords)
|
|
161
|
+
|
|
162
|
+
const requiredTerms = [
|
|
163
|
+
'Evidence Level',
|
|
164
|
+
'verified-unit',
|
|
165
|
+
'verified-component',
|
|
166
|
+
'verified-api',
|
|
167
|
+
'verified-browser',
|
|
168
|
+
'verified-ci',
|
|
169
|
+
'accepted-owner',
|
|
170
|
+
'accepted-release',
|
|
171
|
+
'external-required',
|
|
172
|
+
'Evidence status answers whether the work is result, verified, or accepted.',
|
|
173
|
+
'Evidence level answers what kind of proof produced that status.',
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
const checks = [
|
|
177
|
+
check('EL01', 'taxonomy defines all evidence levels and separates status from level', requiredTerms.every((term) => taxonomy.includes(term)), 'references/evidence-taxonomy.md'),
|
|
178
|
+
check('EL02', 'quality gates require explicit evidence level for UI/browser/API/CI claims', qualityGates.includes('Evidence level uses `evidence-taxonomy.md`') && qualityGates.includes('verified-browser') && qualityGates.includes('verified-component'), 'references/quality-gates.md'),
|
|
179
|
+
check('EL03', 'continue packet exposes latest evidence level and downgrade summary', continuePacket.includes('analyzeEvidenceLevels') && continuePacket.includes('evidenceLevels') && continuePacket.includes('latestEvidenceLevel'), 'scripts/generate-continue-packet.mjs'),
|
|
180
|
+
check('EL04', 'close gate checks evidence level validity and downgrade warnings', closeGate.includes('analyzeEvidenceLevels') && closeGate.includes('CG09') && closeGate.includes('evidence level'), 'scripts/audit-close-gate.mjs'),
|
|
181
|
+
check('EL05', 'validation routes include evidence level audit', validationProfile.includes('audit-evidence-levels.mjs') && validator.includes('audit-evidence-levels.mjs'), 'validation profile and validate-gse'),
|
|
182
|
+
check('EL06', 'target evidence index parses', evidenceIndex.ok, evidenceIndex.ok ? `${evidenceIndex.records.length} record(s)` : evidenceIndex.error),
|
|
183
|
+
check('EL07', 'target evidence levels are valid when present', analysis.invalidLevel.length === 0, analysis.invalidLevel.length ? JSON.stringify(analysis.invalidLevel) : 'no invalid evidence levels'),
|
|
184
|
+
check('EL08', 'fixture detects downgraded UI/browser proof without failing parse', fixtureAnalysis.downgraded.length === 1 && fixtureAnalysis.invalidLevel.length === 0, `${fixtureAnalysis.downgraded.length} downgrade(s), ${fixtureAnalysis.invalidLevel.length} invalid level(s)`),
|
|
185
|
+
]
|
|
186
|
+
const passed = checks.filter((item) => item.status === 'passed').length
|
|
187
|
+
const failed = checks.length - passed
|
|
188
|
+
return {
|
|
189
|
+
target: resolvedTarget,
|
|
190
|
+
generatedAt: new Date().toISOString(),
|
|
191
|
+
summary: { status: failed === 0 ? 'passed' : 'failed', passed, failed, total: checks.length },
|
|
192
|
+
workflows: {
|
|
193
|
+
evidenceLevels: failed === 0 ? 'verified' : 'failed',
|
|
194
|
+
recordsWithLevel: analysis.recordsWithLevel,
|
|
195
|
+
missingLevel: analysis.missingLevel.length,
|
|
196
|
+
downgraded: analysis.downgraded.length,
|
|
197
|
+
},
|
|
198
|
+
evidenceLevels: analysis,
|
|
199
|
+
checks,
|
|
200
|
+
limits: [
|
|
201
|
+
'Evidence level is a proof-strength dimension; it does not replace result/verified/accepted status.',
|
|
202
|
+
'Missing evidenceLevel is tolerated for historical records but should be added to new records.',
|
|
203
|
+
'Downgraded evidence is surfaced as a warning path in continue/close gates; project policy decides whether it blocks close.',
|
|
204
|
+
],
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const isCli = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])
|
|
209
|
+
|
|
210
|
+
if (isCli) {
|
|
211
|
+
const target = targetArg || createFixture()
|
|
212
|
+
const report = audit(target)
|
|
213
|
+
|
|
214
|
+
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
215
|
+
else console.log(JSON.stringify(report, null, 2))
|
|
216
|
+
if (report.summary.status === 'failed') process.exit(1)
|
|
217
|
+
}
|