# TEST_REPORT

## JUJU 0.8.2 — cross-platform setup/native acceptance, 2026-09-11

0.8.2 is gated by executable evidence rather than package-presence checks. Final frozen-source command logs, artifact metadata and registry verification are stored under `release-evidence/0.8.2/`; this document intentionally does not embed the tarball hash so publication receipts can be recorded after the shipped files are frozen.

| Environment | Evidence actually exercised before release |
|---|---|
| macOS arm64 / Node v22.23.2 | typecheck, lint, build, complete core/integration/security/compatibility suite, packaging install, `juju setup` deep probes and real Seatbelt confinement |
| Windows Server x64 / Node v24.21.0 / built-in Administrator | isolated 0.8.2 tarball install; private state ACL; 10/10 setup components; real Chromium browser sandbox; SAPI speech; real desktop JPEG capture + focus + UI Automation; Windows SRT provisioning/WFP plus five confinement checks; real MCP STDIO session with 74 tools, setup-managed Git and `run_command sandbox:true` |
| Debian bookworm arm64 / Node 22 (Linux container) | fresh tarball install; `juju setup` dependency installation/check; bubblewrap confinement; Xvfb X11 with X-Resource/XTEST + same-user D-Bus/AT-SPI; real process identity, capture, focus and accessibility enumeration |

Windows sandbox native checks proved: workspace write succeeds; an outside write is denied; JUJU owner-state read is denied; direct network is denied when requested; ACL/session cleanup restores the watched objects. The MCP STDIO follow-up separately proved a sandboxed workspace write and an attempted `C:\ProgramData` write returning `EPERM`.

Windows-specific failures found during acceptance were fixed and re-exercised rather than waived: Playwright AppContainer RX inheritance, missing `ProgramData` in the sanitized child environment, snake_case `srt-win` status parsing, explicit `srtWin` API wiring, private-profile launcher traversal, RX-only helper access for the dedicated sandbox identity, and an attempted ACL grant on protected `System32`.

The Linux desktop claim is intentionally limited to X11/XWayland-style sessions with `DISPLAY`, XTEST/X-Resource and AT-SPI. Pure Wayland portal-only behavior was not exercised. The Windows desktop claim requires an unlocked interactive session. External ChatGPT custom-MCP, a second Windows OS user, enabled 8.3 aliases, Defender/OneDrive permutations and Windows ARM64 remain separate manual/compatibility evidence rather than inferred passes.

The historical 0.8.1 and 0.8.0 sections below remain as the record of the earlier ACL hotfix/candidate state.

## JUJU 0.8.1 — Windows ACL owner hotfix, 2026-09-10

Actual environment: **darwin arm64 / Node v22.23.2**. Full local gate:
`node release-evidence/0.8.1/run-gates.mjs`, exit 0, completed
2026-09-10T14:48:18.063Z. Raw logs and machine-readable results are in
`release-evidence/0.8.1/verification.json` and adjacent files.

| Gate | Actual result |
|---|---|
| build / typecheck / lint | Each exit 0 |
| test:all — core | 452 passed, 30 skipped, zero failed |
| test:all — packaging | 13 passed, zero skipped/failed |
| Combined unique coverage | **465 passed, 30 skipped, zero failed** |
| test:windows focused rerun | 50 passed, 30 skipped, zero failed; not added again |
| Separate packaging rerun | 13 passed, zero skipped/failed; not added again |
| Guarded source/test/script/config hashes and mtimes | 188 files unchanged before/after |
| New native Windows ACL-owner tests | 9 skipped on this POSIX host — NOT Windows passes |
| Original Windows Server / Administrator retest | OWNER_PENDING |

The 30 skipped cases comprise 21 existing Windows-only tests and nine new
owner regression cases. Six new source-structure checks passed, but do not
execute PowerShell, emulate UAC, or certify NTFS behavior. Native tests require
an enabled Administrators token; they do not silently skip fixture failures on
Windows. They cover group-owner protect, file/directory verify with DACL
preservation, authenticated IPC descriptors, three foreign-owner cases,
permissive DACL rejection before repair, and junction refusal.

Runtime changes are confined to `src/platform/privateFs.ts`. Package/lockfile
version is 0.8.1, and test:windows includes the new tests. Existing security
checks remain in place. Source fingerprint excludes documentation/generated
outputs; the tarball has a separate artifact checksum. Publication is explicitly
owner-authorized after this local gate; consult the publish and fresh-registry
install receipts in `release-evidence/0.8.1/` for the actual outcome. No Git
commit/push/reset/clean, global install replacement or connected-server restart
is part of this task. Broader Windows native support is not certified here.

## JUJU 0.8.0 follow-up verification — 2026-09-10

This section supersedes the earlier candidate snapshot below for the current
source. Command: `node scripts/verify-windows-candidate.mjs`, exit **0**.
Actual host: **darwin arm64 / Node v22.23.2**. Exact timestamps, commands,
exit codes and JSON reporter counts are recorded in
`release-evidence/0.8.0/continuation/verification.json`.

| Gate | Actual result |
|---|---|
| Build / typecheck / lint | All exit 0 |
| Core (unit, integration, security, compatibility) | **446 passed, 21 skipped, 0 failed**, 54 files |
| Packaging and isolated fresh-install tests | **13 passed, 0 skipped, 0 failed**, 1 file |
| Combined, without double-counting focused reruns | **459 passed, 21 skipped, 0 failed**, 480 tests in 55 files |
| Focused platform rerun | 44 passed, 21 skipped, 0 failed; included in the core coverage above |
| Guarded source/test/script/config fingerprint | 186 files, before/after digests identical |
| Native Windows Node 22/24 and Windows 11 manual acceptance | **NOT_RUN** |

The 21 skipped tests are explicitly Windows-only: 18 NTFS/executable/schedule
cases, two batch/sandbox runtime cases and one DACL case. They are not passes.
Real cross-platform regression fixtures ran on this Mac, not on an emulated
Windows environment. The source fingerprint excludes documentation and generated
dist/schemas; its exact guarded inputs are in `continuation/source-manifest.json`.

