@wacando/agent 0.0.0-stage → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.agents/plugins/marketplace.json +10 -0
  2. package/.claude-plugin/marketplace.json +12 -0
  3. package/.cursor-plugin/marketplace.json +12 -0
  4. package/README.md +166 -2
  5. package/STATUS.md +121 -0
  6. package/THIRD-PARTY-NOTICES.txt +1928 -0
  7. package/adapters/README.md +12 -0
  8. package/adapters/claude/mcp.mjs +7 -0
  9. package/adapters/codex/mcp.mjs +7 -0
  10. package/adapters/cursor/mcp.mjs +7 -0
  11. package/bin/wacando-agent.mjs +243 -0
  12. package/docs/AGENT_TOOLS.md +129 -0
  13. package/docs/CURSOR_IDENTITY_RESUME.md +579 -0
  14. package/docs/MCP-AUDIT.md +355 -0
  15. package/docs/MCP-CONTRACT.md +138 -0
  16. package/docs/MIGRATION-2.0.md +36 -0
  17. package/docs/OMEMO_PREKEY_INTEGRATION.md +125 -0
  18. package/docs/ONBOARDING-VALIDATION.md +88 -0
  19. package/docs/ONBOARDING.md +212 -0
  20. package/docs/ONBOARDING_PLUGIN_CONTRACT.md +156 -0
  21. package/docs/PLUGIN_HANDOFF_FOLLOWUP.md +178 -0
  22. package/docs/PUBLIC_ONBOARDING_READINESS.md +156 -0
  23. package/docs/RELEASE.md +25 -0
  24. package/docs/WACANDO_PACKAGES.md +26 -0
  25. package/docs/evidence/issue-2/DOCUMENTARY_FOLLOWUP.md +107 -0
  26. package/docs/evidence/issue-2/QUALIFICATION_LINK_FOLLOWUP.md +105 -0
  27. package/docs/evidence/issue-2/REVIEW_FOLLOWUP.md +93 -0
  28. package/docs/evidence/issue-2/baseline.txt +76 -0
  29. package/docs/evidence/issue-2/check-mcp.txt +14 -0
  30. package/docs/evidence/issue-2/check.txt +376 -0
  31. package/docs/evidence/issue-2/codex-exec-help.json +11 -0
  32. package/docs/evidence/issue-2/codex-help.json +10 -0
  33. package/docs/evidence/issue-2/cursor-help.json +10 -0
  34. package/docs/evidence/issue-2/documentary-check.txt +376 -0
  35. package/docs/evidence/issue-2/documentary-validation.txt +7 -0
  36. package/docs/evidence/issue-2/local-build-api.txt +203 -0
  37. package/docs/evidence/issue-2/local-build-first.txt +87 -0
  38. package/docs/evidence/issue-2/local-build-policy-first.txt +34 -0
  39. package/docs/evidence/issue-2/local-build-policy.txt +153 -0
  40. package/docs/evidence/issue-2/local-build-web.txt +219 -0
  41. package/docs/evidence/issue-2/local-check-mcp.txt +14 -0
  42. package/docs/evidence/issue-2/local-check.txt +376 -0
  43. package/docs/evidence/issue-2/local-codex-probe.txt +3 -0
  44. package/docs/evidence/issue-2/local-codex-probe2.txt +3 -0
  45. package/docs/evidence/issue-2/local-codex.txt +2 -0
  46. package/docs/evidence/issue-2/local-cursor-probe.txt +1 -0
  47. package/docs/evidence/issue-2/local-cursor.txt +2 -0
  48. package/docs/evidence/issue-2/local-down.txt +32 -0
  49. package/docs/evidence/issue-2/local-health.txt +1 -0
  50. package/docs/evidence/issue-2/local-live.txt +28 -0
  51. package/docs/evidence/issue-2/local-seed.txt +26 -0
  52. package/docs/evidence/issue-2/local-status.txt +6 -0
  53. package/docs/evidence/issue-2/local-up.txt +18 -0
  54. package/docs/evidence/issue-2/prepare-local-stack.py +67 -0
  55. package/docs/evidence/issue-2/qualification-body-validation.txt +9 -0
  56. package/docs/evidence/issue-2/qualification-link-check.txt +376 -0
  57. package/docs/evidence/issue-2/qualification-link-validation.txt +20 -0
  58. package/docs/evidence/issue-2/review-check.txt +376 -0
  59. package/docs/evidence/issue-2/review-validation.txt +218 -0
  60. package/docs/evidence/issue-7/README.md +21 -0
  61. package/docs/evidence/issue-7/check-mcp.txt +9 -0
  62. package/docs/evidence/issue-7/check.txt +381 -0
  63. package/docs/evidence/issue-7/live.txt +23 -0
  64. package/docs/evidence/issue-8/README.md +56 -0
  65. package/docs/evidence/issue-8/check-mcp.txt +9 -0
  66. package/docs/evidence/issue-8/check.txt +465 -0
  67. package/docs/evidence/issue-8/e2e-desktop-observer-human-devices.txt +30 -0
  68. package/docs/evidence/issue-8/e2e-desktop-observer-main-without-109.txt +17 -0
  69. package/docs/evidence/issue-8/e2e-desktop-observer.txt +26 -0
  70. package/docs/evidence/issue-8/live-regression-human-devices.txt +24 -0
  71. package/docs/evidence/issue-8/live-regression.txt +23 -0
  72. package/docs/evidence/issue-8/review-fixes/README.md +30 -0
  73. package/docs/evidence/issue-8/review-fixes/check-mcp.txt +9 -0
  74. package/docs/evidence/issue-8/review-fixes/check.txt +484 -0
  75. package/docs/evidence/issue-8/review-fixes/e2e-desktop-observer.txt +28 -0
  76. package/docs/evidence/issue-8/review-fixes/onboarding-live.txt +15 -0
  77. package/docs/evidence/issue-8/review-fixes/session-replacement-live.txt +13 -0
  78. package/docs/evidence/npm-release/check-mcp.txt +9 -0
  79. package/docs/evidence/npm-release/check.txt +484 -0
  80. package/docs/evidence/npm-release/e2e-desktop-observer.txt +28 -0
  81. package/package.json +66 -4
  82. package/packages/core/limits.mjs +24 -0
  83. package/packages/core/store.mjs +92 -0
  84. package/packages/core/validation.mjs +25 -0
  85. package/packages/mcp/agent-tools.mjs +82 -0
  86. package/packages/mcp/server.mjs +161 -0
  87. package/packages/mcp/stdio.mjs +42 -0
  88. package/packages/onboarding/network.mjs +60 -0
  89. package/packages/onboarding/service.mjs +235 -0
  90. package/packages/onboarding/storage.mjs +99 -0
  91. package/packages/onboarding/version.mjs +2 -0
  92. package/packages/runtime/conversations.mjs +384 -0
  93. package/packages/runtime/device.mjs +34 -0
  94. package/packages/runtime/index.mjs +8 -0
  95. package/packages/runtime/pairing.mjs +110 -0
  96. package/packages/runtime/runtime.mjs +213 -0
  97. package/packages/runtime/session.mjs +52 -0
  98. package/packages/server/cli.mjs +18 -0
  99. package/packages/server/server.mjs +110 -0
  100. package/packages/server/stream.mjs +42 -0
  101. package/packages/web/app.js +85 -0
  102. package/packages/web/history.js +48 -0
  103. package/packages/web/index.html +17 -0
  104. package/packages/web/style.css +1 -0
  105. package/plugins/wacando/.codex-plugin/plugin.json +18 -0
  106. package/plugins/wacando/.mcp.json +8 -0
  107. package/plugins/wacando/skills/wacando/SKILL.md +33 -0
  108. package/plugins/wacando-claude/.claude-plugin/plugin.json +10 -0
  109. package/plugins/wacando-claude/.mcp.json +8 -0
  110. package/plugins/wacando-claude/README.md +88 -0
  111. package/plugins/wacando-claude/skills/open/SKILL.md +66 -0
  112. package/plugins/wacando-cursor/.cursor-plugin/plugin.json +11 -0
  113. package/plugins/wacando-cursor/README.md +48 -0
  114. package/plugins/wacando-cursor/commands/wacando-open.md +10 -0
  115. package/plugins/wacando-cursor/mcp.json +8 -0
  116. package/plugins/wacando-cursor/skills/wacando/SKILL.md +50 -0
  117. package/provenance.json +503 -0
