@t275005746/gse 0.1.2 → 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.
@@ -0,0 +1,49 @@
1
+ # Public Channel Publication Record
2
+
3
+ Publication status: accepted
4
+
5
+ Channel type: github-release
6
+
7
+ Channel name: GitHub Release
8
+
9
+ Channel URL: https://github.com/275005746/gse/releases/tag/v0.1.2
10
+
11
+ Package or listing version: v0.1.2
12
+
13
+ Artifact digest: not-applicable
14
+
15
+ Review or approval status: published
16
+
17
+ Evidence owner: 275005746
18
+
19
+ Evidence date: 2026-07-10
20
+
21
+ Evidence URL or run id: https://github.com/275005746/gse/releases/tag/v0.1.2
22
+
23
+ ## Verification
24
+
25
+ Verification command: gh release view v0.1.2 --repo 275005746/gse --json tagName,url,isDraft,isPrerelease
26
+
27
+ Verification result: passed
28
+
29
+ ## Acceptance
30
+
31
+ Evidence status: accepted
32
+
33
+ Accepted by: 275005746
34
+
35
+ Accepted at: 2026-07-10
36
+
37
+ ## Boundaries
38
+
39
+ - Does this prove public registry publication? false
40
+ - Does this prove marketplace approval? unknown
41
+ - Does this prove installability from the channel? true
42
+
43
+ ## Residual Risk
44
+
45
+ - GitHub Release proves source release visibility; npm remains the package registry install channel.
46
+
47
+ ## Next Action
48
+
49
+ - Keep GitHub Release v0.1.2 aligned with npm @t275005746/gse@0.1.2.
@@ -1,49 +1,49 @@
1
- # Public Channel Publication Record
2
-
3
- Publication status: accepted
4
-
5
- Channel type: package-registry
6
-
7
- Channel name: npm
8
-
9
- Channel URL: https://www.npmjs.com/package/@t275005746/gse
10
-
11
- Package or listing version: 0.1.0
12
-
13
- Artifact digest: sha512-DcnRp6yZv/LjON/uowlze5yuV2JIAWfOD9GGQhVpIGX5IgmA7r9j2FkIDFT3n4abSZ5q/3SH7rh56gICFrml3Q==
14
-
15
- Review or approval status: published
16
-
17
- Evidence owner: t275005746
18
-
19
- Evidence date: 2026-07-08
20
-
21
- Evidence URL or run id: https://www.npmjs.com/package/@t275005746/gse
22
-
23
- ## Verification
24
-
25
- Verification command: node scripts/validate-gse.mjs --root . --json
26
-
27
- Verification result: passed
28
-
29
- ## Acceptance
30
-
31
- Evidence status: accepted
32
-
33
- Accepted by: 275005746
34
-
35
- Accepted at: 2026-07-08
36
-
37
- ## Boundaries
38
-
39
- - Does this prove public registry publication? true
40
- - Does this prove marketplace approval? unknown
41
- - Does this prove installability from the channel? true
42
-
43
- ## Residual Risk
44
-
45
- - Public channel publication is not accepted until real external evidence is attached.
46
-
47
- ## Next Action
48
-
49
- - Attach public channel publication evidence and re-run final readiness.
1
+ # Public Channel Publication Record
2
+
3
+ Publication status: accepted
4
+
5
+ Channel type: package-registry
6
+
7
+ Channel name: npm
8
+
9
+ Channel URL: https://www.npmjs.com/package/@t275005746/gse
10
+
11
+ Package or listing version: 0.1.2
12
+
13
+ Artifact digest: sha512-QiMQGnpM515sR4/dEz4q8+Lau0m026Pxo83lBshH2aVoWw+ooR8W8Vz2nM4bSWqEC1rbkP95WAYS9GA5g4yYUA==
14
+
15
+ Review or approval status: published
16
+
17
+ Evidence owner: 275005746
18
+
19
+ Evidence date: 2026-07-10
20
+
21
+ Evidence URL or run id: https://www.npmjs.com/package/@t275005746/gse/v/0.1.2
22
+
23
+ ## Verification
24
+
25
+ Verification command: cmd /c npm view @t275005746/gse@0.1.2 name version dist.integrity dist-tags --json
26
+
27
+ Verification result: passed
28
+
29
+ ## Acceptance
30
+
31
+ Evidence status: accepted
32
+
33
+ Accepted by: 275005746
34
+
35
+ Accepted at: 2026-07-10
36
+
37
+ ## Boundaries
38
+
39
+ - Does this prove public registry publication? true
40
+ - Does this prove marketplace approval? unknown
41
+ - Does this prove installability from the channel? true
42
+
43
+ ## Residual Risk
44
+
45
+ - Native host slash-command support remains a separate host invocation claim.
46
+
47
+ ## Next Action
48
+
49
+ - Use npm @t275005746/gse@0.1.2 as the public install baseline for post-release sanity and downstream project adoption.
package/.gse/state.json CHANGED
@@ -5,18 +5,18 @@
5
5
  "canonicalPlan": ".gse/gse-design-master-plan.md",