Follow-up coverage adds rollback/recovery rejection after an ancestor becomes
a link or junction (even with identical file hashes), and after a hardlink is
introduced. Real Pyright tests now use native Node plus the JS entrypoint.
Packaging invokes npm through a platform-aware adapter, checks installed bin
shims separately from JS entrypoints, and prevents self-dependency/lock drift.
The Windows suite also covers case-colliding plans, read-only files, and explicit
unsandboxed schedule consent. Desktop grants are refused on Windows before saving;
media readiness probes and Git capability detection use the trusted resolver.

Latest local package and receipt:
`release-evidence/0.8.0/continuation/juju-mcp-0.8.0.tgz` and `artifact.json`.
Earlier logs and artifacts remain historical evidence, not the current package.
No npm publication, git commit/tag, global installation or running-server replacement
was performed. Windows remains **EXPERIMENTAL** until its native CI and manual gates pass.

## JUJU 0.8.0 candidate — local gate, 2026-09-10

Environment actually exercised: **darwin arm64, Node v22.23.2**.
Command: `npm run build && npm run test:all` — **exit 0**.
Raw evidence: `release-evidence/0.8.0/final-gate.log` and `final-gate.exit`.
Core run started at 20:28:19 local Asia/Bangkok; packaging at 20:28:42.

| Gate | Actual local result |
|---|---|
| Build / typecheck / lint | Passed |
| Unit / integration / security / compatibility | **446 passed, 18 skipped, 0 failed**; 54 files (53 passed, 1 entirely skipped) |
| Packaging, including isolated fresh-prefix install | **12 passed, 0 failed**; 1 file |
| Combined | **458 passed, 18 skipped, 0 failed**; 55 test files total |
| Native Windows Node 22 / 24 CI | NOT_RUN; workflow added, no native result claimed |
| Windows 11 / second-user / Defender / actual 8.3 manual acceptance | MANUAL_NOT_RUN |
| npm publish / production deployment | NOT_DONE |

All 18 skips on this host are explicitly Windows-only: 15 NTFS/executable
boundary cases, 2 Windows batch/sandbox runtime cases and 1 Windows DACL case.
They are **not passes**. The portable platform contracts, real local
filesystem/jobs/IPC contracts and existing regression suites did run.
The fresh packaging install result is macOS evidence, not Windows evidence.

The resumed baseline exposed two regressions: the LSP in-workspace denial
message and an oversized IPC fixture still using the old unauthenticated
protocol. Both were repaired without relaxing authorization, then rechecked
in the focused gate (55 passed / 18 skipped) and this full gate. Preserve
`resumed-baseline.log` as failure evidence rather than replacing it with the
passing log. `windows-contracts-local.log` predates the package-version bump
and is implementation-focused evidence; `final-gate.log` is the 0.8.0 run.

New coverage includes native argv, long private shell scripts, Thai/spaced
paths, BOM/CRLF edit and rollback, stale hashes, job cancellation/timeouts,
IPC mutual authentication, invalid proofs, replay and spoof rejection,
descriptor tampering, plus Windows-only NTFS/DACL cases. Full/compact/hybrid
catalog invariants and existing OAuth/ACL/journal tests remain in the gate.

Windows remains **EXPERIMENTAL**. The native CI and manual gates in
[WINDOWS_0.8.0](WINDOWS_0.8.0.md) and [MANUAL_ACCEPTANCE](MANUAL_ACCEPTANCE.md)
are outstanding, including any legacy test portability repairs uncovered
by a native run. Local package metadata is recorded in
`release-evidence/0.8.0/artifact.json` and `verification.json`.

The older release sections below retain their historical results.

## JUJU 0.7.1 release gate — 2026-09-10

Environment: macOS 26.3.1 arm64, Node v22.23.2, npm 10.9.8. Command:
`npm run build && npm run test:all` — exit 0.

| Gate | Recorded result |
|---|---|
| Typecheck / lint / build | AUTOMATED_PASS |
| Unit, integration, security, compatibility | 400 passed in 49 files; no skips recorded in this environment |
| Packaging | 12 passed in 1 file |
| Combined | **412/412 tests, 50 files** |

New 0.7.1 coverage: compact catalog invariants (≤ 20 tools, full coverage map,
per-gateway minimum scope, strict schemas), juju_discover query/detail with
deterministic schemaHash and pagination, gateway security (read-only token
denied on every effectful gateway with the TARGET scope in detail, nested
workspace-context override rejected, stale epoch/mismatch, secret and
traversal guards, inspect-mode approval bound to the target operation,
WORKSPACE_ACCESS_REQUIRED on revoked ACL, FILE_CHANGED passthrough, enum
rejection of unknown operations), full write→read→edit→read-back→delete over
HTTP compact, run_command idempotency replay through the gateway, assistance
plan/preview/verify through gateways, image/audio content-block passthrough
(image_view, browser_observe, media_read after speech synthesis), browser
fill/click with effect idempotency, game step, workflow save/search/run,
STDIO full-by-default plus explicit `--tools compact`, explicit IdToken TTL
(no oidc-provider default-TTL notice during an openid login), PACK-12 compact
schema shipped and served from the installed tarball. The 24 direct-contract
suites now pin `toolSurface: 'full'` explicitly; the compact default is
covered by its own suites. Surface size evidence (tools/list-equivalent payload incl. output schemas):
full 74 tools / 237 755 bytes vs compact 19 / 46 834 (−80.3%); live measured
tools/list 236 518 → 46 707 bytes.

Manual gates NOT claimed by this run: live ChatGPT rescan/write/edit through
the real UI (see MANUAL_ACCEPTANCE.md), external tunnel acceptance,
Linux/macOS Intel/Node 24.

## JUJU 0.7.0 release gate — 2026-09-10

Environment: macOS 26.3.1 arm64, Node v22.23.2, npm 10.9.8. Command:
`npm run build && npm run test:all` — exit 0.

