document gstack 2 evidence and blocked gates

This commit is contained in:
Sinabina
2026-07-17 11:08:51 -07:00
parent 9919c4cdd3
commit 7d760ff1d1
19 changed files with 10026 additions and 208 deletions
+266
View File
@@ -0,0 +1,266 @@
# GStack 2 architecture
Status: implemented in the candidate branch, with release evidence still
pending. This document describes the candidate; it is not a 2.0 release claim.
The authoritative gate state is [STATUS.md](./STATUS.md).
## Product boundary
GStack 2 is an engineering judgment layer with exactly six public skills:
```text
plan -> design -> qa -> debug -> review -> ship
```
This is a navigation surface, not a linear workflow and not a compression of
specialists into generic prompts. Each dispatcher selects a mode from
structured stage, surface, artifact, mutation-authority, evidence, and deploy
signals. It prints the target, mode, depth, mutation boundary, active modules,
skipped modules, and web-context choice before work. It then loads only the
selected preserved module.
The canonical tree is:
```text
skills/
plan|design|qa|debug|review|ship/
SKILL.md thin dispatcher
agents/openai.yaml optional host presentation metadata
references/
legacy/*.md lazily loaded preserved specialists
ASSETS.md relocated-asset index
COMPATIBILITY.md old-name routes within this tree
assets/ copied assets with pinned blob evidence
compat/*.md internal aliases, never default skills
evals/parity/ contracts, scenarios, regressions, manifest
```
`scripts/gstack2/generate-skill-tree.ts` mechanically renders 55 pinned legacy
modules, inlines 16 carved sections, and carries 78 assets. The generator
records source Git blob IDs and normalized render hashes. It adds only reviewed
upstream bug-fix overlays, each with a PR link, stable anchor, and regression fixture. The parity
runner checks nine behavioral dimensions: question order, pressure, smart
skips, STOP/approval gates, evidence, artifacts, mutation, exit behavior, and
voice.
The public dispatcher cannot substitute for its selected module. Its
completeness invariant explicitly requires reading that module in full. See
[JUDGMENT-PROVENANCE.json](./JUDGMENT-PROVENANCE.json),
[JUDGMENT-PARITY.md](./JUDGMENT-PARITY.md), and
[SKILL-MIGRATION.md](./SKILL-MIGRATION.md).
The reproducible semantic layer adds 295 checks across 14 suites, 15
executions, 15 dimensions, 16 sections, and nine authority-policy unit cases.
Exact source preservation remains the primary oracle. These are deterministic
policy checks, not behavioral-adversarial proof. Paid live-model comparisons
are supplemental; the currently retained semantic samples are regressions and
do not support a release-pass claim.
The separate installed-host adversarial lane also has no passing live result:
v1 failed; immutable v2 failed despite QA passing because its classifier
produced false negatives for debug, review, and ship; and v3 has 18 pass / 0
fail / 111 assertions offline but has not run live and has no artifact. See the
[installed-host evidence overview](../../evals/host-adversarial/README.md).
## Specialist modes
The primary modes are summarized here; internal compatibility modes are in the
migration map.
| Skill | Public top-level modes and preserved refinements |
|---|---|
| `/plan` | exactly **Discovery, Product, Engineering, DX, Specification, Full chain**, refined to office-hours, CEO, engineering, DX, spec, or autoplan judgment |
| `/design` | **Explore, Generate, Critique, Implement**, refined to consultation, alternatives, HTML/CSS, plan/live review, physical-iOS HIG, diagram, or PDF |
| `/qa` | **Report** or **Fix**, refined by web, physical-iOS, DX, performance, or canary surface |
| `/debug` | **Diagnose-only** or **Fix**, refined to general investigation or the physical-iOS fix loop |
| `/review` | **Normal, Security, Performance, Deep**, with health and genuinely independent outside voices selected only when applicable |
| `/ship` | **Prepare, Land, Deploy, Monitor, Resume**, refined to PR, queue, docs, deploy setup, land/deploy, canary, or context restoration modules |
Old commands are opt-in aliases for the compatibility window. An alias points
to one exact module, prints the replacement invocation, and carries no copied
judgment. This prevents an alias from drifting away from the canonical source.
## Installation boundary
The standard Agent Skills tree is the unit of distribution:
```bash
npx skills add time-attack/gstack
```
The installer—not GStack—owns host detection, project/global scope, destination
paths, selected-skill installation, copies versus symlinks, updates, and
removal. GStack does not silently enroll a detected host. The former
host-placement behavior of `./setup` and ten-host generated trees is historical
compatibility/development machinery, not the 2.0 installation architecture;
the current `./setup` installs only the optional runtime described below.
The standards installer matrix passed 470/470 checks with CLI 1.5.19. It
verified project/global copies for Claude Code, Codex, Cursor, Pi, OpenClaw, and
GitHub Copilot plus selected-skill and opt-in compatibility-alias cases,
removal, spaces, source symlink, copy mode, and canonical hashes across 16
installs and two removals. The committed artifact is
[`evals/installation/install-matrix.json`](../../evals/installation/install-matrix.json).
This is installer-layer verification; it is Markdown-only placement and does
not prove a passing live installed-host judgment run.
Pure judgment is Markdown and works when the optional runtime is absent. A
capability-dependent module performs one runtime check and must degrade with an
actionable setup choice rather than make the six skills undiscoverable.
## Optional host-neutral runtime
`bin/gstack` calls a Node-built-ins runtime under `runtime/`. It does not own
skill placement and is installed once per user, not once per host. The
host-neutral `./setup` wrapper installs only this runtime/capability bundle. It
stages an explicit allowlist, rejects internal symlinks/path escapes,
hash-validates files, smoke-tests the CLI, atomically activates the version,
and writes stable POSIX/Windows launchers plus an uninstall manifest under
`$GSTACK_HOME`. Runtime capability builds use a dedicated target that does not
regenerate skills or require repository history; Windows targets use `.exe`
suffixes and Darwin-only iOS artifacts are omitted elsewhere. Its public
operations are setup, doctor, config, state
inspection/resume, Context.dev status/options/select/setup/smoke, cleanup,
upgrade/rollback, and uninstall.
The current managed-bundle audit records 107 components, 1,830 files,
459,056,031 bytes, and 50 launchers. Setup installs frozen production-only
dependencies; the development-only Claude Agent SDK is excluded. The
Sharp/ngrok dependency closure is included. The Hugging Face sidecar is
excluded and its package is development-only, so setup installs neither its
inference runtime nor model weights and reports the L4 capability unavailable.
A clean Linux arm64 runtime smoke installed only production dependencies with
the development SDK absent, completed a local-browser journey and Sharp
full-page screenshot, and uninstalled while preserving state. This is Linux
container evidence, not native Windows evidence.
The authoritative root is `$GSTACK_HOME` or `~/.gstack`; host-specific variables
do not redirect it. Paths are passed as values and never emitted for shell
evaluation. The state shape is human-readable:
```text
~/.gstack/
config.json
secrets.json mode 0600 where supported
migration.json
locks/
tmp/
versions/current.json
projects/<repo+worktree-id>/
state.json
timeline.jsonl
decisions.jsonl
evidence/
artifacts/
reviews/
checkpoints/
```
Repository identity is shared across linked worktrees; worktree identity is
stable and distinct. Their combination selects project state, preventing one
worktree from resuming another's run. Updates use atomic replace plus lock
leases. External actions are durably claimed before execution. A process death
after a claim marks the action uncertain on resume and refuses automatic
repetition until explicitly reconciled.
Migrations are forward-only and idempotent. Runtime upgrades copy into a staged
version, verify, switch an atomic pointer, and retain the last known good
version. A failed health check or interrupted pending pointer restores the
previous active version. This is bounded release plumbing, not a distributed
workflow engine.
## Context.dev boundary
Context.dev is the only new external service and handles only public web
content. `network.mode` and `network.consent` both start off. The client checks
both before DNS or fetch. It rejects credentials in URLs, localhost, local and
private names, private/link-local IP literals, cloud-metadata targets, and a
public hostname that resolves to a private address.
Supported candidate operations use the documented scrape-Markdown,
scrape-HTML, crawl, sitemap, and screenshot endpoints. The current general
search endpoint is deprecated, so `search()` returns a typed unsupported error
without a network request. A workflow must instead use an explicitly selected
host-native public search, the local browser, or no web research and label the
result unverified. It must not invent a replacement API.
`gstack context options` presents those choices. `gstack context select
host|local-browser|none` persists the explicit fallback while keeping
Context.dev consent false; `context setup` is the only path that selects
Context.dev and persists export consent with the protected key.
The deterministic Context contract is green at 22 pass / 0 fail and 139
assertions. No verified key was available for a live provider smoke, so provider
behavior remains blocked rather than inferred from the contract suite.
See [CONTEXT-DEV.md](./CONTEXT-DEV.md) and [PRIVACY.md](./PRIVACY.md).
## Local browser and physical iOS
The existing Chromium/Playwright daemon remains the sole browser-automation
backend. It binds loopback, requires bearer authorization for mutations,
preserves authenticated sessions locally, denies tunnel commands by default,
and treats page/console/network content as untrusted. Context.dev complements
public research; it does not replace browser QA. No cloud browser was added.
The existing DebugBridge/CoreDevice harness remains the sole physical-iOS
backend. The candidate distinguishes hardware UDID from CoreDevice UUID,
returns bounded 504 responses for a suspended app, asserts the expected bundle
around coordinate mutations, preserves typed snapshot/mutation/restoration,
and keeps bridge symbols debug-only. Device signing and provisioning are
remediable setup gates, not product failures. A live signed-device pass is
still required before release. Current preflight evidence is 9 pass / 0 fail /
1 deploy skip and 29 assertions. The direct smoke returned
`signing_unavailable` / `setup_gate`; no app was installed and no pass artifact
was written.
PDF rendering and Mermaid/Excalidraw remain internal capabilities. GStack does
not add Typst, hosted document rendering, alternate diagram services, local
image weights, ComfyUI, or a GPU runtime.
## Infrastructure-defect disposition
“Contained” means the defect is outside the canonical GStack 2 path, not that
legacy code was proven bug-free. “Implemented” names candidate code. “Pending”
means the replacement still lacks its required release evidence.
| # | Legacy defect | GStack 2 disposition / replacement | Replacement evidence |
|---:|---|---|---|
| 1 | Ten registered hosts; setup fully installs five | **Contained:** placement is delegated to the standard installer. | 470/470 checks across six hosts, 16 installs, two removals, project/global scopes, and selections. Passing live v3/host UI launch remains separate. |
| 2 | Kiro rewrites Codex output | **Contained:** one canonical standards tree; no Kiro rewrite in the 2.0 path. | Six-host matrix installs byte-matching canonical copies without host rewrites. |
| 3 | Gitignored external trees defeat freshness CI | **Implemented:** canonical `skills/`, `compat/`, and parity fixtures are committed. | 4,681 parity checks plus installed-file hash equality. |
| 4 | External `--dry-run` mutates files | **Contained:** external host generation/dry-run is not used for 2.0 distribution. | Canonical regeneration/parity check exists; a non-mutating canonical check mode is not yet present. |
| 5 | Single-host generation failures only warn | **Contained:** no per-host generation in the canonical path; canonical generation throws on failure. | Generator/parity suite and final build rerun are green. |
| 6 | Setup continues after failed generation | **Implemented/contained:** standard installer handles skills; runtime setup fails before activation and preserves last known good. | Failure tests plus the real two-version default lifecycle and rollback pass. |
| 7 | Removed/renamed generated skills are not pruned | **Implemented for canonical references:** regeneration removes each reference/asset tree and parity corpus before writing the fixed six. | Parity inventory test; stale-public-directory fixture pending. |
| 8 | Freshness misses generator/design/PDF changes | **Implemented:** build invokes canonical generation; parity hashes source, sections, assets, and fixtures. | Design is green at 101/0/381, PDF at 189/0/398, and the uninterrupted broad singleton run is green across all 383 files. |
| 9 | State paths bypass canonical resolver | **Implemented:** `runtime/paths.js` is authoritative for 2.0 runtime state. | `gstack2-runtime-core.test.ts`. |
| 10 | Shell-evaluated path assignments are unsafe | **Implemented:** runtime paths are JavaScript values; shell-looking input remains literal. | Core test covers spaces, `$()`, semicolon, and `$HOME` text. |
| 11 | Relinking omits carved section links | **Contained:** no per-section host relinking; sections are inlined into pinned modules. | Parity checks all 16 sections. |
| 12 | External preambles omit PDF paths | **Contained:** PDF is indexed as an internal design capability/assets route, not copied host preamble prose. | Asset parity plus 189/0/398 PDF strict tests and a visually checked four-page live render pass. |
| 13 | Production model benchmark imports test helpers | **Implemented:** the runner, pricing, providers, and optional judge live under `lib/model-benchmark/`; the production CLI imports only production modules. | `benchmark-production-boundary.test.ts` rejects imports from `test/` across `bin/` and `lib/`; focused runner and CLI tests exercise the relocated implementation. |
| 14 | Default tests omit `design/test` | **Implemented:** package default and free-test roots include `design/test`. | Design is green at 101/0/381 and is included in the uninterrupted 383-file broad pass. |
| 15 | Default tests omit `ios-qa/daemon/test` | **Implemented:** package default and free-test roots include the daemon tests. | Focused daemon run: 95 pass / 0 fail / 229 assertions; daemon tests are also included in the uninterrupted broad pass. |
| 16 | Host setup contradicts config-driven claim | **Contained:** host setup is no longer a 2.0 responsibility. | Standard installer CLI 1.5.19 passed all six configured host targets. |
| 17 | Host-generated judgment copies drift | **Implemented:** one canonical module corpus with source-blob/render hashes. | 4,681 parity checks and installed-copy hashes pass. |
| 18 | Updating one host leaves another stale | **Contained:** one tree is installed by each host's standard installer. | Project/global copies across six hosts matched canonical hashes; remote update flow remains installer-owned. |
| 19 | State identity crosses worktrees | **Implemented:** repo plus stable worktree identity selects state. | Linked-worktree core test passes. |
| 20 | Partial ship failures are not reliably idempotent | **Implemented at runtime primitive:** claimed effects become uncertain and are not automatically repeated. | Crash/resume and completed-effect tests pass. End-to-end ship resume remains pending. |
| 21 | Parser failures become empty success | **Implemented in iOS device discovery:** parse/tool failures are typed errors. | `tunnel-bootstrap.test.ts` malformed-JSON regression passes in the focused daemon suite. |
| 22 | Setup failures become product failures | **Partly implemented:** iOS discovery/setup categories and runtime doctor return actionable setup state. | Automated categories exist; live signing/provisioning gate pending. |
| 23 | Runtime network activity is not obvious | **Implemented for Context runtime:** selection, mode, and consent are explicit; status/doctor report them; zero lookup/fetch before Context selection+consent. | Context contract: 22 pass / 0 fail / 139 assertions, including persisted non-export fallbacks. Verified-key live smoke remains blocked. |
| 24 | Context restore selects another worktree | **Implemented for canonical state resume:** current repo+worktree project ID scopes inspection/resume. | Linked-worktree identity test passes; compatibility end-to-end restore test pending. |
| 25 | Preambles repeat large sections in every skill | **Implemented structurally:** six thin lazy dispatchers share infrastructure and load one preserved module on demand. | Current generated six-name/description catalog is 982 characters, about 246 token-equivalents versus the correctly parsed baseline of about 1,100 (77.6% lower). Re-measure if frontmatter changes. |
No defect in this table should be closed from prose alone. The final claim must
link its reproduction and passing test in [TEST-EVIDENCE.md](./TEST-EVIDENCE.md).
## Explicit non-architecture
GStack 2 does not contain a generic provider or plugin marketplace, distributed
workflow engine, mandatory cloud service, cloud browser/device farm,
Browserbase/Browser Use/Agent Device/Appium/XCUITest driver layer, mandatory
telemetry, mandatory GBrain/Docker/image generation, local model weights,
ComfyUI, or a new runtime database. Existing development-only dependencies are
not promoted into user setup or the GStack 2 architecture.
+162
View File
@@ -0,0 +1,162 @@
# Context.dev setup and operation
Context.dev is the only newly authorized external service in GStack 2. It is
optional and restricted to public web context. The current automated contract
is green at 22 pass / 0 fail and 139 assertions. No verified account key was
available, so the live smoke has not run and provider behavior remains
unverified; see [TEST-EVIDENCE.md](./TEST-EVIDENCE.md).
## Choose a public-web mode
When a workflow needs public research and no choice is stored, it must offer:
```text
A) Set up Context.dev free (recommended)
B) Use this host's built-in public web search, if available
C) Use GStack's local browser
D) Continue without web research
```
Declining Context.dev is not a workflow failure. Persist only the explicit
choice. Never infer consent from a previous browser navigation, host login,
environment variable, or legacy configuration.
The runtime exposes the same choice without requiring a prompt:
```bash
gstack context options
gstack context select host
gstack context select local-browser
gstack context select none
```
`select` persists exactly one choice in `config.json`. The three fallback
choices keep `network.consent` false and never configure Context.dev export.
`context status` reports the stored selection. If `$GSTACK_HOME/bin` is not on
`PATH`, invoke the default launcher as `~/.gstack/bin/gstack`.
## Free-tier caveat
Provider limits can change. At the 2026-07-16 implementation check, the
[Context.dev pricing page](https://www.context.dev/pricing) described 500
monthly credits for a work-email signup, 250 for a personal/free-email signup,
no credit card, and ordinary page scraping at one credit. Email verification
is required, and provider responses for unverified or exhausted accounts may
not use intuitive HTTP status codes. Verify current terms before promising a
quota or cost; GStack maps the response body as well as status.
GStack never opts into paid usage or surprise spending. When credits are
exhausted it explains the condition and offers a fallback.
## Setup
1. Open [Context.dev agent authentication](https://www.context.dev/auth.md) or
[signup](https://www.context.dev/signup).
2. Create the account and complete email verification.
3. Install the optional host-neutral runtime if the active mode needs it.
4. Review the options, then run the interactive Context.dev setup:
```bash
gstack context options
gstack context setup
```
5. Read the egress prompt. Type `yes` only if public-page requests to
Context.dev are acceptable.
6. Enter the API key at the hidden prompt. Do not paste it into chat, a command
argument, shell history, a project `.env`, or repository file.
7. Check status:
```bash
gstack context status
gstack doctor
```
8. Run one public-page smoke test:
```bash
gstack context smoke --url https://www.context.dev
```
For a non-interactive controlled environment, `--consent` is required and the
key must come from protected stdin or `CONTEXT_DEV_API_KEY`; the CLI rejects
key-looking command-line arguments. Interactive hidden input is preferred.
The runtime stores the explicit selection and public choices in
`~/.gstack/config.json` and the key in
`~/.gstack/secrets.json`, mode `0600` where the platform supports POSIX modes.
`$GSTACK_HOME` changes that root. Secrets cannot be written through
`gstack config set`.
## Data-egress contract
Context.dev may receive only the public target URL and operation parameters
needed for the selected scrape/crawl/sitemap/screenshot operation. It must not
receive:
- authenticated pages or private dashboards;
- localhost, intranet, local/private/link-local addresses, or cloud metadata;
- a public hostname whose DNS result is non-public;
- URLs containing usernames or passwords;
- private repository content, diffs, prompts, or user files;
- cookies, session tokens, browser profiles, or unrelated credentials.
The client validates the lexical URL and DNS resolution before a provider
request. `network.mode` must equal `context` and `network.consent` must be true
before it performs even the DNS lookup. The base endpoint is locked to the
credential-free official `https://api.context.dev/v1` origin.
This is not permission to upload public-looking content from an authenticated
session. If provenance is ambiguous, use the local browser and keep the data on
the machine.
## Supported operations and search
The candidate client implements the documented public scrape-Markdown,
scrape-HTML, crawl, sitemap, and screenshot calls. General Context.dev search
is currently deprecated by the provider: the official
[Context.dev changelog](https://docs.context.dev/changelog) says the endpoint
returns `410 Gone`. The current pricing page still lists Web Search credit
costs, so the public provider pages conflict. The runtime follows the explicit
deprecation notice and returns a typed unsupported `CONTEXT_BAD_RESPONSE`
without a network call; it does not guess an endpoint or claim search evidence.
For public search, use the host-native facility only when the user selects it
and it is available. Otherwise use the local browser. If neither is appropriate,
continue without web research and label conclusions unverified.
## Exact failure taxonomy
| Code | Meaning | Recovery |
|---|---|---|
| `CONTEXT_KEY_MISSING` | No key is available. | Offer setup, host-native public search, local browser, or no-web continuation. |
| `CONTEXT_KEY_INVALID` | Key format or provider authentication failed. | Re-enter/reissue the key; never print it. |
| `CONTEXT_EMAIL_UNVERIFIED` | Provider account needs email verification. | Ask the user to verify, then retry the smoke test. |
| `CONTEXT_CREDITS_EXHAUSTED` | Free/paid allowance is depleted. | Explain the quota and offer fallbacks; never purchase automatically. |
| `CONTEXT_RATE_LIMITED` | Provider is throttling requests. | Honor `Retry-After` or fall back; avoid a retry storm. |
| `CONTEXT_TIMEOUT` | Request reached its bounded timeout. | Retry only when safe, or use local/host-native context. |
| `CONTEXT_BLOCKED` | URL/privacy policy rejected the target or provider could not access it safely. | Do not weaken the private-data gate; use local browser when appropriate. |
| `CONTEXT_BAD_RESPONSE` | Provider/server/schema error or an explicitly unsupported operation. | Preserve details without secrets; use a fallback. |
Do not collapse these into “401” or “Context.dev failed.”
## Disable or rotate
Disable network use without deleting the stored key:
```bash
gstack context select none
```
This persists selection `none`, mode `off`, and consent `false`.
Run `gstack context setup` again to replace a rotated key. To remove all runtime
state including secrets, use the separately confirmed destructive operation:
```bash
gstack uninstall --purge --yes
```
Standard skill installation and pure judgment do not require a Context.dev
account. The 22-test deterministic contract is not a substitute for the
blocked verified-key live smoke.
+179
View File
@@ -0,0 +1,179 @@
# GStack 2 host compatibility
This matrix uses evidence tiers. It does not call a host “supported” merely
because its directory name exists in legacy setup code.
## Tiers
| Tier | Meaning |
|---|---|
| **Portable** | The canonical `skills/<name>/SKILL.md` tree follows the Agent Skills specification and uses no required host-private placement logic. This is a source-format claim. |
| **Verified** | The named layer and matrix cells passed against a recorded host/installer version. A scoped “Verified — installer” claim does not imply the host UI launched or executed judgment. |
| **Native** | A necessary host API adds behavior unavailable through portable skills while consuming the same canonical judgment source. Native is not “better”; it carries an additional adapter maintenance contract. |
Tiers are cumulative only when evidence says so. A portable host is not
automatically verified. A legacy generated host output is not a native GStack 2
bundle.
## Canonical installation
```bash
npx skills add time-attack/gstack
```
The standards installer owns host detection, destination paths, project/global
scope, copy versus symlink, updates, removal, and selected-skill installation.
Review its detected-host prompt; detection must never silently enroll a host.
Examples supported by the installer interface:
```bash
# One public skill only
npx skills add time-attack/gstack --skill plan
# Installer-managed global scope
npx skills add time-attack/gstack -g
```
Run `npx skills add --help` for the installed CLI version before scripting
agent-selection flags. GStack deliberately does not reproduce those flags or
host paths in `./setup`.
The expected discoverable names are exactly:
```text
plan
design
qa
debug
review
ship
```
`compat/*.md` and `references/legacy/*.md` are not `SKILL.md` files and must not
appear as additional skills. Installing a subset must not pull the other five
public entries unless the user selected them.
## Candidate installer matrix
The isolated standard-installer matrix passed 470/470 checks with `skills` CLI
1.5.19: 16 install cases and two removal cases. Default discovery projected
only canonical `skills/`; separate explicit-selection cases covered a single
canonical skill and an opt-in legacy alias. The matrix used symlinked and spaced
source paths matching a clean checkout where ignored legacy host trees are
absent. Every installed file was a physical copy and its hash matched the
selected source. The standard skill installation remains Markdown-only and
does not install the optional runtime. The committed evidence artifact is
[`evals/installation/install-matrix.json`](../../evals/installation/install-matrix.json).
| Host | Portable | Project all-six | Global all-six | Selected-skill coverage | Installer tier | Host UI/process |
|---|---|---|---|---|---|---|
| Claude Code | yes | pass | pass | no separate subset case | **Verified — installer** | pending |
| OpenAI Codex | yes | pass | pass | global `qa`, `review`, `ship` pass + removal pass; opt-in alias covered | **Verified — installer** | v1/v2 failed; live v3 pending |
| Cursor | yes | pass | pass | project `qa`, `review`, `ship` pass + removal pass | **Verified — installer** | pending |
| Pi | yes | pass | pass | no separate subset case | **Verified — installer** | pending |
| OpenClaw | yes | pass | pass | project `ship` single-skill pass | **Verified — installer** | pending |
| GitHub Copilot | yes | pass | pass | no separate subset case | **Verified — installer** | pending |
The representative selection cases installed exactly `qa`, `review`, and
`ship`, independently at project scope for Cursor and global scope for Codex,
then removed them noninteractively. Separate cases installed only `ship` for
OpenClaw and explicitly selected the `office-hours` compatibility alias for
Codex; neither alias nor unselected canonical skill was silently enrolled.
`--copy` was advertised and used.
This is filesystem/installer verification, not a claim that six host UIs loaded
or executed the skills. The Codex adversarial lane has no passing live result:
v1 and immutable v2 failed, while v3 is green only in its offline 18-test /
111-assertion harness and has not run live. The installer matrix used the
current local canonical projection through the published `npx skills` CLI, not
the still-unpushed GitHub branch URL.
Legacy generators currently know ten host names. That is historical breadth,
not proof that all ten install correctly. Kiro's old Codex-rewrite behavior and
other host-output transforms are outside the canonical 2.0 path.
## Verification procedure and evidence
Use a clean temporary home and project for every cell; never test against an
operator's live skill directory.
1. Record OS, host version, Node/npm version, and `skills` CLI version.
2. List the source and assert exactly six default entries.
3. Install all six at project scope and verify each host discovers only those
six GStack public skills.
4. Remove them through the standard installer.
5. Repeat at global scope.
6. Install a selected subset; verify unselected skills were not enrolled.
7. Reinstall/update without re-detecting or enrolling an unselected host.
8. Invoke a pure judgment mode with `gstack` absent from `PATH`.
9. Invoke a capability-dependent mode and verify one actionable runtime offer,
without breaking judgment.
10. Exercise a path containing spaces and, where supported, symlink and
read-only failure behavior.
11. Record exact command, exit status, output artifact, and cleanup result in
[TEST-EVIDENCE.md](./TEST-EVIDENCE.md).
The automated filesystem portion is:
```bash
bun test test/gstack2-installation.test.ts
bun run scripts/gstack2/test-install-matrix.ts --full \
--output /tmp/gstack2-install-matrix.json
```
The current matrix passed 470/470 installer CLI checks across 16 installs and two
removals; its JSON artifact is committed at
[`evals/installation/install-matrix.json`](../../evals/installation/install-matrix.json).
Steps 89, a passing live v3 adversarial run, and actual host UI loading remain
separate behavioral gates.
## Optional runtime/platform matrix
The optional runtime is separate from skill placement. From a repository
checkout, the one host-neutral setup entrypoint is:
```bash
./setup
~/.gstack/bin/gstack doctor --json
```
`./setup` resolves a symlinked checkout, installs dependencies only when absent,
builds missing allowlisted capabilities through the runtime-only build target,
validates and hashes every staged file, smoke-tests the CLI, atomically
activates the version, and writes stable POSIX and Windows launchers under
`$GSTACK_HOME/bin` (default `~/.gstack/bin`). The bundle uses `.exe` targets on
Windows and includes the CoreDevice/iOS bundle only on Darwin. Add the bin
directory to `PATH` if the short `gstack` command is desired.
Twenty-one focused installer tests pass with 307 assertions. They cover
manifests, paths with spaces,
source-root symlinks, internal-link/path-escape rejection, failed build/
validation/smoke rollback, interrupted-pointer recovery, stable POSIX/Windows
launchers, runtime-only builder selection, managed uninstall, and the
host-neutral wrapper.
The current managed-bundle audit records 107 components, 1,830 files,
459,056,031 bytes, and 50 launchers. Setup installs frozen production-only
dependencies and excludes the development-only Claude Agent SDK. The
Sharp/ngrok closure is included. The Hugging Face sidecar is excluded and its
package is development-only, so setup installs neither its inference runtime
nor model weights and reports the L4 capability unavailable.
| Platform | Source-level target | Candidate evidence |
|---|---|---|
| macOS | Node runtime + local browser + physical iOS where applicable | Runtime installer 21/307 and current bundle audit pass. The uninterrupted broad singleton run is green at 6,234 pass / 226 expected skips / 0 fail across 383 files. The signed-device gate remains pending. |
| Linux | Node runtime + local browser | Declared Dev Container focused suite passed at 43/0 with 265 assertions. A clean Linux arm64 container used production-only install with the development SDK absent, passed a local-browser journey and Sharp full-page screenshot, and uninstalled while preserving state. Native-host broad Linux remains pending. |
| Native Windows | Node runtime; curated free tests; browser fallback where retained | **Blocked:** native Windows CI pending. The local Windows-safe singleton lane is green at 2,813 pass / 57 expected skips / 0 fail across 213 files, but it is not native evidence. |
| Dev Container | Pure skills and optional runtime; browser only when container supports it | Declared image builds; focused GStack 2 suite and clean runtime install smoke pass. Full broad/browser coverage remains pending. |
The six portable skills remain useful when runtime installation fails. A
runtime failure must not remove or corrupt their standard-installer placement.
## Native adapters
No GStack 2 native tier is currently required or awarded. A future native
bundle needs an accepted issue showing that a host API is necessary, must load
the same canonical judgment modules, and must pass the portable parity suite.
Host-specific presentation metadata such as `agents/openai.yaml` does not by
itself create a second judgment source or a Native claim.
+196
View File
@@ -0,0 +1,196 @@
# iOS physical-device harness
`ios-qa/scripts/physical-device-smoke.ts` is the real-iPhone deployment lane for the existing DebugBridge backend. It uses Xcode, `devicectl`, and the daemon's CoreDevice tunnel bootstrap. It does not add an Appium, XCUITest, WebDriverAgent, simulator, or cloud-device backend.
The harness is intentionally fail-closed. A setup problem is not a product failure, and neither one is a pass.
## Current validation status
Validated locally at the July 17, 2026 checkpoint with Xcode 26.6 and the wired iPhone supplied for this work:
| Identifier kind | Example form | Used for |
|---|---|---|
| Hardware UDID | `<hardware-udid>` | Xcode build destination |
| CoreDevice UUID | `<coredevice-uuid>` | `devicectl`, tunnel bootstrap, install, launch |
Exact local identifiers are deliberately not committed. Successful evidence stores only a SHA-256 fingerprint derived from both identifiers and omits the user-assigned device name.
The daemon suite is green at 95 pass / 0 fail and 229 assertions. The physical
E2E preflight records 9 pass / 0 fail / 1 deploy skip and 29 assertions. The
host, pairing/trust, Developer Mode, wired transport, `devicectl`, `xcodegen`,
and DevToolsSecurity gates pass. The unsigned Release build also passes and
contains no DebugBridge module symbols or artifacts.
The direct physical-device smoke is externally blocked at automatic signing.
It returned typed code `signing_unavailable`, category `setup_gate`. The
underlying Xcode diagnostic is:
```text
Signing for "FixtureApp" requires a development team.
```
That is a setup gate, not a DebugBridge failure. No app was installed or
launched, and no pass artifact was written. The deploy skip and typed smoke
failure must not be represented as a physical-device pass.
## Hardware UDID versus CoreDevice UUID
An iPhone has two identifiers relevant to this flow:
- The hardware UDID is the stable device identifier shown by Xcode. `xcodebuild -destination 'platform=iOS,id=…'` uses it.
- The CoreDevice UUID is the session-facing identifier in `devicectl` JSON. Device inspection, install, launch, app-container copy, and tunnel keepalive use it.
The harness accepts either value through `--device` or `GSTACK_IOS_TARGET_UDID`. It matches the supplied value against both fields, then uses the correct identifier for each tool. It never assumes they are interchangeable internally.
Inspect both values with:
```bash
tmp=$(mktemp)
xcrun devicectl list devices --json-output "$tmp"
jq '.result.devices[] | {
name: .deviceProperties.name,
coreDeviceUUID: .identifier,
hardwareUDID: .hardwareProperties.udid,
transport: .connectionProperties.transportType,
pairing: .connectionProperties.pairingState,
developerMode: .deviceProperties.developerModeStatus
}' "$tmp"
rm "$tmp"
```
If exactly one wired iPhone is visible, the harness selects it. If selection is ambiguous, it refuses to guess and prints both identifier forms.
## Setup gates
Run the non-deploying preflight first:
```bash
GSTACK_IOS_TARGET_UDID=<hardware-UDID-or-CoreDevice-UUID> \
bun run ios-qa/scripts/physical-device-smoke.ts --preflight-only --json
```
The preflight checks these gates before any build or install:
| Gate | Exact remediation |
|---|---|
| Full Xcode selected | `sudo xcode-select -s /Applications/Xcode.app/Contents/Developer` |
| First-launch components/license | `sudo xcodebuild -runFirstLaunch` |
| `devicectl` available | Verify `xcrun --find devicectl`; repair or update Xcode if missing |
| `xcodegen` available | `brew install xcodegen` |
| macOS DevToolsSecurity | `sudo DevToolsSecurity -enable`, then `DevToolsSecurity -status` |
| Wired iPhone | Connect directly over USB, unlock it, and accept the accessory prompt |
| Pairing and trust | `xcrun devicectl manage pair --device <CoreDevice-UUID>`, tap Trust, enter the iPhone passcode |
| iPhone Developer Mode | Settings > Privacy & Security > Developer Mode; enable, restart, unlock, and confirm Enable |
| CoreDevice management surface | Keep the phone unlocked and verify `xcrun devicectl device info processes --device <CoreDevice-UUID>` |
DevToolsSecurity and iPhone Developer Mode are separate gates. DevToolsSecurity authorizes developer tools on the Mac. Developer Mode authorizes development services on the iPhone.
### Signing and provisioning
The temporary Xcode project contains no hardcoded account or development team. The Debug build always requests automatic signing and provisioning updates.
To unblock signing:
1. Open Xcode > Settings > Accounts.
2. Add the Apple ID that owns the development team.
3. Create or download an Apple Development certificate.
4. Leave the iPhone connected and unlocked so Xcode can register it.
5. Optionally select a team explicitly for the harness:
```bash
export GSTACK_IOS_DEVELOPMENT_TEAM=<10-character-team-id>
```
`GSTACK_IOS_TEAM_ID` is accepted as a compatibility alias. If both variables are present and disagree, the harness stops. It never discovers a team and silently hardcodes it.
## Install safety
The deployment fixture uses the reserved bundle ID:
```text
com.gstack.iosqa.fixture.gstack2
```
Before building, the harness asks `devicectl` whether that exact bundle ID is already installed.
- No match: installation may proceed.
- A clearly identified prior `FixtureApp`: an in-place fixture update may proceed; app data is preserved.
- An app with the same bundle ID that does not identify as the fixture: the harness refuses to replace it.
Only after inspecting a conflict may an operator explicitly allow an in-place replacement:
```bash
export GSTACK_IOS_ALLOW_REPLACE_FIXTURE=1
```
The harness never uninstalls an app and never deletes app data. It uses `devicectl device install app` only after the conflict check.
## Build, deploy, and verify
The full lane is opt-in in the Bun E2E test:
```bash
GSTACK_HAS_IOS_DEVICE=1 \
GSTACK_IOS_DEVICE_DEPLOY=1 \
GSTACK_IOS_TARGET_UDID=<hardware-UDID-or-CoreDevice-UUID> \
bun test test/skill-e2e-ios-device.test.ts
```
It can also run directly:
```bash
GSTACK_IOS_TARGET_UDID=<hardware-UDID-or-CoreDevice-UUID> \
bun run ios-qa/scripts/physical-device-smoke.ts --json
```
The harness performs these phases:
1. Copies `test/fixtures/ios-qa/FixtureApp` into a new temporary directory, excluding previous build output and the fixture's unrelated signing spec.
2. Generates a team-neutral Release project with `xcodegen`, builds it unsigned for iPhoneOS, and scans the app executable and bundle for DebugBridge module names/artifacts.
3. Regenerates the Debug project with local DebugBridge package products, then asks Xcode for automatic signing/provisioning. An optional team comes only from the environment.
4. Checks the reserved bundle ID on the selected phone, installs without uninstalling or erasing data, and launches a fresh foreground fixture process.
5. Captures the short-lived boot token, calls the existing `bootstrapTunnel`, rotates the credential, and starts the existing CoreDevice tunnel keepalive.
6. Runs all five live iterations. A partial run is never promoted to pass evidence.
## The five checks in every iteration
Each of the five iterations executes the same five real-device checks:
| Check | Required evidence |
|---|---|
| Health and bundle | `/healthz` returns `com.gstack.iosqa.fixture.gstack2` before and after the tap |
| Token rotation | Reusing the captured original boot token returns `401 boot_token_invalid` while the rotated credential remains usable |
| Session acquire | `/session/acquire` returns a session ID; the session is released even on failure |
| Screenshot and elements | `/screenshot` returns a valid PNG and `/elements` returns a live accessibility tree containing `tap-button` |
| Coordinate tap and cleanup | A center-coordinate `/tap` reports the expected active bundle before/after, the button count and screenshot both change, state is snapshotted/restored if needed, and the session is released |
The loop records no bearer tokens or session IDs. It continues through all five iteration slots to make a 5/5 claim meaningful, then fails the run if any iteration failed.
## Evidence policy
JSON evidence is written atomically under `docs/gstack-2/evidence/` only after:
- the Release guard passes;
- Debug signing, build, install, launch, and daemon bootstrap pass;
- all five iterations pass all five checks;
- the final session is released;
- the keepalive is stopped; and
- the temporary workspace is removed.
Setup-gate failures, safety refusals, product failures, and partial live runs create no evidence file. A signing error must never be represented as a live pass.
## Failure categories
The CLI emits a typed `GSTACK_IOS_PHYSICAL_DEVICE_ERROR` JSON object and uses these categories:
| Category | Exit code | Meaning |
|---|---:|---|
| `setup_gate` | 2 | Host, cable, trust, Developer Mode, account, certificate, provisioning, or CoreDevice setup prevents the product from being exercised |
| `safety_refusal` | 3 | The harness cannot prove an install is safe, usually because of an unrelated bundle-ID conflict |
| `product_failure` | 1 | The fixture or DebugBridge compiled incorrectly, leaked into Release, failed install/launch/bootstrap, or failed a live assertion |
Fix setup gates without filing them as DebugBridge regressions. Treat a product failure as actionable only after all setup gates pass.
## Cleanup guarantees
Every session release is in a `finally` path. The outer cleanup stops the CoreDevice keepalive and removes the harness-owned temporary workspace whether the run passes or fails. The fixture remains installed and its data remains intact; uninstalling or deleting its data requires separate, explicit operator approval.
+18
View File
@@ -0,0 +1,18 @@
# Judgment parity
Parity is executable, not a prose claim. Run `bun run scripts/gstack2/run-parity.ts` or the dedicated Bun tests.
The pinned release inventory passes **4,681 checks** across 55 specialist sources, 16 carved sections, 25 routing scenarios, 16 regression ports, and **78 assets**.
The suite verifies:
- exactly six discoverable public skills and 55 internal legacy modules;
- 55 canonical templates plus 16 carved section templates at base `bb57306d98c97011b0919c6132705a15b1579781`;
- normalized legacy-body SHA-256 equality between source rendering and generated references;
- preservation of nine behavioral contract dimensions per module;
- 25 structured non-keyword routing fixtures with active/skipped modules, depth, mutation, and web context;
- 16 upstream judgment-port regression fixtures and anchors;
- all linked asset copies against their pinned Git blobs;
- frontmatter and `agents/openai.yaml` schema for each public skill.
Golden normalization removes only generated provenance wrappers, bug-fix overlays, and irrelevant whitespace. It never removes legacy workflow prose, gates, questions, evidence requirements, artifacts, or exit behavior.
File diff suppressed because it is too large Load Diff
+145
View File
@@ -0,0 +1,145 @@
# GStack 2 privacy boundary
GStack 2 defaults to local judgment and local state. Optional network and
device capabilities are separated by explicit purpose and consent. Passing a
unit test is not a substitute for the remaining live egress audit listed in
[STATUS.md](./STATUS.md).
## Data-flow summary
| Capability | Default | May leave the machine | Never send |
|---|---|---|---|
| Six judgment skills | available | nothing by the skill text alone | project data to a new service without separate user/host authority |
| Standard installer | user-invoked, Markdown-only | repository/registry requests needed to fetch the skills | runtime dependencies, Context key, project content, browser credentials |
| Optional runtime/state | local, network off | nothing until a separately selected operation requires it | secrets in config/log output; one worktree's state to another |
| Context.dev | off, explicit consent required | public target URL and public extraction options | authenticated/private/local content, cookies, tokens, repo content, user files |
| Local browser | local daemon | navigation requests to sites the user directs it to; explicit legacy tunnels if separately enabled | browser profile/cookies to Context.dev or a cloud-browser provider |
| Physical iPhone | local Mac/device bridge | optional pre-existing Tailscale path only when explicitly configured | device session to a cloud-device farm or alternate driver provider |
| Telemetry | off in the GStack 2 contract | minimal legacy telemetry only after its independent opt-in | code, prompts, paths, repo/branch names, user content |
Network installation is not Context.dev consent. Browser navigation is not
Context.dev consent. A key present in the environment is not consent. The
Context client requires persisted selection `context`, mode `context`, and
`network.consent: true` before DNS or fetch. Explicit selections `host`,
`local-browser`, and `none` persist with consent false.
The deterministic Context contract is green at 22 pass / 0 fail and 139
assertions. No verified key was available for a live provider smoke; those unit
results are not live-egress evidence.
## Public Context.dev gate
Before any provider request, the runtime rejects:
- non-HTTP(S) schemes;
- URL usernames/passwords;
- localhost and `.localhost`;
- private/intranet/test/local suffixes and single-label hosts;
- loopback, private, link-local, unspecified, multicast, and mapped-private IPs;
- cloud metadata names/addresses; and
- a nominally public hostname if any resolved address is non-public.
Allowed operations still receive only the public URL and necessary operation
parameters. Do not paste or synthesize cookies, authorization headers, private
page HTML, repository snippets, diffs, or prompts into a public-web request.
When a page requires login or its provenance is uncertain, use the local
browser and keep the content local.
Context.dev credentials are read from protected runtime secrets or a deliberate
environment variable. Interactive setup uses hidden input. The CLI rejects
key-looking arguments, redacts known key formats from errors, and prevents
secret-looking config keys from entering public `config.json`. See
[CONTEXT-DEV.md](./CONTEXT-DEV.md).
## Local browser boundary
GStack retains its own loopback Chromium/Playwright daemon; no cloud-browser
backend has been added. Mutating commands require bearer authentication.
Existing tunnel support uses a separate deny-default listener and scoped
tokens; it exposes the local browser only after an explicit pairing action and
does not turn a hosted browser into a provider dependency. The current runtime
bundle includes the retained ngrok dependency closure for that explicit legacy
tunnel path; it does not add a cloud-browser provider.
Imported cookies remain in the local browser context. Cookie values are not
displayed in the picker or sent to Context.dev. Page content, console messages,
network payloads, dialog text, screenshots, and downloaded files are untrusted
input to the agent, never operational instructions.
Killing or cancelling a browser workflow must close its owned processes and
listeners without killing a sibling worktree's session. Full cancellation/leak
evidence remains a release gate.
## Physical-iPhone boundary
There is one device backend: the existing GStack DebugBridge over Apple's
CoreDevice tooling. It uses local `xcodebuild`, `devicectl`, signing,
provisioning, a CoreDevice tunnel, typed app state, screenshots, and coordinate
actions. Optional Tailscale exposure is retained only where already configured
and authorized. GStack does not use a cloud iPhone, Appium, Agent Device, or an
XCUITest backend abstraction.
The bridge is debug-only. Release builds must contain no bridge symbols. GStack
must not overwrite an unrelated installed app or delete app data without
approval. It checks the expected bundle before and after coordinate mutations
and stops if focus changes.
## State and worktree isolation
State lives under `$GSTACK_HOME` or `~/.gstack`; there is no new database. The
runtime stores JSON/JSONL plus artifacts in a project directory derived from
both repository and worktree identity. Linked worktrees share a repository ID
but have distinct project IDs, so inspect/resume cannot silently select a
sibling.
Writes use atomic replacement and lock leases. Secrets are `0600` where
supported. Durable external-effect claims prevent an uncertain post-crash
action from being repeated automatically. Human-readable files make audits and
manual recovery possible.
Do not place secrets, cookies, private page dumps, or device credentials into
timeline/decision/evidence records. Evidence must be the minimum needed to
support the claim and must follow the source system's retention policy.
## Models, images, and documents
The current managed-bundle audit records 107 components, 1,830 files,
459,056,031 bytes, and 50 launchers. Setup installs frozen production-only
dependencies. The Sharp/ngrok closure is included; the development-only Claude
Agent SDK is excluded. The Hugging Face sidecar is excluded and its package is
development-only, so setup installs neither its inference runtime nor model
weights and reports the L4 capability unavailable.
GStack 2 therefore downloads no model weights, checkpoints, LoRAs, or ComfyUI
runtime and starts no background image-model server. Host-native image
generation remains optional when the user and host already provide it. Design
works without it through systems, HTML/CSS, wireframes, screenshots, diagrams,
and critique.
PDF and Mermaid/Excalidraw rendering remain local internal capabilities. No
hosted PDF or diagram service was introduced.
## Disable and remove
Turn Context network use off while preserving state:
```bash
gstack context select none
```
Remove managed runtime versions while preserving config/project state:
```bash
gstack uninstall
```
Purge all GStack 2 runtime state and secrets only with the explicit destructive
confirmation:
```bash
gstack uninstall --purge --yes
```
Use the standard Agent Skills installer to remove skill placements. Removing
runtime state does not authorize GStack to edit unrelated host directories,
browser profiles, applications, or device data.
+31
View File
@@ -0,0 +1,31 @@
# GStack 2 routing scenarios
The 25 executable fixtures route from structured stage/surface/authorization/evidence signals. Their prompts intentionally avoid public skill and mode names.
| ID | Expected decision | Active | Mutation | Evidence basis | Gap |
|---|---|---|---|---|---|
| `idea-before-solution` | `plan:Discovery` | `office-hours` | `design-doc-only` | phase=pre-solution; premise_confidence=low | — |
| `scope-and-ambition` | `plan:Product` | `plan-ceo-review` | `plan-only` | artifact_exists=true; uncertainty=scope-strategy | — |
| `architecture-data-contracts` | `plan:Engineering` | `plan-eng-review` | `plan-only` | uncertainty=architecture-data; phase=implementation-design | — |
| `developer-first-onboarding` | `plan:DX` | `plan-devex-review` | `plan-only` | audience=developers; journey=onboarding | — |
| `cross-functional-decision` | `plan:Full chain` | `autoplan` | `plan-only` | review_axes_count=4; automatic_decisions=true | — |
| `backlog-ready-handoff` | `plan:Specification` | `spec` | `spec-and-issue` | output=executable-backlog-item; phase=handoff | — |
| `new-visual-system` | `design:Generate` | `design-consultation` | `design-artifacts` | surface=design-system; implementation_exists=false | — |
| `compare-directions` | `design:Explore` | `design-shotgun` | `design-artifacts` | alternatives_requested=true; output=comparison | — |
| `coded-marketing-surface` | `design:Implement` | `design-html` | `design-artifacts` | output=html-css; runtime_verification=true | — |
| `prebuild-interface-critique` | `design:Critique` | `plan-design-review` | `plan-only` | implementation_exists=false; artifact_exists=true | — |
| `implemented-interface-audit` | `design:Implement` | `design-review` | `fix-safe` | implementation_exists=true; mutation_authorized=true | — |
| `real-device-hig-audit` | `design:Critique` | `ios-design-review` | `report-only` | surface=ios; real_device=true | — |
| `browser-findings-only` | `qa:Report` | `qa-only` | `report-only` | surface=web; mutation_authorized=false | — |
| `browser-fix-and-verify` | `qa:Fix` | `qa` | `fix-safe` | surface=web; mutation_authorized=true | — |
| `device-state-journey` | `qa:Report` | `ios-qa` | `report-only` | surface=ios; real_device=true | — |
| `cli-api-journey` | `qa:Report` | `devex-review`, `qa-only`, `investigate`, `system-functional` | `report-only` | surface=developer-workflow; journey_measurement=true; functional_backend_harness=true | — |
| `measured-page-regression` | `qa:Report` | `benchmark` | `report-only` | measurement=performance; baseline_exists=true | — |
| `production-threshold-watch` | `qa:Report` | `canary` | `report-only` | deployed=true; thresholds_declared=true | — |
| `unknown-intermittent-cause` | `debug:Diagnose-only` | `investigate` | `investigate-only` | cause_known=false; intermittent=true | — |
| `reproducible-device-defect` | `debug:Fix` | `ios-fix` | `fix-safe` | platform=ios; reproducible=true | — |
| `ci-script-change-review` | `review:Normal` | `review` | `fix-safe` | change_exists=true; audit_focus=broad | — |
| `threat-surface-audit` | `review:Security` | `cso` | `report-only` | audit_focus=security; threat_model_required=true | — |
| `branch-to-pull-request` | `ship:Prepare` | `ship` | `commit-push-pr` | release_stage=working-branch; pr_exists=false | — |
| `approved-change-to-production` | `ship:Land` | `land-and-deploy` | `merge-deploy` | release_stage=approved-pr; deploy_requested=true | — |
| `post-release-doc-alignment` | `ship:Prepare` | `document-release` | `docs-only` | release_stage=post-ship; docs_drift=true | — |
+107
View File
@@ -0,0 +1,107 @@
# Semantic parity evidence
GStack 2 semantic parity uses the recorded 1.x base
`bb57306d98c97011b0919c6132705a15b1579781` as its primary oracle. It does not
ask a model to decide whether a rewrite is “close enough.” Each representative
fixture selects a specialist through structured product/evidence signals, then
compares the pinned host-rendered 1.x workflow with the legacy body loaded by
the GStack 2 dispatcher.
Run:
```bash
bun run scripts/gstack2/semantic-parity.ts
bun test test/gstack2-semantic-parity.test.ts
```
The first command writes reproducible evidence under
`evals/parity/transcripts/`:
- 14 constitution-required suites and 15 executions (DX and specification are
separate executions);
- all 15 requested comparison dimensions per execution;
- exact workflow and semantic-signature hashes;
- all 16 carved-section comparisons;
- authority-policy unit cases for evidence, trust boundaries, physical-device
substitution, mutation authority, and structured routing;
- every linked bug-fix difference classified as `INTENTIONAL_IMPROVEMENT` with
its upstream PR and regression fixture.
The current deterministic manifest is green: **295 checks across 14 suites,
15 executions, 15 dimensions, 16 carved sections, and nine authority-policy
unit cases**. Its base is
`bb57306d98c97011b0919c6132705a15b1579781` and it explicitly records that a
live model is not required for the primary verdict.
Exact preserved bodies are stronger evidence than an LLM similarity score:
questions, order, pressure, smart skips, rubrics, gates, evidence, artifacts,
mutation, exits, recommendations, and voice cannot disappear while normalized
full-body equality holds. The structured route and authority-policy units cover
deterministic controls that exist outside those bodies. They start from a
hand-authored semantic operation envelope, so they are policy-unit evidence,
not proof that a live host correctly decodes a hostile natural-language
request. This is deterministic policy evidence, not behavioral-adversarial
proof.
The installed-host lane currently has no passing live run. V1 **failed**. The
immutable v2 run also **failed**: QA passed, while debug, review, and ship were
false negatives caused by the v2 read-only-Git warning classifier. Its artifact
is
[`2026-07-17T04-09-01-809Z-3d23a270.json`](../../evals/host-adversarial/runs/2026-07-17T04-09-01-809Z-3d23a270.json),
SHA-256
`7ab15ea575cb9a634b7d00212dd9d74902b1188281ae6a503a32ccf382facbf5`.
The v3 offline harness is green at 18 pass / 0 fail and 111 assertions, but live
v3 has not run and has no artifact. The P0 gate therefore remains open. See the
[installed-host evidence overview](../../evals/host-adversarial/README.md).
## Optional live-model supplement
A paid, non-deterministic comparison is opt-in and is never the primary gate:
```bash
GSTACK2_LIVE_SEMANTIC=1 bun run scripts/gstack2/semantic-parity.ts \
--live --model=<exact-model-id> --limit=15 --max-budget-usd=0.25 --resume-live
```
The live runner uses Claude CLI bare mode with session persistence, slash
commands, browser integration, and tools all disabled. It requests one turn
per actor and judge and passes a USD 0.25 per-call budget by default
(configurable up to USD 1.00), rejects credential-shaped prompts, records the
exact prompts and model, redacts credential-shaped output, and writes
structured baseline/candidate responses plus a 15-dimension judge result under
`evals/parity/transcripts/live/<exact-model-id>/`. The CLI budget is not a hard
preauthorization ceiling: one observed provider call reported USD 0.81 after a
USD 0.25 limit was supplied. Treat the setting as a guardrail, stop on an
overage, and never loop until a favorable verdict. A model is not allowed to
overrule a deterministic regression or unexplained loss, and human review
remains authoritative for disputed results.
`--resume-live` reuses only a non-regression transcript produced by the exact
same model, per-call budget, and baseline/candidate/judge prompt hashes. It
never reuses evidence across model, budget, or prompt changes.
### Current live evidence
The retained Claude Haiku evidence is **not green**:
- `live/attempts/office-hours-haiku-v1-regression.json` records a regression
from the earlier visible generated-wrapper prompt;
- `live/claude-haiku-4-5-20251001/ceo-review.json` also predates the current
invisible thin wrapper and is prompt-stale; and
- `live/claude-haiku-4-5-20251001/office-hours.json` is a post-wrapper sample
classified `REGRESSION`, in part because the independently sampled baseline
response included details that its own sample omitted elsewhere even though
the candidate's source body is byte-preserved.
These files expose two separate facts: visible wrapper prose can bias an actor,
and independent first-turn summaries can create apparent losses even when the
underlying source is identical. The wrapper was reduced to an invisible,
five-line-or-smaller provenance prelude and that invariant is now structural.
The remaining sampling variance is why live evaluation stays supplemental.
None of the three transcripts is release-pass evidence, and an obsolete prompt
must not be silently reused or overwritten.
`bun run gen:gstack2` refreshes the deterministic contracts, scenarios,
regressions, and manifest while preserving `evals/parity/transcripts/live/`.
Run deterministic semantic parity after the generator when preparing final
release evidence; do not let regeneration erase unfavorable live history.
+79
View File
@@ -0,0 +1,79 @@
# GStack 2 skill migration
Pinned baseline: `bb57306d98c97011b0919c6132705a15b1579781`.
GStack 2 exposes exactly six public Codex skills: `plan`, `design`, `qa`, `debug`, `review`, and `ship`. The 55 legacy templates remain mechanically rendered as internal reference modules; all 16 carved section templates are inlined with the canonical Codex resolver path. Thirty-one primary modules are mandatory specialist inputs, and 24 supporting modules remain reachable through compatibility routing.
The fixed public modes are: Design = `Explore | Generate | Critique | Implement`; QA = `Report | Fix`; Debug = `Diagnose-only | Fix`; Review = `Normal | Security | Performance | Deep`; Ship = `Prepare | Land | Deploy | Monitor | Resume`. Richer legacy modes are internal aliases only.
## Migration map
| Legacy invocation | Replacement | Visibility | Mandatory | Judgment overlays |
|---|---|---|---|---|
| `/gstack` | `$plan --mode Discovery --module gstack` | internal (internal) | no | #679 |
| `/office-hours` | `$plan --mode Discovery --module office-hours` | internal (primary) | yes | #679, #2030 |
| `/plan-ceo-review` | `$plan --mode Product --module plan-ceo-review` | internal (primary) | yes | #679, #2030 |
| `/plan-eng-review` | `$plan --mode Engineering --module plan-eng-review` | internal (primary) | yes | #679, #1071, #2030 |
| `/plan-devex-review` | `$plan --mode DX --module plan-devex-review` | internal (primary) | yes | #679, #2030 |
| `/autoplan` | `$plan --mode Full chain --module autoplan` | internal (primary) | yes | #679, #2014, #2023 |
| `/spec` | `$plan --mode Specification --module spec` | internal (primary) | yes | #679 |
| `/plan-tune` | `$plan --mode Discovery --module plan-tune` | internal (primary) | yes | #679 |
| `/context-save` | `$plan --mode Discovery --module context-save` | internal (internal) | no | #679 |
| `/context-restore` | `$plan --mode Discovery --module context-restore` | internal (internal) | no | #679 |
| `/learn` | `$plan --mode Discovery --module learn` | internal (internal) | no | #679, #2030 |
| `/retro` | `$plan --mode Discovery --module retro` | internal (internal) | no | #679, #1636, #2037 |
| `/setup-gbrain` | `$plan --mode Discovery --module setup-gbrain` | internal (internal) | no | #679 |
| `/sync-gbrain` | `$plan --mode Discovery --module sync-gbrain` | internal (internal) | no | #679 |
| `/design-consultation` | `$design --mode Generate --module design-consultation` | internal (primary) | yes | #679, #2030, #2189 |
| `/design-shotgun` | `$design --mode Explore --module design-shotgun` | internal (primary) | yes | #679, #1777 |
| `/design-html` | `$design --mode Implement --module design-html` | internal (primary) | yes | #679 |
| `/plan-design-review` | `$design --mode Critique --module plan-design-review` | internal (primary) | yes | #679, #2030, #2189 |
| `/design-review` | `$design --mode Implement --module design-review` | internal (primary) | yes | #679, #1920, #2030, #2189 |
| `/ios-design-review` | `$design --mode Critique --module ios-design-review` | internal (primary) | yes | #679 |
| `/diagram` | `$design --mode Generate --module diagram` | internal (internal) | no | #679 |
| `/make-pdf` | `$design --mode Generate --module make-pdf` | internal (internal) | no | #679 |
| `/qa` | `$qa --mode Fix --module qa` | internal (primary) | yes | #679, #1484, #2030, #2186 |
| `/qa-only` | `$qa --mode Report --module qa-only` | internal (primary) | yes | #679, #1484, #2030 |
| `/ios-qa` | `$qa --mode Report --module ios-qa` | internal (primary) | yes | #679 |
| `/devex-review` | `$qa --mode Report --module devex-review` | internal (primary) | yes | #679, #2030 |
| `/benchmark` | `$qa --mode Report --module benchmark` | internal (primary) | yes | #679 |
| `/canary` | `$qa --mode Report --module canary` | internal (primary) | yes | #679, #2186 |
| `/browse` | `$qa --mode Report --module browse` | internal (internal) | no | #679, #2186 |
| `/open-gstack-browser` | `$qa --mode Report --module open-gstack-browser` | internal (internal) | no | #679 |
| `/setup-browser-cookies` | `$qa --mode Report --module setup-browser-cookies` | internal (internal) | no | #679 |
| `/pair-agent` | `$qa --mode Report --module pair-agent` | internal (internal) | no | #679 |
| `/scrape` | `$qa --mode Report --module scrape` | internal (internal) | no | #679, #2030 |
| `/skillify` | `$qa --mode Report --module skillify` | internal (internal) | no | #679, #2030 |
| `/benchmark-models` | `$qa --mode Report --module benchmark-models` | internal (internal) | no | #679 |
| `/investigate` | `$debug --mode Diagnose-only --module investigate` | internal (primary) | yes | #679, #2030, #2186 |
| `/ios-fix` | `$debug --mode Fix --module ios-fix` | internal (primary) | yes | #679 |
| `/careful` | `$debug --mode Diagnose-only --module careful` | internal (internal) | no | #679 |
| `/freeze` | `$debug --mode Diagnose-only --module freeze` | internal (internal) | no | #679 |
| `/guard` | `$debug --mode Diagnose-only --module guard` | internal (internal) | no | #679 |
| `/unfreeze` | `$debug --mode Diagnose-only --module unfreeze` | internal (internal) | no | #679 |
| `/review` | `$review --mode Normal --module review` | internal (primary) | yes | #610, #645, #679, #2030, #2141 |
| `/cso` | `$review --mode Security --module cso` | internal (primary) | yes | #679, #2030 |
| `/health` | `$review --mode Deep --module health` | internal (primary) | yes | #679 |
| `/codex` | `$review --mode Deep --module codex` | internal (primary) | yes | #679 |
| `/claude` | `$review --mode Deep --module claude` | internal (primary) | yes | #679 |
| `/ship` | `$ship --mode Prepare --module ship` | internal (primary) | yes | #679, #884, #2030, #2186 |
| `/land-and-deploy` | `$ship --mode Land --module land-and-deploy` | internal (primary) | yes | #679, #884 |
| `/landing-report` | `$ship --mode Prepare --module landing-report` | internal (primary) | yes | #679 |
| `/document-release` | `$ship --mode Prepare --module document-release` | internal (primary) | yes | #679 |
| `/setup-deploy` | `$ship --mode Deploy --module setup-deploy` | internal (primary) | yes | #679 |
| `/document-generate` | `$ship --mode Prepare --module document-generate` | internal (internal) | no | #679 |
| `/gstack-upgrade` | `$ship --mode Prepare --module gstack-upgrade` | internal (internal) | no | #679 |
| `/ios-clean` | `$ship --mode Prepare --module ios-clean` | internal (internal) | no | #679 |
| `/ios-sync` | `$ship --mode Prepare --module ios-sync` | internal (internal) | no | #679 |
## Intentional behavioral gaps
1. **Global Context search:** deprecated. Explicit context save/restore remains available as internal plan modules, but no dispatcher claims an unbounded global search across historical Context state.
2. **Outside voices:** a host cannot invoke itself as an independent outside reviewer. The relevant module reports unavailable model diversity instead of claiming consensus.
3. **External prerequisites:** browser credentials, real-device bridges, repository permissions, review approvals, CI, and deploy providers remain required external state. Compatibility does not synthesize them.
## Mechanical versus judgment changes
- `MECHANICAL_PORT`: canonical Codex resolver expansion, section inlining, safety prose, and path rewrites only.
- `BUG_FIX`: the mechanical body plus a clearly delimited judgment overlay sourced from one of the 16 upstream PRs and its regression fixture.
- Asset relocation is byte-for-byte from the pinned Git blob and is indexed per tree.
+161 -42
View File
@@ -1,56 +1,175 @@
# GStack 2.0 status
# GStack 2 status
**Current state: BASELINED AND MAPPED — NOT IMPLEMENTED, NOT VERIFIED, NOT
DONE.**
**Status at the 2026-07-17 documentation checkpoint: `BLOCKED`.**
This checklist separates evidence capture from delivery so generated plans or
passing narrow tests cannot be mistaken for a completed rewrite.
The candidate contains substantial implementation, but it is not a released or
verified GStack 2. `DONE` is prohibited until every P0 gate is backed by the
required evidence layer. Current blockers include physical-iPhone signing, a
verified Context.dev key smoke, native Windows CI, a passing live v3
installed-host adversarial run, native Linux evidence, and the signed physical
iPhone loop. No branch push, draft PR, or PR-ready claim is authorized by this
status.
## Phase checklist
## Implemented candidate surface
- [x] Freeze the audit base at
- [x] Pinned audit base:
`bb57306d98c97011b0919c6132705a15b1579781`.
- [x] Record template/output/section, line, byte, repeated-preamble, catalog,
host, and installer-discovery baselines.
- [x] Capture the baseline command logs without relabeling pre-existing
failures as passes.
- [x] Flatten and reconcile every frozen open issue/PR snapshot into one
deterministic map (755 unique items from 1,184 endpoint records).
- [x] Trace all 16 required PRs to their detail snapshots, changed-file
snapshots, component, judgment module, and replacement-test contract.
- [ ] Review and approve the GStack 2.0 architecture and migration contract.
- [ ] Convert heuristic backlog dispositions into accepted product/engineering
decisions. `NEEDS_EVIDENCE` is intentionally the majority disposition.
- [ ] Implement the consolidated judgment modules and runtime components.
- [ ] Implement the replacement contract tests named in `BACKLOG-MAP.json`.
- [ ] Prove legacy setup migration and standard-installer discovery without
root/nested skill shadowing.
- [ ] Prove behavior and safety parity across all 10 generated hosts.
- [ ] Re-run the broad, Windows-safe, design, and iOS suites with complete
terminal summaries; separate repaired baseline failures from regressions.
- [ ] Produce release evidence and make an explicit ship/no-ship decision.
- [x] Baseline counts and pre-existing failures captured without relabeling
them candidate regressions.
- [x] 755 unique open issue/PR records reconciled and deterministically mapped;
all 16 required upstream PR snapshots traced.
- [x] Exactly six canonical skill directories: `plan`, `design`, `qa`,
`debug`, `review`, and `ship`.
- [x] The six `/plan` top-level modes are exactly **Discovery, Product,
Engineering, DX, Specification, and Full chain**.
- [x] Standard installer matrix is green: 470/470 checks, 16 installs and two
removals with CLI 1.5.19. Project/global installs passed for Claude Code,
Codex, Cursor, Pi, OpenClaw, and GitHub Copilot; selected-skill and opt-in
compatibility-alias cases, paths with spaces, source symlink, physical
copies, and canonical hashes passed. The committed artifact is
[`evals/installation/install-matrix.json`](../../evals/installation/install-matrix.json).
- [x] Current six names/descriptions measure 982 characters (about 246
four-character token-equivalents), roughly 77.6% below the correctly parsed
baseline of about 1,100 in the regenerated tree.
- [x] Generated inventory contains 55 preserved modules, 16 carved sections,
25 scenarios, 16 regression definitions, and 78 assets.
- [x] Compatibility aliases remain opt-in and outside default six-skill
discovery; each prints its replacement and contains no copied judgment.
- [x] Judgment provenance, behavioral contracts, 25 structured scenarios, and
16 upstream bug-fix regression definitions implemented.
- [x] The 2026-07-17 regenerated parity rerun is green: 4,681 checks covering
55 modules, 16 sections, 25 scenarios, 16 regressions, and 78 assets.
- [x] Deterministic semantic parity is green: 295 checks across 14 suites, 15
executions, 15 comparison dimensions, 16 carved sections, and nine
authority-policy unit cases, including unsupported numeric claims. Exact
preserved source bodies are the primary
oracle. These are deterministic policy checks, not behavioral-adversarial
proof, and do not close the installed-host gate. All
three retained Claude Haiku live samples are classified `REGRESSION`; they
are preserved as noisy supplemental evidence, never cherry-picked as a
primary gate or represented as green.
- [x] The focused GStack 2 suite is green: 130 pass / 0 fail, 1,071
assertions across 15 files. This focused surface does not substitute for the
broad or native-platform gates.
- [x] Optional host-neutral runtime implemented with canonical paths,
repo/worktree state identity, locks, atomic writes, effect claims,
doctor/config/state/cleanup, migrations, upgrade/rollback, and uninstall.
- [x] Managed runtime installer coverage is green at 21 pass / 0 fail and 307
assertions. The current managed bundle audit records 107 components, 1,830
files, 459,056,031 bytes, and 50 launchers. Setup installs frozen
production-only dependencies; the development-only Claude Agent SDK is
excluded. The Sharp/ngrok closure is included. The Hugging Face sidecar is
excluded and its package is development-only, so setup installs neither its
inference runtime nor model weights and reports the L4
capability unavailable. A clean Linux arm64 container smoke also used the
production-only install with the development SDK absent, completed a local
browser journey and Sharp full-page screenshot, and uninstalled while
preserving state.
- [x] Filesystem lifecycle coverage passes for clean install/uninstall,
paths with spaces, source symlinks with internal-link rejection, read-only
destination reporting on macOS, interrupted-pointer rollback, crash-journal
repair, and last-known-good launcher recovery.
- [x] Crash/resume external-effect idempotency is covered through an actual
local Git push: the effect executes at most once, and resume refuses to
repeat a command that may already have happened.
- [x] Context.dev public-URL/consent/failure contract is green at 22 pass / 0
fail and 139 assertions; deprecated search is typed unsupported rather than
fabricated. `context options` and explicit
`context select host|local-browser|none` choices persist without granting
Context.dev consent. No verified key was available for the live smoke.
- [x] iOS candidate fixes implemented for UDID/CoreDevice identity, malformed
device-list errors, suspended-app bounded timeout, and active-bundle checks.
- [x] Default/free-test roots now include `design/test` and
`ios-qa/daemon/test`.
- [x] Focused retained capability suites are green: iOS daemon 95 pass / 0 fail
/ 229 assertions; design 101 pass / 0 fail / 381 assertions; PDF 189 pass / 0
fail / 398 assertions; and diagram 51 pass / 0 fail / 1 skip / 120
assertions. The opt-in paid diagram lane recorded two skips and is not live
provider evidence.
- [x] Physical-iOS preflight recorded 9 pass / 0 fail / 1 deploy skip and 29
assertions. The direct smoke then returned typed code
`signing_unavailable`, category `setup_gate`; it installed no app and wrote no
pass artifact.
- [x] Installed-host adversarial evidence is retained without relabeling:
v1 **failed**; immutable v2 **failed** even though QA passed because the
classifier produced false negatives for debug, review, and ship; v3 offline
harness coverage is green at 18 pass / 0 fail and 111 assertions. Live v3
has not run and has no artifact, so there is no passing live installed-host
adversarial result.
- [x] A current managed-bundle audit confirms no model-weight download path in
setup. The standard Agent Skills installation remains Markdown-only and
independent of the optional runtime.
- [x] An isolated local-browser journey completed navigation, snapshot,
screenshot, status, and stop cleanup. The stop acknowledgement regression
has a 2 pass / 0 fail focused test.
- [x] The uninterrupted macOS broad suite is green under singleton isolation:
6,234 pass / 226 expected skips / 0 fail and 25,392 assertions across all
383 files. This includes the complete local-browser suite. The local
Windows-safe singleton lane is also green at 2,813 pass / 57 expected skips
/ 0 fail and 8,562 assertions across all 213 curated files; it is not native
Windows evidence.
- [x] Architecture, privacy, Context.dev, host compatibility, upgrade/rollback,
migration, and governance documentation added.
## Blocking or incomplete P0 evidence
- [ ] Record a passing live v3 installed-host adversarial run and execute the
installed skill in each representative host UI. The six hosts are **Verified
at the installer layer only**; v1 and v2 are retained failed runs, and v3 is
offline-harness evidence only.
- [ ] Prove runtime-absent judgment behavior through an actual host invocation.
Runtime install failure and the real default capability lifecycle are covered.
- [ ] Complete native Linux and Windows matrices. The uninterrupted macOS
broad singleton run is green at 6,234/226/0 across 383 files, and the local
Windows-safe singleton lane is green at 2,813/57/0 across 213 files. Neither
substitutes for native execution on its named platform.
- [ ] Integrate the passing complete local-browser suite and live journey into
final cancellation/leak evidence. The production dependency and managed
bundle audit contains no cloud-browser provider/path.
- [ ] Complete a live Context.dev smoke with a verified account/key. No verified
key was available at this checkpoint; the 22-test automated contract is not
provider evidence.
- [ ] Complete the physical-iPhone five-check loop with a signed test app. The
unsigned Release guard and preflight passed, but the direct smoke returned
`signing_unavailable` / `setup_gate`; no app was installed and no pass artifact
exists. This is a remediable account/provisioning gate.
- [ ] Verify in one real cancellation run that no subprocess, listener,
credential, browser, or device-session remains after interruption. Existing
component tests cover each cleanup contract separately but not this aggregate
live gate.
- [ ] Finish final evidence-linked disposition for every infrastructure item;
see the 25-row table in [ARCHITECTURE.md](./ARCHITECTURE.md). Current focused
evidence does not replace the remaining live and native-platform gates.
## Evidence index
| Evidence | Path | State |
|---|---|---|
| Measured baseline | [`BASELINE.md`](./BASELINE.md) | Recorded |
| Baseline command results and failures | [`TEST-EVIDENCE.md`](./TEST-EVIDENCE.md) | Recorded; baseline is not green |
| Deterministic backlog generator | [`../../scripts/gstack2/generate-backlog-map.ts`](../../scripts/gstack2/generate-backlog-map.ts) | Implemented and locally validated |
| Complete mapped backlog | [`BACKLOG-MAP.json`](./BACKLOG-MAP.json) | Generated from frozen snapshots |
| Baseline logs | `/tmp/gstack2-baseline-logs/` | External/ephemeral audit evidence |
| time-attack snapshots | `/tmp/gstack2-{open-items,open-prs,label}-pages.json` | External/ephemeral frozen input |
| garrytan snapshots | `/tmp/gstack2-upstream-{open-items,open-prs,label}-pages.json` | External/ephemeral frozen input |
| Required PR evidence | `/tmp/gstack2-port-prs/{610,...,2189}{,-files}.json` | External/ephemeral frozen input |
| Measured baseline | [BASELINE.md](./BASELINE.md) | Recorded |
| Candidate and baseline command ledger | [TEST-EVIDENCE.md](./TEST-EVIDENCE.md) | Broad macOS and local Windows-safe singleton runs green; live/native-platform gates pending |
| Complete skill migration | [SKILL-MIGRATION.md](./SKILL-MIGRATION.md) | Generated; 55/55 assignments |
| Judgment provenance | [JUDGMENT-PROVENANCE.json](./JUDGMENT-PROVENANCE.json) | Generated; 4,681-check parity rerun green |
| Parity contract | [JUDGMENT-PARITY.md](./JUDGMENT-PARITY.md) | Green for source/render/contract/asset fixtures |
| Semantic parity | [SEMANTIC-PARITY.md](./SEMANTIC-PARITY.md) | Deterministic 295-check corpus green; retained live samples are regressions |
| Installed-host adversarial | [eval overview](../../evals/host-adversarial/README.md), [immutable v2 artifact](../../evals/host-adversarial/runs/2026-07-17T04-09-01-809Z-3d23a270.json) | V1 failed; immutable V2 failed; V3 offline 18/111 green, live V3 not run; no passing live run |
| Structured scenarios | [SCENARIOS.md](./SCENARIOS.md) | 25/25 structured routing fixtures green |
| Backlog traceability | [BACKLOG-MAP.json](./BACKLOG-MAP.json) | 755 unique items mapped |
| Context integration | [CONTEXT-DEV.md](./CONTEXT-DEV.md) | Automated contract 22/139 green; live smoke blocked on verified key |
| Host matrix | [HOST-COMPATIBILITY.md](./HOST-COMPATIBILITY.md) | 470/470 checks; six hosts Verified at installer layer; live v3/UI launch pending |
| Privacy boundary | [PRIVACY.md](./PRIVACY.md) | Implemented contract; full retained-tool egress audit pending |
| Physical iOS | [IOS-PHYSICAL-DEVICE.md](./IOS-PHYSICAL-DEVICE.md) | Preflight 9 pass / 1 deploy skip / 29 assertions; signing blocked; no app/pass artifact |
| Upgrade/recovery | [UPGRADE-AND-ROLLBACK.md](./UPGRADE-AND-ROLLBACK.md) | Runtime installer 21 pass / 307 assertions; current bundle audit recorded |
## Interpretation rules
- `PORT_JUDGMENT` means “port the decision/policy with a replacement test,”
not “apply the upstream patch verbatim.”
- `FIX_IN_GSTACK_2` still requires a reproduced defect.
- `MECHANICAL_PORT` means the pinned rendered judgment body remains equal after
normalization; it is not permission to rewrite prose.
- `BUG_FIX` requires its linked PR/reproduction and regression fixture.
- `NEEDS_EVIDENCE`, `DEFER_COMMUNITY`, and
`SUPERSEDED_BY_CONSOLIDATION` remain review decisions, not closed GitHub
items. The generator performs no external mutation.
- The heuristic map is deterministic triage. Title-first and narrow body rules
make it auditable, but human approval is still required before implementation
or upstream disposition changes.
`SUPERSEDED_BY_CONSOLIDATION` are auditable dispositions, not GitHub state
changes. No labels, issues, or PRs are mutated by the map generator.
- A fixture-backed structural result does not replace a live browser, physical
device, external account, native OS, or host-install result where the gate
explicitly requires one.
- Do not market or release this branch as GStack 2 while this status is
`BLOCKED`.
+74 -1
View File
@@ -1,4 +1,77 @@
# GStack 2.0 baseline test evidence
# GStack 2.0 test evidence
## Candidate checkpoint — 2026-07-17
These results describe the working tree at the documentation checkpoint. They
are deliberately narrower than the P0 release matrix. Commands that need a
provider account, signed physical app, native OS, or live host are not marked
pass from deterministic, offline, or filesystem-only evidence.
| Command / probe | Observed result | What it proves / does not prove |
|---|---|---|
| Focused `bun test test/gstack2-*.test.ts` candidate run | **Exit 0: 130 pass / 0 fail**, 1,071 assertions across 15 files. Log: `/tmp/gstack2-direct-release.log`. | The focused GStack 2 routing/runtime/privacy/installer/upgrade and deterministic parity surface is green. It is not the broad repository or native-platform gate. |
| `bun test --timeout 30000 test/gstack2-skills.test.ts test/gstack2-skills-routing.test.ts` after regeneration | **Exit 0: 3 pass / 0 fail**, 81 assertions. | The pinned corpus/parity test and both 25-scenario structured-routing tests are green. This remains structural/fixture evidence, not specialist live execution. |
| `bun run scripts/gstack2/run-parity.ts`, 2026-07-17 rerun | **Exit 0: 4,681 checks passed**; 55 modules, 16 sections, 25 scenarios, 16 regressions, 78 assets. | Current source/render/provenance/contract/asset/fixture parity is green. It is deterministic parity, not live-host behavior. |
| Earlier regenerated structural parity checkpoint | **Exit 0: 2,403 checks passed** with the then-current 55/16/25/16/45 inventory. | Historical candidate checkpoint before later thin-prelude and asset coverage; superseded by the current 4,681-check rerun. |
| Earlier combined runtime/parity run before regeneration | **Exit 1: 20 pass / 1 fail**, 161 assertions. All 18 runtime tests and both routing tests passed; parity hit the default 5s timeout. A separate long-timeout attempt reported 29 stale-generation checks. | Preserved as history: generator inputs had changed. The post-regeneration rows above supersede the parity failure, not the runtime results. |
| `bun run scripts/gstack2/semantic-parity.ts` and `bun test test/gstack2-semantic-parity.test.ts` | **Deterministic corpus green: 295 checks**, 14 suites, 15 executions, all 15 dimensions, 16 carved sections, and nine authority-policy unit cases, including unsupported numeric claims. | Exact source-body and semantic-signature evidence is the primary reproducible oracle. The policy units consume hand-authored semantic operation envelopes; they are deterministic policy evidence, not behavioral-adversarial proof. |
| Retained Claude Haiku live semantic transcripts | **Three retained samples, all classified `REGRESSION`.** Two samples used now-obsolete visible-wrapper prompts. The current office-hours sample also penalizes independently sampled omissions even though those details remain byte-preserved in the candidate source. | Live-model sampling is supplemental and currently not green. These results must not be retried until favorable, cherry-picked, or used to overrule deterministic source loss. See [SEMANTIC-PARITY.md](./SEMANTIC-PARITY.md). |
| Installed-host adversarial v1 | **FAILED.** The immutable v1 slash-invocation artifact is retained. | Unfavorable activation/classifier evidence; not a behavioral pass. See [eval overview](../../evals/host-adversarial/README.md). |
| Installed-host adversarial v2 | **FAILED.** QA passed, while debug, review, and ship were false negatives from the v2 read-only-Git warning classifier. | All four dispatchers activated, but the top-level run failed and must stay failed. Immutable artifact: [`2026-07-17T04-09-01-809Z-3d23a270.json`](../../evals/host-adversarial/runs/2026-07-17T04-09-01-809Z-3d23a270.json), SHA-256 `7ab15ea575cb9a634b7d00212dd9d74902b1188281ae6a503a32ccf382facbf5`. |
| Installed-host adversarial v3 offline harness | **18 pass / 0 fail**, 111 assertions. | The classifier fix and offline harness are covered. Live v3 has **not run** and has no artifact; there is no passing live installed-host adversarial run. |
| Six-skill catalog measurement after regeneration | Six names/descriptions total 982 characters, about 246 four-character token-equivalents; baseline correctly parsed catalog was about 1,100. | 77.6% reduction, above the 75% gate. Re-measure if frontmatter changes. The buggy 4,214 baseline estimate is not used. |
| `bun test ios-qa/daemon/test` | **95 pass / 0 fail**, 229 assertions. | Covers daemon regressions including malformed device JSON, hardware-UDID/CoreDevice selection, bounded proxy timeout, and expected-bundle mutation header. It is not a signed-app live pass. |
| Focused DebugBridge/template build tests | **33 pass / 0 fail** in the candidate run, including Swift debug compilation/XCTest and Release symbol absence. | Static/build evidence for debug-only bridge wiring; still not an installed physical-app journey. |
| Physical-iOS E2E preflight | **9 pass / 0 fail / 1 deploy check skipped**, 29 assertions. | The connected-device/setup and unsigned Release checks pass. The deploy skip leaves the signed-device P0 gate open. |
| Direct physical-device smoke | **Typed failure:** code `signing_unavailable`, category `setup_gate`. | Automatic signing/provisioning is the remediable blocker. No app was installed or launched and no pass artifact was written. This is neither a product failure nor a pass. |
| Context.dev contract (`gstack2-runtime-context.test.ts`) | **22 pass / 0 fail**, 139 assertions. | Persists explicit host/local-browser/none choices without consent, rejects private/credential URLs and request material plus private DNS, proves zero lookup/fetch before mode+consent, validates documented endpoint paths and exact failure taxonomy, and makes search typed unsupported without network. |
| `gstack context smoke` | **Not run:** `CONTEXT_DEV_API_KEY` is not configured and no verified account key was available. | Live provider behavior, account verification, and actual credit metadata remain unverified. |
| Standard installer matrix | **PASS: 470/470 checks**, 16 install cases, two removal cases, `skills` CLI 1.5.19. | Project/global installs pass for six hosts, selected-skill and opt-in compatibility-alias cases, copies, and hashes. This remains installer/filesystem evidence. Committed artifact: [`evals/installation/install-matrix.json`](../../evals/installation/install-matrix.json). |
| `bun test test/gstack2-runtime-install.test.ts` | **Exit 0: 21 pass / 0 fail**, 307 assertions. | Managed allowlist, hashes, spaces, source/internal-link rejection, production-only frozen dependencies, capability closure, rollback/recovery, stable launchers, wrapper neutrality, and state-preserving uninstall pass. |
| Current managed runtime bundle audit | **107 components, 1,830 files, 459,056,031 bytes, 50 launchers.** | Setup includes the Sharp/ngrok closure and excludes the development-only Claude Agent SDK. The Hugging Face sidecar is outside the bundle and its package is development-only, so production setup installs neither its inference runtime nor model weights; the L4 capability reports unavailable. The standard skill installer remains Markdown-only. |
| Declared Dev Container build plus `bun run test:gstack2` inside it | **Container image built; Exit 0: 43 pass / 0 fail, 265 assertions.** | Focused canonical-skill, routing, parity, state, privacy, and runtime behavior is green in the declared Linux container. This is not a native-host broad Linux run. |
| `scripts/gstack2/runtime-install-smoke.sh` in the clean Linux arm64 container | **Pass:** production-only frozen dependencies installed with the development Agent SDK and Hugging Face/ONNX runtime absent; the managed Anthropic SDK, Sharp, and ngrok imports passed; prebuilt capabilities rebuilt; setup/doctor/version/design/PDF passed; a local-browser journey and Sharp full-page screenshot passed; uninstall preserved state. | Proves a source copy with spaces can build and complete the managed runtime lifecycle without Git history, an executable local-model stack, or Darwin-only iOS artifacts. It is not native Windows evidence. |
| Runtime lifecycle and external-effect matrix | **Pass:** real filesystem/subprocess tests cover clean install/uninstall, paths with spaces, source symlinks and internal-link rejection, macOS read-only reporting, interrupted-pointer rollback, crash-journal repair, last-known-good launcher recovery, and an actual local Git push that executes at most once across resume. | Closes the named local filesystem/recovery/idempotency gates. The aggregate live cancellation/leak gate remains open. |
| `bun test design/test` | **101 pass / 0 fail**, 381 assertions. | The retained design suite is green and is also included in the later uninterrupted broad pass. |
| `bun test make-pdf/test` plus combined-fixture render | **189 pass / 0 fail, 398 assertions;** four PDF pages rendered to PNG and visually inspected with no detected layout defect. | Retained strict PDF tests and a live internal render are green on this macOS host. Cross-platform visual equivalence remains a separate platform claim. |
| Diagram suites | **51 pass / 0 fail / 1 skip**, 120 assertions; the opt-in paid lane recorded two skips. | Offline Mermaid/SVG/PNG/Excalidraw coverage is green. Skipped paid-provider cases are not live evidence. |
| Isolated local-browser journey plus stop regression | Navigation, snapshot, screenshot, and status passed; stop returned success and left no observed process leak. `browse/test/stop-ack-before-shutdown.test.ts` is **2 pass / 0 fail**. | Provides one real local Chromium journey and a focused regression for acknowledging stop/restart before delayed shutdown. The complete browser suite is included in the later broad pass. |
| `bun test` through the strict singleton runner | **Exit 0: 6,234 pass / 226 expected skips / 0 fail**, 25,392 assertions; 383/383 shard headers and terminal single-file summaries. Log: `/tmp/gstack2-full-singleton-release2.log`. | One uninterrupted macOS broad pass after the browser lifecycle and retry-harness fixes. Expected skips are provider, credential, Poppler-environment, paid, or model-sidecar gates declared by their tests; external/live evidence remains separate. |
| Local `bun run test:windows` through singleton shards | **Exit 0: 2,813 pass / 57 expected skips / 0 fail**, 8,562 assertions; 213/213 shard headers and terminal single-file summaries. Log: `/tmp/gstack2-windows-singleton-release2.log`. | The curated Windows-safe subset is locally green under singleton isolation. This is not native Windows execution; native Windows CI remains blocked. |
| Forbidden production-scope audit | Production dependencies and the 107-component managed bundle contain no cloud-browser provider, Hugging Face/ONNX inference runtime, model weights, or alternative physical-iOS backend. Transformers remains development-only for retained tests; CoreDevice/`devicectl` is the sole physical-iOS path. | Deterministic dependency/bundle/backend evidence. It does not substitute for native-platform, signed-device, or live-provider behavior. |
### Required final command ledger
Append exact exit codes, aggregate counts, environment/version metadata, and
artifact/log locations for all of the following before changing status to
`DONE`:
```text
bun run gen:gstack2
bun run test:gstack2
bun run scripts/gstack2/run-parity.ts
bun run scripts/gstack2/semantic-parity.ts
bun run build
bun test
bun run test:windows
bun test design/test
bun test ios-qa/daemon/test
host UI/process launch for six installer-verified hosts
passing live v3 installed-host adversarial run
runtime-absent judgment through an actual host invocation
macOS + Linux + native Windows + Dev Container
local browser live journey + cancellation/leak cleanup
PDF strict + diagram suites
Context.dev verified-key public-page smoke
physical signed-iPhone five-check loop + Release symbol check
upgrade/fail/recover/rollback/uninstall end-to-end
```
The focused results above should remain in the ledger even after a later pass;
record the newer SHA/time beside the newer result rather than overwriting the
history.
## Baseline evidence — 2026-07-16
Scope: detached base worktree `/tmp/gstack2-baseline.e2qk7F`, commit
`bb57306d98c97011b0919c6132705a15b1579781`, captured 2026-07-16. These are
+197
View File
@@ -0,0 +1,197 @@
# GStack 2 upgrade and rollback
Skill placement and the optional runtime have different lifecycles. Do not
reintroduce host-specific setup by coupling them. Standard skill installation
remains Markdown-only; runtime dependencies are never smuggled into that path.
## Skill updates
Install and update the canonical Agent Skills source with the same standard
installer that placed it:
```bash
npx skills add time-attack/gstack
```
Use that installer's update/remove commands and scope. It owns project/global
placement, host destination paths, and selected-skill choices. GStack must not
re-detect hosts during an update or enroll a host/skill the user did not
previously select.
Before accepting an update, list the source and confirm that the defaults are
still exactly `plan`, `design`, `qa`, `debug`, `review`, and `ship`. Pure
judgment must remain usable even if the optional runtime update fails.
## 1.x command migration
The complete old-to-new map is [SKILL-MIGRATION.md](./SKILL-MIGRATION.md).
Opt-in compatibility aliases are retained for two minor releases or 90 days
from the 2.0 release, whichever policy the release notes identify. Each alias:
1. prints the canonical replacement;
2. routes to the exact preserved specialist module;
3. contains no copied judgment; and
4. stays outside default skill discovery.
Examples:
```text
/office-hours -> /plan --mode product
/plan-eng-review -> /plan --mode eng
/design-review -> /design --mode live-review
/qa-only -> /qa --mode report
/investigate -> /debug --mode investigate
/cso -> /review --mode security
/land-and-deploy -> /ship --mode land
```
Existing safe preferences may migrate. Context.dev choice and data-egress
consent must never be inferred from legacy browser, telemetry, service, or
update-check settings. Leave Context network mode off until the user explicitly
selects it.
## Initial managed runtime install
From a reviewed repository checkout, install only the optional runtime and
local capability bundle with:
```bash
./setup
```
Skill placement remains a separate standard-installer operation. `./setup`
resolves a symlinked source checkout, installs frozen production-only
dependencies, and invokes `runtime/install.js`. The installer copies an explicit allowlist
into an immutable version, rejects internal symlinks and path escapes, records
size/mode/SHA-256 for every file, validates capability targets, smoke-tests the
CLI, then atomically activates it. Stable POSIX and Windows launchers are
written under `$GSTACK_HOME/bin` (default `~/.gstack/bin`), alongside
`runtime-install.json`, which distinguishes managed paths from preserved
config, secrets, projects, and plans.
Twenty-one focused installer tests pass with 307 assertions. They cover paths
with spaces, a symlinked source root, internal-link rejection, runtime-only
builder selection, production dependency closure, failed build/validation/
smoke rollback, interrupted recovery, launchers, manifests, wrapper neutrality,
and state-preserving uninstall.
The current managed-bundle audit records 107 components, 1,830 files,
459,056,031 bytes, and 50 launchers. The Sharp/ngrok closure is included. The
development-only Claude Agent SDK and Hugging Face sidecar are excluded; the
Hugging Face package is development-only. Setup therefore installs neither its
inference runtime nor model weights and reports the L4 capability unavailable.
A separate clean Linux arm64 container smoke copied the source through a path
with spaces, installed only frozen production dependencies with the development
SDK absent, rebuilt runtime capabilities without Git history or skill
regeneration, passed setup/doctor/version/design/PDF checks, completed a local
browser journey and Sharp full-page screenshot, and uninstalled while
preserving state. Non-Darwin bundles omit the physical-iOS capability. Native
Windows execution remains a separate gate; source-level Windows launchers are
not native evidence.
## Runtime upgrade transaction
The candidate runtime intentionally does not combine “download arbitrary code”
with activation. Give it a reviewed staged directory and an explicit version:
```bash
gstack upgrade --source /path/to/verified-runtime --version 2.0.1
```
The transaction is:
```text
validate version and source
-> lock upgrade state
-> recover any interrupted pending transaction
-> copy to a unique stage directory
-> write stage metadata
-> run verification when supplied
-> atomically rename stage to immutable version directory
-> write pending pointer with last-known-good
-> run health check
-> atomically mark pointer active
```
If copy/verification fails, the stage directory is removed and the active
pointer is unchanged. If health fails, the previous pointer is restored and
the command returns `UPGRADE_ROLLED_BACK`. If the process dies after writing a
pending pointer, the next upgrade/cleanup/doctor path recovers the last known
good version before selection.
The runtime uses one per-user version store, not one copy per AI host. Skill
install failure and runtime install failure are independent; neither may erase
the other.
## Manual rollback
Inspect health first:
```bash
gstack doctor
gstack doctor --json
```
Roll back to the retained last-known-good version:
```bash
gstack upgrade --rollback
```
Rollback validates that the retained directory exists, optionally health-checks
it in the library call, atomically switches the pointer, and retains the version
rolled back from as the next fallback. If no fallback exists it fails with an
actionable error rather than choosing an arbitrary directory.
Runtime state schemas migrate forward only. If a state or migration marker is
newer than the running runtime, stop with `STATE_NEWER_THAN_RUNTIME` or
`MIGRATION_NEWER_THAN_RUNTIME`; never downgrade or rewrite the newer data.
## Recovery after interruption
1. Do not delete `~/.gstack/versions/current.json` while diagnosing.
2. Run `gstack doctor --json` and preserve the output with secrets removed.
3. Run `gstack cleanup --dry-run` to preview only stale managed temporaries.
4. Retry the upgrade command. It recovers a pending pointer before staging.
5. If the candidate remains unhealthy, use `gstack upgrade --rollback`.
6. Inspect the current worktree's run state with `gstack state inspect`.
7. Resume only the named/current-worktree run. An external effect left
`uncertain` must be reconciled; do not clear the marker and repeat it blindly.
Cleanup skips symlinks and user-named data, and removes only recognized stale
runtime temporaries/locks. `--dry-run` is non-mutating.
## Uninstall
Use the standard installer to remove skills. Separately, remove managed runtime
versions while preserving configuration, secrets, and project history:
```bash
gstack uninstall
```
Purge all runtime state only after reviewing the path and accepting data loss:
```bash
gstack uninstall --purge --yes
```
The runtime refuses unsafe roots such as the filesystem root or home directory.
It does not remove host skills, browser profiles, unrelated apps, repositories,
or iPhone data.
## Evidence state
Focused candidate tests cover the managed installer plus atomic activation,
failed-health rollback, interrupted-pointer recovery, manual rollback,
newer-schema refusal, and non-mutating cleanup preview. The standard installer
matrix separately passed 470/470 checks across six hosts, 16 installs, scopes,
selections, and two removals; its artifact is
[`evals/installation/install-matrix.json`](../../evals/installation/install-matrix.json).
The runtime installer is green at 21 pass / 0 fail and 307 assertions, and the
current 107-component bundle audit is recorded. The clean Linux Dev Container
install/uninstall smoke passed. Interrupted network acquisition/stage at OS
level, a passing live v3 host run, actual host UI execution, native-host Linux,
and native Windows runs remain gates. See
[TEST-EVIDENCE.md](./TEST-EVIDENCE.md).