@@ -0,0 +1,156 @@
1
+ # Public onboarding readiness — September 23, 2026
2
+
3
+ Local site/plugin interoperability is validated within the scope of the
4
+ [integration record](OMEMO_PREKEY_INTEGRATION.md). The next gate is deployment
5
+ of the onboarding API and web application, then the complete HTTPS/WSS journey.
6
+ This is not approval to publish the npm package.
7
+
8
+ ## Production observations and deployment candidate
9
+
10
+ Unauthenticated GET probes with redirects disabled, on September 23 at
11
+ 00:16 UTC, returned 404 from both:
12
+
13
+ - `https://app.wacando.fr/v1/onboarding`
14
+ - `https://api.wacando.fr/v1/onboarding`
15
+
16
+ A credential-free WebSocket connection to `wss://xmpp.wacando.fr/ws` opened
17
+ with negotiated subprotocol `xmpp`. TLS certificate verification was enabled.
18
+ This proves only the public WebSocket upgrade, not SASL authentication, session
19
+ grants, OMEMO or STOP in production. No production account was created.
20
+
21
+ The source route requires a human session; after deployment, an unauthenticated
22
+ GET should return the expected 401 rather than 404. A 401 alone is not acceptance:
23
+ the authenticated owner response and actual plugin callbacks must also pass.
24
+
25
+ The existing Wacando runbook is `../wacando/docs/deploy/wacando.md`; its workflow
26
+ is `.github/workflows/wacando.yml`. It builds API, policy and web images from
27
+ main, pins `IMAGE_TAG` to the commit SHA, and deploys via Coolify. At inspection,
28
+ onboarding, its migration, web changes and OMEMO repairs were still uncommitted
29
+ in the upstream checkout, mixed with other work. No release commit has been
30
+ selected in this session. Redeploying the existing image cannot incorporate
31
+ those working-tree changes. Select and review the actual release candidate
32
+ before triggering the workflow; preserve unrelated changes.
33
+
34
+ Required candidate contents and checks:
35
+
36
+ 1. Include the API routes, auth changes, schema and migration
37
+ `apps/api/drizzle/0001_lonely_starfox.sql`, journal/snapshot, and matching web
38
+ proxy/onboarding UI. Include the OMEMO fixes used by the local qualification.
39
+ 2. Run the upstream candidate's CI and migration checks using disposable test
40
+ infrastructure, then follow the existing runbook for backup, deployment and
41
+ rollback. The API entrypoint runs migrations: merely replacing the web image
42
+ does not deploy onboarding. Do not remove production tables for rollback.
43
+ 3. Preserve the provisioned database, secrets and routing. The production API
44
+ sets `XMPP_DOMAIN=wacando.fr`; the enrollment response currently defaults to
45
+ `wss://xmpp.wacando.fr/ws` for that domain. Verify the actual response after
46
+ deployment rather than assuming build-time web settings configure the API.
47
+ 4. `WACANDO_PLUGIN_INSTALL_COMMAND` is read by the API but is not currently
48
+ forwarded by the checked-in production Compose API environment. Before the
49
+ later npm launch, wire it into the deployment configuration and verify the
50
+ owner response contains the exact published, versioned command. Leave it
51
+ unset until a real package/version exists; do not invent availability.
52
+ 5. Record deployed image digests, migration result and route health, then execute
53
+ the HTTPS/WSS acceptance below. No production deployment was performed here.
54
+
55
+ ## HTTPS/WSS acceptance after deployment
56
+
57
+ Use synthetic owners and the final installed plugin. Preserve existing host
58
+ configuration and use the literal site-generated prompts. Record the host
59
+ version and final bundle hash, without storing prompt tokens or credentials.
60
+
61
+ - The real MCP verification tool makes the owner's installation green.
62
+ - The second prompt binds the intended agent to the selected installation.
63
+ - Enrollment returns the expected secure XMPP destination; the durable credential
64
+ obtains a grant, XMPP authentication and OMEMO publication succeed before the
65
+ connected callback. Follow no credential-bearing redirect.
66
+ - The existing peer and plugin decrypt in both directions; both owners observe
67
+ both senders in their real browsers. Server scans find no plaintext canaries.
68
+ - A host restart preserves identity/keys and resumes using the saved credential,
69
+ without consuming another temporary token. Heartbeat recovery and STOP pass.
70
+ - Expiry, replay, wrong installation and revocation fail as specified, with no
71
+ durable credentials in MCP output or host logs. Revoke test agents afterward.
72
+
73
+ The current live scripts deliberately restrict their target to loopback. Do not
74
+ remove that restriction casually or claim their local pass covers production;
75
+ prepare a scoped production fixture and explicit synthetic-account cleanup.
76
+
77
+ ## Host qualification
78
+
79
+ The final bundle is identified by the hash in the integration record.
80
+ `scripts/check-host-onboarding.mjs` exercises real Codex CLI with a separately
81
+ installed copy and literal site prompts. See that record for the latest result.
82
+
83
+ Codex CLI 0.153.4 passed verification, enrollment and fresh-host resume with
84
+ the final bundle. Cursor Agent CLI `2026.08.25-3e8eec8` also passed all three
85
+ steps with the actual copied Cursor plugin loaded via `--plugin-dir`. Both runs
86
+ checked installation/connection callbacks and found no durable credential
87
+ markers in host output. The fixtures revoked their synthetic agents afterward.
88
+
89
+ ```sh
90
+ WACANDO_TEST_HOST=cursor \
91
+ WACANDO_LIVE_TEST_ORIGIN=http://localhost:3005 \
92
+ WACANDO_CHECKOUT=/home/kyle/work/wacando \
93
+ node scripts/check-host-onboarding.mjs
94
+ ```
95
+
96
+ Cursor used `--auto-review`, with workspace trust limited to the newly created
97
+ fixture directory; no `--force`, `--yolo`, sandbox disable or blanket MCP
98
+ approval was used. An initial harness path error and then a workspace-trust
99
+ refusal were corrected before the passing run. These were setup failures and
100
+ did not validate the plugin. The tests do not exercise Cursor IDE installation
101
+ UI or its built-in browser.
102
+
103
+ Cursor Agent CLI is installed and authenticated, version `2026.08.25-3e8eec8`.
104
+ The `cursor --version` error came from a PATH-searching shell shim; it did not
105
+ prove Cursor was absent. The initial absence claim was incorrect.
106
+ `claude` is not available in this shell's PATH; this does not prove absence
107
+ elsewhere. Claude still needs both real tools, host reload and credential-based
108
+ resume in an installed, authenticated host. Record its actual version and
109
+ browser availability. Successful packaged-process tests alone do not qualify
110
+ an actual host. Existing global host configuration was preserved.
111
+
112
+ ## Consumed-prekey recovery: definition for implementation review
113
+
114
+ Current behavior remains fail-closed. No automatic repair is implemented and
115
+ no previously deleted private prekey can be reconstructed. The following is a
116
+ proposed bounded recovery design for the shared Wacando OMEMO components, not
117
+ a plugin transport replacement or an already accepted protocol change:
118
+
119
+ 1. Distinguish a missing consumed prekey from authentication failure or an
120
+ untrusted identity. Persist neither plaintext nor secrets in diagnostics.
121
+ 2. Keep the receiver's identity and all healthy sender/device ratchets. Publish
122
+ the remaining/replenished public bundle with monotonically increasing IDs;
123
+ never restore deleted one-time private keys or reuse their IDs.
124
+ 3. For the affected sender/device pair, obtain a fresh authenticated bundle and
125
+ establish a new session only through the existing provider's supported
126
+ handshake. Specify an authenticated recovery signal and duplicate handling
127
+ before implementation; do not infer successful delivery from publication.
128
+ 4. Bound automatic attempts per peer/device and back off. Do not silently reset
129
+ trust or retry old ciphertext as if it belonged to the new session. Message
130
+ resend needs a defined duplicate/delivery policy; require an explicit user
131
+ resend when delivery is uncertain. Never replay old transcript content
132
+ automatically into a new conversation.
133
+ 5. Prove forced stale-bundle collisions, two devices under one sender, concurrent
134
+ senders, restarts during recovery, replay, ratchet preservation and STOP with
135
+ real crypto. STOP/revocation must cancel recovery, and a closed conversation
136
+ must never reopen. No plaintext fallback is permitted.
137
+
138
+ Until that design is implemented and independently reviewed upstream, surface
139
+ the failure and preserve local state. A new onboarding token cannot repair an
140
+ OMEMO session. Do not prescribe deleting local state or recreating an agent as
141
+ a proven fix. This differs from the documented lost-enrollment-response case,
142
+ whose current API recovery requires revoking the identity and using a new handle.
143
+
144
+ ## Unexplained timeouts remain open
145
+
146
+ The first integration run had five deadline failures; the unchanged rerun passed.
147
+ The [integration record](OMEMO_PREKEY_INTEGRATION.md) retains their exact counts
148
+ and scope. The MCP helper's default deadline was 3 seconds and relocated-package
149
+ tests had a 10-second deadline. No per-request startup/queue/event-loop timing
150
+ was captured in the failed run, so contention is only a hypothesis.
151
+
152
+ On recurrence, capture redacted request IDs/methods, startup/initialization
153
+ latencies, child exit status, event-loop delay and concurrent workload timings.
154
+ Compare isolated and overlapping runs with identical code and deadlines. Do not
155
+ raise timeouts or mark the incident resolved solely because a retry passes.
156
+ The earlier transient enrollment connection failure remains a separate incident.
@@ -0,0 +1,25 @@
1
+ # Releasing `@wacando/agent`
2
+
3
+ The runtime is published **publicly** on registry.npmjs.org as
4
+ `@wacando/agent` (bin `wacando-agent`) by `.github/workflows/release.yml`,
5
+ with the repository secret `NPM_TOKEN` (granular automation token with
6
+ read/write on the `wacando` npm org). The repository stays private.
7
+
8
+ 1. Bump the version in `package.json`, `packages/onboarding/version.mjs` and the
9
+ three plugin manifests (`npm test` checks they agree), merge to `main`.
10
+ 2. `git tag v<version> origin/main && git push origin v<version>`.
11
+
12
+ The workflow (self-hosted `lbframe-ci`, pinned Node 24 builder image) checks the
13
+ tag equals the package version (stable tags must be on `main`; prereleases
14
+ `-rc.N` may point at a PR head and get the `next` dist-tag), runs `npm ci` and
15
+ `npm run check`, packs, dry-runs, publishes with `--access public`, then in a
16
+ clean `node:22` container installs `@wacando/agent@<version>` globally from the
17
+ registry, anonymously, and runs `wacando-agent --version` / `--help`.
18
+
19
+ - No `--provenance`: npm refuses provenance for private source repositories and
20
+ on self-hosted runners.
21
+ - No Actions artifacts are uploaded (the organization's storage quota is shared).
22
+ - Licence: `UNLICENSED` (proprietary; no open-source licence has been decided).
23
+ The README states the terms; dependencies keep their own licences
24
+ (`THIRD-PARTY-NOTICES.txt`).
25
+ - A version can never be republished: bump instead.
@@ -0,0 +1,26 @@
1
+ # Wacando packages (public npm)
2
+
3
+ The runtime depends on the shared Wacando packages built from the private
4
+ `lbframe/wacando` repository and published **publicly on registry.npmjs.org**
5
+ by its `packages.yml` workflow (lbframe/wacando `docs/PACKAGES.md`):
6
+
7
+ | Package | Used for |
8
+ |---|---|
9
+ | `@wacando/contracts` | product types, handles, JID mapping |
10
+ | `@wacando/xmpp` | presence echo (`announceAvailable`), MUC, MAM, PEP, origin checks, policy deliveries |
11
+ | `@wacando/omemo` | native OMEMO on the official `@signalapp/libsignal-client`; `./wire` policy submission/digest helpers |
12
+
13
+ - `package.json` pins exact versions; `package-lock.json` pins each archive's
14
+ SHA-512 from `registry.npmjs.org`.
15
+ - `scripts/check-deps.mjs` (first step of `npm run check`) fails unless the
16
+ three packages resolve from the public registry at the pinned versions, with
17
+ no nested copy, the official libsignal present and no `@privacyresearch/*`
18
+ (classic GPL backend) anywhere in the graph.
19
+ - No Wacando source is copied into this repository. The temporary `deps/`
20
+ archives used while GitHub Packages was billing-blocked are gone.
21
+
22
+ Updating: `npm install --save-exact @wacando/contracts@<v> @wacando/xmpp@<v> @wacando/omemo@<v> && npm run notices && npm run check`.
23
+
24
+ `@signalapp/libsignal-client` ships native prebuilds for macOS x64/arm64,
25
+ Windows x64/arm64 and Linux x64/arm64 inside its npm package; no compiler is
26
+ needed (`node-gyp-build` picks the prebuild for the running platform).
@@ -0,0 +1,107 @@
1
+ # Issue #2 documentary follow-up — October 15, 2026
2
+
3
+ Initial local and PR #9 HEAD: `24ace6ef95d4a4f595dd712b325a1fc7cbbba449`.
4
+ Branch: `fix/cursor-identity-resume`. Repository: `lbframe/wacando-agent`
5
+ (private; the local directory/remote retain the historical `wacando-plugin` name).
6
+ PR #9 was OPEN/draft; plugin issue #2 and Wacando #17 were OPEN.
7
+
8
+ King's explicit decision relayed in mission
9
+ `1dc1a826-eefb-4610-bdfa-5027f88ab4d0`: issue #2 acceptance covers identity
10
+ resume and revocation through all three runtime profiles on real
11
+ Postgres/ejabberd/OMEMO. Actual Cursor/Codex/Claude CLI qualification is deferred
12
+ to [Wacando #17](https://github.com/lbframe/wacando/issues/17).
13
+ Independent review is pending. This is an acceptance-scope correction, not a
14
+ new implementation or a change to recorded outcomes.
15
+
16
+ | Evidence | Observed outcome | Acceptance scope |
17
+ | --- | --- | --- |
18
+ | [Original live runtime suite](local-live.txt) | 3 passed, 0 failed, 0 skipped: codex, cursor, claude runtime profiles | PASS for issue #2 runtime resume/revocation; no actual CLI claim |
19
+ | [Original full live check](local-check.txt) | 57 passed, 0 failed, 0 skipped | Existing regression and runtime acceptance evidence |
20
+ | [Cursor checker](local-cursor.txt), [probe](local-cursor-probe.txt) | Exit 1 before confirmed MCP; EROFS writing host sandbox-policy state | Cursor CLI NOT QUALIFIED in the sandbox; never PASS |
21
+ | [Codex checker](local-codex.txt), [initial probe](local-codex-probe.txt), [second probe](local-codex-probe2.txt) | Exit 1 before confirmed MCP; read-only filesystem initializing app-server | Codex CLI NOT QUALIFIED in the sandbox; never PASS |
22
+ | Actual Claude CLI | No onboarding/resume attempt recorded in this evidence | Claude CLI NOT QUALIFIED in the sandbox; runtime PASS is separate |
23
+ | [Documentary follow-up check](documentary-check.txt) | Exit 0; 54 passed, 0 failed, 3 skipped | Current build/generated-runtime/regression check; live stack not restarted |
24
+
25
+ All previously committed raw outputs remain byte-for-byte unchanged. The
26
+ [manual procedure](../../CURSOR_IDENTITY_RESUME.md#manual-cli-qualification-after-host-restart)
27
+ provides exact per-CLI launch commands, a consumed-token placeholder, private
28
+ local fingerprint comparison, normal shutdown and fresh-host revocation
29
+ rejection. It was not executed here. The prior CLI `--help` success assertion
30
+ is withdrawn below; no CLI or MCP qualification follows from help output.
31
+
32
+ ## Commands and results for this follow-up
33
+
34
+ From the plugin checkout:
35
+
36
+ ```sh
37
+ git branch --show-current
38
+ git rev-parse HEAD
39
+ git ls-remote origin refs/heads/fix/cursor-identity-resume
40
+ gh pr view 9 --repo lbframe/wacando-agent --json title,body,headRefName,headRefOid,isDraft,state,url
41
+ gh issue view 2 --repo lbframe/wacando-agent --json title,body,state,url
42
+ gh issue view 17 --repo lbframe/wacando --json title,body,state,url
43
+ gh issue view 42 --repo lbframe/wacando --json title,body,state,url
44
+ ```
45
+
46
+ Exit 0. Local branch `fix/cursor-identity-resume`, local/remote/PR initial HEAD
47
+ `24ace6ef95d4a4f595dd712b325a1fc7cbbba449`, draft/open PR and open issues
48
+ confirmed. Initial bodies incorrectly treated CLI qualification as an issue #2
49
+ acceptance blocker. Wacando #17's existing blockers are agent #3/#4 and service
50
+ #12/#16/#40/#37; #42's existing blockers are #40/#37. Plugin #2 has no recorded
51
+ blocked-by dependency. These dependency edges are preserved.
52
+
53
+ ```sh
54
+ timeout 20s codex --help
55
+ timeout 20s codex exec --help
56
+ timeout 20s cursor-agent --help
57
+ ```
58
+
59
+ Historical claims only; these are not archived execution evidence.
60
+ Correction after independent review: no raw outputs for these commands were
61
+ archived. The previous blanket exit-0/flag-verification claim is unsupported
62
+ and withdrawn, including for Claude; this evidence does not establish that
63
+ `claude` was available. The previously quoted Codex warning also has no archived
64
+ help transcript here. Check flags on each target host before executing the
65
+ manual procedure. That earlier follow-up claimed no supported help verification.
66
+ The later [completion record](QUALIFICATION_LINK_FOLLOWUP.md) archives new safe
67
+ Cursor/Codex help outputs only; no `claude --help` run or CLI qualification is claimed.
68
+
69
+ ```sh
70
+ env -u WACANDO_LIVE_TEST_ORIGIN npm_config_cache=/tmp/wacando-issue2-npm-cache timeout 600s npm run check
71
+ ```
72
+
73
+ Exit 0; [complete output](documentary-check.txt). Build and all three exact
74
+ runtime checks pass. Tests: 57 total, 54 pass, 0 fail, 3 live cases skipped.
75
+ No independent lint/typecheck script exists. The existing live PASS is retained;
76
+ this run made no API request and did not recreate the retired ephemeral stack.
77
+
78
+ [Document checks](documentary-validation.txt) record link targets, shell/Node
79
+ syntax, unchanged prior evidence and the docs-only diff. The revocation wording
80
+ claim in that record was too broad: it checked a message from the wrong path
81
+ for an already-saved identity, and is corrected by the
82
+ [review follow-up](REVIEW_FOLLOWUP.md).
83
+
84
+ The successful `git diff --check` claim applies to the documentary follow-up
85
+ `24ace6ef95d4a4f595dd712b325a1fc7cbbba449..abd3e52a285808df5b4cc3e1f53621421ef9b316`,
86
+ not the cumulative PR diff `origin/main...HEAD`. That cumulative diff contains
87
+ trailing whitespace in preserved raw evidence logs and exits 2; the logs must
88
+ remain byte-for-byte unchanged.
89
+ The final PR/issue bodies preserve the scope split, draft/open state, and #42
90
+ retirement dependency. The worker supplies checks and evidence; independent
91
+ review is a separate next step, not performed here.
92
+
93
+ ## Residual limits
94
+
95
+ Actual CLIs are NOT QUALIFIED in the sandbox. Their current EROFS results are
96
+ not successful enrollment/resume, and no new CLI onboarding/reboot/revocation
97
+ run is claimed. Crash locks, the 45-second cleanup cap, host UIs, macOS/Windows,
98
+ encrypted conversation exchange, replacement app/pairing flow and production
99
+ remain outside this follow-up's validation. No lock was removed, no credentials
100
+ were requested or copied, and no host installation/configuration was changed.
101
+ No merge or publication occurred.
102
+
103
+ The [Wacando #42](https://github.com/lbframe/wacando/issues/42) retirement
104
+ dependency remains: v1 web onboarding and its prompt builder support the current
105
+ fixture/procedure. Coordinate #17 with that retirement: once the web flow is removed, initial
106
+ setup must use the approved replacement app/pairing flow. This evidence does
107
+ not qualify the replacement or add a dependency edge to #42.
@@ -0,0 +1,105 @@
1
+ # Qualification-link completion — October 15, 2026
2
+
3
+ Task `58463914-cf55-4d12-8f7b-f736dd97e3f0`, PR #9, branch
4
+ `fix/cursor-identity-resume`. The requested starting HEAD was
5
+ `abd3e52a285808df5b4cc3e1f53621421ef9b316`. A concurrent task left local commit
6
+ `24159b9c1724c8a2ae9b59386ea7e7c1e32bc147` with the saved-identity wording
7
+ correction and checks, then stopped. This completion retains that documentation
8
+ and adds immutable links and the authorized PR/issue body corrections.
9
+ Independent follow-up review and merge remain pending; no runtime edit,
10
+ publication, merge or issue close is part of this work.
11
+
12
+ ## Corrected acceptance
13
+
14
+ The [review correction](REVIEW_FOLLOWUP.md) traces `enroll()` with saved state
15
+ to `open()`, whose line 189 returns:
16
+
17
+ ```text
18
+ Agent revoked or durable access rejected. Connection attempts have stopped. Check the identity on the site.
19
+ ```
20
+
21
+ After that rejection has persisted local revocation, line 72 instead returns:
22
+
23
+ ```text
24
+ Agent revoked. Connection attempts have stopped. Create a new identity on the site.
25
+ ```
26
+
27
+ Line 81's shorter message belongs to first enrollment, not the saved-identity
28
+ scenario. The live test asserts `/Agent revoked/`; the procedure requires an
29
+ actual error result matching `/^Agent revoked[. ]/`, without affirmative
30
+ connection, after prior successful resume and confirmed owner revocation of the
31
+ same identity. It also requires responsive host, normal cleanup and identical
32
+ private-identity fingerprint. The message alone covers other access denials
33
+ and cannot prove owner revocation. This is source tracing, not a manual test.
34
+ `qualification_origin` must be exactly `URL.origin`, including scheme, host and
35
+ optional port, without trailing slash/path; the literal partition hash otherwise
36
+ differs and the helper fails closed.
37
+
38
+ ## Durable references and GitHub bodies
39
+
40
+ The procedure document, PR #9 body, plugin #2 body and Wacando #17 checklist
41
+ use the immutable original reviewed snapshot at
42
+ `abd3e52a285808df5b4cc3e1f53621421ef9b316` instead of branch links. That snapshot
43
+ predates the wording correction: the current document and updated bodies state
44
+ the corrected acceptance explicitly. It is not a newly executed qualification.
45
+
46
+ The first three #2 boxes describe proven runtime acceptance and are checked;
47
+ independent follow-up review/merge stays unchecked, with #2 OPEN/in progress and
48
+ PR #9 OPEN/draft. All #17 qualification boxes remain unchecked. The #17 blocker
49
+ line and native dependencies are preserved exactly; #42 remains a retirement
50
+ coordination dependency with its existing blockers #40/#37. No dependency edge
51
+ is added or removed. API read-back results are recorded in
52
+ [body verification](qualification-body-validation.txt).
53
+
54
+ ## Commands and real results
55
+
56
+ Safe help only, no prompt or MCP invocation:
57
+
58
+ ```sh
59
+ timeout 20s codex --help
60
+ timeout 20s codex exec --help
61
+ timeout 20s cursor-agent --help
62
+ ```
63
+
64
+ Each exited 0. Complete combined stdout/stderr is stored losslessly as the
65
+ `combined_output` JSON string in [Codex](codex-help.json),
66
+ [Codex exec](codex-exec-help.json), and [Cursor](cursor-help.json). Decode that
67
+ string for exact bytes, including padded blank lines. Codex emits its read-only
68
+ PATH-alias warning. Cursor's `--workspace`/`--plugin-dir` and Codex's `-C`/prompt
69
+ syntax are present. These are new help runs, not proof of the prior unarchived
70
+ claims or of CLI qualification. No `claude --help` was run; its flags remain
71
+ unverified. Claude's absence from the reviewer's PATH is not contradicted by
72
+ availability in another runtime.
73
+
74
+ ```sh
75
+ env -u WACANDO_LIVE_TEST_ORIGIN npm_config_cache=/tmp/wacando-issue2-npm-cache timeout 600s npm run check
76
+ ```
77
+
78
+ Exit 0, [complete output](qualification-link-check.txt): 57 tests, **54 passed,
79
+ 0 failed, 3 live cases skipped**, with build/generated equality passing. No
80
+ separate lint/typecheck scripts exist. No new MCP/packaging implementation
81
+ change justifies another Inspector run.
82
+
83
+ [Document validation](qualification-link-validation.txt) records actual local
84
+ link/anchor checks, shell/Node syntax checks without executing the procedure,
85
+ raw evidence byte equality, docs-only scope and whitespace results. The
86
+ historical `git diff --check 24ace6e..abd3e52` passes only that delta. The current
87
+ follow-up `git diff --check abd3e52` passes separately. The cumulative PR diff
88
+ `git diff --check origin/main` still exits 2 for preserved raw evidence logs;
89
+ those logs remain byte-identical. No full-PR whitespace PASS is claimed.
90
+
91
+ ## Remaining untested items
92
+
93
+ The manual restart procedure is **NOT EXECUTED**. Actual Cursor/Codex/Claude CLI
94
+ verification, host restart/reboot, identity resume, event-shape compatibility and
95
+ owner revocation remain **NOT QUALIFIED in this sandbox**, deferred to
96
+ [Wacando #17](https://github.com/lbframe/wacando/issues/17). Prior Cursor/Codex
97
+ EROFS failures remain failures, and Claude onboarding has no recorded attempt.
98
+ Existing real API/Postgres/ejabberd/OMEMO runtime acceptance is retained; no live
99
+ stack/API/CLI procedure was rerun. Crash locks, SIGKILL/short host deadlines,
100
+ the 45-second cleanup cap, host UIs, macOS/Windows, encrypted conversation
101
+ exchange, replacement app/pairing flow and production remain untested.
102
+ [#42](https://github.com/lbframe/wacando/issues/42) still requires coordinating
103
+ retirement of v1 web onboarding/prompt building with #17's initial setup.
104
+ No host configuration or installation was changed, credentials accessed, lock
105
+ removed, permission widened, package published, merge performed or issue closed.
@@ -0,0 +1,93 @@
1
+ # PR #9 review corrections — October 15, 2026
2
+
3
+ Starting HEAD: `abd3e52a285808df5b4cc3e1f53621421ef9b316`, existing branch
4
+ `fix/cursor-identity-resume`. Local documentation correction only, prepared for
5
+ independent review of [PR #9](https://github.com/lbframe/wacando-agent/pull/9).
6
+ At local commit `24159b9`, no push, publication, GitHub comment/review/body edit,
7
+ merge or issue closure had occurred. That earlier task left acceptance boxes and
8
+ branch-based external evidence links unchanged. The subsequent
9
+ [completion record](QUALIFICATION_LINK_FOLLOWUP.md) records the broader authorized
10
+ follow-up: immutable links and bodies, with proven runtime boxes checked and
11
+ review/merge still pending. This note preserves the earlier check scope.
12
+
13
+ ## MEDIUM-1: follow the saved-identity path
14
+
15
+ The manual procedure first proves resume with the same saved identity and an
16
+ unusable token. `enroll()` reads that identity, skips initial token redemption,
17
+ and calls `open()` (`packages/onboarding/service.mjs:72–99`). In a fresh host,
18
+ `open()` requests `/v1/xmpp/session`; HTTP 403/`AGENT_REVOKED` becomes `ApiError`
19
+ in `network.mjs:39`. Its catch stops retries, persists `revoked: true` and throws
20
+ at `service.mjs:189`:
21
+
22
+ ```text
23
+ Agent revoked or durable access rejected. Connection attempts have stopped. Check the identity on the site.
24
+ ```
25
+
26
+ If background recovery has already persisted revocation, the guard at line 72
27
+ instead throws:
28
+
29
+ ```text
30
+ Agent revoked. Connection attempts have stopped. Create a new identity on the site.
31
+ ```
32
+
33
+ Line 81's shorter message belongs to initial enrollment without saved agent
34
+ state. It was the wrong expected output for this scenario. The revised procedure
35
+ requires an actual MCP tool error (`packages/mcp/server.mjs:98`), the anchored
36
+ `/^Agent revoked[. ]/` prefix (`scripts/host-result.mjs:20`), and no affirmative
37
+ connection. The live test uses `/Agent revoked/` (`tests/onboarding-live.test.mjs:71`);
38
+ it is existing runtime evidence, not a newly executed CLI qualification.
39
+
40
+ An error string alone cannot establish owner revocation: `open()` also rejects
41
+ other HTTP 401/403 access denials. The procedure additionally requires confirmed
42
+ owner-UI revocation of the same previously resumed identity, exactly one actual
43
+ tool result, a responsive host, unchanged private-identity fingerprint and normal
44
+ lock cleanup. Missing results, generic failures, timeouts and host prose cannot
45
+ pass. No implementation or generated file was changed.
46
+
47
+ ## LOW corrections and evidence scope
48
+
49
+ - `qualification_origin` must exactly equal `new URL(configuredApiUrl).origin`.
50
+ `enroll()` and `CredentialStore.directory()` partition on that normalized
51
+ origin; the manual fingerprint function hashes the supplied string literally.
52
+ A trailing slash or other normalization difference selects the wrong directory
53
+ and fails closed. The procedure now gives the exact requirement and an example.
54
+ - The earlier `--help` exit-0 assertion has no archived outputs. It is withdrawn
55
+ in both authored documents, including the Claude claim. No new help run is
56
+ claimed. Launch flags must be checked on the target host; this correction
57
+ establishes neither Claude availability nor CLI qualification.
58
+ - The historical documentary whitespace check covers `24ace6e..abd3e52`, not
59
+ the cumulative PR. That historical range and the present follow-up pass.
60
+ `origin/main...abd3e52` exits 2 for whitespace in preserved raw evidence logs.
61
+ Those bytes are intentionally retained; the cumulative result is a residual
62
+ evidence-format limitation, not a new implementation failure.
63
+ - The previous validation record's wording check was incorrect for the scenario;
64
+ its claim is explicitly corrected, rather than reused as proof.
65
+
66
+ ## Commands and actual results
67
+
68
+ Required repository check, run in the foreground with a ten-minute bound:
69
+
70
+ ```sh
71
+ env -u WACANDO_LIVE_TEST_ORIGIN npm_config_cache=/tmp/wacando-issue2-npm-cache timeout 600s npm run check
72
+ ```
73
+
74
+ Exit 0. [Complete raw output](review-check.txt): build and all three exact
75
+ runtime checks pass; 57 tests, 54 pass, 0 fail, 3 live cases skipped. No separate
76
+ lint/typecheck scripts exist. The build reproduced the committed generated
77
+ files without changing them. No MCP/packaging implementation change was made,
78
+ so `check:mcp` was not rerun.
79
+
80
+ [Documentary validation](review-validation.txt) contains actual source-path,
81
+ local-link, shell/Node syntax, evidence-byte and whitespace check results,
82
+ including the full cumulative whitespace diagnostics. Syntax checking did not
83
+ execute the operator's procedure. All 22 files present at `24ace6e`, plus the
84
+ prior documentary check log, are byte-for-byte preserved.
85
+
86
+ Actual Cursor/Codex/Claude CLI enrollment, restart/reboot, resume and revocation
87
+ remain NOT QUALIFIED in this sandbox; prior EROFS limitations remain. No live
88
+ API/XMPP stack was restarted for this correction. Existing runtime acceptance
89
+ evidence is unchanged. Independent review of this local correction is pending.
90
+ [Wacando #17](https://github.com/lbframe/wacando/issues/17) owns CLI qualification;
91
+ [Wacando #42](https://github.com/lbframe/wacando/issues/42) still owns retirement
92
+ of the v1 web onboarding/prompt-builder dependency. Future app/pairing flow,
93
+ crash locks, host UIs, other platforms and production remain untested.
@@ -0,0 +1,76 @@
1
+ TAP version 13
2
+ # Subtest: cursor shutdown waits for session cleanup and releases its own lock without changing keys
3
+ not ok 1 - cursor shutdown waits for session cleanup and releases its own lock without changing keys
4
+ ---
5
+ duration_ms: 1658.574925
6
+ type: 'test'
7
+ location: '/tmp/wacando-issue2-before.56NFHw/tests/onboarding-shutdown.test.mjs:16:3'
8
+ failureType: 'testCodeFailure'
9
+ error: |-
10
+ MCP must finish protected session cleanup before forcing exit
11
+
12
+ 0 !== null
13
+
14
+ code: 'ERR_ASSERTION'
15
+ name: 'AssertionError'
16
+ expected: ~
17
+ actual: 0
18
+ operator: 'strictEqual'
19
+ stack: |-
20
+ TestContext.<anonymous> (file:///tmp/wacando-issue2-before.56NFHw/tests/onboarding-shutdown.test.mjs:57:12)
21
+ async Test.run (node:internal/test_runner/test:1054:7)
22
+ async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3)
23
+ ...
24
+ # Subtest: codex shutdown waits for session cleanup and releases its own lock without changing keys
25
+ not ok 2 - codex shutdown waits for session cleanup and releases its own lock without changing keys
26
+ ---
27
+ duration_ms: 1553.895394
28
+ type: 'test'
29
+ location: '/tmp/wacando-issue2-before.56NFHw/tests/onboarding-shutdown.test.mjs:16:3'
30
+ failureType: 'testCodeFailure'
31
+ error: |-
32
+ MCP must finish protected session cleanup before forcing exit
33
+
34
+ 0 !== null
35
+
36
+ code: 'ERR_ASSERTION'
37
+ name: 'AssertionError'
38
+ expected: ~
39
+ actual: 0
40
+ operator: 'strictEqual'
41
+ stack: |-
42
+ TestContext.<anonymous> (file:///tmp/wacando-issue2-before.56NFHw/tests/onboarding-shutdown.test.mjs:57:12)
43
+ async Test.run (node:internal/test_runner/test:1054:7)
44
+ async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
45
+ ...
46
+ # Subtest: MCP shutdown finishes saving an in-flight verification response before exiting
47
+ not ok 3 - MCP shutdown finishes saving an in-flight verification response before exiting
48
+ ---
49
+ duration_ms: 1261.625698
50
+ type: 'test'
51
+ location: '/tmp/wacando-issue2-before.56NFHw/tests/onboarding-shutdown.test.mjs:68:1'
52
+ failureType: 'testCodeFailure'
53
+ error: |-
54
+ The active verification still needs to save its response
55
+
56
+ 0 !== null
57
+
58
+ code: 'ERR_ASSERTION'
59
+ name: 'AssertionError'
60
+ expected: ~
61
+ actual: 0
62
+ operator: 'strictEqual'
63
+ stack: |-
64
+ TestContext.<anonymous> (file:///tmp/wacando-issue2-before.56NFHw/tests/onboarding-shutdown.test.mjs:90:10)
65
+ async Test.run (node:internal/test_runner/test:1054:7)
66
+ async Test.processPendingSubtests (node:internal/test_runner/test:744:7)
67
+ ...
68
+ 1..3
69
+ # tests 3
70
+ # suites 0
71
+ # pass 0
72
+ # fail 3
73
+ # cancelled 0
74
+ # skipped 0
75
+ # todo 0
76
+ # duration_ms 4531.867881
@@ -0,0 +1,14 @@
1
+
2
+ > wacando-plugins@1.0.0 check:mcp
3
+ > npm run build && node scripts/check-mcp.mjs
4
+
5
+
6
+ > wacando-plugins@1.0.0 build
7
+ > node scripts/build.mjs
8
+
9
+ Built self-contained codex plugin: wacando@1.0.0
10
+ Built self-contained cursor plugin: wacando-cursor@1.0.0
11
+ Built self-contained claude plugin: wacando-claude@1.0.0
12
+ Official Inspector 2.7.0 passed: wacando
13
+ Official Inspector 2.7.0 passed: wacando-cursor
14
+ Official Inspector 2.7.0 passed: wacando-claude