@t275005746/gse 0.1.1 → 0.2.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.
- package/.gse/releases/public-github-release-v0.1.2.md +49 -0
- package/.gse/releases/public-registry-publication-npm.md +49 -49
- package/.gse/state.json +148 -26
- package/CHANGELOG.md +52 -8
- package/README.md +13 -6
- package/README.zh-CN.md +13 -6
- package/SKILL.md +32 -12
- package/assets/templates/dispatch-packet.md +22 -14
- package/assets/templates/evidence.md +11 -5
- package/assets/templates/role-fallback-packet.md +49 -0
- package/package.json +18 -10
- package/references/agent-roles.md +41 -20
- package/references/commands.md +75 -45
- package/references/drift-audit.md +2 -1
- package/references/evidence-taxonomy.md +46 -9
- package/references/file-ownership.md +17 -13
- package/references/final-form-roadmap.md +203 -0
- package/references/final-readiness.md +3 -3
- package/references/host-adapters.md +38 -10
- package/references/learning-system.md +24 -8
- package/references/maintenance-cadence.md +51 -0
- package/references/project-guards.md +52 -0
- package/references/quality-gates.md +18 -11
- package/references/role-dispatch-fallback.md +54 -0
- package/references/tool-adapters.md +13 -3
- package/scripts/audit-close-gate-hardening.mjs +188 -0
- package/scripts/audit-close-gate.mjs +219 -33
- package/scripts/audit-command-execution.mjs +30 -17
- package/scripts/audit-commands.mjs +7 -5
- package/scripts/audit-completion-plan-drill.mjs +271 -0
- package/scripts/audit-completion-readiness.mjs +9 -6
- package/scripts/audit-continue-preflight.mjs +318 -0
- package/scripts/audit-evidence-levels.mjs +217 -0
- 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.mjs +3 -3
- package/scripts/audit-fresh-session-readiness.mjs +1 -1
- package/scripts/audit-host-capabilities.mjs +237 -0
- 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-npm-package-metadata.mjs +8 -2
- package/scripts/audit-npm-publish-dry-run.mjs +10 -4
- package/scripts/audit-npm-tarball-install.mjs +9 -3
- package/scripts/audit-owner-external-gate-kit.mjs +12 -11
- package/scripts/audit-project-guards.mjs +189 -0
- package/scripts/audit-project.mjs +14 -11
- package/scripts/audit-public-acceptance-handoff.mjs +10 -10
- package/scripts/audit-public-acceptance-readiness.mjs +6 -6
- package/scripts/audit-public-release-checklist.mjs +17 -15
- 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-status-manifest.mjs +4 -4
- package/scripts/audit-roadmap-consistency.mjs +11 -7
- package/scripts/audit-role-dispatch-fallback.mjs +212 -0
- package/scripts/audit-session-sync.mjs +127 -0
- package/scripts/audit-state-freshness.mjs +6 -5
- package/scripts/audit-state-repair.mjs +360 -0
- package/scripts/audit-target-hardening-drills.mjs +518 -0
- package/scripts/audit-tool-fallback-policy.mjs +180 -0
- package/scripts/audit-ui-browser-evidence-policy.mjs +191 -0
- package/scripts/audit-validation-profiles.mjs +6 -4
- package/scripts/backfill-evidence-levels.mjs +98 -0
- package/scripts/check-encoding.mjs +72 -0
- package/scripts/generate-continue-packet.mjs +1487 -0
- package/scripts/generate-final-acceptance-packet.mjs +23 -8
- package/scripts/generate-final-form-progress-report.mjs +25 -23
- package/scripts/generate-host-runtime-evidence-handoff.mjs +23 -16
- package/scripts/generate-maintenance-snapshot.mjs +216 -0
- package/scripts/generate-public-acceptance-handoff.mjs +26 -14
- package/scripts/generate-release-owner-action-plan.mjs +4 -3
- package/scripts/generate-release-status-manifest.mjs +4 -3
- package/scripts/init-project.mjs +144 -63
- package/scripts/record-learning.mjs +37 -8
- 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/validate-gse.mjs +262 -9
|
@@ -88,9 +88,10 @@ function actionFor(row, publicGate) {
|
|
|
88
88
|
|
|
89
89
|
function renderPacket(audit) {
|
|
90
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
|
|
91
|
+
const matrix = audit.matrix ?? []
|
|
92
|
+
const verified = matrix.filter((row) => row.status === 'verified')
|
|
93
|
+
const pending = matrix.filter((row) => row.status === 'owner-required' || row.status === 'external-required')
|
|
94
|
+
const notClaimed = matrix.filter((row) => row.status === 'not-claimed')
|
|
94
95
|
const lines = []
|
|
95
96
|
lines.push('# GSE Final Acceptance Packet')
|
|
96
97
|
lines.push('')
|
|
@@ -105,8 +106,9 @@ function renderPacket(audit) {
|
|
|
105
106
|
lines.push('')
|
|
106
107
|
lines.push('- Local readiness: ' + (audit.workflows?.finalReadinessMatrix ?? 'unknown'))
|
|
107
108
|
lines.push('- Public accepted: ' + (audit.workflows?.publicAccepted ?? 'unknown'))
|
|
108
|
-
lines.push('- Verified rows: ' + verified.length)
|
|
109
|
-
lines.push('- Pending owner/external rows: ' + pending.length)
|
|
109
|
+
lines.push('- Verified rows: ' + verified.length)
|
|
110
|
+
lines.push('- Pending owner/external rows: ' + pending.length)
|
|
111
|
+
lines.push('- Optional not-claimed rows: ' + notClaimed.length)
|
|
110
112
|
lines.push('')
|
|
111
113
|
lines.push('## Verified Local Capabilities')
|
|
112
114
|
lines.push('')
|
|
@@ -114,7 +116,7 @@ function renderPacket(audit) {
|
|
|
114
116
|
lines.push('')
|
|
115
117
|
lines.push('## Pending Acceptance Gates')
|
|
116
118
|
lines.push('')
|
|
117
|
-
for (const row of pending) {
|
|
119
|
+
for (const row of pending) {
|
|
118
120
|
lines.push('### ' + row.area)
|
|
119
121
|
lines.push('')
|
|
120
122
|
lines.push('- Status: ' + row.status)
|
|
@@ -122,7 +124,19 @@ function renderPacket(audit) {
|
|
|
122
124
|
lines.push('- Required action: ' + actionFor(row, publicDoctor.gates.get(row.area)))
|
|
123
125
|
lines.push('- Acceptance rule: do not mark accepted until the evidence is real, dated, and re-audited.')
|
|
124
126
|
lines.push('')
|
|
125
|
-
}
|
|
127
|
+
}
|
|
128
|
+
if (pending.length === 0) {
|
|
129
|
+
lines.push('- No owner/external acceptance gates are pending.')
|
|
130
|
+
lines.push('')
|
|
131
|
+
}
|
|
132
|
+
if (notClaimed.length > 0) {
|
|
133
|
+
lines.push('## Optional Not-Claimed Rows')
|
|
134
|
+
lines.push('')
|
|
135
|
+
for (const row of notClaimed) {
|
|
136
|
+
lines.push('- ' + row.area + ': not claimed; evidence boundary: ' + row.evidence)
|
|
137
|
+
}
|
|
138
|
+
lines.push('')
|
|
139
|
+
}
|
|
126
140
|
lines.push('## Re-Verification Commands')
|
|
127
141
|
lines.push('')
|
|
128
142
|
lines.push('```bash')
|
|
@@ -172,7 +186,8 @@ const report = {
|
|
|
172
186
|
written: dryRun ? 0 : 1,
|
|
173
187
|
summary: {
|
|
174
188
|
verifiedRows: audit.data.matrix.filter((row) => row.status === 'verified').length,
|
|
175
|
-
pendingRows: audit.data.matrix.filter((row) => row.status
|
|
189
|
+
pendingRows: audit.data.matrix.filter((row) => row.status === 'owner-required' || row.status === 'external-required').length,
|
|
190
|
+
notClaimedRows: audit.data.matrix.filter((row) => row.status === 'not-claimed').length,
|
|
176
191
|
publicAccepted: audit.data.workflows?.publicAccepted ?? 'unknown',
|
|
177
192
|
},
|
|
178
193
|
}
|
|
@@ -60,12 +60,13 @@ const publicAcceptanceData = parseJson(publicAcceptance.stdout)
|
|
|
60
60
|
const hostRuntimeData = parseJson(hostRuntime.stdout)
|
|
61
61
|
|
|
62
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
|
|
67
|
-
const
|
|
68
|
-
const
|
|
63
|
+
const verifiedRows = countBy(matrix, 'verified')
|
|
64
|
+
const ownerRequiredRows = countBy(matrix, 'owner-required')
|
|
65
|
+
const externalRequiredRows = countBy(matrix, 'external-required')
|
|
66
|
+
const notClaimedRows = countBy(matrix, 'not-claimed')
|
|
67
|
+
const acceptedRows = countBy(matrix, 'accepted')
|
|
68
|
+
const totalRows = matrix.length
|
|
69
|
+
const localReadyRows = verifiedRows + acceptedRows
|
|
69
70
|
const publicAccepted = finalReadinessData?.workflows?.publicAccepted ?? 'unknown'
|
|
70
71
|
const pendingGates = publicAcceptanceData?.pendingGates ?? matrix.filter((row) => row.status !== 'verified')
|
|
71
72
|
const licenseDecisionVerified = matrix.some((row) => row.area === 'License decision' && (row.status === 'verified' || row.status === 'accepted'))
|
|
@@ -78,10 +79,10 @@ const cannotClaim = [
|
|
|
78
79
|
'native slash-command support unless real host runtime evidence exists',
|
|
79
80
|
]
|
|
80
81
|
|
|
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' : '
|
|
82
|
+
const localRows = totalRows - ownerRequiredRows - externalRequiredRows - notClaimedRows
|
|
83
|
+
const localEngineeringScore = percent(localReadyRows, localRows)
|
|
84
|
+
const finalFormScore = publicAccepted === 'verified' ? 100 : percent(localReadyRows, totalRows)
|
|
85
|
+
const status = publicAccepted === 'verified' ? 'accepted' : 'release-evidence-pending'
|
|
85
86
|
|
|
86
87
|
const report = {
|
|
87
88
|
schemaVersion: 1,
|
|
@@ -96,14 +97,15 @@ const report = {
|
|
|
96
97
|
readiness: {
|
|
97
98
|
totalRows,
|
|
98
99
|
localRows,
|
|
99
|
-
verifiedRows,
|
|
100
|
-
acceptedRows,
|
|
101
|
-
ownerRequiredRows,
|
|
102
|
-
externalRequiredRows,
|
|
103
|
-
|
|
100
|
+
verifiedRows,
|
|
101
|
+
acceptedRows,
|
|
102
|
+
ownerRequiredRows,
|
|
103
|
+
externalRequiredRows,
|
|
104
|
+
notClaimedRows,
|
|
105
|
+
publicAccepted,
|
|
104
106
|
pendingGateCount: pendingGates.length,
|
|
105
107
|
},
|
|
106
|
-
|
|
108
|
+
pendingReleaseEvidence: pendingGates.map((gate) => ({
|
|
107
109
|
area: gate.area,
|
|
108
110
|
status: gate.status,
|
|
109
111
|
owner: gate.owner ?? (gate.status === 'owner-required' ? 'project owner' : 'external system or host'),
|
|
@@ -149,15 +151,15 @@ function renderMarkdown(data) {
|
|
|
149
151
|
lines.push('- Full final-form readiness: ' + data.scores.fullFinalFormReadiness + '%')
|
|
150
152
|
lines.push('- Scoring basis: ' + data.scores.scoringBasis)
|
|
151
153
|
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')
|
|
154
|
+
lines.push('- Matrix rows: ' + data.readiness.verifiedRows + ' verified, ' + data.readiness.ownerRequiredRows + ' owner-required, ' + data.readiness.externalRequiredRows + ' external-required, ' + data.readiness.notClaimedRows + ' not-claimed, ' + data.readiness.totalRows + ' total')
|
|
153
155
|
lines.push('- Local rows: ' + data.readiness.localRows)
|
|
154
156
|
lines.push('')
|
|
155
|
-
lines.push('##
|
|
156
|
-
lines.push('')
|
|
157
|
-
if (data.
|
|
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.
|
|
157
|
+
lines.push('## Pending Release Evidence')
|
|
158
|
+
lines.push('')
|
|
159
|
+
if (data.pendingReleaseEvidence.length === 0) {
|
|
160
|
+
lines.push('- None reported by final readiness. Re-run close gate and release audits before claiming completion.')
|
|
161
|
+
} else {
|
|
162
|
+
for (const blocker of data.pendingReleaseEvidence) {
|
|
161
163
|
lines.push('- ' + blocker.area + ': ' + blocker.status)
|
|
162
164
|
lines.push(' - Owner: ' + blocker.owner)
|
|
163
165
|
lines.push(' - Evidence now: ' + blocker.evidence)
|
|
@@ -108,21 +108,28 @@ function commandFor(hostFamily) {
|
|
|
108
108
|
].join(' ')
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
function renderHandoff(audit, hostRows) {
|
|
112
|
-
const inventory = audit.inventory ?? {}
|
|
113
|
-
const lines = []
|
|
114
|
-
lines.push('# GSE Host Runtime Evidence Handoff')
|
|
111
|
+
function renderHandoff(audit, hostRows) {
|
|
112
|
+
const inventory = audit.inventory ?? {}
|
|
113
|
+
const lines = []
|
|
114
|
+
lines.push('# GSE Host Runtime Evidence Handoff')
|
|
115
115
|
lines.push('')
|
|
116
116
|
lines.push('Generated: ' + new Date().toISOString())
|
|
117
117
|
lines.push('Root: ' + displayRoot)
|
|
118
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('##
|
|
124
|
-
lines.push('')
|
|
125
|
-
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('## Fast Path')
|
|
124
|
+
lines.push('')
|
|
125
|
+
lines.push('- Native slash-command evidence is the final external gate.')
|
|
126
|
+
lines.push('- If a host can invoke `/gse continue` natively, record that first.')
|
|
127
|
+
lines.push('- Use portable text-command records only when native slash-command proof is unavailable.')
|
|
128
|
+
lines.push('- Keep host capability status separate from portable `.gse/` workflow status.')
|
|
129
|
+
lines.push('')
|
|
130
|
+
lines.push('## Current Runtime Evidence')
|
|
131
|
+
lines.push('')
|
|
132
|
+
lines.push('- Host runtime invocation records: ' + (inventory.records ?? 0))
|
|
126
133
|
lines.push('- Verified or accepted records: ' + (inventory.closeableRecords ?? 0))
|
|
127
134
|
lines.push('- Hosts with records: ' + (inventory.hosts?.length ? inventory.hosts.join(', ') : 'none'))
|
|
128
135
|
lines.push('- Native slash-command records: ' + (inventory.nativeSlashCommandRecords ?? 0))
|
|
@@ -164,11 +171,11 @@ function renderHandoff(audit, hostRows) {
|
|
|
164
171
|
lines.push('- Keep host capability status separate from portable `.gse/` workflow status.')
|
|
165
172
|
lines.push('- Treat subagents, MCP, LSP, browser tools, hooks, and plugins as host/session-specific until current evidence proves them.')
|
|
166
173
|
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
|
-
}
|
|
174
|
+
lines.push('## Next Action')
|
|
175
|
+
lines.push('')
|
|
176
|
+
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. Start with native slash-command proof when the host supports it.')
|
|
177
|
+
return lines.join('\n') + '\n'
|
|
178
|
+
}
|
|
172
179
|
|
|
173
180
|
const audit = runHostAudit()
|
|
174
181
|
if (!audit.ok) {
|
|
@@ -0,0 +1,216 @@
|
|
|
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 target = path.resolve(readArg('--target', root))
|
|
16
|
+
const installedRoot = readArg('--installed-root', null)
|
|
17
|
+
const execute = args.includes('--execute')
|
|
18
|
+
const jsonOnly = args.includes('--json')
|
|
19
|
+
const skipReleaseBundle = args.includes('--skip-release-bundle')
|
|
20
|
+
const packageSmoke = args.includes('--package-smoke')
|
|
21
|
+
const canonicalOut = path.join(root, '.gse', 'maintenance', 'latest-maintenance-snapshot.json')
|
|
22
|
+
const out = path.resolve(readArg('--out', canonicalOut))
|
|
23
|
+
const isCanonicalOut = out === path.resolve(canonicalOut)
|
|
24
|
+
|
|
25
|
+
function exists(relativePath) {
|
|
26
|
+
return fs.existsSync(path.join(root, relativePath))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function runNode(script, commandArgs, options = {}) {
|
|
30
|
+
const command = [process.execPath, path.join(root, 'scripts', script), ...commandArgs]
|
|
31
|
+
const result = spawnSync(command[0], command.slice(1), {
|
|
32
|
+
cwd: root,
|
|
33
|
+
encoding: 'utf8',
|
|
34
|
+
windowsHide: true,
|
|
35
|
+
...options,
|
|
36
|
+
})
|
|
37
|
+
const stdout = (result.stdout ?? '').trim()
|
|
38
|
+
let parsed = null
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(stdout)
|
|
41
|
+
} catch {
|
|
42
|
+
parsed = null
|
|
43
|
+
}
|
|
44
|
+
const failed = parsed?.summary?.failed
|
|
45
|
+
const ok = (result.status ?? 1) === 0 || failed === 0
|
|
46
|
+
return {
|
|
47
|
+
command: command.join(' '),
|
|
48
|
+
status: result.status ?? 1,
|
|
49
|
+
ok,
|
|
50
|
+
summary: parsed?.summary ?? null,
|
|
51
|
+
workflows: parsed?.workflows ?? null,
|
|
52
|
+
stdout,
|
|
53
|
+
stderr: (result.stderr ?? '').trim(),
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function maintenanceChecks() {
|
|
58
|
+
const checks = [
|
|
59
|
+
{
|
|
60
|
+
id: 'MS01',
|
|
61
|
+
area: 'maintenance cadence',
|
|
62
|
+
script: 'audit-maintenance-cadence.mjs',
|
|
63
|
+
args: ['--root', root, '--json'],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'MS02',
|
|
67
|
+
area: 'final-form roadmap',
|
|
68
|
+
script: 'audit-final-form-roadmap.mjs',
|
|
69
|
+
args: ['--root', root, '--json'],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'MS03',
|
|
73
|
+
area: 'state freshness',
|
|
74
|
+
script: 'audit-state-freshness.mjs',
|
|
75
|
+
args: ['--root', root, '--json'],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: 'MS04',
|
|
79
|
+
area: 'continue preflight',
|
|
80
|
+
script: 'run-gse-command.mjs',
|
|
81
|
+
args: ['--root', root, '--target', target, '--command', '/gse continue', '--json', '--compact'],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: 'MS05',
|
|
85
|
+
area: 'evidence levels',
|
|
86
|
+
script: 'audit-evidence-levels.mjs',
|
|
87
|
+
args: ['--root', root, '--target', target, '--json'],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'MS06',
|
|
91
|
+
area: 'learning drift',
|
|
92
|
+
script: 'audit-learning-drift.mjs',
|
|
93
|
+
args: ['--root', root, '--target', target, '--json'],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: 'MS07',
|
|
97
|
+
area: 'public acceptance',
|
|
98
|
+
script: 'audit-public-acceptance-readiness.mjs',
|
|
99
|
+
args: ['--root', root, '--json'],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'MS08',
|
|
103
|
+
area: 'installed sync',
|
|
104
|
+
script: 'audit-installed-sync.mjs',
|
|
105
|
+
args: installedRoot
|
|
106
|
+
? ['--root', root, '--installed-root', path.resolve(installedRoot), '--json']
|
|
107
|
+
: ['--root', root, '--json'],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'MS09',
|
|
111
|
+
area: 'session sync',
|
|
112
|
+
script: 'audit-session-sync.mjs',
|
|
113
|
+
args: ['--root', root, '--json'],
|
|
114
|
+
},
|
|
115
|
+
]
|
|
116
|
+
if (!skipReleaseBundle) {
|
|
117
|
+
checks.push({
|
|
118
|
+
id: 'MS10',
|
|
119
|
+
area: 'release bundle freshness',
|
|
120
|
+
script: 'audit-release-bundle.mjs',
|
|
121
|
+
args: ['--root', root, '--json'],
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
return checks.filter((item) => exists(path.join('scripts', item.script)))
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const checks = packageSmoke
|
|
128
|
+
? maintenanceChecks().filter((item) => item.id !== 'MS02')
|
|
129
|
+
: maintenanceChecks()
|
|
130
|
+
const results = checks.map((item) => {
|
|
131
|
+
const run = runNode(item.script, item.args)
|
|
132
|
+
return {
|
|
133
|
+
id: item.id,
|
|
134
|
+
area: item.area,
|
|
135
|
+
status: run.ok ? 'passed' : 'failed',
|
|
136
|
+
command: run.command,
|
|
137
|
+
summary: run.summary,
|
|
138
|
+
workflows: run.workflows,
|
|
139
|
+
stderr: run.stderr,
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const passed = results.filter((item) => item.status === 'passed').length
|
|
144
|
+
const failed = results.length - passed
|
|
145
|
+
const installedSync = results.find((item) => item.id === 'MS08')
|
|
146
|
+
const releaseBundle = results.find((item) => item.id === 'MS10')
|
|
147
|
+
const report = {
|
|
148
|
+
schemaVersion: 1,
|
|
149
|
+
root,
|
|
150
|
+
target,
|
|
151
|
+
installedRoot: installedRoot ? path.resolve(installedRoot) : null,
|
|
152
|
+
generatedAt: new Date().toISOString(),
|
|
153
|
+
execute,
|
|
154
|
+
out,
|
|
155
|
+
summary: {
|
|
156
|
+
status: failed === 0 ? 'passed' : 'failed',
|
|
157
|
+
passed,
|
|
158
|
+
failed,
|
|
159
|
+
total: results.length,
|
|
160
|
+
installedSyncMode: installedRoot ? 'installed-root' : 'package-only',
|
|
161
|
+
releaseBundleChecked: Boolean(releaseBundle),
|
|
162
|
+
packageSmoke,
|
|
163
|
+
},
|
|
164
|
+
workflows: {
|
|
165
|
+
maintenanceSnapshot: failed === 0 ? 'verified' : 'failed',
|
|
166
|
+
installedSync: installedSync?.workflows?.installedSync ?? (installedRoot ? 'unknown' : 'package-only'),
|
|
167
|
+
releaseBundleFreshness: releaseBundle?.workflows?.releaseBundle ?? (skipReleaseBundle ? 'skipped' : 'unknown'),
|
|
168
|
+
},
|
|
169
|
+
results,
|
|
170
|
+
limits: [
|
|
171
|
+
'This snapshot proves recurring maintenance checks ran at a point in time.',
|
|
172
|
+
'When writing the canonical latest-maintenance-snapshot.json, failed checks are written to latest-maintenance-snapshot.failed.json and do not overwrite the last passing snapshot.',
|
|
173
|
+
packageSmoke ? 'Package smoke mode skips source-worktree final-form roadmap freshness because package installs intentionally omit full local evidence history.' : '',
|
|
174
|
+
'It does not prove native host slash-command support.',
|
|
175
|
+
'Without --installed-root, installed sync is package-only and does not prove an installed copy is fresh.',
|
|
176
|
+
].filter(Boolean),
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function writeSnapshotFiles(targetPath, snapshot) {
|
|
180
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true })
|
|
181
|
+
fs.writeFileSync(targetPath, JSON.stringify(snapshot, null, 2) + '\n', 'utf8')
|
|
182
|
+
const mdPath = targetPath.replace(/\.json$/i, '.md')
|
|
183
|
+
fs.writeFileSync(mdPath, [
|
|
184
|
+
'# GSE Maintenance Snapshot',
|
|
185
|
+
'',
|
|
186
|
+
'Generated: ' + snapshot.generatedAt,
|
|
187
|
+
'Root: ' + snapshot.root,
|
|
188
|
+
'Target: ' + snapshot.target,
|
|
189
|
+
'Status: ' + snapshot.summary.status,
|
|
190
|
+
'',
|
|
191
|
+
'## Checks',
|
|
192
|
+
'',
|
|
193
|
+
...snapshot.results.map((item) => `- ${item.status === 'passed' ? '[x]' : '[ ]'} ${item.id} ${item.area}: ${item.summary?.status ?? item.status}`),
|
|
194
|
+
'',
|
|
195
|
+
'## Limits',
|
|
196
|
+
'',
|
|
197
|
+
...snapshot.limits.map((item) => '- ' + item),
|
|
198
|
+
'',
|
|
199
|
+
].join('\n'), 'utf8')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (execute) {
|
|
203
|
+
const targetOut = failed > 0 && isCanonicalOut
|
|
204
|
+
? out.replace(/\.json$/i, '.failed.json')
|
|
205
|
+
: out
|
|
206
|
+
report.writtenTo = targetOut
|
|
207
|
+
report.canonicalWritePolicy = failed > 0 && isCanonicalOut
|
|
208
|
+
? 'failed-canonical-write-isolated'
|
|
209
|
+
: 'written'
|
|
210
|
+
writeSnapshotFiles(targetOut, report)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
214
|
+
else console.log(JSON.stringify(report, null, 2))
|
|
215
|
+
|
|
216
|
+
if (failed > 0) process.exit(1)
|
|
@@ -71,19 +71,29 @@ function renderHandoff(doctor) {
|
|
|
71
71
|
lines.push('Root: ' + displayRoot)
|
|
72
72
|
lines.push('Release label: ' + releaseLabel)
|
|
73
73
|
lines.push('')
|
|
74
|
-
lines.push('## Purpose')
|
|
75
|
-
lines.push('')
|
|
76
|
-
lines.push('Give the owner and future agents one executable checklist for public acceptance. This handoff does not choose a license, publish a package, configure a repository, approve a marketplace listing, or prove host-native slash-command support.')
|
|
77
|
-
lines.push('')
|
|
78
|
-
lines.push('##
|
|
79
|
-
lines.push('')
|
|
74
|
+
lines.push('## Purpose')
|
|
75
|
+
lines.push('')
|
|
76
|
+
lines.push('Give the owner and future agents one executable checklist for public acceptance. This handoff does not choose a license, publish a package, configure a repository, approve a marketplace listing, or prove optional host-native slash-command support.')
|
|
77
|
+
lines.push('')
|
|
78
|
+
lines.push('## Fast Path')
|
|
79
|
+
lines.push('')
|
|
80
|
+
lines.push('- Portable `/gse` command execution is the core command path.')
|
|
81
|
+
lines.push('- Native slash-command evidence is optional per host adapter, not a GSE core completion gate.')
|
|
82
|
+
lines.push('- Do not treat portable text-command records or generated pointers as native proof for a host adapter.')
|
|
83
|
+
lines.push('')
|
|
84
|
+
lines.push('## Current Boundary')
|
|
85
|
+
lines.push('')
|
|
80
86
|
lines.push('- Public accepted: ' + (doctor.summary?.publicAccepted ?? doctor.workflows?.publicAccepted ?? 'unknown'))
|
|
81
87
|
lines.push('- Pending owner/external gates: ' + gates.length)
|
|
82
88
|
lines.push('- Source of truth: `scripts/audit-public-acceptance-readiness.mjs` and `references/final-readiness.md`')
|
|
83
89
|
lines.push('')
|
|
84
90
|
lines.push('## Execution Order')
|
|
85
91
|
lines.push('')
|
|
86
|
-
|
|
92
|
+
if (gates.length === 0) {
|
|
93
|
+
lines.push('- No owner/external gates are pending. Re-run final readiness and close gate before publishing a final claim.')
|
|
94
|
+
lines.push('')
|
|
95
|
+
}
|
|
96
|
+
for (const gate of gates) {
|
|
87
97
|
lines.push('### ' + stageFor(gate) + ' - ' + gate.area)
|
|
88
98
|
lines.push('')
|
|
89
99
|
lines.push('- Current status: ' + gate.status)
|
|
@@ -127,13 +137,15 @@ function renderHandoff(doctor) {
|
|
|
127
137
|
lines.push('')
|
|
128
138
|
lines.push('## Next Action')
|
|
129
139
|
lines.push('')
|
|
130
|
-
if (
|
|
131
|
-
lines.push('
|
|
132
|
-
} else {
|
|
133
|
-
lines.push('Start with the public security contact, then attach public repository, CI, publication, and host runtime evidence as those systems become available.')
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
}
|
|
140
|
+
if (gates.length === 0) {
|
|
141
|
+
lines.push('No owner/external acceptance gate is pending. Optional host-native slash-command support can be recorded later per host adapter if a host exposes it.')
|
|
142
|
+
} else if (gateNames.has('License decision')) {
|
|
143
|
+
lines.push('Start with the owner-required license decision and public security contact, then attach public repository, CI, publication, and host runtime evidence as those systems become available. Record native slash-command evidence first when the host supports it.')
|
|
144
|
+
} else {
|
|
145
|
+
lines.push('Start with the public security contact, then attach public repository, CI, publication, and host runtime evidence as those systems become available. Record native slash-command evidence first when the host supports it.')
|
|
146
|
+
}
|
|
147
|
+
return lines.join('\n') + '\n'
|
|
148
|
+
}
|
|
137
149
|
|
|
138
150
|
const doctor = runDoctor()
|
|
139
151
|
if (!doctor.ok) {
|
|
@@ -88,8 +88,9 @@ function render(manifest) {
|
|
|
88
88
|
lines.push('## Claim Boundary')
|
|
89
89
|
lines.push('')
|
|
90
90
|
lines.push('- Local validation does not mean public acceptance.')
|
|
91
|
-
lines.push('-
|
|
92
|
-
lines.push('-
|
|
91
|
+
lines.push('- Portable command execution is the GSE core command path.')
|
|
92
|
+
lines.push('- Native slash-command support requires a real host invocation record only when a host adapter claims it.')
|
|
93
|
+
lines.push('- Owner and external gates must be recorded with accepted evidence before GSE can claim accepted public release readiness.')
|
|
93
94
|
lines.push('')
|
|
94
95
|
lines.push('## Action Groups')
|
|
95
96
|
lines.push('')
|
|
@@ -132,7 +133,7 @@ function render(manifest) {
|
|
|
132
133
|
lines.push('## Limits')
|
|
133
134
|
lines.push('')
|
|
134
135
|
lines.push('- This plan is generated from the current release status manifest.')
|
|
135
|
-
lines.push('- It does not select a license, publish a package, configure a repository, run public CI, approve a marketplace listing, or prove host-native slash-command support.')
|
|
136
|
+
lines.push('- It does not select a license, publish a package, configure a repository, run public CI, approve a marketplace listing, or prove optional host-native slash-command support.')
|
|
136
137
|
return lines.join('\n') + '\n'
|
|
137
138
|
}
|
|
138
139
|
|
|
@@ -81,7 +81,8 @@ try {
|
|
|
81
81
|
publicAccepted: workflowStatus(finalReadiness.data, 'publicAccepted'),
|
|
82
82
|
finalReadinessMatrix: workflowStatus(finalReadiness.data, 'finalReadinessMatrix'),
|
|
83
83
|
localValidationDoesNotMeanPublicAcceptance: true,
|
|
84
|
-
nativeSlashCommandRequiresHostRecord: true,
|
|
84
|
+
nativeSlashCommandRequiresHostRecord: true,
|
|
85
|
+
nativeSlashCommandIsOptionalAdapterClaim: true,
|
|
85
86
|
},
|
|
86
87
|
readiness: {
|
|
87
88
|
verified: compactRows(matrix, 'verified'),
|
|
@@ -160,8 +161,8 @@ try {
|
|
|
160
161
|
},
|
|
161
162
|
limits: [
|
|
162
163
|
'This manifest is generated from local audits and evidence records.',
|
|
163
|
-
'It does not
|
|
164
|
-
'Owner-required and external-required gates remain incomplete until accepted evidence records promote them.',
|
|
164
|
+
'It does not prove optional native slash-command support for any host adapter.',
|
|
165
|
+
'Owner-required and external-required gates remain incomplete until accepted evidence records promote them.',
|
|
165
166
|
],
|
|
166
167
|
}
|
|
167
168
|
} catch (error) {
|