memoir-cli 3.11.3 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -124
- package/bin/memoir-work.js +9 -0
- package/bin/memoir.js +72 -8
- package/docs/AUDIT-REMEDIATION.md +55 -0
- package/docs/CASE_TAPE_AMNESIA.md +39 -0
- package/docs/HANDOFF-SECURITY-AUDIT.md +106 -0
- package/docs/LOCAL-HANDOFF-VALIDATION.md +129 -0
- package/docs/MCP-V2-MIGRATION.md +17 -0
- package/docs/PROJECT-HANDOFF.md +255 -0
- package/docs/PROJECT-VIEW-DEBUG.md +66 -0
- package/docs/PROJECT-VIEW-VALIDATION.md +136 -0
- package/docs/RELEASE-3.14-VALIDATION.md +36 -0
- package/docs/RELIABILITY-ROLLOUT.md +57 -0
- package/docs/RETRIEVAL-INDEX.md +45 -0
- package/docs/RETRIEVAL-RESULTS.md +26 -0
- package/docs/SPEC.md +684 -0
- package/evals/CONTINUITY-PROTOCOL.md +45 -0
- package/evals/cases.json +200 -0
- package/evals/results/retrieval-2026-09-05.json +5333 -0
- package/evals/retrieval-performance.mjs +99 -0
- package/evals/run.mjs +87 -0
- package/package.json +13 -5
- package/src/adapters/index.js +13 -6
- package/src/adapters/restore.js +83 -36
- package/src/cloud/auth.js +12 -15
- package/src/cloud/constants.js +6 -2
- package/src/cloud/storage.js +130 -93
- package/src/commands/activate.js +43 -9
- package/src/commands/cloud.js +56 -5
- package/src/commands/consolidate.js +49 -10
- package/src/commands/diff.js +2 -2
- package/src/commands/doctor.js +3 -3
- package/src/commands/forget.js +100 -0
- package/src/commands/push.js +164 -161
- package/src/commands/recall.js +42 -0
- package/src/commands/restore.js +32 -44
- package/src/commands/resume.js +15 -164
- package/src/commands/session.js +51 -9
- package/src/commands/snapshot.js +6 -7
- package/src/commands/status.js +23 -1
- package/src/commands/upgrade.js +13 -11
- package/src/commands/validate.js +16 -0
- package/src/commands/view.js +2 -2
- package/src/commands/why.js +4 -3
- package/src/config.js +9 -40
- package/src/context/capture.js +135 -33
- package/src/context/handoffs.js +72 -0
- package/src/events/summary.js +122 -0
- package/src/integrations/setup.js +88 -0
- package/src/mcp.js +151 -283
- package/src/memory/lexical-index.js +65 -0
- package/src/memory/repository.js +16 -0
- package/src/memory/scope.js +65 -0
- package/src/memory/search.js +598 -0
- package/src/memory/store.js +141 -0
- package/src/providers/index.js +182 -51
- package/src/providers/restore.js +5 -1
- package/src/security/encryption.js +34 -60
- package/src/security/files.js +155 -0
- package/src/session/brief.js +47 -0
- package/src/session/inject.js +12 -6
- package/src/session/lock.js +39 -118
- package/src/session/migrations.js +6 -0
- package/src/session/render.js +34 -4
- package/src/session/state.js +305 -34
- package/src/work/cli.js +64 -0
- package/src/work/errors.js +8 -0
- package/src/work/server.js +28 -0
- package/src/work/setup.js +96 -0
- package/src/work/store.js +340 -0
- package/src/work/ui/app.js +205 -0
- package/src/work/ui/index.html +30 -0
- package/src/work/ui/style.css +3 -0
- package/src/work/view.js +93 -0
- package/src/workspace/tracker.js +84 -332
- package/supabase/migrations/202609050001_backup_versions.sql +50 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Project handoff adversarial audit — 2026-09-06
|
|
2
|
+
|
|
3
|
+
**Status: local preview, not a public deployment or a security-certified product.**
|
|
4
|
+
The original functional tests were not a dedicated adversarial audit. This
|
|
5
|
+
follow-up exercised the new project handoff, its MCP interface, CLI, settings
|
|
6
|
+
writer, ledger parser and Git metadata helper using synthetic attack fixtures.
|
|
7
|
+
It found real gaps and changed the implementation. All changes remain local.
|
|
8
|
+
|
|
9
|
+
## Findings and fixes
|
|
10
|
+
|
|
11
|
+
| Finding | Impact | Fix |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| MCP check tool accepted arbitrary host commands | A memory-tool call could read server environment values and write outside the project using server privileges | Disabled command execution over MCP completely. Existing tool name returns a refusal. Checks use the CLI under the coding client's ordinary terminal permissions |
|
|
14
|
+
| Reading Git status executed a configured fsmonitor hook | A resume operation could execute repository-controlled code | Removed dirty-status execution from the shared repository metadata helper. Dirty status is now unknown; per-file freshness still works |
|
|
15
|
+
| JSON serialization hid some secrets from the scanner | Field-leading environment assignments and embedded JSON credentials could be saved | Scan decoded strings, normalize common invisible obfuscation for detection, and reject recognized credentials before storage |
|
|
16
|
+
| Rendered record data could create Markdown structure and image links | A stored answer could imitate a new evidence section or contain active image markup | Escape rendered fields and keep them on one line; explicitly label all stored text untrusted |
|
|
17
|
+
| A file named `__proto__` disappeared from input evidence | Changes to a declared file could fail to invalidate a check | Use dictionaries without an object prototype and validate original input maps without schema normalization dropping that key |
|
|
18
|
+
| Maximum-size check input lists broke subsequent reads | 100 explicit inputs plus automatic manifests created a ledger the old reader rejected | Validate the combined maximum consistently |
|
|
19
|
+
| Incomplete receipt/history validation | Incorrectly typed evidence, reordered history and malformed retractions could be accepted | Strict receipt, metadata, revision-order and history-completeness validation; preserve and refuse malformed data |
|
|
20
|
+
| Non-object Cursor settings could be rewritten | Setup could replace an unexpected existing configuration shape | Reject before any planned settings/instruction edits are applied |
|
|
21
|
+
| Unbounded CLI stdin | Oversized input was buffered and parsed | Enforce a 16 KiB limit while reading and before parsing |
|
|
22
|
+
|
|
23
|
+
Additional hardening sanitizes parser and filesystem errors so damaged-file
|
|
24
|
+
contents are not returned to an MCP client. Unsafe controls and direction
|
|
25
|
+
overrides are rejected after decoding. The memory interface remains local stdio.
|
|
26
|
+
The later project-view feature adds an opt-in HTTP listener bound only to
|
|
27
|
+
127.0.0.1, with a per-process capability, strict Host/Origin validation and no
|
|
28
|
+
command execution. It adds no telemetry, cloud upload or background daemon.
|
|
29
|
+
See [the project-view validation](PROJECT-VIEW-VALIDATION.md) for its separate
|
|
30
|
+
browser and request-security checks. The counts below describe the earlier audit.
|
|
31
|
+
|
|
32
|
+
## Adversarial evidence
|
|
33
|
+
|
|
34
|
+
`test-work-adversarial.mjs` contains **19 scenarios**. The first baseline had
|
|
35
|
+
14 failed assertions. Further probing then reproduced execution of a synthetic
|
|
36
|
+
Git fsmonitor hook and caught a normalization issue in the first prototype-key
|
|
37
|
+
fix. These are regression probes, not 14 independent vulnerability ratings.
|
|
38
|
+
No real credentials, personal home files or external attack targets were used.
|
|
39
|
+
|
|
40
|
+
The final suite passes all 19 assertions. Eighteen scenarios verify defenses;
|
|
41
|
+
one deliberately demonstrates the remaining valid-receipt-tampering boundary
|
|
42
|
+
and verifies that it is explicitly disclosed. A passing test count must not be
|
|
43
|
+
interpreted as proof that every attack is blocked.
|
|
44
|
+
|
|
45
|
+
Covered attacks include host command/environment access through MCP, Git-hook
|
|
46
|
+
execution during resume, damaged-file error leakage, multiple secret formats,
|
|
47
|
+
invisible and directional text, Markdown spoofing, special dictionary keys,
|
|
48
|
+
input limits, malformed and reordered history, configuration clobbering,
|
|
49
|
+
oversized stdin, symlink escape, shell metacharacters and personal-scope requests.
|
|
50
|
+
|
|
51
|
+
Run the dedicated suite with:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
node test-work-adversarial.mjs
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`npm test` includes it alongside the existing functional suites. The dependency
|
|
58
|
+
audit against the npm advisory data reported **zero known vulnerabilities** in
|
|
59
|
+
the production dependency tree at the time of this audit. That result does not
|
|
60
|
+
cover application logic or prove the absence of undisclosed dependency bugs.
|
|
61
|
+
|
|
62
|
+
After the final fixes, **22 full test suites passed** and the installed-package
|
|
63
|
+
smoke test passed. The new 19-scenario adversarial suite and the existing
|
|
64
|
+
17-group handoff suite are included in that result.
|
|
65
|
+
|
|
66
|
+
The live Cursor app connection was reloaded and tested in the existing
|
|
67
|
+
“Memoir project continuation” conversation. A harmless `memoir_work_check`
|
|
68
|
+
request returned the explicit MCP-execution refusal. A subsequent
|
|
69
|
+
`memoir_work_resume` still returned both saved answers and the unauthenticated
|
|
70
|
+
receipt warning. No fallback command was run for this denial probe. This verifies
|
|
71
|
+
the active client received the hardened server, not only an isolated test copy.
|
|
72
|
+
|
|
73
|
+
## What this does not secure
|
|
74
|
+
|
|
75
|
+
- **Valid local receipt forgery remains possible.** A process with ledger write
|
|
76
|
+
access can change a failed exit code to zero and construct valid-looking
|
|
77
|
+
metadata. The suite demonstrates this. Receipts are local, unauthenticated
|
|
78
|
+
observations, not signed attestation or release authorization.
|
|
79
|
+
- **Semantic prompt injection is not solved.** Escaping blocks structural
|
|
80
|
+
spoofing and active Markdown, but an AI can still mishandle hostile text.
|
|
81
|
+
Stored claims and source labels never grant authority.
|
|
82
|
+
- **The CLI is not an independent sandbox.** It executes the authorized command
|
|
83
|
+
with the terminal client's permissions and environment. Declared input hashes
|
|
84
|
+
are evidence scope, not restrictions on what that process can read or write.
|
|
85
|
+
- **Same-user hostile filesystem races are outside the boundary.** Stable
|
|
86
|
+
symlinks and traversal are rejected, but this is not OS-level isolation from
|
|
87
|
+
a process that can concurrently alter the project, server installation or
|
|
88
|
+
ancestor directories. A stronger boundary needs OS-enforced isolation and
|
|
89
|
+
separately protected evidence signing.
|
|
90
|
+
- **Privacy detection is heuristic.** Arbitrary personal sentences and every
|
|
91
|
+
encoded credential cannot be identified automatically. Local files/backups
|
|
92
|
+
are plaintext, and connected AI clients receive the project context they use.
|
|
93
|
+
- **Scope is the new handoff.** This is a focused source and local adversarial
|
|
94
|
+
audit, not an independent penetration test of all legacy Memoir commands,
|
|
95
|
+
hosted APIs, cloud authorization or cross-tenant isolation. Those were not
|
|
96
|
+
exercised against a live service here.
|
|
97
|
+
|
|
98
|
+
## Local audit trail
|
|
99
|
+
|
|
100
|
+
Baseline and rerun logs are beside this checkout:
|
|
101
|
+
`../memoir-adversarial-before.log`,
|
|
102
|
+
`../memoir-adversarial-additional-before.log`,
|
|
103
|
+
`../memoir-adversarial-after.log`, and
|
|
104
|
+
`../memoir-security-full-tests.log`. The dependency result is
|
|
105
|
+
`../memoir-handoff-npm-audit.json`. Current execution receipts and the saved audit
|
|
106
|
+
decision are in the ignored `.memoir/work.json`; none of these logs were published.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Local handoff validation — 2026-09-06
|
|
2
|
+
|
|
3
|
+
The Codex → Cursor → Codex workflow completed in this Memoir checkout on this
|
|
4
|
+
Mac. Both continuations used the saved answers and reused the saved integration
|
|
5
|
+
check. This exercise was performed before publication; the counts below describe that local candidate.
|
|
6
|
+
|
|
7
|
+
This report records the original functional exercise. A subsequent
|
|
8
|
+
[adversarial audit](HANDOFF-SECURITY-AUDIT.md) found and fixed security gaps.
|
|
9
|
+
In the hardened version, check execution is available through the CLI under
|
|
10
|
+
normal terminal permissions; the MCP check tool deliberately refuses commands.
|
|
11
|
+
Memory reads also omit Git dirty-status checks to avoid executing repository
|
|
12
|
+
hooks. Later receipts supersede the original receipts described below.
|
|
13
|
+
|
|
14
|
+
For everyday use, open the **same folder and branch** in either tool and say
|
|
15
|
+
**“Continue this project.”** Run one-time setup in the project you want to continue. See
|
|
16
|
+
[the usage guide](PROJECT-HANDOFF.md) for the full reference.
|
|
17
|
+
|
|
18
|
+
## What was tested in actual clients
|
|
19
|
+
|
|
20
|
+
| Step | Observed result | Evidence |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| Codex, first session | Saved the goal, two user answers, an output-privacy decision, a real integration receipt and Cursor's next task | Ledger revisions 1–6; local Codex event log |
|
|
23
|
+
| Cursor desktop, local environment | Resumed without receiving the task description again, wrote the requested guide, marked its task done and left a review for Codex | Cursor conversation “Memoir project continuation”; ledger revisions 7–8; guide file |
|
|
24
|
+
| Codex, fresh return session | Found Cursor's completed task, reviewed and corrected the guide, preserved answers and marked the review done | Ledger revision 13; local Codex return event log/result |
|
|
25
|
+
| Cursor MCP connection | Initially disabled; enabling only this project's Memoir source connected four tools. A follow-up direct `memoir_work_resume` call returned both answers and the matching check | Cursor Customize → MCPs and the conversation's tool result |
|
|
26
|
+
|
|
27
|
+
Codex ran using the app-bundled **CLI 0.153.4**, with the existing configured
|
|
28
|
+
model, in two fresh sessions. Cursor was the installed **desktop app 3.17.19**,
|
|
29
|
+
using **This Mac**, this checkout and `fix/audit-reliability`. This was not a
|
|
30
|
+
separate fresh Codex desktop-chat test. The older standalone Codex CLI 0.146.0
|
|
31
|
+
could not run the configured model; it was left unchanged.
|
|
32
|
+
|
|
33
|
+
Codex loaded the project MCP configuration, but its test sessions' `never`
|
|
34
|
+
approval policy refused MCP calls. Both sessions successfully used the generated
|
|
35
|
+
CLI fallback. No approval policy or model setting was relaxed. Cursor's initial
|
|
36
|
+
work also used the fallback before its new project connection was enabled.
|
|
37
|
+
Successful server setup alone is not treated as proof of client acceptance.
|
|
38
|
+
|
|
39
|
+
## Did it reduce repeated work?
|
|
40
|
+
|
|
41
|
+
- Both continuations reused the original delivery and privacy answers; their
|
|
42
|
+
record revisions remained 2 and 3. No repeated answered question was observed.
|
|
43
|
+
- The integration check was executed **once during the three-leg round trip**.
|
|
44
|
+
Cursor and returning Codex both reused its revision-5 receipt because its
|
|
45
|
+
declared files and runtime still matched.
|
|
46
|
+
- Cursor obtained its task from the handoff, and Codex obtained the review from
|
|
47
|
+
Cursor's update. Neither continuation prompt copied those task descriptions
|
|
48
|
+
or the earlier conversation.
|
|
49
|
+
- Returning Codex added a separate documentation check. Its first attempt
|
|
50
|
+
mishandled Git's no-index exit status; the corrected check passed. Memoir
|
|
51
|
+
retained the failed receipt and the later pass. This was additional work on
|
|
52
|
+
a new check, not a rerun of the saved integration check.
|
|
53
|
+
|
|
54
|
+
This demonstrates continuity in one useful local exercise. It is not a timed
|
|
55
|
+
comparison against working without Memoir, a guarantee of fewer questions in
|
|
56
|
+
every task, or evidence that agents will always follow the instructions.
|
|
57
|
+
|
|
58
|
+
## Changed conditions and rechecks
|
|
59
|
+
|
|
60
|
+
After the round trip, the setup message was clarified and the integration
|
|
61
|
+
fixture was strengthened to actually exercise paths containing spaces and
|
|
62
|
+
quotes. A fresh resume correctly changed the integration result to
|
|
63
|
+
`needs-recheck` and named:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
Changed input: src/work/setup.js
|
|
67
|
+
Changed input: test-work-handoff.mjs
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The documentation check also became stale because it included the setup source.
|
|
71
|
+
The guide then gained the final usage and removal instructions. Targeted reruns
|
|
72
|
+
passed: integration receipt **14**, documentation receipt **15**. Both now show
|
|
73
|
+
matching declared inputs. The warning cleared because the checks ran against
|
|
74
|
+
the new files; no completion flag was manually substituted for a check.
|
|
75
|
+
|
|
76
|
+
Relevant file changes, missing files, changed local Node runtime, newly added
|
|
77
|
+
dependency manifests, failed executions and changes during a run trigger
|
|
78
|
+
specific recheck reasons. Unrelated documentation edits do not invalidate the
|
|
79
|
+
integration result. External observations always need current verification:
|
|
80
|
+
for example, a prior Stripe dashboard check does not prove today's settings.
|
|
81
|
+
Only the declared inputs are covered, so agents must include all relevant files.
|
|
82
|
+
|
|
83
|
+
## Implementation and verification
|
|
84
|
+
|
|
85
|
+
- Separate project ledger and MCP server; no global personal-memory or transcript
|
|
86
|
+
import. Records include source, rationale, branch, revisions and next-action
|
|
87
|
+
completion. Corrections reject stale revisions; retractions retain history.
|
|
88
|
+
- Checks execute an argument array and retain exit status, timestamps, input
|
|
89
|
+
fingerprints and an output digest. Raw terminal output is discarded.
|
|
90
|
+
- Setup preserves unrelated project settings and backs up changed existing
|
|
91
|
+
files. Existing conflicting Memoir connections are preserved with a warning.
|
|
92
|
+
No unrelated global configuration was edited. Only the new project source
|
|
93
|
+
was enabled in Cursor's UI.
|
|
94
|
+
- **21 test suites passed**, including the project handoff suite. The final
|
|
95
|
+
focused run passed **17 groups**, including privacy canaries, actual process
|
|
96
|
+
execution, stale-input detection, concurrency, settings preservation, real
|
|
97
|
+
MCP restarts and fallback paths containing spaces and quotes.
|
|
98
|
+
- The **installed-package smoke test passed** with the new project CLI, setup,
|
|
99
|
+
check receipt and MCP resume, alongside the existing backup/restore tests.
|
|
100
|
+
- The guide's examples, command help and whitespace were checked; its semantic
|
|
101
|
+
content was also reviewed against the implementation. A passing syntax check
|
|
102
|
+
alone does not establish that a guide is correct.
|
|
103
|
+
|
|
104
|
+
## What remains manual or limited
|
|
105
|
+
|
|
106
|
+
- Choose the same local checkout and branch, then ask the next agent to continue.
|
|
107
|
+
The ledger is ignored by Git: GitHub pushes, another worktree or another
|
|
108
|
+
computer do not carry it. The older Memoir backup commands do not sync this
|
|
109
|
+
new ledger.
|
|
110
|
+
- A client can require project trust or MCP approval. Cursor's connection is
|
|
111
|
+
enabled here; Codex can use the fallback under its existing policy.
|
|
112
|
+
- Agents must save important decisions and use Memoir's check command/tool.
|
|
113
|
+
Ordinary shell checks and unsaved conversation are not captured by a hook.
|
|
114
|
+
- Personal-scope records and recognized secrets are rejected, and raw output is
|
|
115
|
+
not retained. Detection is heuristic. Project files and backups are plaintext
|
|
116
|
+
locally; connected AI clients receive the project context used for the task.
|
|
117
|
+
This is not an isolation barrier against a process with filesystem access.
|
|
118
|
+
- External app settings can change independently. Evidence is scoped and
|
|
119
|
+
attributable, but local receipts and source labels are not cryptographic
|
|
120
|
+
authentication against a process allowed to edit the ledger.
|
|
121
|
+
|
|
122
|
+
## Local evidence locations
|
|
123
|
+
|
|
124
|
+
The ignored `.memoir/` directory contains `work.json`, the refreshed
|
|
125
|
+
`HANDOFF.md`, both Codex event logs and results, `after-input-change.json`, and
|
|
126
|
+
the final integration/documentation receipts. Exact setup backups are under
|
|
127
|
+
`.memoir/setup-backups/`. Full-suite and package-test logs are beside this
|
|
128
|
+
checkout in `../memoir-handoff-full-tests.log` and
|
|
129
|
+
`../memoir-handoff-packed-test.log`. These local logs are not published.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# MCP SDK v2 compatibility assessment
|
|
2
|
+
|
|
3
|
+
Checked 5 September 2026. Memoir currently declares `@modelcontextprotocol/sdk ^1.29.0` and Node `>=18`.
|
|
4
|
+
|
|
5
|
+
The [official SDK repository](https://github.com/modelcontextprotocol/typescript-sdk) documents v2 as stable for the 2026-07-28 protocol specification, with separate server/client packages and Standard Schema support. The npm manifests for [server 2.0.0](https://registry.npmjs.org/@modelcontextprotocol/server/2.0.0) and [client 2.0.0](https://registry.npmjs.org/@modelcontextprotocol/client/2.0.0) both declare Node `>=20`. The upstream README promises v1 bug/security fixes for at least six months after v2 release. This is a planned compatibility migration, not evidence that Memoir's current SDK is vulnerable.
|
|
6
|
+
|
|
7
|
+
A direct dependency replacement would break Memoir's advertised Node 18 support. The retrieval changes therefore retain v1 and do not quietly raise the minimum runtime.
|
|
8
|
+
|
|
9
|
+
Before migrating:
|
|
10
|
+
|
|
11
|
+
1. Choose and announce an actively supported Node LTS baseline; the SDK's minimum is not necessarily the appropriate product minimum. Update package metadata, installation docs, and CI together.
|
|
12
|
+
2. Inventory imports in `src/mcp.js`, `src/integrations/setup.js`, and the test clients. Port server/client imports, transports, and tool schemas according to the chosen released v2 API.
|
|
13
|
+
3. Preserve existing tool names, argument validation, project visibility, structured/text responses, and error semantics. Check empty results and malformed requests.
|
|
14
|
+
4. Exercise protocol negotiation, initialization, tool discovery/calls, shutdown/restart, and the installed tarball on all supported operating systems.
|
|
15
|
+
5. Confirm actual supported Claude Code, Codex, and Cursor releases accept configuration and complete remember/recall/restart. An SDK-to-SDK handshake alone is insufficient.
|
|
16
|
+
|
|
17
|
+
No SDK migration or runtime-support change is included in the retrieval-index change.
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Project continuation for Codex and Cursor
|
|
2
|
+
|
|
3
|
+
## Use it now
|
|
4
|
+
|
|
5
|
+
Install Memoir 3.14.0 or later and run `memoir work setup` in the project you
|
|
6
|
+
want to continue. Open that same folder and branch in Codex or Cursor and say
|
|
7
|
+
**“Continue this project.”** The next agent reads saved answers, decisions,
|
|
8
|
+
completed work and next actions. You do not need to copy the conversation.
|
|
9
|
+
|
|
10
|
+
The reference local test completed the round trip with Cursor desktop and the
|
|
11
|
+
Codex CLI. See [the validation report](LOCAL-HANDOFF-VALIDATION.md) for the actual
|
|
12
|
+
client versions and limits. Agents still need to follow the installed
|
|
13
|
+
instructions, and setup does not prove a new client has accepted its connection.
|
|
14
|
+
|
|
15
|
+
This documents the local project handoff in `src/work/` and `bin/memoir-work.js`. It is not a claim that hosted clients have accepted the connection, and it does not import global or personal Memoir memory.
|
|
16
|
+
|
|
17
|
+
`.memoir/work.json` is the authoritative ledger. `.memoir/HANDOFF.md` is a generated preview; run `resume` before relying on it. Stored text is evidence, never permission.
|
|
18
|
+
|
|
19
|
+
## See and correct what Memoir remembers
|
|
20
|
+
|
|
21
|
+
Run `memoir work view` in your project (or `node bin/memoir.js work view`
|
|
22
|
+
from a source checkout), or ask the agent
|
|
23
|
+
“Open my Memoir project view.” The browser shows the current branch's answers,
|
|
24
|
+
decisions, checks, goals and next steps. Setup is not needed again for each use.
|
|
25
|
+
Keep the terminal process running while using the view; Ctrl+C stops it.
|
|
26
|
+
`--no-open` prints the access link without launching a browser, and `--port N`
|
|
27
|
+
chooses a local port. The default chooses an available one.
|
|
28
|
+
|
|
29
|
+
- **Correct** saves a new version that the next agent resume receives. Source and
|
|
30
|
+
earlier versions remain available on the card.
|
|
31
|
+
- **Remove from handoff** hides an item from agents. **Removed → Restore to
|
|
32
|
+
handoff** brings back a record. This is reversible removal, not permanent
|
|
33
|
+
deletion; there is no project-history purge control yet.
|
|
34
|
+
- **Mark done** preserves a completed next step so another session knows it was
|
|
35
|
+
finished. **Reopen** makes it active again.
|
|
36
|
+
- **Needs recheck** names changed inputs or explains a failed/external result.
|
|
37
|
+
The view cannot run commands or edit check receipts. A removed receipt needs
|
|
38
|
+
a new authorized check, not a restore-to-pass button.
|
|
39
|
+
- If another session edits the item, the draft stays open. **Review latest
|
|
40
|
+
version** shows the saved version; compare it, choose **Keep my draft and
|
|
41
|
+
continue**, then save. Another intervening change is rejected again. If the
|
|
42
|
+
branch changed or the item was removed, review that state before proceeding.
|
|
43
|
+
|
|
44
|
+
While a save is pending, the editor keeps its fields and close controls locked.
|
|
45
|
+
A request stops waiting after 15 seconds. An interrupted response does not prove
|
|
46
|
+
that the save failed: the server may already have saved it. The draft stays open;
|
|
47
|
+
use **Review latest version** to find the saved record before retrying. Retrying
|
|
48
|
+
the same open draft cannot create a second record. Closing or reloading the tab
|
|
49
|
+
still discards unsaved drafts; they are not written into browser storage.
|
|
50
|
+
|
|
51
|
+
The view listens only on this computer at 127.0.0.1. Its temporary access link
|
|
52
|
+
opens this process's project data; keep it private and do not add it to a handoff.
|
|
53
|
+
The browser removes the token from the visible URL and keeps it only in that
|
|
54
|
+
browser tab's session storage. Reopen from the terminal's full link after losing
|
|
55
|
+
that session. There is no account, upload, command runner or settings editor.
|
|
56
|
+
The agent's permissions and the local plaintext/unsigned-evidence limits below
|
|
57
|
+
still apply. Other same-user processes are not an isolation boundary.
|
|
58
|
+
|
|
59
|
+
## One-time setup
|
|
60
|
+
|
|
61
|
+
From the Memoir source checkout after installing its dependencies:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
node bin/memoir-work.js --project "$(pwd)" setup --tools codex,cursor
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
To connect another project on this computer, replace `"$(pwd)"` with that
|
|
68
|
+
project's absolute folder path. Keep the Memoir installation in place: the
|
|
69
|
+
generated connection and fallback refer to it. For this tested Cursor version,
|
|
70
|
+
open **Customize → MCPs → memoir-work** and enable the project source if it shows
|
|
71
|
+
Disabled. Existing unrelated connections remain unchanged.
|
|
72
|
+
|
|
73
|
+
`--tools` accepts `codex`, `cursor`, or both (default: both). Setup verifies a live MCP handshake: the server must expose `memoir_work_resume`, `memoir_work_record`, `memoir_work_check`, and `memoir_work_retract`.
|
|
74
|
+
|
|
75
|
+
If the handshake succeeds, setup writes only the files that actually change:
|
|
76
|
+
|
|
77
|
+
| File | Role |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `AGENTS.md` | Managed instruction block (`<!-- memoir:project-work -->` … `<!-- /memoir:project-work -->`), for either tool selection |
|
|
80
|
+
| `.cursor/rules/memoir-work.mdc` | With `cursor`: same instructions; a new file gets `alwaysApply: true`, existing frontmatter is preserved |
|
|
81
|
+
| `.cursor/mcp.json` | With `cursor`: `mcpServers.memoir-work` stdio entry |
|
|
82
|
+
| `.codex/config.toml` | With `codex`: `mcp_servers.memoir-work` stdio entry |
|
|
83
|
+
| `.gitignore` | Keeps `/.memoir/`, `/.codex/config.toml`, `/.cursor/mcp.json`, and `/.cursor/rules/memoir-work.mdc` out of ordinary commits |
|
|
84
|
+
|
|
85
|
+
The MCP entry runs `src/work/server.js` with `MEMOIR_PROJECT_ROOT` set to the project directory and `DO_NOT_TRACK=1`. Previous contents of changed, non-empty text files are copied under `.memoir/setup-backups/<uuid>/` before edits are written. Empty or newly created files have no backup entry. Setup is not a transaction across all files; an interrupted write can leave partial edits.
|
|
86
|
+
|
|
87
|
+
A second setup with unchanged generated content leaves the listed files alone, but still verifies the server and refreshes `.memoir/HANDOFF.md`. The `.gitignore` additions apply for either tool selection.
|
|
88
|
+
|
|
89
|
+
Text outside the managed instruction block and existing TOML comments are preserved. Cursor configuration must be valid JSON: comments are unsupported, and adding a connection rewrites JSON formatting while preserving unrelated settings and servers. An existing `memoir-work` entry is left unchanged; a different command, args, or project root produces a CLI-fallback warning. Other differences, such as `DO_NOT_TRACK`, are not reconciled. Parsing errors, detected malformed instruction markers, or an explicitly invalid MCP server map or Memoir connection (including null, false, zero, empty strings and arrays) abort before the planned edits are written. This is not comprehensive client-configuration validation.
|
|
90
|
+
|
|
91
|
+
After setup, open the project in Cursor or Codex, accept the normal project/MCP trust prompt if shown, and start with “Continue this project.” Setup alone does not verify client acceptance; see the recorded observation below for this project's tested routes.
|
|
92
|
+
|
|
93
|
+
## Daily Codex / Cursor workflow
|
|
94
|
+
|
|
95
|
+
1. **Resume first.** Call `memoir_work_resume` (or `node bin/memoir-work.js --project "$(pwd)" resume`). Reuse recorded answers and applicable checks marked **PASSED; declared inputs still match**. Matching file hashes alone do not make a failed or external check current.
|
|
96
|
+
2. **Do the recorded next action within the user's current scope.** Mark a next action `done` only after completing it. Pass that record's revision as `expected_revision` from the current resume, not the overall handoff revision.
|
|
97
|
+
3. **Record as you go.** Save explicit project decisions, resolved questions, and the next action with `memoir_work_record`. Identify the source. Do not save personal preferences, credentials, raw transcripts, or guesses as answers.
|
|
98
|
+
4. **Capture checks through Memoir's CLI.** Run `memoir work check` through the client's normal terminal permissions and sandbox. The MCP check tool deliberately refuses execution. An ordinary shell pass outside the wrapper is not recorded evidence.
|
|
99
|
+
5. **Update the action at the stopping point.** Save its completion or remaining authorized work and relevant decisions. If the action is complete, no additional task needs to be invented. Updates are written immediately; no separate handoff request is needed.
|
|
100
|
+
|
|
101
|
+
MCP tools (stdio server, project-bound):
|
|
102
|
+
|
|
103
|
+
| Tool | Purpose |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `memoir_work_resume` | Current branch: answers, decisions, next actions, and checks with freshness |
|
|
106
|
+
| `memoir_work_record` | Save a project-only `goal`, `answer`, `decision`, or `next` |
|
|
107
|
+
| `memoir_work_check` | Refuse host command execution and direct existing clients to the CLI check command |
|
|
108
|
+
| `memoir_work_retract` | Hide a mistaken record from the current view; history stays local |
|
|
109
|
+
|
|
110
|
+
CLI fallback (`memoir work` delegates to the same entry):
|
|
111
|
+
|
|
112
|
+
Use the direct `bin/memoir-work.js` entry for the project-only workflow. Generated project instructions contain absolute, quoted paths to Node, this entry, and the project root; use those if `node` is unavailable on the client PATH. A configured MCP tool can also be unavailable because its call requires approval under a policy that forbids approval. Use the authorized CLI fallback in that case; do not change approval policies or app settings as part of continuation.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
node bin/memoir-work.js --project "$(pwd)" resume
|
|
116
|
+
node bin/memoir-work.js --project "$(pwd)" resume --json
|
|
117
|
+
node bin/memoir-work.js --project "$(pwd)" record --file .memoir/record-input.json
|
|
118
|
+
node bin/memoir-work.js --project "$(pwd)" check CHECK_ID --title 'What this proves' --files SOURCE_FILE TEST_FILE -- node TEST_FILE
|
|
119
|
+
node bin/memoir-work.js --project "$(pwd)" retract RECORD_ID --revision N --category record
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`--file -` reads record JSON from stdin. For `record`, provide exactly one of `--json` or `--file`; a record file must be project-relative and at most 16 KiB. Record fields: `id`, `kind` (`goal` \| `answer` \| `decision` \| `next`), `text`, `source`; optional `answer`, `why`, `status`, `expected_revision`, `scope`. `scope` defaults to `project` and accepts no other value.
|
|
123
|
+
|
|
124
|
+
## Correction
|
|
125
|
+
|
|
126
|
+
Resume first. Corrections require the target record's current revision as `expected_revision`. History is appended; the latest matching branch record is what resume shows unless retracted. The numbers and IDs below are illustrative: use an existing record's actual ID and revision, and only describe a user correction when one was actually given.
|
|
127
|
+
|
|
128
|
+
Create `.memoir/record-input.json` (gitignored under `/.memoir/`):
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"id": "answer.provider",
|
|
133
|
+
"kind": "answer",
|
|
134
|
+
"text": "Payment provider?",
|
|
135
|
+
"answer": "CorrectedPay",
|
|
136
|
+
"source": "User correction after resume",
|
|
137
|
+
"expected_revision": 3
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
node bin/memoir-work.js --project "$(pwd)" record --file .memoir/record-input.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Rules from the current implementation:
|
|
146
|
+
|
|
147
|
+
- Omitting `expected_revision` on an existing ID fails.
|
|
148
|
+
- A new ID may omit `expected_revision` or pass `0`. A non-zero revision on a missing ID fails.
|
|
149
|
+
- A correction cannot change `kind`; use another ID.
|
|
150
|
+
- Only `next` records may use `status: "done"`. An `answer` requires `answer`.
|
|
151
|
+
- IDs match `^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$`. Text fields are 1–2000 characters after trim.
|
|
152
|
+
|
|
153
|
+
MCP equivalent: `memoir_work_record` with the same object under `record`.
|
|
154
|
+
|
|
155
|
+
## Retraction
|
|
156
|
+
|
|
157
|
+
Retraction removes the record from the current resume view. The ledger keeps the history, and the same ID can be recorded again.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
node bin/memoir-work.js --project "$(pwd)" resume
|
|
161
|
+
node bin/memoir-work.js --project "$(pwd)" retract next.test --revision 12 --category record
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Then record a replacement, passing that same record revision as `expected_revision` (12 in this example), not the newer revision of the retraction or overall handoff. Resume again before the correction; the retracted record is hidden, so retain its original revision or consult its latest entry in `.memoir/work.json`.
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"id": "next.test",
|
|
169
|
+
"kind": "next",
|
|
170
|
+
"text": "Add test",
|
|
171
|
+
"source": "Correction after retract",
|
|
172
|
+
"status": "open",
|
|
173
|
+
"expected_revision": 12
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`--category check` retracts a saved check the same way. Resume before retracting; a stale revision is rejected. MCP: `memoir_work_retract` with `id`, `expected_revision`, and optional `category` (`record` default).
|
|
178
|
+
|
|
179
|
+
## Check evidence and freshness
|
|
180
|
+
|
|
181
|
+
`memoir work check` spawns argv with `shell: false` in the project directory. The MCP server never runs that command: memory-tool approval must not grant a separate host shell. Use the CLI through the client's normal terminal permissions. The CLI stores:
|
|
182
|
+
|
|
183
|
+
- actual `exit_code` (and `signal` / start error if any)
|
|
184
|
+
- SHA-256 of each declared input, plus any present common manifests (`package.json`, `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `requirements.txt`, `pyproject.toml`, `uv.lock`)
|
|
185
|
+
- `inputs_stable` (hashes unchanged during the run)
|
|
186
|
+
- `output_sha256` and `output_bytes`
|
|
187
|
+
- `runtime` (`platform/arch/node-version`)
|
|
188
|
+
- `environment` (`local` default, or `external`)
|
|
189
|
+
- `evidence_source: memoir-executed-process`
|
|
190
|
+
|
|
191
|
+
Raw stdout/stderr is hashed and discarded. A delayed older execution cannot replace a newer result for the same ID. CLI exit status is 1 when `exit_code !== 0`, the command timed out, or inputs were not stable.
|
|
192
|
+
|
|
193
|
+
Resume labels a check **PASSED; declared inputs still match** only when freshness is `inputs-match`. Otherwise it is **NEEDS RECHECK**, with reasons. Recheck when any of these apply:
|
|
194
|
+
|
|
195
|
+
- execution evidence is missing
|
|
196
|
+
- non-zero exit, timeout, signal, or more than 8 MiB of output
|
|
197
|
+
- inputs changed while the check ran
|
|
198
|
+
- `environment` is `external` (settings can change independently)
|
|
199
|
+
- the local runtime changed
|
|
200
|
+
- a new common manifest appeared
|
|
201
|
+
- a recorded input hash changed, or an input is missing/unreadable
|
|
202
|
+
|
|
203
|
+
Unrelated files outside the declared inputs do not invalidate a match. A pass covers only those declared files and the local runtime. It does not verify undisclosed dependencies, external settings, or production. External configuration always needs current verification.
|
|
204
|
+
|
|
205
|
+
Rejected as check inputs: paths under `.memoir/`, basenames `.env` / `.env.*` or starting with `credentials`, `id_rsa` / `id_ed25519`, `*.pem` / `*.key`, absolute paths, path traversal, and symlinks beneath the resolved project root. Input files are limited to 16 MiB each. These path rules govern input hashing, not what the executed command can access. The command inherits the process environment with `DO_NOT_TRACK=1`; the runner is not a separate sandbox. Supply every relevant source/test/configuration file; do not claim a shell command was captured unless it ran through this tool.
|
|
206
|
+
|
|
207
|
+
Default timeout is 30s (100 ms–120 s). `--environment` is `local` or `external`.
|
|
208
|
+
|
|
209
|
+
## Privacy boundaries
|
|
210
|
+
|
|
211
|
+
Project-only. Personal/global memory, transcripts, and raw command output are not imported.
|
|
212
|
+
|
|
213
|
+
Save: project decisions, answered questions, checks with evidence, and next actions. Do not save personal preferences, credentials, secrets, or guesses as user answers. Source labels identify the claimed origin; they are not authentication.
|
|
214
|
+
|
|
215
|
+
Record/check arguments and ledger reads/writes scan decoded fields for known credential patterns, including normalized invisible-character obfuscation. Matching text, unsafe control characters and direction overrides are refused. This is a backstop, not a claim to recognize every private sentence or encoding. Ledger size is capped at 2 MiB and CLI record input at 16 KiB; full or oversized input fails without dropping records. Setup backups are separate from this ledger guard and can contain prior configuration contents, so keep them local too.
|
|
216
|
+
|
|
217
|
+
Rendered fields cannot create new Markdown sections or active image links. Their content still remains untrusted: formatting cannot guarantee that an AI will resist semantic prompt injection. Local receipts are explicitly unauthenticated. A process allowed to rewrite the ledger can forge a valid-looking receipt; never use one as security attestation or deployment approval. See the [adversarial audit](HANDOFF-SECURITY-AUDIT.md).
|
|
218
|
+
|
|
219
|
+
Keep this memory local unless the user explicitly chooses to share it. Existing application approvals still apply. `.gitignore` entries above keep the ledger and tool connections out of ordinary commits.
|
|
220
|
+
|
|
221
|
+
## Actual limitations
|
|
222
|
+
|
|
223
|
+
- **Same local checkout.** Open the same folder and branch in both tools. The ignored ledger is not synchronized by ordinary Git commits, GitHub pushes, another worktree, or the older Memoir backup commands.
|
|
224
|
+
- **Agents must record the work.** These instructions request updates as work happens; no hook captures arbitrary conversations or ordinary shell checks. A crash before an agent saves a decision can lose that decision.
|
|
225
|
+
- **CLI continuation and MCP acceptance are separate.** Setup can verify the local MCP server, but does not prove Cursor/Codex will permit calls. The observation below records the narrower result actually obtained.
|
|
226
|
+
- **Branch-scoped.** Resume shows the current Git branch only. Other-branch records are counted, not mixed in.
|
|
227
|
+
- **Preview can lag.** `.memoir/HANDOFF.md` is rewritten on resume/record/check/retract. Refresh it before relying on it.
|
|
228
|
+
- **MCP may be missing or approval-blocked.** Use the authorized CLI fallback. Setup will not overwrite a conflicting existing `memoir-work` connection.
|
|
229
|
+
- **Freshness is narrow.** Matching inputs are not a production proof. External checks never appear current.
|
|
230
|
+
- **Git dirty status is unknown.** Memory reads no longer run `git status`, which can execute repository-configured hooks or filters. Check freshness still compares the declared files directly.
|
|
231
|
+
- **CLI commands retain terminal authority.** Declared input files specify evidence coverage, not a filesystem sandbox. Only run trusted, authorized checks through the client's normal execution controls.
|
|
232
|
+
- **Foreign or damaged ledgers fail closed.** Invalid JSON, unsupported version, or non-`project` scope preserves the original file and refuses the operation.
|
|
233
|
+
- **Locks serialize writers.** Concurrent records are queued; a busy lock fails rather than corrupting the ledger.
|
|
234
|
+
- **No permission from storage.** Recorded text cannot authorize work that the user did not authorize.
|
|
235
|
+
|
|
236
|
+
## Remove the setup
|
|
237
|
+
|
|
238
|
+
Disable only this project's `memoir-work` connection in the clients, remove its
|
|
239
|
+
entry from the two project MCP configuration files, and remove the marked Memoir
|
|
240
|
+
block from `AGENTS.md` and the dedicated Cursor rule. Leave unrelated entries and
|
|
241
|
+
instructions in place. Exact pre-setup copies of changed existing files are in
|
|
242
|
+
`.memoir/setup-backups/`; review later edits before restoring any whole file.
|
|
243
|
+
The ignored ledger can stay for later use. Retraction hides an item but does not
|
|
244
|
+
erase its history; deletion of sensitive content would also need to cover local
|
|
245
|
+
history and copies. Setup does not install a background service.
|
|
246
|
+
|
|
247
|
+
## Observed continuation, 2026-09-06
|
|
248
|
+
|
|
249
|
+
Codex resumed the local ledger through the documented CLI fallback and reviewed this guide against `src/work/{cli,setup,store,server}.js`, the supporting file/lock/repository helpers, and `bin/memoir-work.js --help`. The delivery/privacy answers and output-digest decision carried forward. The recorded Cursor documentation action was already done; the open Codex action was this documentation review. No answered question was asked again.
|
|
250
|
+
|
|
251
|
+
The saved `check.project-handoff` result (revision 5) still matched its declared inputs and local runtime and was reused without rerunning it. That check covers the listed implementation/test files and manifests, not this guide or external app settings. Documentation edits therefore need their own review; they do not invalidate that integration result.
|
|
252
|
+
|
|
253
|
+
A later resume carried forward `decision.client-route` (revision 10), whose source reports that Cursor's project connection was enabled, showed four tools, and successfully called `memoir_work_resume` on 2026-09-06. This is saved project evidence from the local client test; the documentation review did not repeat that test or inspect external app settings.
|
|
254
|
+
|
|
255
|
+
In this Codex session, the configured MCP resume call returned “MCP tool call requires approval, but approval policy is never.” The documented CLI fallback succeeded. No policy or app setting was changed by this review. Successful CLI continuation does not establish successful Codex MCP use. Source labels are claims, not authentication, and saved client observations do not verify current external settings. Those settings and current client acceptance need verification before claiming they still work; such verification was outside this documentation-only continuation.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Local debugging follow-up — 2026-09-06
|
|
2
|
+
|
|
3
|
+
The user asked Codex to debug the implementation itself. This pass reproduced
|
|
4
|
+
failure cases locally, fixed the shipped handlers/setup code, and verified the
|
|
5
|
+
changes without modifying real client settings, committing, pushing or deploying.
|
|
6
|
+
|
|
7
|
+
## Reproduced problems and fixes
|
|
8
|
+
|
|
9
|
+
| Problem | Reproduction and resulting behavior |
|
|
10
|
+
|---|---|
|
|
11
|
+
| A delayed refresh replaced a successful correction with old data | A deterministic transport returned responses out of order. Refresh responses now lose authority when a newer read, edit or mutation starts |
|
|
12
|
+
| A slow save closed a different draft and reported it saved | Reproduced in the actual browser with an eight-second server delay: cancel the first editor, open a second draft, then receive the first response. The second editor closed with a false success message. Save controls now prevent that transition and completion stays tied to its original editor |
|
|
13
|
+
| A retry could duplicate a newly saved record after its reply was lost | Each submit previously generated a new ID. The open draft now retains one ID, so a committed retry conflicts with its first save and can be reviewed. Actual browser/server testing dropped the response after the write, retried, and found exactly one saved record |
|
|
14
|
+
| Cancelling a version comparison left the main view stale | Latest context was read but not rendered. Closing now displays the latest accepted snapshot. Delayed comparison responses also cannot affect a different editor |
|
|
15
|
+
| Adding memory before context loaded threw an error | Add stays disabled until the first context load; the handler also guards absent context |
|
|
16
|
+
| Restricted browser storage prevented the page loading | The launch capability remains usable in page memory if session storage is unavailable. It is still removed from the visible URL and expires with the server process |
|
|
17
|
+
| Setup overwrote malformed, falsey configuration values | Synthetic null/false/zero/empty-string maps and existing entries were rewritten before the fix. Both Codex and Cursor invalid maps/entries now stop setup before planned settings or instruction writes |
|
|
18
|
+
| Duplicate closing instruction markers were accepted | Setup now refuses the ambiguous block and preserves its original contents |
|
|
19
|
+
|
|
20
|
+
Requests now have a 15-second client wait limit. Timeout or connection failure
|
|
21
|
+
keeps the draft and explicitly says that the change may already be saved. It
|
|
22
|
+
never claims that stopping the wait rolled back the server write. The editor
|
|
23
|
+
unlocks for recovery. Drafts do not survive closing/reloading the tab.
|
|
24
|
+
|
|
25
|
+
## Validation
|
|
26
|
+
|
|
27
|
+
The first six recovery cases all failed against the original shipped event
|
|
28
|
+
handlers. After the fixes and four additional race/recovery probes,
|
|
29
|
+
`test-work-view-ui.mjs` passes **10 scenarios**. This dependency-free harness
|
|
30
|
+
executes the shipped script and its event handlers with a deterministic DOM and
|
|
31
|
+
transport. It is not a substitute for a full browser engine.
|
|
32
|
+
|
|
33
|
+
Actual browser testing used an isolated synthetic project and the real local
|
|
34
|
+
HTTP server, with a test-only wrapper delaying or dropping responses. It
|
|
35
|
+
confirmed the original slow-save failure, the fixed pending-editor behavior,
|
|
36
|
+
correct success text, recovery after a lost acknowledgement, no duplicated
|
|
37
|
+
record after retry, and fresh main-page context after closing comparison.
|
|
38
|
+
No synthetic questions, answers or access capabilities entered the user's
|
|
39
|
+
project ledger.
|
|
40
|
+
|
|
41
|
+
**24 full suites passed: zero failures and zero skips.** This includes the
|
|
42
|
+
10 recovery scenarios, 14 view request-security/correction groups, 17 handoff
|
|
43
|
+
integration groups and now 21 adversarial scenarios. One adversarial scenario
|
|
44
|
+
continues to demonstrate valid local receipt forgery as an explicitly disclosed
|
|
45
|
+
limitation. Passing these tests is not proof of comprehensive security.
|
|
46
|
+
|
|
47
|
+
The saved view/recovery, handoff, adversarial and guide checks were refreshed
|
|
48
|
+
because `src/work/ui/app.js`, `src/work/ui/index.html`, `src/work/setup.js`,
|
|
49
|
+
regression tests and guide wording changed. Their receipts list their actual
|
|
50
|
+
inputs; unrelated checks do not become stale solely because this report changes.
|
|
51
|
+
The full-suite log remains ordinary local evidence, not a forged Memoir receipt.
|
|
52
|
+
|
|
53
|
+
Local evidence files are under ignored `.memoir/`: `debug-ui-check.json`,
|
|
54
|
+
`debug-view-check.json`, `debug-security-check.json`, `debug-handoff-check.json`
|
|
55
|
+
and `debug-full-suites.log`. The installed-package check also passed, including shipped view assets and
|
|
56
|
+
authenticated access; its output is in `debug-packed.log`.
|
|
57
|
+
|
|
58
|
+
## Limits
|
|
59
|
+
|
|
60
|
+
This fixes the reproduced recovery and preservation problems. Existing limits
|
|
61
|
+
remain: project records are plaintext; secret scanning is heuristic; receipts
|
|
62
|
+
and source labels are unauthenticated; hostile same-user processes are outside
|
|
63
|
+
the local view's isolation boundary; agents must save and read project context.
|
|
64
|
+
This debugging task reused the original delivery/privacy answers without asking
|
|
65
|
+
again. It supplies one ordinary development-task observation, not a measured
|
|
66
|
+
comparison of daily time savings.
|