6
6
  "phase": "final-form",
7
7
  "currentSummary": {
8
- "status": "release-metadata-0.1.2-verified",
8
+ "status": "support-slice-boundary-verified",
9
9
  "localEngineeringReadiness": 100,
10
10
  "fullFinalFormReadiness": 100,
11
11
  "publicAccepted": "verified",
12
12
  "pendingExternalGate": null,
13
- "currentPlan": "Commit and publish GSE 0.1.2 from verified release metadata."
13
+ "currentPlan": "GSE-155 is verified in source: /gse continue now surfaces currentSlice.supportSliceBoundary for deliberate product maintenance and suppresses only soft CP23 when its narrow boundary is declared. Keep /gse doctor and audit-public-acceptance-readiness.mjs as final-form source of truth."
14
14
  },
15
15
  "currentSlice": {
16
- "id": "GSE-147-release-metadata-0.1.2",
17
- "outcome": "Publish GSE 0.1.2 with npm install guidance and public GitHub repository metadata aligned.",
16
+ "id": "GSE-155-support-slice-boundary",
17
+ "outcome": "GSE /gse continue now lets product projects explicitly bound a deliberate support slice so CP23 distinguishes bounded maintenance from unbounded repeated support work.",
18
18
  "status": "verified",
19
- "nextAction": "Commit the verified `0.1.2` release metadata slice, then run `npm publish`, create `v0.1.2`, and push the branch/tag from that committed state."
19
+ "nextAction": "Use supportSliceBoundary only for deliberate bounded product maintenance; otherwise select a user-visible product delta and preserve native slash-command evidence as a host-specific external gate."
20
20
  },
21
21
  "toolStatuses": {
22
22
  "browser": "unknown",
@@ -25,22 +25,23 @@
25
25
  "subagents": "unknown",
26
26
  "ci": "documented"
27
27
  },
28
- "lastEvidence": ".gse/evidence/2026-07-10.md",
28
+ "lastEvidence": ".gse/evidence/2026-07-11.md",
29
29
  "blockedGates": [],
30
30
  "nextChecks": [
31
31
  "node scripts/run-gse-command.mjs --root . --target . --command \"/gse doctor\" --json",
32
32
  "node scripts/audit-public-acceptance-readiness.mjs --root . --json",
33
- "cmd /c npm view @t275005746/gse version --json",
34
- "cmd /c npm publish --access public",
35
- "cmd /c npm view @t275005746/gse version dist-tags --json",
36
- "git tag v0.1.2",
37
- "git push origin codex/gse-final-form-roadmap",
38
- "git push origin v0.1.2"
33
+ "node scripts/audit-continue-preflight.mjs --root . --json",
34
+ "node scripts/run-validation-profile.mjs --target . --profile lite --json",
35
+ "cmd /c npm run check:encoding",
36
+ "node scripts/audit-installed-sync.mjs --root . --installed-root C:\\Users\\Admin\\.codex\\skills\\gse --json",
37
+ "node scripts/generate-maintenance-snapshot.mjs --root . --target . --installed-root C:\\Users\\Admin\\.codex\\skills\\gse --skip-release-bundle --execute --json",
38
+ "node scripts/run-gse-command.mjs --root . --target . --command \"/gse close\" --json",
39
+ "git diff --check"
39
40
  ],
40
41
  "residualRisks": [
41
- "Process skills provide workflow discipline and portable artifacts; they do not prove host-native slash-command, subagent, browser, MCP, LSP, CI, or host UI support.",
42
- "Native slash-command support remains an optional per-host adapter claim and is not claimed without a real host invocation record.",
43
- "Browser, MCP, LSP, and subagent statuses remain unknown until project/session evidence is recorded."
42
+ "supportSliceBoundary is optional metadata and must stay a narrow scope or exit criterion, not a replacement for product-visible progress.",
43
+ "Existing product projects need future slices to add or infer userVisibleDelta from their real UI/API/provider/export evidence; CP22 still detects repeated internal drift.",
44
+ "Native slash-command support remains an optional per-host adapter claim and is not claimed without a real host invocation record."
44
45
  ],
