fix: add production runtime RC release channel

Publish signed prerelease artifacts from v2.0.0-rc.* tags, bind bootstrap trust to the immutable RC tag, make missing-release errors actionable, and install the six public skills from the canonical subpath.
This commit is contained in:
Sinabina
2026-07-20 16:51:59 -07:00
parent d6ef673e4d
commit b0047cc525
84 changed files with 367 additions and 140 deletions
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Full chain --module autoplan`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `autoplan` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `autoplan` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module benchmark-models`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `benchmark-models` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `benchmark-models` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module benchmark`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `benchmark` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `benchmark` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module browse`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `browse` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `browse` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module canary`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `canary` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `canary` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$debug --mode Diagnose-only --module careful`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `careful` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill debug`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `careful` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill debug`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$review --mode Deep --module claude`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `claude` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill review`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `claude` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill review`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$review --mode Deep --module codex`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `codex` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill review`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `codex` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill review`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module context-restore`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `context-restore` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `context-restore` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module context-save`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `context-save` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `context-save` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$review --mode Security --module cso`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `cso` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill review`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `cso` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill review`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Generate --module design-consultation`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-consultation` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-consultation` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Implement --module design-html`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-html` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-html` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Implement --module design-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Explore --module design-shotgun`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-shotgun` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `design-shotgun` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module devex-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `devex-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `devex-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Generate --module diagram`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `diagram` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `diagram` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Prepare --module document-generate`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `document-generate` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `document-generate` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Prepare --module document-release`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `document-release` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `document-release` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$debug --mode Diagnose-only --module freeze`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `freeze` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill debug`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `freeze` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill debug`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Prepare --module gstack-upgrade`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `gstack-upgrade` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `gstack-upgrade` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module gstack`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `gstack` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `gstack` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$debug --mode Diagnose-only --module guard`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `guard` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill debug`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `guard` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill debug`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$review --mode Deep --module health`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `health` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill review`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `health` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill review`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$debug --mode Diagnose-only --module investigate`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `investigate` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill debug`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `investigate` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill debug`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Prepare --module ios-clean`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-clean` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-clean` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Critique --module ios-design-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-design-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-design-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$debug --mode Fix --module ios-fix`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-fix` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill debug`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-fix` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill debug`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module ios-qa`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-qa` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-qa` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Prepare --module ios-sync`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-sync` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `ios-sync` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Land --module land-and-deploy`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `land-and-deploy` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `land-and-deploy` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Prepare --module landing-report`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `landing-report` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `landing-report` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module learn`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `learn` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `learn` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Generate --module make-pdf`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `make-pdf` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `make-pdf` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module office-hours`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `office-hours` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `office-hours` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module open-gstack-browser`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `open-gstack-browser` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `open-gstack-browser` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module pair-agent`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `pair-agent` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `pair-agent` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Product --module plan-ceo-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-ceo-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-ceo-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$design --mode Critique --module plan-design-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-design-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill design`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-design-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill design`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode DX --module plan-devex-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-devex-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-devex-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Engineering --module plan-eng-review`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-eng-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-eng-review` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module plan-tune`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-tune` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `plan-tune` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module qa-only`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `qa-only` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `qa-only` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module retro`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `retro` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `retro` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module scrape`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `scrape` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `scrape` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module setup-browser-cookies`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `setup-browser-cookies` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `setup-browser-cookies` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$ship --mode Deploy --module setup-deploy`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `setup-deploy` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill ship`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `setup-deploy` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill ship`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module setup-gbrain`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `setup-gbrain` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `setup-gbrain` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$qa --mode Report --module skillify`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `skillify` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill qa`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `skillify` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill qa`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Specification --module spec`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `spec` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `spec` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$plan --mode Discovery --module sync-gbrain`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `sync-gbrain` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill plan`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `sync-gbrain` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill plan`.
+1 -1
View File
@@ -12,4 +12,4 @@ Print this replacement invocation, then dispatch to it exactly:
`$debug --mode Diagnose-only --module unfreeze`
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `unfreeze` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack --skill debug`.
Do not reproduce or summarize the retired specialist here. The canonical dispatcher must load its preserved `unfreeze` module. If that dispatcher is not installed, tell the user to install it with `npx skills add time-attack/gstack/skills --skill debug`.
+1 -1
View File
@@ -7,4 +7,4 @@ When no public-web choice is stored, present: A) Context.dev free setup (recomme
Persist only the explicit choice with `gstack context select host`, `gstack context select local-browser`, or `gstack context select none`. For Context.dev, show `gstack context options`, then use `gstack context setup` and its hidden key prompt; consent and key storage belong to the runtime, never this judgment prompt. Do not infer Context choice or consent.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack` and is never inferred from runtime state.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack/skills` and is never inferred from runtime state.
@@ -13,8 +13,12 @@ import { fileURLToPath } from "node:url";
export const BOOTSTRAP_SCHEMA_VERSION = 2;
export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
// Keep the runtime compatibility version separate from the immutable release
// channel. Release candidates carry the 2.0.0 runtime contract while letting
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
export const OFFICIAL_MANIFEST_URL =
`https://github.com/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/gstack-runtime-manifest.json`;
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
const CAPABILITY_DEPENDENCIES = Object.freeze({
browser: Object.freeze([]),
@@ -47,9 +51,9 @@ const ALLOWED_DOWNLOAD_HOSTS = new Set([
"objects.githubusercontent.com",
"release-assets.githubusercontent.com",
]);
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/`;
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/`;
const OFFICIAL_CERTIFICATE_IDENTITY =
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/v${BOOTSTRAP_RUNTIME_VERSION}`;
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/${BOOTSTRAP_RELEASE_TAG}`;
const GITHUB_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
export async function main(argv = process.argv.slice(2), options = {}) {
@@ -90,7 +94,9 @@ export async function main(argv = process.argv.slice(2), options = {}) {
);
const manifestUrl = options.manifestUrl ?? OFFICIAL_MANIFEST_URL;
assertOfficialUrl(manifestUrl, { manifest: true });
const manifest = await fetchJson(fetch_, manifestUrl);
const manifest = await fetchJson(fetch_, manifestUrl, {
official: manifestUrl === OFFICIAL_MANIFEST_URL,
});
validateManifest(manifest, target);
const home = path.resolve(parsed.home ?? process.env.GSTACK_HOME ?? path.join(os.homedir(), ".gstack"));
const reusable = await inspectReusableRuntime(home, manifest.version).catch(() => null);
@@ -300,10 +306,18 @@ function sha256File(file) {
});
}
async function fetchJson(fetch_, url) {
async function fetchJson(fetch_, url, options = {}) {
const response = await fetch_(url, { headers: { Accept: "application/json" }, redirect: "follow" });
assertFinalDownloadUrl(response.url || url);
if (!response.ok) throw bootstrapError(`Download failed with HTTP ${response.status}`, "BOOTSTRAP_DOWNLOAD_FAILED");
if (!response.ok) {
if (options.official && response.status === 404) {
throw bootstrapError(
`Official runtime release ${BOOTSTRAP_RELEASE_TAG} is not published at ${url}. No files were downloaded or installed.`,
"BOOTSTRAP_RELEASE_UNAVAILABLE",
);
}
throw bootstrapError(`Manifest download failed with HTTP ${response.status} from ${url}. No files were downloaded or installed.`, "BOOTSTRAP_DOWNLOAD_FAILED");
}
const value = await response.json();
if (!value || typeof value !== "object") throw bootstrapError("Manifest returned invalid JSON", "BOOTSTRAP_MANIFEST_INVALID");
return value;
+1 -1
View File
@@ -7,4 +7,4 @@ When no public-web choice is stored, present: A) Context.dev free setup (recomme
Persist only the explicit choice with `gstack context select host`, `gstack context select local-browser`, or `gstack context select none`. For Context.dev, show `gstack context options`, then use `gstack context setup` and its hidden key prompt; consent and key storage belong to the runtime, never this judgment prompt. Do not infer Context choice or consent.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack` and is never inferred from runtime state.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack/skills` and is never inferred from runtime state.
@@ -13,8 +13,12 @@ import { fileURLToPath } from "node:url";
export const BOOTSTRAP_SCHEMA_VERSION = 2;
export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
// Keep the runtime compatibility version separate from the immutable release
// channel. Release candidates carry the 2.0.0 runtime contract while letting
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
export const OFFICIAL_MANIFEST_URL =
`https://github.com/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/gstack-runtime-manifest.json`;
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
const CAPABILITY_DEPENDENCIES = Object.freeze({
browser: Object.freeze([]),
@@ -47,9 +51,9 @@ const ALLOWED_DOWNLOAD_HOSTS = new Set([
"objects.githubusercontent.com",
"release-assets.githubusercontent.com",
]);
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/`;
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/`;
const OFFICIAL_CERTIFICATE_IDENTITY =
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/v${BOOTSTRAP_RUNTIME_VERSION}`;
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/${BOOTSTRAP_RELEASE_TAG}`;
const GITHUB_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
export async function main(argv = process.argv.slice(2), options = {}) {
@@ -90,7 +94,9 @@ export async function main(argv = process.argv.slice(2), options = {}) {
);
const manifestUrl = options.manifestUrl ?? OFFICIAL_MANIFEST_URL;
assertOfficialUrl(manifestUrl, { manifest: true });
const manifest = await fetchJson(fetch_, manifestUrl);
const manifest = await fetchJson(fetch_, manifestUrl, {
official: manifestUrl === OFFICIAL_MANIFEST_URL,
});
validateManifest(manifest, target);
const home = path.resolve(parsed.home ?? process.env.GSTACK_HOME ?? path.join(os.homedir(), ".gstack"));
const reusable = await inspectReusableRuntime(home, manifest.version).catch(() => null);
@@ -300,10 +306,18 @@ function sha256File(file) {
});
}
async function fetchJson(fetch_, url) {
async function fetchJson(fetch_, url, options = {}) {
const response = await fetch_(url, { headers: { Accept: "application/json" }, redirect: "follow" });
assertFinalDownloadUrl(response.url || url);
if (!response.ok) throw bootstrapError(`Download failed with HTTP ${response.status}`, "BOOTSTRAP_DOWNLOAD_FAILED");
if (!response.ok) {
if (options.official && response.status === 404) {
throw bootstrapError(
`Official runtime release ${BOOTSTRAP_RELEASE_TAG} is not published at ${url}. No files were downloaded or installed.`,
"BOOTSTRAP_RELEASE_UNAVAILABLE",
);
}
throw bootstrapError(`Manifest download failed with HTTP ${response.status} from ${url}. No files were downloaded or installed.`, "BOOTSTRAP_DOWNLOAD_FAILED");
}
const value = await response.json();
if (!value || typeof value !== "object") throw bootstrapError("Manifest returned invalid JSON", "BOOTSTRAP_MANIFEST_INVALID");
return value;
+1 -1
View File
@@ -7,4 +7,4 @@ When no public-web choice is stored, present: A) Context.dev free setup (recomme
Persist only the explicit choice with `gstack context select host`, `gstack context select local-browser`, or `gstack context select none`. For Context.dev, show `gstack context options`, then use `gstack context setup` and its hidden key prompt; consent and key storage belong to the runtime, never this judgment prompt. Do not infer Context choice or consent.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack` and is never inferred from runtime state.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack/skills` and is never inferred from runtime state.
@@ -13,8 +13,12 @@ import { fileURLToPath } from "node:url";
export const BOOTSTRAP_SCHEMA_VERSION = 2;
export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
// Keep the runtime compatibility version separate from the immutable release
// channel. Release candidates carry the 2.0.0 runtime contract while letting
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
export const OFFICIAL_MANIFEST_URL =
`https://github.com/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/gstack-runtime-manifest.json`;
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
const CAPABILITY_DEPENDENCIES = Object.freeze({
browser: Object.freeze([]),
@@ -47,9 +51,9 @@ const ALLOWED_DOWNLOAD_HOSTS = new Set([
"objects.githubusercontent.com",
"release-assets.githubusercontent.com",
]);
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/`;
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/`;
const OFFICIAL_CERTIFICATE_IDENTITY =
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/v${BOOTSTRAP_RUNTIME_VERSION}`;
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/${BOOTSTRAP_RELEASE_TAG}`;
const GITHUB_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
export async function main(argv = process.argv.slice(2), options = {}) {
@@ -90,7 +94,9 @@ export async function main(argv = process.argv.slice(2), options = {}) {
);
const manifestUrl = options.manifestUrl ?? OFFICIAL_MANIFEST_URL;
assertOfficialUrl(manifestUrl, { manifest: true });
const manifest = await fetchJson(fetch_, manifestUrl);
const manifest = await fetchJson(fetch_, manifestUrl, {
official: manifestUrl === OFFICIAL_MANIFEST_URL,
});
validateManifest(manifest, target);
const home = path.resolve(parsed.home ?? process.env.GSTACK_HOME ?? path.join(os.homedir(), ".gstack"));
const reusable = await inspectReusableRuntime(home, manifest.version).catch(() => null);
@@ -300,10 +306,18 @@ function sha256File(file) {
});
}
async function fetchJson(fetch_, url) {
async function fetchJson(fetch_, url, options = {}) {
const response = await fetch_(url, { headers: { Accept: "application/json" }, redirect: "follow" });
assertFinalDownloadUrl(response.url || url);
if (!response.ok) throw bootstrapError(`Download failed with HTTP ${response.status}`, "BOOTSTRAP_DOWNLOAD_FAILED");
if (!response.ok) {
if (options.official && response.status === 404) {
throw bootstrapError(
`Official runtime release ${BOOTSTRAP_RELEASE_TAG} is not published at ${url}. No files were downloaded or installed.`,
"BOOTSTRAP_RELEASE_UNAVAILABLE",
);
}
throw bootstrapError(`Manifest download failed with HTTP ${response.status} from ${url}. No files were downloaded or installed.`, "BOOTSTRAP_DOWNLOAD_FAILED");
}
const value = await response.json();
if (!value || typeof value !== "object") throw bootstrapError("Manifest returned invalid JSON", "BOOTSTRAP_MANIFEST_INVALID");
return value;
+1 -1
View File
@@ -7,4 +7,4 @@ When no public-web choice is stored, present: A) Context.dev free setup (recomme
Persist only the explicit choice with `gstack context select host`, `gstack context select local-browser`, or `gstack context select none`. For Context.dev, show `gstack context options`, then use `gstack context setup` and its hidden key prompt; consent and key storage belong to the runtime, never this judgment prompt. Do not infer Context choice or consent.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack` and is never inferred from runtime state.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack/skills` and is never inferred from runtime state.
@@ -13,8 +13,12 @@ import { fileURLToPath } from "node:url";
export const BOOTSTRAP_SCHEMA_VERSION = 2;
export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
// Keep the runtime compatibility version separate from the immutable release
// channel. Release candidates carry the 2.0.0 runtime contract while letting
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
export const OFFICIAL_MANIFEST_URL =
`https://github.com/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/gstack-runtime-manifest.json`;
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
const CAPABILITY_DEPENDENCIES = Object.freeze({
browser: Object.freeze([]),
@@ -47,9 +51,9 @@ const ALLOWED_DOWNLOAD_HOSTS = new Set([
"objects.githubusercontent.com",
"release-assets.githubusercontent.com",
]);
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/`;
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/`;
const OFFICIAL_CERTIFICATE_IDENTITY =
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/v${BOOTSTRAP_RUNTIME_VERSION}`;
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/${BOOTSTRAP_RELEASE_TAG}`;
const GITHUB_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
export async function main(argv = process.argv.slice(2), options = {}) {
@@ -90,7 +94,9 @@ export async function main(argv = process.argv.slice(2), options = {}) {
);
const manifestUrl = options.manifestUrl ?? OFFICIAL_MANIFEST_URL;
assertOfficialUrl(manifestUrl, { manifest: true });
const manifest = await fetchJson(fetch_, manifestUrl);
const manifest = await fetchJson(fetch_, manifestUrl, {
official: manifestUrl === OFFICIAL_MANIFEST_URL,
});
validateManifest(manifest, target);
const home = path.resolve(parsed.home ?? process.env.GSTACK_HOME ?? path.join(os.homedir(), ".gstack"));
const reusable = await inspectReusableRuntime(home, manifest.version).catch(() => null);
@@ -300,10 +306,18 @@ function sha256File(file) {
});
}
async function fetchJson(fetch_, url) {
async function fetchJson(fetch_, url, options = {}) {
const response = await fetch_(url, { headers: { Accept: "application/json" }, redirect: "follow" });
assertFinalDownloadUrl(response.url || url);
if (!response.ok) throw bootstrapError(`Download failed with HTTP ${response.status}`, "BOOTSTRAP_DOWNLOAD_FAILED");
if (!response.ok) {
if (options.official && response.status === 404) {
throw bootstrapError(
`Official runtime release ${BOOTSTRAP_RELEASE_TAG} is not published at ${url}. No files were downloaded or installed.`,
"BOOTSTRAP_RELEASE_UNAVAILABLE",
);
}
throw bootstrapError(`Manifest download failed with HTTP ${response.status} from ${url}. No files were downloaded or installed.`, "BOOTSTRAP_DOWNLOAD_FAILED");
}
const value = await response.json();
if (!value || typeof value !== "object") throw bootstrapError("Manifest returned invalid JSON", "BOOTSTRAP_MANIFEST_INVALID");
return value;
+1 -1
View File
@@ -7,4 +7,4 @@ When no public-web choice is stored, present: A) Context.dev free setup (recomme
Persist only the explicit choice with `gstack context select host`, `gstack context select local-browser`, or `gstack context select none`. For Context.dev, show `gstack context options`, then use `gstack context setup` and its hidden key prompt; consent and key storage belong to the runtime, never this judgment prompt. Do not infer Context choice or consent.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack` and is never inferred from runtime state.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack/skills` and is never inferred from runtime state.
@@ -13,8 +13,12 @@ import { fileURLToPath } from "node:url";
export const BOOTSTRAP_SCHEMA_VERSION = 2;
export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
// Keep the runtime compatibility version separate from the immutable release
// channel. Release candidates carry the 2.0.0 runtime contract while letting
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
export const OFFICIAL_MANIFEST_URL =
`https://github.com/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/gstack-runtime-manifest.json`;
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
const CAPABILITY_DEPENDENCIES = Object.freeze({
browser: Object.freeze([]),
@@ -47,9 +51,9 @@ const ALLOWED_DOWNLOAD_HOSTS = new Set([
"objects.githubusercontent.com",
"release-assets.githubusercontent.com",
]);
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/`;
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/`;
const OFFICIAL_CERTIFICATE_IDENTITY =
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/v${BOOTSTRAP_RUNTIME_VERSION}`;
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/${BOOTSTRAP_RELEASE_TAG}`;
const GITHUB_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
export async function main(argv = process.argv.slice(2), options = {}) {
@@ -90,7 +94,9 @@ export async function main(argv = process.argv.slice(2), options = {}) {
);
const manifestUrl = options.manifestUrl ?? OFFICIAL_MANIFEST_URL;
assertOfficialUrl(manifestUrl, { manifest: true });
const manifest = await fetchJson(fetch_, manifestUrl);
const manifest = await fetchJson(fetch_, manifestUrl, {
official: manifestUrl === OFFICIAL_MANIFEST_URL,
});
validateManifest(manifest, target);
const home = path.resolve(parsed.home ?? process.env.GSTACK_HOME ?? path.join(os.homedir(), ".gstack"));
const reusable = await inspectReusableRuntime(home, manifest.version).catch(() => null);
@@ -300,10 +306,18 @@ function sha256File(file) {
});
}
async function fetchJson(fetch_, url) {
async function fetchJson(fetch_, url, options = {}) {
const response = await fetch_(url, { headers: { Accept: "application/json" }, redirect: "follow" });
assertFinalDownloadUrl(response.url || url);
if (!response.ok) throw bootstrapError(`Download failed with HTTP ${response.status}`, "BOOTSTRAP_DOWNLOAD_FAILED");
if (!response.ok) {
if (options.official && response.status === 404) {
throw bootstrapError(
`Official runtime release ${BOOTSTRAP_RELEASE_TAG} is not published at ${url}. No files were downloaded or installed.`,
"BOOTSTRAP_RELEASE_UNAVAILABLE",
);
}
throw bootstrapError(`Manifest download failed with HTTP ${response.status} from ${url}. No files were downloaded or installed.`, "BOOTSTRAP_DOWNLOAD_FAILED");
}
const value = await response.json();
if (!value || typeof value !== "object") throw bootstrapError("Manifest returned invalid JSON", "BOOTSTRAP_MANIFEST_INVALID");
return value;
+1 -1
View File
@@ -7,4 +7,4 @@ When no public-web choice is stored, present: A) Context.dev free setup (recomme
Persist only the explicit choice with `gstack context select host`, `gstack context select local-browser`, or `gstack context select none`. For Context.dev, show `gstack context options`, then use `gstack context setup` and its hidden key prompt; consent and key storage belong to the runtime, never this judgment prompt. Do not infer Context choice or consent.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack` and is never inferred from runtime state.
Capability-dependent work follows `references/RUNTIME.md`. Pure judgment never requires the runtime. Skill placement remains owned by `npx skills add time-attack/gstack/skills` and is never inferred from runtime state.
@@ -1,5 +1,5 @@
<!-- GENERATED by scripts/gstack2/generate-skill-tree.ts; do not edit. -->
<!-- GSTACK2_PROVENANCE source=gstack-upgrade/SKILL.md.tmpl base=bb57306d98c97011b0919c6132705a15b1579781 blob=5402a1da3c857cbf50668085fce53172b72bba0d baseline_render_sha256=609971d414a31d49180e2630bd79a10b8d09085203f7e48c03d2ca69c2ef129a ported_render_sha256=a913cf77f76c4d68c576a06190b498e3d8d3b60b85498a68f173b23a7f800828 disposition=DUPLICATE_INFRASTRUCTURE -->
<!-- GSTACK2_PROVENANCE source=gstack-upgrade/SKILL.md.tmpl base=bb57306d98c97011b0919c6132705a15b1579781 blob=5402a1da3c857cbf50668085fce53172b72bba0d baseline_render_sha256=609971d414a31d49180e2630bd79a10b8d09085203f7e48c03d2ca69c2ef129a ported_render_sha256=2c8cf9e505b7da27730bf646a33ee38e8092259f3335a524c71e57ba5b602541 disposition=DUPLICATE_INFRASTRUCTURE -->
<!-- GSTACK2_ROUTING replacement=$ship --mode Prepare --module gstack-upgrade visibility=internal depth=standard mutation=installation web=none -->
<!-- GSTACK2_LEGACY_BODY_START source=gstack-upgrade -->
@@ -7,7 +7,7 @@
The 1.x host-directory detector, vendored-copy synchronizer, and destructive Git replacement blocks were duplicated installation infrastructure. GStack 2 delegates skill placement and updates to the standard Agent Skills installer and manages the optional shared runtime atomically.
- Update selected skills with `npx skills add time-attack/gstack` using the user's existing project/global choice. Never infer or enroll a host.
- Update selected skills with `npx skills add time-attack/gstack/skills` using the user's existing project/global choice. Never infer or enroll a host.
- Upgrade a complete local runtime package with `gstack upgrade --source <complete-gstack-package> --version <version>`.
- Roll back the runtime with `gstack upgrade --rollback`.
- Run `gstack doctor` after either operation.
@@ -13,8 +13,12 @@ import { fileURLToPath } from "node:url";
export const BOOTSTRAP_SCHEMA_VERSION = 2;
export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
// Keep the runtime compatibility version separate from the immutable release
// channel. Release candidates carry the 2.0.0 runtime contract while letting
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
export const OFFICIAL_MANIFEST_URL =
`https://github.com/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/gstack-runtime-manifest.json`;
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
const CAPABILITY_DEPENDENCIES = Object.freeze({
browser: Object.freeze([]),
@@ -47,9 +51,9 @@ const ALLOWED_DOWNLOAD_HOSTS = new Set([
"objects.githubusercontent.com",
"release-assets.githubusercontent.com",
]);
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/v${BOOTSTRAP_RUNTIME_VERSION}/`;
const OFFICIAL_RELEASE_PREFIX = `/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/`;
const OFFICIAL_CERTIFICATE_IDENTITY =
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/v${BOOTSTRAP_RUNTIME_VERSION}`;
`https://github.com/time-attack/gstack/.github/workflows/release-artifacts.yml@refs/tags/${BOOTSTRAP_RELEASE_TAG}`;
const GITHUB_OIDC_ISSUER = "https://token.actions.githubusercontent.com";
export async function main(argv = process.argv.slice(2), options = {}) {
@@ -90,7 +94,9 @@ export async function main(argv = process.argv.slice(2), options = {}) {
);
const manifestUrl = options.manifestUrl ?? OFFICIAL_MANIFEST_URL;
assertOfficialUrl(manifestUrl, { manifest: true });
const manifest = await fetchJson(fetch_, manifestUrl);
const manifest = await fetchJson(fetch_, manifestUrl, {
official: manifestUrl === OFFICIAL_MANIFEST_URL,
});
validateManifest(manifest, target);
const home = path.resolve(parsed.home ?? process.env.GSTACK_HOME ?? path.join(os.homedir(), ".gstack"));
const reusable = await inspectReusableRuntime(home, manifest.version).catch(() => null);
@@ -300,10 +306,18 @@ function sha256File(file) {
});
}
async function fetchJson(fetch_, url) {
async function fetchJson(fetch_, url, options = {}) {
const response = await fetch_(url, { headers: { Accept: "application/json" }, redirect: "follow" });
assertFinalDownloadUrl(response.url || url);
if (!response.ok) throw bootstrapError(`Download failed with HTTP ${response.status}`, "BOOTSTRAP_DOWNLOAD_FAILED");
if (!response.ok) {
if (options.official && response.status === 404) {
throw bootstrapError(
`Official runtime release ${BOOTSTRAP_RELEASE_TAG} is not published at ${url}. No files were downloaded or installed.`,
"BOOTSTRAP_RELEASE_UNAVAILABLE",
);
}
throw bootstrapError(`Manifest download failed with HTTP ${response.status} from ${url}. No files were downloaded or installed.`, "BOOTSTRAP_DOWNLOAD_FAILED");
}
const value = await response.json();
if (!value || typeof value !== "object") throw bootstrapError("Manifest returned invalid JSON", "BOOTSTRAP_MANIFEST_INVALID");
return value;