| Gate | Recorded result |
|---|---|
| Typecheck / lint / build | AUTOMATED_PASS |
| Unit, integration, security, compatibility | 363 passed in 43 files; no skips |
| Packaging | 11 passed in 1 file; no skips |
| Combined | **374/374 tests, 44 files** |
| Production dependency npm audit | 0 reported vulnerabilities at release check |

Evidence is stored outside the npm payload in `release-evidence/0.7.0/gate.log`
and `dependency-audit.json`. The final packed/registry verification receipts are
maintained separately in the release directory; they must not be inferred merely
from a successful test run or a publishing notice.

New coverage includes coding-assistance tools, real image/audio content over MCP,
local FFmpeg decoding, Whisper transcription, macOS TTS, Chromium form actions,
actual video seek/play/pause, browser game key release, workflow state checks,
principal/path boundaries and uncertain-effect receipts. Packaging verifies that
media setup and both feature guides are shipped, models/media/state are not, and
installed setup check/help do not create a model or JUJU configuration.

New native desktop controls use a fake OS adapter with actual image buffers.
Real owner-window input/gameplay, microphone/system-audio capture, external AI
client/tunnel, Linux/macOS Intel/Node24 acceptance are not claimed by this gate.
Windows support is not added. These limits remain explicit in MULTIMODAL.md.

## Historical release evidence (0.6.3 and earlier)

Actual results from running the automated suite on the build machine. Status
values follow the spec: `AUTOMATED_PASS`, `AUTOMATED_FAIL`, `MANUAL_PASS`,
`MANUAL_NOT_RUN`, `NOT_SUPPORTED`.

## Run environment

- macOS 26.3.1, Darwin arm64 · Node v22.23.2, npm 10.9.8
- git 2.50.1 present; ripgrep NOT on the Node PATH here (the JS/worker search
  fallback is what the suite exercised); `/usr/bin/sandbox-exec` present
- pyright (devDependency) for the LSP suites
- Commands: `npm run typecheck`, `npm run lint`, `npx vitest run` (JSON reporter
  → `node scripts/test-report.mjs`)
- Latest release-gate date: 2026-09-10 (Asia/Bangkok; UTC logs begin 2026-09-09)

## Summary

| Suite | Result |
|---|---|
| typecheck (TS strict + exactOptionalPropertyTypes) | AUTOMATED_PASS — 0 errors |
| lint | AUTOMATED_PASS — 0 errors |
| all vitest suites | **AUTOMATED_PASS — 293/293 tests, 37 files** (284 in unit/integration/security/compatibility + 9 packaging; `npm run test:all` exit 0 on 2026-09-10 for 0.6.3 OAuth approval commands) |

The complete 0.6.3 command runs 284 tests across 36 unit, integration,
security and compatibility files, followed by 9 packaging tests in one file.
Earlier release totals are retained in the dated entries below as historical results;
removed 0.5.x chat workflows do not apply to 0.6.0.

Integration tests use real components — real HTTP server, real `oidc-provider`, real
`better-sqlite3`, real child processes, the real MCP SDK v2 client (HTTP and
stdio transports), real `pyright` language server, real macOS `sandbox-exec`.
Security boundaries are exercised with local fixtures; real OAuth accounts
and external tunnels are not used. Tests use loopback networking, and the
packaging install may fetch dependencies from npm.

## Acceptance-case coverage map

### A. CLI / root / configuration — `integration/cli.test.ts`, `unit/spoolAndConfig.test.ts`
CLI-01..10, CFG-01..05: AUTOMATED_PASS (install-from-tarball, CWD capture in a
monorepo, port-in-use exit, unsafe-root refusal, locked mode, malicious
`.juju.json`/AGENTS.md inert, persistence across restart, no HTTP admin route).
CLI-07 (two profiles at once) is exercised only for single-port paths.

### B. MCP protocol — `integration/m0-transport-oauth.test.ts`, `compatibility/mcp.test.ts`, `integration/stdio.test.ts`
MCP-01..10: AUTOMATED_PASS (modern SDK client, 2025 stateless, 405 on
GET/DELETE, schema validation, structured output + isError, deterministic
catalog, cursor scoping). stdio transport: AUTOMATED_PASS. MCP-11 Inspector:
MANUAL_NOT_RUN.

### C. Authentication / boundary — `security/auth.test.ts`
AUTH-01..18: AUTOMATED_PASS (anonymous 401 + metadata, PKCE, revocation, scope
intersection, Host/Origin/null, body caps, exact callback, interaction id
cannot self-approve, restart persistence, no token in audit). AUTH-19/20:
covered by fail-closed config + local proxy fixture; real-proxy end-to-end
MANUAL_NOT_RUN.

### D. Files / search — `unit/pathPolicy`, `unit/ignores`, `security/pathTraversal`, `unit/coreUtils`, `integration/agentTools`
FS-01..13: AUTOMATED_PASS, including the new search modes, glob filter, context
lines and the terminable regex worker.

### E. Changes / journal / rollback — `integration/changes.test.ts`, `integration/faultInjection.test.ts`, `integration/directTools.test.ts`
CHG-01..15: AUTOMATED_PASS. CHG-08 (injected write failure mid-changeset →
revert or PARTIAL_RECOVERY_REQUIRED) and CHG-09 (simulated crash →
recovery_required on boot, mutations blocked until resolved) are now covered
by `faultInjection.test.ts`.

### F. Jobs / Git / diagnostics — `integration/jobs.test.ts`, `integration/gitAndDiag.test.ts`, `integration/agentTools.test.ts`
JOB-01..13, GIT-01..03, DIAG-01..02: AUTOMATED_PASS; plus parallel
`run_commands`, `background` + `job_wait`, macOS sandbox enforcement, git
commit/log with secret filtering.