45
46
  "riskArchive": [
46
47
  {
package/CHANGELOG.md CHANGED
@@ -4,6 +4,30 @@ All notable GSE changes should be recorded here before a public package, catalog
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.2.0 - 2026-07-11
8
+
9
+ ### Added
10
+
11
+ - Product-visible progress drift guard for `/gse continue`, so repeated internal/component slices surface a product-visible recovery candidate before support work self-replicates.
12
+ - Product outcome gate for product projects, requiring a named user-visible delta or an explicitly bounded support slice.
13
+ - Optional `currentSlice.supportSliceBoundary` metadata for deliberate maintenance slices; bounded support slices now surface their exit criterion without weakening `CP22` drift detection.
14
+ - Target hardening drill adoption summaries and repair plans that distinguish GSE core gaps from target-local hygiene.
15
+
16
+ ### Changed
17
+
18
+ - `/gse repair --execute` guidance is gated behind target worktree ownership before mutating target `.gse` state or evidence.
19
+ - Encoding close checks now use the npm script path and avoid creating dependency artifacts.
20
+ - `validate-gse` now includes the latest target-hardening and product-outcome guard coverage.
21
+
22
+ ### Verified
23
+
24
+ - `v0.1.2..HEAD` contains the product outcome, product drift, bounded support, target repair ownership, and adoption hygiene slices intended for this minor release.
25
+ - Public registry and GitHub release evidence for `0.1.2` remain accepted; `0.2.0` must receive its own npm/GitHub publication evidence after publish.
26
+
27
+ ### Boundary
28
+
29
+ - Native host slash-command support remains optional per host adapter and is not claimed without host invocation evidence.
30
+
7
31
  ## 0.1.2 - 2026-07-10
8
32
 
9
33
  ### Added
@@ -33,8 +57,12 @@ All notable GSE changes should be recorded here before a public package, catalog
33
57
  - `validate-gse.mjs` consolidates structural, project bootstrap, adoption, host adapter, compatibility, release, distribution, signing, command, target validation, and lifecycle audits.
34
58
  - AION and MuseFlow were used as real long-running target-project validation fixtures for GSE adoption checks.
35
59
 
36
- ### Not Yet Accepted
37
-
38
- - Public registry publication and marketplace approval are not verified.
39
- - Host-native slash-command execution is not verified except where a host-specific record explicitly says so.
40
- - Open-source license selection remains an owner decision and must be recorded before a public release is accepted.
60
+ ### Accepted
61
+
62
+ - Public npm registry publication and GitHub Release evidence are accepted for `@t275005746/gse@0.1.2`.
63
+ - MIT license selection is recorded for the public release.
64
+
65
+ ### Not Claimed
66
+
67
+ - Host-native slash-command execution is not verified except where a host-specific record explicitly says so.
68
+ - Marketplace approval remains separate from npm/GitHub publication evidence.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t275005746/gse",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Goal-Spec-Evidence Engineering workflow skill for long-running agent-assisted software projects.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -106,7 +106,8 @@ Expected behavior:
106
106
  5. Keep owner/external evidence visible as public/release/host-specific claim requirements without converting it into GSE core workflow debt.
107
107
  6. Use `completionPlan.requiredSteps`, `completionPlan.requiredCloseCommands`, and active `completionPlan.conditionalCloseCommands` as the exact close checklist before claiming a slice is done.
108
108
  7. Use `gateTaxonomy` to distinguish default core blockers from release gates and host-adapter claim gates. Release and host-adapter gates block only the specific claim unless project policy promotes them.
109
- 8. Execute, verify, record evidence, update `.gse/state.json` and `.gse/evidence/index.jsonl`, and close only when accepted by the applicable gate.
109
+ 8. For a deliberate product support slice, set `currentSlice.supportSliceBoundary` to a narrow scope or exit criterion; `/gse continue` surfaces it and keeps `CP23` as a soft outcome-steering check.
110
+ 9. Execute, verify, record evidence, update `.gse/state.json` and `.gse/evidence/index.jsonl`, and close only when accepted by the applicable gate.
110
111
 
111
112
  Portable helper:
112
113
 
@@ -60,6 +60,8 @@ Completed slices:
60
60
  - Done: generated/noisy artifacts stay visible in `/gse continue` as ignored paths but no longer count as actionable changes or trigger conditional close commands by themselves.
61
61
  - Done: active residual risks and archived risk history are counted separately so `/gse continue` does not make historical risk archive entries look like current blockers.
62
62
  - Done: the human-facing `/gse continue` prompt is a short action packet with project, root, slice, next action, close summary, risk summary, gate boundary, and do-step instead of long explanatory prose.
63
+ - Done: product-visible progress drift is surfaced through `compactState.productProgressDrift`, `CP22`, and a first-ranked `product-visible-recovery` next-slice candidate when repeated internal/component-level provenance or boundary slices risk replacing visible product workflow progress.
64
+ - Done: product outcome gating is surfaced through `compactState.productOutcomeGate`, `CP23`, and a first-ranked `product-visible-recovery` candidate when a product project repeatedly opens support/internal slices without a named user-visible delta; a deliberate support slice can declare a narrow `supportSliceBoundary`; GSE self-development is classified as `skill` and is not forced through this product gate.
63
65
 
64
66
  Acceptance:
65
67
 
@@ -155,7 +157,7 @@ Acceptance:
155
157
 
156
158
  These items should drive future slices only when the claim is being made:
157
159
 
158
- - Short entry takeover is verified through the portable runner; `/gse continue` now exposes a compact action prompt, `completionPlan`, `gateTaxonomy`, generated/noisy ignored paths, and active-versus-archived risk counts. Real host-native slash-command evidence is optional per host adapter.
160
+ - Short entry takeover is verified through the portable runner; `/gse continue` now exposes a compact action prompt, `completionPlan`, `gateTaxonomy`, generated/noisy ignored paths, active-versus-archived risk counts, product-visible progress drift warnings, and product outcome gating for product projects. Real host-native slash-command evidence is optional per host adapter.
159
161
  - Project guards, learning promotion candidates, learning drift status, no-fake-dispatch/file-ownership close checks, host capability records, and target-project hardening drills now surface or execute through portable audits; AION/MuseFlow drill warnings remain project-local readiness signals, not GSE hard failures.
160
162
  - Evidence index validity is a hard preflight; evidence level granularity, state/evidence repair actions, and conservative historical evidence-level backfill are implemented.
161
163
  - Role fallback packets and host capability records are auditable through scaffold, `/gse continue`, and focused audits; real subagent dispatch still needs current host evidence.
@@ -25,6 +25,18 @@ function run(command, commandArgs, cwd) {
25
25
  }
26
26
  }
27
27
 
28
+ function runCommandString(command, cwd) {
29
+ const result = process.platform === 'win32'
30
+ ? spawnSync('cmd', ['/c', command.replace(/^cmd\s+\/c\s+/i, '')], { cwd, encoding: 'utf8', windowsHide: true })
31
+ : spawnSync(command, [], { cwd, encoding: 'utf8', shell: true, windowsHide: true })
32
+ return {
33
+ command,
34
+ status: result.status ?? 1,
35
+ stdout: (result.stdout ?? '').trim(),
36
+ stderr: (result.stderr ?? '').trim(),
37
+ }
38
+ }
39
+
28
40
  function parseJson(text) {
29
41
  try { return JSON.parse(text) } catch { return null }
30
42
  }
@@ -136,6 +148,31 @@ function drill(label, mutate, expectedActiveIds) {
136
148
  }
137
149
  }
