@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
package/scripts/init-project.mjs
CHANGED
|
@@ -200,24 +200,39 @@ const results = [
|
|
|
200
200
|
subagents: 'unknown',
|
|
201
201
|
ci: 'unknown',
|
|
202
202
|
},
|
|
203
|
-
lastEvidence:
|
|
203
|
+
lastEvidence: `.gse/evidence/${date}.md`,
|
|
204
204
|
residualRisks: [
|
|
205
205
|
'Project commands and host tools are unknown until verified in this repository.',
|
|
206
206
|
],
|
|
207
207
|
}),
|
|
208
208
|
),
|
|
209
|
-
writeIfMissing(
|
|
210
|
-
'evidence/index.jsonl',
|
|
209
|
+
writeIfMissing(
|
|
210
|
+
'evidence/index.jsonl',
|
|
211
211
|
JSON.stringify({
|
|
212
|
-
date,
|
|
213
|
-
recordType: 'adoption',
|
|
214
|
-
status: 'result',
|
|
215
|
-
|
|
216
|
-
|
|
212
|
+
date,
|
|
213
|
+
recordType: 'adoption',
|
|
214
|
+
status: 'result',
|
|
215
|
+
evidenceLevel: 'result',
|
|
216
|
+
requiredEvidenceLevel: 'verified-unit',
|
|
217
|
+
summary: `Initialized GSE ${mode} scaffold.`,
|
|
218
|
+
evidenceFile: `.gse/evidence/${date}.md`,
|
|
217
219
|
commands: [`node <gse-skill>/scripts/init-project.mjs --target <project-root> --mode ${requestedMode}`],
|
|
218
|
-
nextAction: 'Record project-specific profile, canonical plan, quality gates, and first verified slice.',
|
|
219
|
-
}) + '\n',
|
|
220
|
-
),
|
|
220
|
+
nextAction: 'Record project-specific profile, canonical plan, quality gates, and first verified slice.',
|
|
221
|
+
}) + '\n',
|
|
222
|
+
),
|
|
223
|
+
writeIfMissing(
|
|
224
|
+
`evidence/${date}.md`,
|
|
225
|
+
`# GSE Adoption Evidence
|
|
226
|
+
|
|
227
|
+
- Date: ${date}
|
|
228
|
+
- Status: result
|
|
229
|
+
- Evidence level: result
|
|
230
|
+
- Summary: Initialized GSE ${mode} scaffold.
|
|
231
|
+
- Command: \`node <gse-skill>/scripts/init-project.mjs --target <project-root> --mode ${requestedMode}\`
|
|
232
|
+
|
|
233
|
+
Next action: Record project-specific profile, canonical plan, quality gates, and first verified slice.
|
|
234
|
+
`,
|
|
235
|
+
),
|
|
221
236
|
writeIfMissing(
|
|
222
237
|
'README.md',
|
|
223
238
|
`# GSE Workflow
|
|
@@ -230,8 +245,9 @@ Start meaningful work by reading:
|
|
|
230
245
|
2. .gse/state.json.
|
|
231
246
|
3. .gse/project-profile.md.
|
|
232
247
|
4. .gse/goal-map.md.
|
|
233
|
-
5. .gse/quality-gates.md.
|
|
234
|
-
6.
|
|
248
|
+
5. .gse/quality-gates.md.
|
|
249
|
+
6. .gse/project-guards.md.
|
|
250
|
+
7. The relevant change folder under .gse/changes/ when one exists.
|
|
235
251
|
|
|
236
252
|
Core loop:
|
|
237
253
|
|
|
@@ -336,8 +352,8 @@ Describe the durable project outcome here.
|
|
|
336
352
|
- Add project-specific risks here.
|
|
337
353
|
`,
|
|
338
354
|
),
|
|
339
|
-
writeIfMissing(
|
|
340
|
-
'quality-gates.md',
|
|
355
|
+
writeIfMissing(
|
|
356
|
+
'quality-gates.md',
|
|
341
357
|
`# Quality Gates
|
|
342
358
|
|
|
343
359
|
## Universal
|
|
@@ -361,12 +377,31 @@ Describe the durable project outcome here.
|
|
|
361
377
|
|
|
362
378
|
## Learning
|
|
363
379
|
|
|
364
|
-
- Capture reusable lessons and promote recurring issues into gates.
|
|
365
|
-
`,
|
|
366
|
-
),
|
|
367
|
-
writeIfMissing(
|
|
368
|
-
'
|
|
369
|
-
`#
|
|
380
|
+
- Capture reusable lessons and promote recurring issues into gates.
|
|
381
|
+
`,
|
|
382
|
+
),
|
|
383
|
+
writeIfMissing(
|
|
384
|
+
'project-guards.md',
|
|
385
|
+
`# Project Guards
|
|
386
|
+
|
|
387
|
+
Project guards are reusable preflight rules promoted from repeated project lessons.
|
|
388
|
+
|
|
389
|
+
GSE reads this file during \`/gse continue\` and surfaces active guards before implementation. Keep it short, project-local, and evidence-bound.
|
|
390
|
+
|
|
391
|
+
| ID | Guard | Severity | Trigger | Check | Status |
|
|
392
|
+
|---|---|---|---|---|---|
|
|
393
|
+
| WIN-SHELL | Use shell syntax that matches the active host. On Windows, prefer \`cmd /c\` for npm, pnpm, npx, and similar commands when PowerShell shims or operators are unreliable. | high | Windows shell or package-manager command | Confirm command syntax is valid for the current shell before running or documenting it. | active |
|
|
394
|
+
| SPARSE-GIT | Check sparse checkout before staging generated workflow folders. | high | \`.gse/\`, host adapter, or generated scaffold changes | If sparse checkout is active and the path is outside the cone, use sparse-aware staging or record the limitation. | active |
|
|
395
|
+
| UTF8-DOC | Use UTF-8-safe readers for Chinese or multilingual docs before judging mojibake. | high | Chinese docs, encoding complaints, generated docs | Read with Node UTF-8 or another UTF-8-safe viewer; run the project encoding check when docs changed. | active |
|
|
396
|
+
| EVIDENCE-STALE | Treat stale, broken, or schema-weak evidence as a preflight problem. | high | \`.gse/evidence/index.jsonl\`, state, close gate | Validate JSONL and make sure latest evidence matches the current slice before closing. | active |
|
|
397
|
+
| UI-EVIDENCE | Label UI/browser verification downgrades explicitly. | medium | UI, browser, screenshot, component test, visual behavior | Mark evidence as unit, component, API, browser, CI, owner, release, or external instead of hiding downgrade under a generic verified label. | active |
|
|
398
|
+
| SUBAGENT-HONEST | Do not claim subagent dispatch unless the current host exposes real dispatch evidence. | high | multi-agent, subagent, role dispatch, parallel work | If no real dispatch tool exists, run roles sequentially or use file/tool parallelism and say so. | active |
|
|
399
|
+
| SYNC-NO-INTERRUPT | Do not interrupt running project sessions with cross-thread GSE sync messages. | high | GSE upgrade sync, delegation, background thread message | Prefer evidence records or owner action notes; only send a short cross-thread sync when the target session is idle or the owner explicitly asks. | active |
|
|
400
|
+
`,
|
|
401
|
+
),
|
|
402
|
+
writeIfMissing(
|
|
403
|
+
'tooling.md',
|
|
404
|
+
`# Tooling
|
|
370
405
|
|
|
371
406
|
Minimum tools: git, shell, and project test/build commands.
|
|
372
407
|
|
|
@@ -379,12 +414,30 @@ Recommended tools:
|
|
|
379
414
|
- Comet for change lifecycle when available.
|
|
380
415
|
- Self-improvement or learnings files for durable lessons.
|
|
381
416
|
|
|
382
|
-
Do not claim a tool was used when it was not available.
|
|
383
|
-
`,
|
|
384
|
-
),
|
|
385
|
-
writeIfMissing(
|
|
386
|
-
'
|
|
387
|
-
`#
|
|
417
|
+
Do not claim a tool was used when it was not available.
|
|
418
|
+
`,
|
|
419
|
+
),
|
|
420
|
+
writeIfMissing(
|
|
421
|
+
'host-capabilities.md',
|
|
422
|
+
`# Host Capabilities
|
|
423
|
+
|
|
424
|
+
Record current project and host capability facts here. A generated adapter, portable command, or another host's evidence is not proof for this host.
|
|
425
|
+
|
|
426
|
+
Status vocabulary: \`verified\`, \`documented\`, \`unknown\`, \`unavailable\`, \`external-required\`.
|
|
427
|
+
|
|
428
|
+
| Capability | Host/Tool | Status | Evidence | Claim Boundary | Last Checked |
|
|
429
|
+
|---|---|---|---|---|---|
|
|
430
|
+
| native-slash-command | current host | external-required | - | Native slash-command support requires real host runtime invocation evidence, not portable \`/gse\` runner output. | - |
|
|
431
|
+
| browser | browser or Playwright | unknown | - | Browser proof requires a real browser/component/screenshot command for this project. | - |
|
|
432
|
+
| mcp | MCP servers | unknown | - | MCP status is host and project specific. | - |
|
|
433
|
+
| lsp | LSP or code index | unknown | - | LSP/index status is current-session specific unless project docs prove it. | - |
|
|
434
|
+
| subagent | host dispatch | unknown | - | Real subagent dispatch requires verified host/tool evidence; sequential role fallback is not real dispatch. | - |
|
|
435
|
+
| ci | project CI | unknown | - | CI is verified only after a workflow/config or run is checked for this project. | - |
|
|
436
|
+
`,
|
|
437
|
+
),
|
|
438
|
+
writeIfMissing(
|
|
439
|
+
'learnings.md',
|
|
440
|
+
`# Learnings
|
|
388
441
|
|
|
389
442
|
Record only reusable lessons.
|
|
390
443
|
|
|
@@ -417,13 +470,19 @@ Record only reusable lessons.
|
|
|
417
470
|
## Next Action
|
|
418
471
|
`,
|
|
419
472
|
),
|
|
420
|
-
writeIfMissing(
|
|
421
|
-
'templates/evidence.md',
|
|
422
|
-
`# Evidence
|
|
423
|
-
|
|
424
|
-
##
|
|
425
|
-
|
|
426
|
-
|
|
473
|
+
writeIfMissing(
|
|
474
|
+
'templates/evidence.md',
|
|
475
|
+
`# Evidence
|
|
476
|
+
|
|
477
|
+
## Status
|
|
478
|
+
|
|
479
|
+
- Evidence status:
|
|
480
|
+
- Evidence level:
|
|
481
|
+
- Required evidence level:
|
|
482
|
+
|
|
483
|
+
## Commands
|
|
484
|
+
|
|
485
|
+
## Results
|
|
427
486
|
|
|
428
487
|
## Files Changed
|
|
429
488
|
|
|
@@ -582,10 +641,11 @@ Host-specific folders such as .codex/, .claude/, .agents/, or runtime-specific d
|
|
|
582
641
|
|
|
583
642
|
- Goal map: .gse/goal-map.md
|
|
584
643
|
- Quality gates: .gse/quality-gates.md
|
|
585
|
-
- Agent roles: .gse/agents/roles.md
|
|
586
|
-
- Dispatch rules: .gse/agents/dispatch.md
|
|
587
|
-
-
|
|
588
|
-
-
|
|
644
|
+
- Agent roles: .gse/agents/roles.md
|
|
645
|
+
- Dispatch rules: .gse/agents/dispatch.md
|
|
646
|
+
- Role fallback packets: .gse/agents/role-fallback-packets.md
|
|
647
|
+
- Project skills: .gse/skills/README.md
|
|
648
|
+
- LSP/index notes: .gse/lsp/README.md
|
|
589
649
|
|
|
590
650
|
## Adapter Rule
|
|
591
651
|
|
|
@@ -598,43 +658,64 @@ Do not duplicate the whole workflow into a host-specific folder. Add a short poi
|
|
|
598
658
|
|
|
599
659
|
Use these roles as boundaries, whether they are executed by real subagents or sequentially by one agent.
|
|
600
660
|
|
|
601
|
-
| Role | Responsibility | Write Access |
|
|
602
|
-
|---|---|---|
|
|
603
|
-
| Coordinator | Scope, context, final judgment, integration | yes |
|
|
604
|
-
|
|
|
605
|
-
|
|
|
606
|
-
|
|
|
607
|
-
|
|
|
608
|
-
|
|
|
609
|
-
|
|
|
610
|
-
|
|
|
611
|
-
|
|
612
|
-
|
|
661
|
+
| Role | Responsibility | Write Access |
|
|
662
|
+
|---|---|---|
|
|
663
|
+
| Coordinator | Scope, context, final judgment, integration | yes |
|
|
664
|
+
| Planner | Outcome, scope, acceptance, evidence, risk, next action | docs/state only |
|
|
665
|
+
| Product Analyst | Outcome, user pain, priority, non-goals | docs only |
|
|
666
|
+
| Architect | Contracts, data flow, risks, rollback | docs/code by assignment |
|
|
667
|
+
| Locator | Files, symbols, call chains, existing tests | no |
|
|
668
|
+
| Implementer | Bounded implementation slice | assigned files only |
|
|
669
|
+
| Verifier | Focused checks and evidence level | evidence/test output only |
|
|
670
|
+
| Reviewer | Diff review, regressions, missing tests | no |
|
|
671
|
+
| Docs/Evidence | Slice log, ADR links, learning entries | docs only |
|
|
672
|
+
| Release | Release, owner, CI, package, marketplace, registry, and host-runtime boundaries | docs/release only |
|
|
673
|
+
`,
|
|
674
|
+
),
|
|
613
675
|
writeIfMissing(
|
|
614
676
|
'agents/dispatch.md',
|
|
615
677
|
`# Agent Dispatch
|
|
616
678
|
|
|
617
679
|
Use real subagent tools only when the host exposes them.
|
|
618
680
|
|
|
619
|
-
## Dispatch Packet
|
|
620
|
-
|
|
621
|
-
- Role:
|
|
622
|
-
-
|
|
623
|
-
-
|
|
624
|
-
-
|
|
625
|
-
-
|
|
626
|
-
-
|
|
681
|
+
## Dispatch Packet
|
|
682
|
+
|
|
683
|
+
- Role:
|
|
684
|
+
- Real delegation used: yes | no
|
|
685
|
+
- Objective:
|
|
686
|
+
- Allowed files:
|
|
687
|
+
- Forbidden actions:
|
|
688
|
+
- Role output evidence:
|
|
689
|
+
- Expected output:
|
|
690
|
+
- Verification:
|
|
627
691
|
|
|
628
692
|
## Rules
|
|
629
693
|
|
|
630
694
|
- Do not delegate final judgment.
|
|
631
695
|
- Avoid parallel writes to the same file.
|
|
632
696
|
- Say explicitly when subagent tools are unavailable and execute roles sequentially.
|
|
633
|
-
- Keep prompts free of expected answers when using agents for validation.
|
|
634
|
-
`,
|
|
635
|
-
),
|
|
636
|
-
writeIfMissing(
|
|
637
|
-
'
|
|
697
|
+
- Keep prompts free of expected answers when using agents for validation.
|
|
698
|
+
`,
|
|
699
|
+
),
|
|
700
|
+
writeIfMissing(
|
|
701
|
+
'agents/role-fallback-packets.md',
|
|
702
|
+
`# Role Fallback Packets
|
|
703
|
+
|
|
704
|
+
These packets make role-separated work auditable even when real subagent tools are unavailable.
|
|
705
|
+
|
|
706
|
+
| Role | Mode | Real delegation used | Tool status | Fallback output | Evidence | Stop condition | Write access |
|
|
707
|
+
|---|---|---|---|---|---|---|---|
|
|
708
|
+
| Planner | sequential-role | no | unknown | Slice plan with outcome, scope, acceptance, evidence, risk, and next action | .gse/current-slice.md or planning note | Goal, roadmap, or acceptance source is contradictory | docs/state only |
|
|
709
|
+
| Locator | sequential-role | no | unknown | File, symbol, command, and existing-test map | search output or locator notes | Required files cannot be found or ownership is unclear | read-only |
|
|
710
|
+
| Implementer | sequential-role | no | unknown | Bounded diff in assigned files | git diff and changed-file list | Target files have unsafe unrelated dirty changes | assigned files only |
|
|
711
|
+
| Verifier | sequential-role | no | unknown | Focused command results and evidence level | command output summary and evidence record | Required focused check cannot run or fails without a repair path | evidence/test output only |
|
|
712
|
+
| Reviewer | sequential-role | no | unknown | Spec compliance and quality findings | review notes or explicit no-findings statement | Diff exceeds scope or missing tests are material | read-only |
|
|
713
|
+
| Docs/Evidence | sequential-role | no | unknown | Slice evidence, state, goal-map, and roadmap updates | .gse/evidence/index.jsonl and .gse/evidence/YYYY-MM-DD.md | Evidence cannot be recorded or JSONL is invalid | docs/evidence only |
|
|
714
|
+
| Release | sequential-role | no | unknown | Release, owner, external, CI, package, and host-runtime boundary check | final-readiness or public-acceptance audit summary | Local evidence is being used to claim owner/external support | docs/release only |
|
|
715
|
+
`,
|
|
716
|
+
),
|
|
717
|
+
writeIfMissing(
|
|
718
|
+
'skills/README.md',
|
|
638
719
|
`# Project Skills
|
|
639
720
|
|
|
640
721
|
Record project-local skills and reusable workflows here.
|
|
@@ -72,10 +72,10 @@ if (!fs.existsSync(gseDir) || !fs.statSync(gseDir).isDirectory()) {
|
|
|
72
72
|
process.exit(1)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const existing = fs.existsSync(learningsPath) ? fs.readFileSync(learningsPath, 'utf8').replace(/^\uFEFF/, '') : '# Learnings\n\n'
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
const existing = fs.existsSync(learningsPath) ? fs.readFileSync(learningsPath, 'utf8').replace(/^\uFEFF/, '') : '# Learnings\n\n'
|
|
76
|
+
const existingLines = existing.split(/\r?\n/)
|
|
77
|
+
const duplicateSummaryLineIndex = existingLines.findIndex((line) => line.trim().startsWith('- Summary:') && normalize(line.replace(/^- Summary:\s*/, '')) === normalize(summary))
|
|
78
|
+
const duplicate = duplicateSummaryLineIndex !== -1
|
|
79
79
|
|
|
80
80
|
const relativePath = path.relative(target, learningsPath).replace(/\\/g, '/')
|
|
81
81
|
const entry = [
|
|
@@ -90,10 +90,39 @@ const entry = [
|
|
|
90
90
|
'',
|
|
91
91
|
].join('\n')
|
|
92
92
|
|
|
93
|
-
if (duplicate) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
if (duplicate) {
|
|
94
|
+
if (execute) {
|
|
95
|
+
let insertAt = duplicateSummaryLineIndex + 1
|
|
96
|
+
let occurrenceLineIndex = -1
|
|
97
|
+
for (let cursor = duplicateSummaryLineIndex + 1; cursor < existingLines.length; cursor += 1) {
|
|
98
|
+
const line = existingLines[cursor]
|
|
99
|
+
if (/^##\s+/.test(line)) break
|
|
100
|
+
if (line.trim().startsWith('- Occurrences:')) {
|
|
101
|
+
occurrenceLineIndex = cursor
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
if (line.trim().startsWith('- Source:')) insertAt = cursor
|
|
105
|
+
}
|
|
106
|
+
if (occurrenceLineIndex === -1) {
|
|
107
|
+
existingLines.splice(insertAt, 0, '- Occurrences: 2')
|
|
108
|
+
} else {
|
|
109
|
+
const current = Number(existingLines[occurrenceLineIndex].replace(/^- Occurrences:\s*/, '').trim()) || 1
|
|
110
|
+
existingLines[occurrenceLineIndex] = '- Occurrences: ' + String(current + 1)
|
|
111
|
+
}
|
|
112
|
+
fs.writeFileSync(learningsPath, existingLines.join('\n').replace(/\n*$/, '\n'), 'utf8')
|
|
113
|
+
report({
|
|
114
|
+
status: 'updated',
|
|
115
|
+
target,
|
|
116
|
+
path: relativePath,
|
|
117
|
+
summary,
|
|
118
|
+
reason: 'duplicate summary counted without appending another entry',
|
|
119
|
+
evidenceStatus: 'verified',
|
|
120
|
+
})
|
|
121
|
+
process.exit(0)
|
|
122
|
+
}
|
|
123
|
+
report({
|
|
124
|
+
status: 'skipped',
|
|
125
|
+
target,
|
|
97
126
|
path: relativePath,
|
|
98
127
|
summary,
|
|
99
128
|
reason: 'duplicate summary already exists',
|
|
@@ -0,0 +1,87 @@
|
|
|
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 execute = args.includes('--execute')
|
|
15
|
+
const jsonOnly = args.includes('--json')
|
|
16
|
+
const recordPath = path.join(root, '.gse', 'session-sync.jsonl')
|
|
17
|
+
|
|
18
|
+
function requiredArg(name) {
|
|
19
|
+
const value = readArg(name)
|
|
20
|
+
if (!value) {
|
|
21
|
+
console.error(`${name} is required`)
|
|
22
|
+
process.exit(1)
|
|
23
|
+
}
|
|
24
|
+
return value
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function normalizeStatus(value) {
|
|
28
|
+
return String(value || '').trim().toLowerCase()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const allowedStatuses = new Set([
|
|
32
|
+
'sent',
|
|
33
|
+
'installed-sync',
|
|
34
|
+
'skipped',
|
|
35
|
+
'failed',
|
|
36
|
+
'archived',
|
|
37
|
+
'unavailable',
|
|
38
|
+
])
|
|
39
|
+
|
|
40
|
+
const status = normalizeStatus(requiredArg('--status'))
|
|
41
|
+
if (!allowedStatuses.has(status)) {
|
|
42
|
+
console.error(`--status must be one of: ${[...allowedStatuses].join(', ')}`)
|
|
43
|
+
process.exit(1)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const record = {
|
|
47
|
+
schemaVersion: 1,
|
|
48
|
+
recordedAt: new Date().toISOString(),
|
|
49
|
+
capability: readArg('--capability', 'gse-capability-sync'),
|
|
50
|
+
status,
|
|
51
|
+
method: requiredArg('--method'),
|
|
52
|
+
threadId: readArg('--thread-id', null),
|
|
53
|
+
project: readArg('--project', null),
|
|
54
|
+
workspace: readArg('--workspace', null),
|
|
55
|
+
evidence: requiredArg('--evidence'),
|
|
56
|
+
messageSummary: readArg('--message-summary', ''),
|
|
57
|
+
limits: [
|
|
58
|
+
'This record proves a sync attempt or installed-copy parity record, not that the target session adopted the capability.',
|
|
59
|
+
'A thread sync is accepted only when the transport returned success or when the failure/archived status is recorded honestly.',
|
|
60
|
+
],
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const report = {
|
|
64
|
+
root,
|
|
65
|
+
recordPath,
|
|
66
|
+
execute,
|
|
67
|
+
summary: {
|
|
68
|
+
status: execute ? 'written' : 'dry-run',
|
|
69
|
+
threadId: record.threadId,
|
|
70
|
+
syncStatus: record.status,
|
|
71
|
+
method: record.method,
|
|
72
|
+
},
|
|
73
|
+
record,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (execute) {
|
|
77
|
+
fs.mkdirSync(path.dirname(recordPath), { recursive: true })
|
|
78
|
+
fs.appendFileSync(recordPath, JSON.stringify(record) + '\n', 'utf8')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (jsonOnly) console.log(JSON.stringify(report, null, 2))
|
|
82
|
+
else {
|
|
83
|
+
console.log(`GSE session sync record: ${report.summary.status}`)
|
|
84
|
+
console.log(`Status: ${record.status}`)
|
|
85
|
+
console.log(`Method: ${record.method}`)
|
|
86
|
+
if (record.threadId) console.log(`Thread: ${record.threadId}`)
|
|
87
|
+
}
|
|
@@ -95,26 +95,31 @@ const commandMap = {
|
|
|
95
95
|
effect: 'read-only',
|
|
96
96
|
summary: 'Show GSE commands and project entry files.',
|
|
97
97
|
},
|
|
98
|
-
continue: {
|
|
99
|
-
route: 'scripts/generate-
|
|
100
|
-
effect: 'read-only',
|
|
101
|
-
summary: '
|
|
102
|
-
},
|
|
103
|
-
next: {
|
|
104
|
-
route: 'scripts/generate-
|
|
105
|
-
effect: 'read-only',
|
|
106
|
-
summary: 'Alias for /gse continue.',
|
|
98
|
+
continue: {
|
|
99
|
+
route: 'scripts/generate-continue-packet.mjs',
|
|
100
|
+
effect: 'read-only',
|
|
101
|
+
summary: 'Run a hard continuation preflight and generate a compact state packet.',
|
|
102
|
+
},
|
|
103
|
+
next: {
|
|
104
|
+
route: 'scripts/generate-continue-packet.mjs',
|
|
105
|
+
effect: 'read-only',
|
|
106
|
+
summary: 'Alias for /gse continue.',
|
|
107
107
|
},
|
|
108
108
|
status: {
|
|
109
109
|
route: 'scripts/generate-final-form-progress-report.mjs or .gse/state.json',
|
|
110
110
|
effect: 'read-only',
|
|
111
111
|
summary: 'Show project state, or GSE final-form progress when the target is the GSE skill.',
|
|
112
112
|
},
|
|
113
|
-
doctor: {
|
|
114
|
-
route: 'scripts/audit-public-acceptance-readiness.mjs or scripts/audit-target-project.mjs',
|
|
115
|
-
effect: 'read-only',
|
|
116
|
-
summary: 'Diagnose final-form public/host
|
|
117
|
-
},
|
|
113
|
+
doctor: {
|
|
114
|
+
route: 'scripts/audit-public-acceptance-readiness.mjs or scripts/audit-target-project.mjs',
|
|
115
|
+
effect: 'read-only',
|
|
116
|
+
summary: 'Diagnose final-form public/host claim evidence for GSE, or target-project GSE readiness for normal projects.',
|
|
117
|
+
},
|
|
118
|
+
repair: {
|
|
119
|
+
route: 'scripts/audit-state-repair.mjs',
|
|
120
|
+
effect: 'read-only by default; reversible risk compaction with --execute',
|
|
121
|
+
summary: 'Diagnose or safely repair stale state, broken evidence JSONL, and overlong residual risks.',
|
|
122
|
+
},
|
|
118
123
|
acceptance: {
|
|
119
124
|
route: 'scripts/audit-public-acceptance-readiness.mjs or scripts/audit-target-project.mjs',
|
|
120
125
|
effect: 'read-only',
|
|
@@ -145,11 +150,16 @@ const commandMap = {
|
|
|
145
150
|
effect: 'read-only by default; write-with-execute for install target writes',
|
|
146
151
|
summary: 'Dry-run or install GSE from a local package path or URL-shaped package source.',
|
|
147
152
|
},
|
|
148
|
-
'public-release': {
|
|
149
|
-
route: 'scripts/generate-public-release-checklist.mjs or scripts/audit-public-release-checklist.mjs',
|
|
150
|
-
effect: 'read-only by default; write-with-execute for canonical checklist generation',
|
|
151
|
-
summary: 'Dry-run or generate the ordered owner/public release checklist.',
|
|
152
|
-
},
|
|
153
|
+
'public-release': {
|
|
154
|
+
route: 'scripts/generate-public-release-checklist.mjs or scripts/audit-public-release-checklist.mjs',
|
|
155
|
+
effect: 'read-only by default; write-with-execute for canonical checklist generation',
|
|
156
|
+
summary: 'Dry-run or generate the ordered owner/public release checklist.',
|
|
157
|
+
},
|
|
158
|
+
maintenance: {
|
|
159
|
+
route: 'scripts/generate-maintenance-snapshot.mjs',
|
|
160
|
+
effect: 'read-only',
|
|
161
|
+
summary: 'Generate a recurring maintenance snapshot for benchmark, drift, evidence, installed sync, session sync, and release freshness checks.',
|
|
162
|
+
},
|
|
153
163
|
owner: {
|
|
154
164
|
route: 'scripts/audit-public-acceptance-readiness.mjs',
|
|
155
165
|
effect: 'read-only',
|
|
@@ -170,11 +180,11 @@ const commandMap = {
|
|
|
170
180
|
effect: 'read-only',
|
|
171
181
|
summary: 'Select and run focused verification according to project quality gates.',
|
|
172
182
|
},
|
|
173
|
-
learn: {
|
|
174
|
-
route: 'scripts/record-learning.mjs',
|
|
175
|
-
effect: 'read-only by default; write-with-execute for .gse/learnings.md',
|
|
176
|
-
summary: 'Record a reusable project lesson
|
|
177
|
-
},
|
|
183
|
+
learn: {
|
|
184
|
+
route: 'scripts/record-learning.mjs or scripts/audit-learning-promotion.mjs',
|
|
185
|
+
effect: 'read-only by default; write-with-execute for .gse/learnings.md or candidate-only .gse/learning-promotions.md',
|
|
186
|
+
summary: 'Record a reusable project lesson, or run promotion analysis with --promote.',
|
|
187
|
+
},
|
|
178
188
|
slice: {
|
|
179
189
|
route: 'references/spec-workflow.md',
|
|
180
190
|
effect: 'read-only',
|
|
@@ -207,8 +217,8 @@ if (execute && verb === 'init') {
|
|
|
207
217
|
const changeId = rest.find((item) => !item.startsWith('--')) ?? 'gse-change'
|
|
208
218
|
const level = rest.includes('--level') ? rest[rest.indexOf('--level') + 1] : 'standard'
|
|
209
219
|
execution = runNode('init-change.mjs', ['--target', target, '--change-id', changeId, '--level', level, '--json'])
|
|
210
|
-
} else if (verb === 'continue' || verb === 'next') {
|
|
211
|
-
execution = runNode('generate-
|
|
220
|
+
} else if (verb === 'continue' || verb === 'next') {
|
|
221
|
+
execution = runNode('generate-continue-packet.mjs', ['--root', root, '--target', target, '--json'])
|
|
212
222
|
} else if (verb === 'status') {
|
|
213
223
|
const targetHasFinalFormReport = fs.existsSync(path.join(target, 'scripts', 'generate-final-form-progress-report.mjs'))
|
|
214
224
|
&& fs.existsSync(path.join(target, 'references', 'final-readiness.md'))
|
|
@@ -238,13 +248,19 @@ if (execute && verb === 'init') {
|
|
|
238
248
|
}),
|
|
239
249
|
stderr: state ? '' : '.gse/state.json is missing or invalid',
|
|
240
250
|
}
|
|
241
|
-
} else if (verb === 'doctor' || verb === 'acceptance') {
|
|
251
|
+
} else if (verb === 'doctor' || verb === 'acceptance') {
|
|
242
252
|
const targetHasPublicAcceptanceDoctor = fs.existsSync(path.join(target, 'scripts', 'audit-public-acceptance-readiness.mjs'))
|
|
243
253
|
&& fs.existsSync(path.join(target, 'references', 'final-readiness.md'))
|
|
244
254
|
execution = targetHasPublicAcceptanceDoctor
|
|
245
255
|
? runNode('audit-public-acceptance-readiness.mjs', ['--root', target, '--json'])
|
|
246
|
-
: runNode('audit-target-project.mjs', ['--target', target, '--json'])
|
|
247
|
-
} else if (verb === '
|
|
256
|
+
: runNode('audit-target-project.mjs', ['--target', target, '--json'])
|
|
257
|
+
} else if (verb === 'repair') {
|
|
258
|
+
const repairArgs = ['--root', root, '--target', target, '--json']
|
|
259
|
+
if (execute) repairArgs.push('--write')
|
|
260
|
+
const maxRiskIndex = rest.indexOf('--max-active-risks')
|
|
261
|
+
if (maxRiskIndex !== -1) repairArgs.push('--max-active-risks', rest[maxRiskIndex + 1] || '6')
|
|
262
|
+
execution = runNode('audit-state-repair.mjs', repairArgs)
|
|
263
|
+
} else if (verb === 'owner-actions' || verb === 'owner') {
|
|
248
264
|
const targetHasPublicAcceptanceDoctor = fs.existsSync(path.join(target, 'scripts', 'audit-public-acceptance-readiness.mjs'))
|
|
249
265
|
&& fs.existsSync(path.join(target, 'references', 'final-readiness.md'))
|
|
250
266
|
if (targetHasPublicAcceptanceDoctor) {
|
|
@@ -445,7 +461,7 @@ if (execute && verb === 'init') {
|
|
|
445
461
|
stderr: 'target does not expose scripts/install-gse.mjs',
|
|
446
462
|
}
|
|
447
463
|
}
|
|
448
|
-
} else if (verb === 'public-release') {
|
|
464
|
+
} else if (verb === 'public-release') {
|
|
449
465
|
const targetHasPublicReleaseChecklist = fs.existsSync(path.join(target, 'scripts', 'generate-public-release-checklist.mjs'))
|
|
450
466
|
&& fs.existsSync(path.join(target, 'scripts', 'audit-public-release-checklist.mjs'))
|
|
451
467
|
if (targetHasPublicReleaseChecklist) {
|
|
@@ -471,9 +487,19 @@ if (execute && verb === 'init') {
|
|
|
471
487
|
error: '/gse public-release is only available for GSE skill packages that include public release checklist scripts.',
|
|
472
488
|
}),
|
|
473
489
|
stderr: 'target does not expose scripts/generate-public-release-checklist.mjs and scripts/audit-public-release-checklist.mjs',
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
} else if (verb === '
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
} else if (verb === 'maintenance') {
|
|
493
|
+
const maintenanceArgs = ['--root', target, '--target', target, '--json']
|
|
494
|
+
const installedRootIndex = rest.indexOf('--installed-root')
|
|
495
|
+
if (installedRootIndex !== -1 && rest[installedRootIndex + 1]) maintenanceArgs.push('--installed-root', rest[installedRootIndex + 1])
|
|
496
|
+
const outIndex = rest.indexOf('--out')
|
|
497
|
+
if (outIndex !== -1 && rest[outIndex + 1]) maintenanceArgs.push('--out', path.resolve(rest[outIndex + 1]))
|
|
498
|
+
if (rest.includes('--skip-release-bundle')) maintenanceArgs.push('--skip-release-bundle')
|
|
499
|
+
if (rest.includes('--package-smoke')) maintenanceArgs.push('--package-smoke')
|
|
500
|
+
if (execute) maintenanceArgs.push('--execute')
|
|
501
|
+
execution = runNode('generate-maintenance-snapshot.mjs', maintenanceArgs)
|
|
502
|
+
} else if (verb === 'audit') {
|
|
477
503
|
execution = runNode('audit-target-project.mjs', ['--target', target, '--json'])
|
|
478
504
|
} else if (verb === 'close') {
|
|
479
505
|
execution = runNode('audit-close-gate.mjs', ['--target', target, '--json'])
|
|
@@ -481,20 +507,26 @@ if (execute && verb === 'init') {
|
|
|
481
507
|
const profileIndex = rest.indexOf('--profile')
|
|
482
508
|
const profile = profileIndex === -1 ? 'lite' : (rest[profileIndex + 1] || 'lite')
|
|
483
509
|
execution = runNode('run-validation-profile.mjs', ['--target', target, '--profile', profile, '--json'])
|
|
484
|
-
} else if (verb === 'learn') {
|
|
485
|
-
|
|
486
|
-
'--target', target,
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
510
|
+
} else if (verb === 'learn') {
|
|
511
|
+
if (rest.includes('--promote')) {
|
|
512
|
+
const promotionArgs = ['--root', root, '--target', target, '--json']
|
|
513
|
+
if (execute) promotionArgs.push('--write')
|
|
514
|
+
execution = runNode('audit-learning-promotion.mjs', promotionArgs)
|
|
515
|
+
} else {
|
|
516
|
+
const learningArgs = [
|
|
517
|
+
'--target', target,
|
|
518
|
+
'--summary', readRestValue(rest, '--summary'),
|
|
519
|
+
'--trigger', readRestValue(rest, '--trigger', 'reusable lesson'),
|
|
520
|
+
'--source', readRestValue(rest, '--source', 'run-gse-command'),
|
|
521
|
+
'--promotion', readRestValue(rest, '--promotion', 'first occurrence: learning note'),
|
|
522
|
+
'--json',
|
|
523
|
+
]
|
|
524
|
+
const impact = readRestValue(rest, '--impact')
|
|
525
|
+
if (impact) learningArgs.push('--impact', impact)
|
|
526
|
+
if (execute) learningArgs.push('--execute')
|
|
527
|
+
execution = runNode('record-learning.mjs', learningArgs)
|
|
528
|
+
}
|
|
529
|
+
}
|
|
498
530
|
|
|
499
531
|
const report = {
|
|
500
532
|
root,
|
|
@@ -48,11 +48,30 @@ function run(script, commandArgs) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function commandList(selectedProfile) {
|
|
51
|
-
const common = [
|
|
52
|
-
['audit-commands.mjs', ['--root', root, '--json']],
|
|
53
|
-
['audit-
|
|
54
|
-
['audit-
|
|
55
|
-
|
|
51
|
+
const common = [
|
|
52
|
+
['audit-commands.mjs', ['--root', root, '--json']],
|
|
53
|
+
['audit-continue-preflight.mjs', ['--root', root, '--json']],
|
|
54
|
+
['audit-completion-plan-drill.mjs', ['--root', root, '--json']],
|
|
55
|
+
['audit-project-guards.mjs', ['--root', root, '--json']],
|
|
56
|
+
['backfill-evidence-levels.mjs', ['--root', target, '--json']],
|
|
57
|
+
['audit-evidence-levels.mjs', ['--root', root, '--target', target, '--json']],
|
|
58
|
+
['audit-evidence-review-queue.mjs', ['--root', root, '--target', target, '--json']],
|
|
59
|
+
['audit-ui-browser-evidence-policy.mjs', ['--root', root, '--target', target, '--json']],
|
|
60
|
+
['audit-role-dispatch-fallback.mjs', ['--root', root, '--target', target, '--json']],
|
|
61
|
+
['audit-close-gate-hardening.mjs', ['--root', root, '--json']],
|
|
62
|
+
['audit-state-repair.mjs', ['--root', root, '--target', target, '--json']],
|
|
63
|
+
['audit-learning-promotion.mjs', ['--root', root, '--target', target, '--json']],
|
|
64
|
+
['audit-learning-drift.mjs', ['--root', root, '--target', target, '--json']],
|
|
65
|
+
['audit-host-capabilities.mjs', ['--root', root, '--target', target, '--json']],
|
|
66
|
+
['audit-tool-fallback-policy.mjs', ['--root', root, '--target', target, '--json']],
|
|
67
|
+
['audit-target-hardening-drills.mjs', ['--root', root, '--json']],
|
|
68
|
+
['audit-maintenance-cadence.mjs', ['--root', root, '--json']],
|
|
69
|
+
['audit-maintenance-snapshot.mjs', ['--root', root, '--json']],
|
|
70
|
+
['audit-installed-sync.mjs', ['--root', root, '--json']],
|
|
71
|
+
['audit-session-sync.mjs', ['--root', root, '--json']],
|
|
72
|
+
['audit-command-execution.mjs', ['--root', root, '--profile', 'lite', '--json']],
|
|
73
|
+
['audit-learning-system.mjs', ['--root', root, '--json']],
|
|
74
|
+
]
|
|
56
75
|
|
|
57
76
|
const targetChecks = target === root
|
|
58
77
|
? []
|