### G. Semantics / handoff / packaging — `integration/semantics.test.ts`, `integration/lsp.test.ts`, `integration/lspTools.test.ts`, `packaging/pack.test.ts`
SEM-01..06 (TS) AUTOMATED_PASS; Python via pyright (symbols, cross-file
references excluding comments/strings, rename plan applied through the
journal, diagnostics) AUTOMATED_PASS; HAND-01..02, PACK-01..06 AUTOMATED_PASS
(tarball manifest = catalog, no secrets/state, no install hooks, fresh install
runs `juju doctor`). PACK-03 Linux: run the included CI workflow — not
inferred from macOS.

### H. Manual gates
MAN-01..11: MANUAL_NOT_RUN (real ChatGPT / tunnel / client UIs). See
[MANUAL_ACCEPTANCE.md](MANUAL_ACCEPTANCE.md).

## Honest gaps / follow-ups
- Linux enforcement of the bwrap sandbox and the whole suite on Linux: CI only.
- gopls / rust-analyzer not exercised (same LSP protocol; pyright only).
- PERF-01/02 benchmarks not recorded.
- Windows unsupported.

## 2026-09-09 — OAuth consent correction and npm installation guide

- Added AUTH-22 using `openid juju:read juju:write juju:exec`: failed before
  the correction because provider resume redirected to a second interaction.
  After correction it completes one approval, exchanges the authorization code
  and dispatches authenticated MCP `tools/list`.
- `npm run typecheck`, `npm run lint`, `npm run build`: exit 0.
- `npm run test:security`: exit 0, 32/32 tests across 3 files.
- Expanded root README with Thai installation, STDIO, ChatGPT static OAuth,
  Codex OAuth, consent/trust distinction, sandbox limitations, updates and
  troubleshooting. Verified its local links and explicit section anchors.
- `npm run test:pack`: exit 0, 6/6 tests, after the documentation update.
- `npm pack --dry-run --json`: exit 0; root README included in package files.
- No claim of a full test:all rerun for this documentation update. Live ChatGPT
  reconnection after the consent correction: MANUAL_NOT_RUN. Registry publish
  for these changes: NOT_RUN.

## 2026-09-09 — 0.1.1 release gate

`npm run test:all` exited 0: typecheck and lint passed; 183 tests across
21 unit/integration/security/compatibility files passed, followed by 6/6
packaging tests. Total: 189 passing tests across 22 files. This supersedes
the earlier note that test:all had not been rerun. Live ChatGPT remains a
manual gate, not inferred from these results.

## 2026-09-09 — 0.2.0 local release gate

`npm run test:all` exited 0: typecheck and lint passed; **195/195** tests in
23 unit/integration/security/compatibility files, then **6/6** packaging tests.
Total **201 passing tests across 24 files**. The full run followed the final
code changes (workspace-bound pending OAuth requests and local-config audit).

New evidence includes identity-token reuse only after per-path consent,
read-only scope intersection, another client denied, immediate ACL/grant
revocation, legacy grant-marker protection, refresh after root switch, root
inode replacement resetting trust/access, foreign workspace journal isolation,
private config token/Host/Origin/forwarded-header checks, occupied admin port,
and real CLI startups for bare juju / --allow --all / --bypass. Pairing of
--allow and --all is validated. Existing explicit STDIO tests still pass.

Browser fixture check: read grant saved through rendered local UI, survived a
page reload; token fragment removed from displayed URL. Fixture shut down after
verification. This does not assert a successful live ChatGPT connection or
Cloudflare tunnel test. External 0.2 flow remains MANUAL_NOT_RUN.

## 2026-09-09 — 0.2.1 scopes migration and terminal readability

Migration 4 repairs workspace_clients.scopes copied as space-separated text by
migration 3. Regression fixtures reconstruct schema 2 and schema 3 databases,
verify preserved scopes and revoked access, and reopen the database to ensure
revocations are not re-granted. Malformed ACL values deny access without JSON
parse exceptions. Terminal color tests preserve plain output and URL text.

The first full run was interrupted because CLI tests used fixed config port
21731, now occupied by the owner's running server. Tests now use isolated
configPort:0; production default remains 21731. The owner's server was not
stopped. A cleanup wait also now handles children that already exited.