138
150
 
151
+ function encodingCommandCleanlinessDrill() {
152
+ const fixture = createFixture()
153
+ try {
154
+ write(path.join(fixture, 'docs', 'usage.md'), '# Usage\n')
155
+ const { result, data } = continuePacket(fixture)
156
+ const command = data?.compactState?.completionPlan?.conditionalCloseCommands?.find((item) => item.id === 'encoding')?.command ?? ''
157
+ const runResult = command ? runCommandString(command, fixture) : { command: '', status: 1, stdout: '', stderr: 'encoding command missing' }
158
+ const nodeModulesExists = fs.existsSync(path.join(fixture, 'node_modules'))
159
+ const pnpmLockExists = fs.existsSync(path.join(fixture, 'pnpm-lock.yaml'))
160
+ return {
161
+ label: 'encoding close command runs without creating dependency artifacts',
162
+ packetStatus: result.status,
163
+ command,
164
+ status: runResult.status,
165
+ stdout: runResult.stdout,
166
+ stderr: runResult.stderr,
167
+ nodeModulesExists,
168
+ pnpmLockExists,
169
+ ok: result.status === 0 && runResult.status === 0 && command.includes('npm run check:encoding') && !nodeModulesExists && !pnpmLockExists,
170
+ }
171
+ } finally {
172
+ fs.rmSync(fixture, { recursive: true, force: true })
173
+ }
174
+ }
175
+
139
176
  const drills = [
140
177
  drill('clean worktree activates no conditionals', null, []),
141
178
  drill('docs change activates encoding only', (dir) => { write(path.join(dir, 'docs', 'usage.md'), '# Usage\n') }, ['encoding']),
@@ -166,6 +203,7 @@ const drills = [
166
203
  write(path.join(dir, 'pnpm-lock.yaml'), 'lockfileVersion: 9.0\nsettings:\n strictPeerDependencies: false\n')
167
204
  }, ['encoding']),
168
205
  ]
206
+ const encodingCleanliness = encodingCommandCleanlinessDrill()
169
207
 
170
208
  const checks = [
171
209
  check('CPD01', 'clean worktree does not falsely activate conditional close commands', drills[0].ok, drills[0].actualActiveIds.join(',') || 'none'),
@@ -178,6 +216,7 @@ const checks = [
178
216
  check('CPD08', 'tracked lockfile changes remain actionable and can trigger configured close checks', drills[7].ok && drills[7].changedPaths.includes('pnpm-lock.yaml') && drills[7].ignoredGeneratedPathCount === 0, `actual=${drills[7].actualActiveIds.join(',') || 'none'} changed=${drills[7].changedPaths.join(',') || 'none'}`),
179
217
  check('CPD09', 'non-release capability maintenance uses skip-release-bundle', drills[2].activeCommands.some((item) => item.includes('generate-maintenance-snapshot.mjs') && item.includes('--skip-release-bundle')), drills[2].activeCommands.join(' | ')),
180
218
  check('CPD10', 'release-sensitive maintenance keeps full release bundle freshness', drills[3].activeCommands.some((item) => item.includes('generate-maintenance-snapshot.mjs') && !item.includes('--skip-release-bundle')), drills[3].activeCommands.join(' | ')),
219
+ check('CPD11', 'encoding close command does not create dependency artifacts', encodingCleanliness.ok, `command=${encodingCleanliness.command}; node_modules=${encodingCleanliness.nodeModulesExists}; pnpm-lock=${encodingCleanliness.pnpmLockExists}`, encodingCleanliness.stderr),
181
220
  ]
182
221
 
183
222
  const passed = checks.filter((item) => item.status === 'passed').length
@@ -190,8 +229,10 @@ const report = {
190
229
  completionPlanDrill: failed === 0 ? 'verified' : 'failed',
191
230
  cleanWorktreeFalsePositiveGuard: drills[0].ok ? 'verified' : 'failed',
192
231
  dirtyWorktreeConditionalRouting: failed === 0 ? 'verified' : 'failed',
232
+ encodingCommandCleanliness: encodingCleanliness.ok ? 'verified' : 'failed',
193
233
  },
194
234
  drills,
235
+ encodingCleanliness,
195
236
  checks,
196
237
  limits: [
197
238
  'This audit verifies portable /gse continue completionPlan routing in temporary git fixtures.',
@@ -143,22 +143,96 @@ function verifiedSliceFixture() {
143
143
  fs.writeFileSync(goalMapPath, '# Goal Map\n\n- Active slice: Continue fixture verified.\n- Next action: Open the next fixture slice with a deliberately long machine-readable reason that should remain available to successor agents even when the display reason is compacted for the short entry prompt and JSON packet overview.\n', 'utf8')
144
144
  return dir
145
145
  }
146
-
147
- const validFixture = fixture(false)
148
- const invalidFixture = fixture(true)
149
- const verifiedFixture = verifiedSliceFixture()
150
- const directValid = run('generate-continue-packet.mjs', ['--root', root, '--target', validFixture, '--json'])
151
- const directInvalid = run('generate-continue-packet.mjs', ['--root', root, '--target', invalidFixture, '--json'])
152
- const directVerified = run('generate-continue-packet.mjs', ['--root', root, '--target', verifiedFixture, '--json'])
153
- const commandValid = run('run-gse-command.mjs', ['--root', root, '--target', validFixture, '--command', '/gse continue', '--json'])
146
+
147
+ function productDriftFixture() {
148
+ const dir = fixture(false)
149
+ const statePath = path.join(dir, '.gse', 'state.json')
150
+ const goalMapPath = path.join(dir, '.gse', 'goal-map.md')
151
+ const indexPath = path.join(dir, '.gse', 'evidence', 'index.jsonl')
152
+ const state = JSON.parse(fs.readFileSync(statePath, 'utf8'))
153
+ state.currentSlice.status = 'verified'
154
+ state.currentSlice.outcome = 'Response-inspection decision provenance continuity.'
155
+ state.currentSlice.nextAction = 'Continue downstream provenance boundary hardening for the next handoff layer.'
156
+ state.residualRisks = []
157
+ fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n', 'utf8')
158
+ fs.writeFileSync(goalMapPath, '# Goal Map\n\n- Active slice: Internal provenance verified.\n- Next action: Continue downstream provenance boundary hardening for the next handoff layer.\n', 'utf8')
159
+ const records = [1, 2, 3, 4].map((index) => ({
160
+ date: '2026-07-08',
161
+ recordType: 'slice',
162
+ status: 'verified',
163
+ evidenceLevel: 'verified-component',
164
+ requiredEvidenceLevel: 'verified-component',
165
+ summary: `Internal provenance boundary handoff continuity ${index}.`,
166
+ evidenceFile: '.gse/evidence/2026-07-08.md',
167
+ commands: ['focused component store test'],
168
+ nextAction: 'Continue downstream provenance boundary hardening.',
169
+ }))
170
+ fs.writeFileSync(indexPath, records.map((record) => JSON.stringify(record)).join('\n') + '\n', 'utf8')
171
+ return dir
172
+ }
173
+
174
+ function productVisibleFixture() {
175
+ const dir = fixture(false)
176
+ const statePath = path.join(dir, '.gse', 'state.json')
177
+ const indexPath = path.join(dir, '.gse', 'evidence', 'index.jsonl')
178
+ const state = JSON.parse(fs.readFileSync(statePath, 'utf8'))
179
+ state.currentSlice.status = 'verified'
180
+ state.currentSlice.outcome = 'Provider API workflow now returns a visible generation result.'
181
+ state.currentSlice.nextAction = 'Open the next user-visible export workflow slice.'
182
+ state.currentSlice.userVisibleDelta = 'Users can run the provider workflow and see a generated result or actionable failure state.'
183
+ state.residualRisks = []
184
+ fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n', 'utf8')
185
+ const records = [
186
+ {
187
+ date: '2026-07-08',
188
+ recordType: 'slice',
189
+ status: 'verified',
190
+ evidenceLevel: 'verified-api',
191
+ requiredEvidenceLevel: 'verified-api',
192
+ summary: 'Provider API workflow smoke returned a visible result payload.',
193
+ userVisibleDelta: 'Users can run the provider workflow and see a generated result or actionable failure state.',
194
+ evidenceFile: '.gse/evidence/2026-07-08.md',
195
+ commands: ['provider workflow API smoke'],
196
+ nextAction: 'Open the next user-visible export workflow slice.',
197
+ },
198
+ ]
199
+ fs.writeFileSync(indexPath, records.map((record) => JSON.stringify(record)).join('\n') + '\n', 'utf8')
200
+ return dir
201
+ }
202
+
203
+ function boundedSupportFixture() {
204
+ const dir = productDriftFixture()
205
+ const statePath = path.join(dir, '.gse', 'state.json')
206
+ const state = JSON.parse(fs.readFileSync(statePath, 'utf8'))
207
+ state.currentSlice.supportSliceBoundary = 'Repair only the malformed evidence index, then return to a user-visible export workflow slice.'
208
+ fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n', 'utf8')
209
+ return dir
210
+ }
211
+
212
+ const validFixture = fixture(false)
213
+ const invalidFixture = fixture(true)
214
+ const verifiedFixture = verifiedSliceFixture()
215
+ const driftFixture = productDriftFixture()
216
+ const visibleFixture = productVisibleFixture()
217
+ const boundedSupport = boundedSupportFixture()
218
+ const directValid = run('generate-continue-packet.mjs', ['--root', root, '--target', validFixture, '--json'])
219
+ const directInvalid = run('generate-continue-packet.mjs', ['--root', root, '--target', invalidFixture, '--json'])
220
+ const directVerified = run('generate-continue-packet.mjs', ['--root', root, '--target', verifiedFixture, '--json'])
221
+ const directProductDrift = run('generate-continue-packet.mjs', ['--root', root, '--target', driftFixture, '--json'])
222
+ const directProductVisible = run('generate-continue-packet.mjs', ['--root', root, '--target', visibleFixture, '--json'])
223
+ const directBoundedSupport = run('generate-continue-packet.mjs', ['--root', root, '--target', boundedSupport, '--json'])
224
+ const commandValid = run('run-gse-command.mjs', ['--root', root, '--target', validFixture, '--command', '/gse continue', '--json'])
154
225
  const commandCompact = run('run-gse-command.mjs', ['--root', root, '--target', validFixture, '--command', '/gse continue', '--json', '--compact'])
155
226
  const commandInvalid = run('run-gse-command.mjs', ['--root', root, '--target', invalidFixture, '--command', '/gse continue', '--json'])
156
227
  const gseSelf = run('run-gse-command.mjs', ['--root', root, '--target', root, '--command', '/gse continue', '--json', '--compact'])
157
228
 
158
229
  const validData = parseJson(directValid.stdout)
159
- const invalidData = parseJson(directInvalid.stdout)
160
- const verifiedData = parseJson(directVerified.stdout)
161
- const commandValidData = parseJson(commandValid.stdout)
230
+ const invalidData = parseJson(directInvalid.stdout)
231
+ const verifiedData = parseJson(directVerified.stdout)
232
+ const productDriftData = parseJson(directProductDrift.stdout)
233
+ const productVisibleData = parseJson(directProductVisible.stdout)
234
+ const boundedSupportData = parseJson(directBoundedSupport.stdout)
235
+ const commandValidData = parseJson(commandValid.stdout)
162
236
  const commandCompactData = parseJson(commandCompact.stdout)
163
237
  const commandInvalidData = parseJson(commandInvalid.stdout)
164
238
  const gseSelfData = parseJson(gseSelf.stdout)
@@ -184,7 +258,7 @@ const checks = [
184
258
  check('CPF12', 'continue packet surfaces latest maintenance snapshot freshness', validData?.preflight?.checks?.some((item) => item.id === 'CP20') && validData?.compactState?.maintenanceSnapshot?.status === 'passed' && validData?.compactState?.maintenanceSnapshot?.installedSync === 'package-only', 'scripts/generate-continue-packet.mjs'),
185
259
  check('CPF13', 'continue packet keeps owner/external records out of core workflow blockers', validData?.limits?.some((item) => item.includes('not GSE core workflow blockers')) && !validData?.limits?.some((item) => item.includes('block final acceptance')) && !fs.readFileSync(path.join(root, 'scripts', 'generate-continue-packet.mjs'), 'utf8').includes('Blocked final-acceptance gates'), 'scripts/generate-continue-packet.mjs'),
186
260
  check('CPF14', 'continue packet exposes exact completion plan and close commands', Array.isArray(validData?.compactState?.completionPlan?.requiredCloseCommands) && validData.compactState.completionPlan.requiredCloseCommands.some((item) => item.includes('run-validation-profile.mjs')) && validData.compactState.completionPlan.requiredCloseCommands.some((item) => item.includes('/gse close')) && validData.compactState.completionPlan.requiredSteps.some((item) => item.includes('evidence/index.jsonl')), 'compactState.completionPlan'),
187
- check('CPF15', 'continue packet activates conditional close commands from detected changed capability/docs/release files', validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'encoding' && item.active && item.command.includes('pnpm check:encoding')) && validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'installed-sync' && item.active && item.command.includes('audit-installed-sync.mjs')) && validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'release-bundle' && item.active && item.command.includes('generate-release-bundle.mjs')) && validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'session-sync' && item.active && item.command.includes('audit-session-sync.mjs')), 'compactState.completionPlan.conditionalCloseCommands'),
261
+ check('CPF15', 'continue packet activates conditional close commands from detected changed capability/docs/release files', validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'encoding' && item.active && item.command.includes('npm run check:encoding')) && validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'installed-sync' && item.active && item.command.includes('audit-installed-sync.mjs')) && validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'release-bundle' && item.active && item.command.includes('generate-release-bundle.mjs')) && validData?.compactState?.completionPlan?.conditionalCloseCommands?.some((item) => item.id === 'session-sync' && item.active && item.command.includes('audit-session-sync.mjs')), 'compactState.completionPlan.conditionalCloseCommands'),
188
262
  check('CPF16', 'continue packet exposes core/release/host-adapter gate taxonomy', validData?.compactState?.gateTaxonomy?.core?.blocking === true && validData?.compactState?.gateTaxonomy?.release?.scope?.includes('public release') && validData?.compactState?.gateTaxonomy?.hostAdapter?.scope?.includes('native slash-command') && validData?.compactState?.gateTaxonomy?.rule?.includes('block only the specific public, release, or host claim'), 'compactState.gateTaxonomy'),