Final `npm run test:all`: exit 0; **205/205 tests across 25 files** (recorded
0.2.1 total; an earlier edit incorrectly mixed in 0.3.0's counts). Live owner
server restart after installation remains a user action; no npm publish in
this patch task.

## 0.3.0 — Local Config dashboard and runtime workspace switch

- `security/workspaceSwitch.test.ts` — WS-01 capability/origin/proxy-header refusal and no switch tool in the catalog; WS-02 real A→B switch (MCP serves B, stale context WORKSPACE_MISMATCH, client refused until the owner grants B, write FORBIDDEN under a read-only ACL, per-workspace history, IPC socket follows, old socket gone, audit row, back to A restores A's own trust/ACL); WS-03 refusal while a job runs (job untouched) and while a request is in flight, then success; WS-04 typed refusals for missing/file/home/relative/empty/non-string targets and no-op on the same root; WS-05 refusal when another live JUJU process serves the target; WS-06 pending approvals of the old workspace are denied.
- `security/localConfig.test.ts` — adds: packaged UI served with a `'self'`-only CSP, no inline script/handlers, no `innerHTML`, token never echoed, 501 NOT_SUPPORTED for single-workspace entries.
- `integration/cli.test.ts` CLI-NEW — updated to the nested state shape and asserts the run-mode override field.
- `packaging/pack.test.ts` PACK-07 — the three UI assets ship in the tarball.
- Browser check (AI-driven, fixture server on 21740/21741, isolated config dir): dark default and persisted theme cycling, desktop and 375 px layouts, real switch A→B with the project_overview hint and refreshed permissions/clients, client scope save, revoke with confirmation dialog, trusted confirmation dialog with cancel, keyboard focus ring. Clipboard writes were denied by the embedded browser, so the copy button's error path was exercised, not the success path.

## 2026-09-09 — 0.3.1 workspace safety corrections

- `npm run test:all`: exit 0; typecheck/lint passed, 209 tests across 25 files
  and 7 packaging tests passed (**216/216 across 26 files**).
- WS-07: stale local config contexts cannot alter ACL/trust or switch roots;
  includes A→B→A with a stale epoch and a valid fresh-state save.
- WS-08: a delayed real tool handler survives an aborted HTTP fetch; switching
  is refused until the handler and audit finish, then succeeds.
- WS-09: a partial HTTP request on the old listener is disconnected during
  shutdown; after same-port restart valid token succeeds and revoked token
  gets 401. HTTP stores are not closed under old surviving connections.
- AUTH-18 repeated in isolation three times: all exit 0. The earlier full-run
  500 was intermittent; these results do not prove every possible restart
  race is eliminated, but the old-connection lifecycle defect is addressed.
- Browser fixture: two Local Config tabs, A→B switch in one, attempted read
  ACL save from stale A tab in the other. UI displayed refusal; no silent
  retry. Temporary fixture server and tabs were closed after verification.
- Production ChatGPT/tunnel flow after this patch: MANUAL_NOT_RUN. No registry
  publishing in this task; installed server processes require restart.

## 2026-09-09 — 0.3.1 documentation and registry release preparation

- Updated README upgrade instructions for HTTP/OAuth and explicit STDIO,
  release notes, identity/ACL architecture, compatibility, browser acceptance,
  and the two-profile tunnel example (distinct MCP and private config ports).
- No runtime source changed after the passing 216-test 0.3.1 gate above.
- `npm run test:pack`: exit 0, 7/7 tests after the documentation edits; this
  rebuilds the runtime/UI/schemas and installs the tarball in a fresh fixture.
- Local documentation link and code-fence validation: exit 0 (9 files).
- The final tarball file list and integrity are recorded in the adjacent
  `juju-mcp-0.3.1.manifest.json` in the source checkout. Publishing is a separate
  operation; registry verification is not inferred from packing or a dry run.

## 2026-09-09 — 0.4.0 desktop extension

- `npm run test:all`: exit 0; typecheck/lint pass, 228 tests in 27 core files
  plus 8 packaging tests: **236/236 tests in 28 files**.
- 13 desktop unit cases: off-by-default, local app/TTL validation, boot/root
  separation, view-only denial, helper absence, snapshot principal/expiry/cache
  limits, coordinate validation, approval ordering, policy revocation while
  awaiting capture, serialized calls, drained shutdown and durable retry/
  uncertain outcome semantics without storing input text or screenshots.
- 6 desktop security cases use real HTTP/OAuth/SQLite/IPC with a **fake OS
  adapter** to avoid manipulating the user's desktop: scope/path/context checks,
  local consent, exact action approval, revocation, image dispatch, private
  stop token/epoch boundary and CLI acknowledgment. The OS adapter is simulated;
  those cases do not prove native click/type correctness.
- PACK-08 verifies bundled Swift source alongside the runtime without native
  installation/enabling hooks. Existing 43 coding tools remain covered.
- `npm run test:desktop:native`: exit 0 on macOS 26.3.1 arm64, Node 22.23.2.
  Swift compilation, only the owned fixture-window screenshot (600×432),
  Vision OCR and native refusal without Accessibility passed. Screen Recording
  true, Accessibility false. Positive OS control and AX are MANUAL_NOT_RUN.
  Receipt: `artifacts/desktop-native-report.json` (local, excluded from tarball).
- Private Local Config browser fixture: Desktop grant displayed, stop clicked,
  off state and success notice observed. Fixture and tab were shut down.
- README/docs updated after the suite; the final UI-only adjustment preserves
  the stop button's disabled state after its busy handler finishes. No live
  server was stopped, OS permissions changed, tunnel configured or npm release
  published as part of this feature work.

## 2026-09-09 — 0.4.1 remembered desktop consent

- Targeted desktop unit/security plus CLI: 42/42 tests, exit 0.
- `npm run test:all`: exit 0, typecheck/lint passed; 238 core tests plus
  8 packaging tests = **246/246 in 28 files**. Log for this local run:
  `/private/tmp/juju-041-tests.log`.
- Six additional unit cases verify persistent consent survives time/boot only
  for the same workspace; snapshots remain 30 seconds; view still cannot send
  input; another SQLite connection can revoke immediately; identical re-grants
  invalidate old snapshots by revision; temporary consent replaces remembered
  consent; malformed/ambiguous records fail closed and legacy grants stay temporary.
- Two additional security cases exercise the real installed-CLI build against
  a running HTTP/OAuth fixture: saved policy takes effect, read-only tokens
  remain denied, there is no remote enable tool, CLI disable takes effect, and
  repository configuration/AGENTS cannot grant desktop access. Existing private
  UI stop test now revokes a persistent grant and checks it stays off on reboot.
  OS adapters are fake in these cases, not proof of native input.
- Two additional CLI cases save before startup with no listener/repo edits,
  start/restart the nested Thai/space path, verify the parent has no grant,
  revoke while stopped, and reject missing --yes or --persist with --minutes.
- Fresh-tarball install test also runs saved allow and offline disable from
  the packaged CLI. No new dependencies or native helper changes.
- Native click/type/AX and external ChatGPT/tunnel tests were not rerun for
  this change. The owner supplied separate terminal output showing macOS
  permissions true; that is not an agent-run positive input test. Manual
  browser rendering of the new persistent-label text: MANUAL_NOT_RUN.

### 0.4.1 local UI follow-up — copyable desktop command

- Added a dedicated, wrapping command box and copy button using the existing
  clipboard handler. No permission or server behavior changes.
- `npm run build` and `npm run lint`: exit 0. Browser fixture with an isolated
  workspace/config shows the exact Chrome --persist command and help text;
  screenshot inspected. Clicking the button through the browser locator showed
  the success label. Embedded clipboard adapter readback did not match, so
  cross-client paste/clipboard verification remains MANUAL_NOT_RUN.
- The 246-test gate above predates this HTML/CSS/copy-wiring-only follow-up;
  the full suite was not repeated. The local tarball is rebuilt with these UI
  assets; no npm publication and no user workspace permission was changed.

## 2026-09-09 — 0.4.2 owner kill with login continuity

- `npm run test:all`: exit 0; typecheck/lint passed. **254/254 tests in 30 files**
  (246 core, 8 packaging). Full log: `/private/tmp/juju-042-tests.log`.
- Targeted shutdown/stdio/jobs/workspace/security suites after adding instance
  endpoints: 31/31 tests, exit 0. Prior targeted OAuth/shutdown run: 42/42.
- Three new integration cases run the built CLI from an unrelated CWD:
  two HTTP servers and two stdio servers (same root) stop, their owned long job
  stops, an unrelated Node process and another JUJU config remain live, and
  repeated kill is a no-op. Fake names/PIDs are never used as signal targets.
- Real OAuth fixture: existing access token dispatches after kill/restart;
  refresh credentials obtain a new working access token; revoked credentials
  remain rejected; signing/cookie keys and config bytes are unchanged. Epoch
  changes and client/path access survives. No external accounts/tunnel used.
- Five new negative cases cover mismatched live identity, symlink/non-private
  IPC, acknowledged but unfinished stop, expected PID/epoch refusal and bounded
  IPC responses. No public kill endpoint is introduced.
- Packed-install smoke also runs `juju kill --json` from the home directory
  against its isolated fixture config; it finds no server without changing
  auth state or starting a listener.
- Additional local compatibility check started the previously installed
  **0.4.1** HTTP CLI in an isolated config, then stopped it using the new built
  CLI from another directory: **PASS, legacy process exit 0**. User servers
  were not stopped by this development test.
- Live ChatGPT automatic retry/reconnection and native desktop input:
  MANUAL_NOT_RUN for this release. Local OAuth continuity does not guarantee
  a particular client's transport retry behavior.

## 2026-09-09 — 0.4.3 large coding inputs

- Final `npm run test:all`: **exit 0; 272/272 tests in 33 files**
  (264 core in 32 files, 8 packaging in one file). Typecheck/lint passed.
  Full log: `/private/tmp/juju-043-tests-final.log`.
- Targeted gates: 56/56, then 58/58, both exit 0. The first full gate failed
  WS-09 because it sent a revoked token on a partial body; moving auth before
  parsing correctly rejected it before it could remain in flight. The partial
  connection fixture now uses a valid token. Its drain/no-500 and post-restart
  revoked-token assertions remain. The final full gate above passes.
- Nine new integration cases: real modern HTTP and legacy stateless dispatch;
  300+ KiB shell source with Unicode/heredoc; idempotent retry; independent
  parallel jobs and bounded echoes; stdin, 0600 source/0700 directory, cancel
  cleanup; 3 MiB write/preview/edit/stale-hash/rollback; 20 KiB native argv;
  real macOS sandbox execution; STDIO **11 MiB file** and **exact 8 MiB shell
  source** through SDK 2.0.0; spawn failure and injected state failure cleanup.
- Six negative integration/security cases: UTF-8 byte caps; invalid batch
  starts no job; no script/process before approval; file-size/secret/traversal
  rejection; HTTP 413 and unauthenticated 401; NUL refusal; multiplicative
  replacements rejected before allocating oversized results (edit, preview, bulk).
- Three unit/CLI cases: owner profiles preserve non-input settings; read-only
  query creates no config; corrupt/invalid/unlimited values cannot overwrite;
  native argv byte/combined limits and shell hard-boundary validation.
- Same macOS 26.3.1 arm64 / Node v22.23.2 / npm 10.9.8; SDK 2.0.0,
  diff 9.0.0, TypeScript 5.9.3, better-sqlite3 13.0.3, oidc-provider 9.12.2.
  No dependency updates. Linux/Intel large-shell execution was not run here.
- Actual ChatGPT/Claude UI payload limits and real tunnel/proxy compatibility:
  MANUAL_NOT_RUN. These tests do not establish unlimited client capacity.
  Registry publication is verified separately from the local test gate.

## 0.5.0 release gate — 2026-09-10 Asia/Bangkok

- `npm run test:all`: exit 0, 275 + 9 tests; source log
  `/private/tmp/juju-050-release-gate.log`. Typecheck and lint pass.
- New suites: usageConsent (5), schedules (6), installed tarball consent (1).
  Tests perform real OAuth, legacy/modern MCP, CLI/IPC, child process launches,
  SQLite migration/restart, and packed-package STDIO with nested Thai/spaced CWD.
- First full run exposed old assertions conflating ACL denial with invalid OAuth
  and fixtures claiming historical schema versions while retaining new tables.
  Updated fixtures reconstruct the real old schema and assert tool denial/no leak.
  The post-kill fixture now confirms a fresh usage round while testing the same
  OAuth/refresh credentials and revocation continuity.
- A subsequent full run caught asynchronous EPIPE while closing stdin on a very
  short scheduled command. Fixed: schedules launch with stdin disabled; JobManager
  handles closed input pipes without an uncaught server error. Full rerun passes.
- Local browser fixture: owner phrase approval, refusal without the schedule
  checkbox, schedule approval, both revocations, and rendered config details
  verified through browser UI. This is an isolated local fixture, not a live
  ChatGPT account test. No user server or OAuth state changed by these checks.
- MANUAL_NOT_RUN: real ChatGPT/Claude/Codex conversation lifecycle, external
  tunnel/cached reconnect UI, multi-day/DST and actual sleep/wake scheduling.
- No new branch-coverage measurement was produced; scenario counts do not claim
  the original 85% coverage target. Windows/macOS x64/Linux/Node24 not run here.

## 0.5.1 local package gate — 2026-09-10 Asia/Bangkok

- `npm run test:all`: exit 0, **312/312 tests in 37 files** (303 core + 9
  packaging). Typecheck and lint both exit 0. Receipt: `release-evidence/0.5.1/test-all.log`.
- Added strict URL/UUID parser cases (18), raw HTTP/owner IPC/private web security
  scenarios (8), actual STDIO CLI allow/reset/restart (1), and schema-5 migration
  preservation (1). PACK-09 additionally exercises installed `chat allow`, direct
  chat-bound reads and reset denial in a nested Thai/spaced CWD.
- Verified: approval before any AI request; no root leakage before consent;
  missing/mismatched chat denial; ambiguous/wrong client denial; repeated allow
  idempotence; path/trust/scope enforcement; specific/all reset; old usage ID
  invalidation after reallow; usage_end revokes parent consent; owned job cancel;
  independent schedule execution and unchanged OAuth; restart/switch-back;
  real directory replacement; timed expiry; owner capability/origin/forwarding/
  stale-workspace rejection; public approval URL returns 404.
- First full run: 302/303 core tests passed; same-port restart probe hit a stale
  Node fetch pooled connection (`ECONNRESET`). The new fixture closes request
  connections and retries only read-only overview probes on those transport
  resets (not mutations, assertions or auth failures). Affected suite rerun:
  18/18 tests passed. Full rerun above passes; no security assertion removed.
- Local browser fixture (isolated config/root, registered test-only public
  client): pasted sample URL, automatic sole-client selection, allow status,
  clipboard button success, per-chat reset, allow again, all-chat reset, and
  expanded CLI instructions verified via UI. Screenshot inspected for readable
  form/long-ID wrapping. Real user config, OAuth and running server untouched.
- Release is local only in this turn. No npm publication, global installation
  replacement or live ChatGPT whitelist/connection test is claimed.
- MANUAL_NOT_RUN: real ChatGPT chat ID forwarding/lifecycle, mobile layout,
  external tunnel, Windows/Linux/macOS x64/Node24 for this change. Verified chat
  identity is NOT_SUPPORTED, not a test result. No new branch coverage metric.

## 0.5.2 WEB URL local gate — 2026-09-10 Asia/Bangkok

- Reported bug: owner `chat allow` rejected a `/c/WEB:UUID` URL because the
  parser accepted only unprefixed UUIDs. Accept the explicit WEB namespace in
  URLs/bare references, normalize casing, and preserve it in storage/output.
- `npm run typecheck` and affected parser/security/STDIO suites: exit 0,
  44/44 tests in 3 files. `npm run test:all`: exit 0, **325/325 tests in 37 files**
  (316 core + 9 packaging), including strict typecheck and lint.
- Added 12 parser cases (WEB forms and malformed/foreign/traversal inputs) and
  one cross-surface regression: actual owner CLI allow, private web API allow,
  raw MCP overview, plain UUID isolation, and WEB ID reset. Existing STDIO and
  installed-package fixtures now include WEB references and restart/revocation.
- Test logs: `release-evidence/0.5.2/affected.log` and `test-all.log`.
- Existing UUID permissions are unchanged; no database migration or OAuth
  registration change. Unknown prefixes, query strings and fragments remain
  rejected. Caller-provided IDs still do not attest real conversation identity.
- Local package only; no global replacement/publication or actual ChatGPT chat
  access. Real-client UI/lifecycle and other OS/architecture runs: MANUAL_NOT_RUN.

## 0.5.3 owner chat-list folder context — 2026-09-10 Asia/Bangkok

- `npm run test:all`: exit 0, 325/325 tests in 37 files (316 core + 9 packaging).
  Typecheck/lint pass. Extended existing scenarios instead of adding test cases.
- Actual HTTP owner CLI: lists the current root and correct folders per client,
  excluding revoked and corrupt read ACLs; same-name clients remain distinct.
  Actual STDIO CLI and installed tarball: exact root/name and client folder,
  including the nested Thai/spaced packaging fixture.
- First core run had a same-port restart ECONNRESET in the existing usageConsent
  fixture, before any assertion. Updated that fixture to close pooled connections
  and retry only overview probes on transport resets (not mutations or assertion
  failures), consistent with the existing chat fixture. Affected suites: 19/19
  pass. The final full run above passes; security assertions remain intact.
- Logs: release-evidence/0.5.3/{initial-core-run,affected,test-all}.log.
- No public MCP response, OAuth/ACL grant, database migration or live user's state
  changed. Folder lists reflect saved read ACLs, not current filesystem existence
  or proof of which client ChatGPT uses. No new external-client/other-platform
  test claimed. Local package only; not published or globally installed here.

## 0.6.0 direct MCP use — 2026-09-10 Asia/Bangkok

- `npm run typecheck && npm run build` plus affected directAccess, schedules,
  stdio and kill suites: exit 0, **17/17 tests in 4 files**.
- `npm run test:all`: exit 0, **284/284 tests in 35 files** (275 core + 9
  packaging), including strict typecheck and lint. Logs:
  `release-evidence/0.6.0/affected.log` and `test-all.log`.
- Removed obsolete feature tests (30 parser, 9 chat, 5 usage, 1 STDIO chat case)
  and added 4 direct-access security regressions. The lower count reflects the
  owner's explicit feature removal, not skipped auth/path/exec safety checks.
  Helpers dispatch tools directly, with no hidden chat/usage approval step.
- Verified actual authenticated HTTP overview/read/write/command execution;
  49-tool schemas without chat/usageId; removed public/private controls;
  anonymous/invalid/revoked-token refusal, inspect exec approval, secret/traversal
  refusal, stale epoch and denied new workspace; legacy revoked rows inert
  across restart while OAuth remains valid. Other security suites still pass.
- STDIO, installed-package, modern/legacy MCP, OAuth/refresh after kill, Desktop,
  large payload, safe change journal and semantic suites remain active. Cron
  proposals are still pending until local approval; actual execution/revoke,
  restart, duplicates, policy/grant boundaries pass in schedule fixtures.
- Opened an isolated Local Config browser fixture: version 0.6.0, Workspace,
  Desktop (off), Permissions, Connection, Scheduled commands and Client access
  rendered; no chat/usage controls. Inspected screenshot and accessibility tree.
  No real owner permissions or OAuth credentials were used. Closed fixture/tab.
  This check covers rendering; full live-client interaction is not claimed.
- Package tests install a real tarball into a fresh prefix and dispatch overview
  and guarded reads from nested Thai/spaced CWD without chat fields. Packaging
  excludes removed compiled consent modules and state/secrets; no install hook.
- SDK 2.0.0 / oidc-provider 9.12.2 / better-sqlite3 13.0.3 unchanged. Tested on
  macOS 26.3.1 arm64 / Node22.23.2 / npm10.9.8. No new branch-coverage metric.
- MANUAL_NOT_RUN: real ChatGPT/Claude/Codex UI/tunnel, Node24, Linux/macOS Intel,
  native Desktop input, multi-day/DST/sleep-wake schedules. Windows unsupported.
  Local artifact only: no npm publication/global installation replacement.

## 0.6.1 current-folder Client access — 2026-09-10 Asia/Bangkok

- `npm run typecheck && npm run build` plus localConfig/workspaceSwitch suites:
  exit 0, **16/16 tests in 2 files** after correcting TypeScript errors in the
  new tests. No failing assertion was skipped or weakened to pass.
- `npm run test:all`: exit 0, **286/286 tests in 35 files** (277 core + 9
  packaging). Typecheck and lint pass. Logs: release-evidence/0.6.1/{affected,
  test-all}.log. No new branch-coverage measurement was made.
- New regressions verify same-name active/other-root/revoked/malformed clients,
  read-only listing, secret/other-root-data exclusion, on-demand available
  clients, auth/Origin/forwarded/stale-context rejection, explicit local add,
  stale duplicate add denial, revoke/re-add eligibility and preserved global
  registration/other-root ACL. Existing workspace switch test now checks that
  an unauthorized client is absent, then appears once explicitly allowed.
- Actual isolated browser UI: initially 1 current-folder card; expanded picker
  lists the other fixture client; selected read and saved -> 2 cards; revoked
  that client -> 1 card. Switched root while picker was open -> picker closed,
  fresh path, 0 cards and explanatory empty state. Screenshot inspected. All
  test data/config were isolated; test tab/server closed afterward.
- Dependencies, 49-tool MCP contract, OAuth and SQLite migrations unchanged.
  Fresh package install/CLI/STDIO and packaged UI tests pass. Final tarball
  integrity/install evidence is recorded in juju-mcp-0.6.1.local-release.json.
- macOS26.3.1 arm64, Node22.23.2/npm10.9.8 only. Real ChatGPT/tunnel and other
  platforms/Node24 are MANUAL_NOT_RUN. No npm publication or global update.

## 0.6.2 owner client deletion — 2026-09-10 Asia/Bangkok

- Typecheck/build and affected clientDeletion/localConfig/auth suites: exit 0,
  **30/30 tests in 3 files**. `npm run test:all`: exit 0, **289/289 tests in
  36 files** (280 core + 9 packaging), typecheck/lint pass. Logs in
  release-evidence/0.6.2/{affected,test-all}.log.
- Three new integration/security scenarios: real access/refresh denial after
  selected deletion with other client access/refresh preserved; all-root ACL
  removal, pending OAuth denial, model cleanup, audit and retained grant history;
  capability/origin/proxy/workspace/confirmation/hash validation; empty/duplicate
  selection refusal; newly registered clients excluded from old selections;
  injected SQLite trigger failure rolls back the entire batch and permits a
  correct retry. Public listener has no corresponding deletion route.
- Browser fixture with two public dummy clients: select one, cancel -> both
  remain; confirm -> only selected registration disappears, current-root client
  remains; select all remaining -> empty registration and current-root lists,
  delete button disabled. Screenshot inspected. Fixture/tab closed; real owner
  state and running server untouched.
- Inspected installed oidc-provider 9.12.2 Client.find implementation: with
  configured clients:[], adapter lookup occurs before dynamic object-cache reuse.
  Same-process refresh-denial tests verify deletion takes effect without restart.
  No dependency/MCP wire change; 49 tools. No new branch-coverage measurement.
- macOS26.3.1 arm64/Node22.23.2/npm10.9.8. Real ChatGPT/tunnel, other OS/Node24,
  and real account deletion remain MANUAL_NOT_RUN. These are local development
  test results; publication and registry-install verification have separate
  release receipts in the source checkout, outside the npm package.

## 0.6.3 — OAuth request IDs starting with hyphens

- Reproduced the printed CLI command failure with deterministic `-` and `--`
  request IDs: before the fix, 3 of 4 regression cases failed (two CLI parsing
  cases and the browser command); the ordinary-ID control passed.
- Terminal and browser instructions now include the standard `--` argument
  separator. Real built CLI calls against isolated SQLite/IPC fixtures approve
  the exact reviewed request and deny another request; consumed requests remain
  rejected. A real OAuth browser response displays the corrected command.
- `npm run typecheck`, `npm run lint`: exit 0.
  `npx vitest run tests/integration/oauthCli.test.ts tests/integration/cli.test.ts
  tests/security/auth.test.ts`: exit 0, **39/39 tests in 3 files**. Logs:
  `release-evidence/oauth-cli-leading-dash/{before,checks,after}.log`.
- Final 0.6.3 release gate: `npm run test:all`, exit 0, **293/293 tests in
  37 files**, typecheck/lint passed. Log: `release-evidence/0.6.3/test-all.log`.
  Publication and final package/registry-install receipts are kept separately
  in the source checkout. Same macOS arm64/Node22 toolchain; external AI-client
  UI/tunnel and other-platform acceptance remain MANUAL_NOT_RUN.
- Existing npm 0.6.2 already accepts
  `juju auth approve -- ID` and `juju auth deny -- ID`. No real owner request
  was approved or denied, and the running global installation was not changed.