189
263
  check('CPF17', 'continue packet prompt is short-entry actionable instead of long-goal prose', promptLines.length <= 6 && validData?.prompt?.includes('GSE continue:') && validData?.prompt?.includes('Root:') && validData?.prompt?.includes('Slice:') && validData?.prompt?.includes('Next:') && validData?.prompt?.includes('Mode: continue-current-slice') && validData?.prompt?.includes('Do: one verifiable slice') && validData?.prompt?.includes('risks=4 active/1 archived') && !validData?.prompt?.includes('Run one verifiable slice, record evidence'), 'compact prompt line count and required action fields'),
190
264
  check('CPF18', 'verified current slice switches short entry into open-next-slice mode', directVerified.status === 0 && verifiedData?.compactState?.nextSliceMode?.action === 'open-next-slice' && verifiedData?.compactState?.nextSliceMode?.currentSliceVerified === true && verifiedData?.prompt?.includes('Mode: open-next-slice'), directVerified.command),
@@ -195,11 +269,19 @@ const checks = [
195
269
  check('CPF23', 'next-slice candidates prefer concrete gaps over meta open-next-slice reminders', directVerified.status === 0 && verifiedData?.compactState?.nextSliceCandidates?.[0]?.source === '.gse/state.json residualRisks' && !verifiedData.compactState.nextSliceCandidates[0].fullReason.toLowerCase().includes('open the next fixture slice'), 'compactState.nextSliceCandidates ranking'),
196
270
  check('CPF24', 'next-slice candidates include structured action packets for short-entry takeover', directVerified.status === 0 && verifiedData?.compactState?.nextSliceCandidates?.every((item) => item.actionPacket?.candidateType && item.actionPacket?.outcomeHint && item.actionPacket?.scopeHint && item.actionPacket?.acceptanceHint && item.actionPacket?.evidenceHint && item.actionPacket?.riskHint && item.actionPacket?.nextActionHint && Array.isArray(item.actionPacket?.focusedChecks) && item.actionPacket.focusedChecks.length >= 1), 'compactState.nextSliceCandidates.actionPacket'),
197
271
  check('CPF25', 'continue packet separates session sync evidence from target-session adoption', validData?.preflight?.checks?.some((item) => item.id === 'CP21') && validData?.compactState?.sessionSyncBoundary?.boundary === 'sync-records-do-not-prove-adoption' && validData?.compactState?.sessionSyncBoundary?.adoptionProven === false && validData?.compactState?.sessionSyncBoundary?.limits?.some((item) => item.includes('not target-session adoption')), 'compactState.sessionSyncBoundary'),
272
+ check('CPF26', 'continue packet detects repeated internal/component slices and prefers product-visible recovery', directProductDrift.status === 0 && productDriftData?.compactState?.productProgressDrift?.status === 'warning' && productDriftData?.preflight?.checks?.some((item) => item.id === 'CP22' && item.status === 'warning') && productDriftData?.compactState?.nextSliceCandidates?.[0]?.actionPacket?.candidateType === 'product-visible-recovery' && productDriftData?.compactState?.nextSliceCandidates?.[0]?.acceptanceHint?.includes('user-visible behavior'), 'compactState.productProgressDrift'),
273
+ check('CPF27', 'product outcome gate warns on repeated support slices in product projects', directProductDrift.status === 0 && productDriftData?.compactState?.productOutcomeGate?.status === 'warning' && productDriftData?.compactState?.productOutcomeGate?.projectType === 'product' && productDriftData?.compactState?.productOutcomeGate?.sliceType === 'support' && productDriftData?.preflight?.checks?.some((item) => item.id === 'CP23' && item.status === 'warning') && productDriftData?.compactState?.nextSliceCandidates?.[0]?.source === 'compactState.productOutcomeGate', 'compactState.productOutcomeGate warning'),
274
+ check('CPF28', 'product outcome gate passes when product slice names a visible delta', directProductVisible.status === 0 && productVisibleData?.compactState?.productOutcomeGate?.status === 'passed' && productVisibleData?.compactState?.productOutcomeGate?.userVisibleDelta?.includes('Users can run') && productVisibleData?.compactState?.nextSliceCandidates?.every((item) => item.source !== 'compactState.productOutcomeGate'), 'compactState.productOutcomeGate passed'),
275
+ check('CPF29', 'GSE self is not forced through product outcome gate', gseSelf.status === 0 && gseSelfData?.compactState?.productOutcomeGate?.status === 'not-applicable' && gseSelfData?.compactState?.productOutcomeGate?.projectType === 'skill', 'compactState.productOutcomeGate not-applicable'),
276
+ check('CPF30', 'bounded product support slices surface their boundary without CP23 warning', directBoundedSupport.status === 0 && boundedSupportData?.compactState?.productOutcomeGate?.status === 'passed' && boundedSupportData?.compactState?.productOutcomeGate?.sliceType === 'support' && boundedSupportData?.compactState?.productOutcomeGate?.supportSliceBoundary?.includes('malformed evidence index') && !boundedSupportData?.preflight?.checks?.some((item) => item.id === 'CP23' && item.status === 'warning'), 'compactState.productOutcomeGate.supportSliceBoundary'),
198
277
  ]
199
-
200
- fs.rmSync(validFixture, { recursive: true, force: true })
201
- fs.rmSync(invalidFixture, { recursive: true, force: true })
202
- fs.rmSync(verifiedFixture, { recursive: true, force: true })
278
+
279
+ fs.rmSync(validFixture, { recursive: true, force: true })
280
+ fs.rmSync(invalidFixture, { recursive: true, force: true })
281
+ fs.rmSync(verifiedFixture, { recursive: true, force: true })
282
+ fs.rmSync(driftFixture, { recursive: true, force: true })
283
+ fs.rmSync(visibleFixture, { recursive: true, force: true })
284
+ fs.rmSync(boundedSupport, { recursive: true, force: true })
203
285
 
204
286
  const passed = checks.filter((item) => item.status === 'passed').length
205
287
  const failed = checks.length - passed
@@ -218,8 +300,10 @@ const report = {
218
300
  nextSliceCandidates: failed === 0 ? 'verified' : 'failed',
219
301
  nextSliceActionPackets: failed === 0 ? 'verified' : 'failed',
220
302
  sessionSyncAdoptionBoundary: failed === 0 ? 'verified' : 'failed',
303
+ productProgressDriftGuard: failed === 0 ? 'verified' : 'failed',
304
+ productOutcomeGate: failed === 0 ? 'verified' : 'failed',
221
305
  },
222
- commands: [directValid.command, directInvalid.command, directVerified.command, commandValid.command, commandCompact.command, commandInvalid.command, gseSelf.command],
306
+ commands: [directValid.command, directInvalid.command, directVerified.command, directProductDrift.command, directProductVisible.command, directBoundedSupport.command, commandValid.command, commandCompact.command, commandInvalid.command, gseSelf.command],
223
307
  checks,
224
308
  limits: [
225
309
  'This audit verifies portable /gse continue semantics and compact packet output.',