Skip to content

docs(mcp): document login-pending.json in the README (WALM-647) - #952

Merged
harrymove-ctrl merged 2 commits into
devfrom
harryphan/walm-647-document-login-pending
Sep 21, 2026
Merged

harrymove-ctrl merged 2 commits into
devfrom
harryphan/walm-647-document-login-pending

Conversation

@harrymove-ctrl

Copy link
Copy Markdown
Collaborator

This is a documentation gap, not a bug — the file handling is correct and this PR changes no code. The MCP writes a second file into the credential directory, login-pending.json, and nothing documented it: git grep login-pending over docs/ and packages/ returned no documentation hits at all, and the whole Credential Storage section named only credentials.json. This extends that section with what the file is, where it lives, its mode, its TTL, and when it is cleared. It also adds the one line for MEMWAL_MCP_TRANSPORT, which was described only in docs/reference/environment-variables.md.

Evidence: on dev,

packages/mcp/README.md:147-153   the entire "Credential Storage" section — credentials.json and --logout, nothing else
packages/mcp/src/auth.ts:441     pendingLoginPath() — sits beside whichever credentials file credsPath() resolves to
packages/mcp/src/auth.ts:433     PENDING_LOGIN_TTL_MS = 24 * 60 * 60_000

Impact: documentation only. Nobody is broken by this; a user who finds the file has no way to know what it is, whether it is a leak, or how to get rid of it, and the answer to the last one (--logout) was already written down for the other file only.

Test: none — this is prose. The behaviour it describes is already pinned: packages/mcp/test/logout-invalidation.test.mjs:681-689 asserts that memwal_logout removes login-pending.json, and packages/mcp/test/login-write-ahead.test.mjs covers the 0600 mode, the write-ahead ordering, and the clear on a completed sign-in.

One thing to know when merging: PR #920 (draft) deletes packages/mcp/test/logout-invalidation.test.mjs and rewrites packages/mcp/README.md, so it will conflict with this textually and the test reference above moves with it.

Closes #925

The Credential Storage section named only credentials.json, so the second
file the MCP writes into the same directory was undocumented — nothing said
what it holds, that it is mode 0600, that it expires after 24 hours, or when
it is cleared.

Also adds the one missing line for MEMWAL_MCP_TRANSPORT, which until now was
described only in docs/reference/environment-variables.md.
Both sides added to the Credential Storage section of packages/mcp/README.md.
Kept both and folded them into one section: the login write-ahead record is
described after the credentials file, the per-project approval model from
WALM-639 follows.

Corrected two facts the WALM-639 merge changed underneath this branch's text.
The record no longer always sits beside credentials.json: a sign-in from an
approved project keeps it in ~/.memwal/login-pending/, one file per project,
so no key material lands in the checkout. MEMWAL_CREDS_DIR still moves it,
and that is now stated where the override's absolute-path-outside-the-project
rule is, rather than as an unqualified aside.
@harrymove-ctrl

Copy link
Copy Markdown
Collaborator Author

Merged dev in after #958, #960, #963 and #956 landed. The only conflict was packages/mcp/README.md, where #958 added its own Credential Storage content.

Both sides were kept and folded into one section: the login-pending.json write-ahead record is described right after the credentials file, then #958's ### Per-project credentials follows with the approval model and MEMWAL_CREDS_DIR.

Two factual corrections, because #958 moved the ground under this branch's text:

  • This PR said the record sits beside credentials.json in whichever directory that file resolves to. That is no longer true for an approved project — pendingLoginPath() in packages/mcp/src/auth.ts now returns <trusted state dir>/login-pending/<hash>.json when resolution came from a project, so the README now says a project sign-in keeps it in ~/.memwal/login-pending/, one file per project, and no key material lands in the checkout. The global and MEMWAL_CREDS_DIR cases are unchanged and still login-pending.json beside the credentials file.
  • "MEMWAL_CREDS_DIR moves both" is still true, but it is now stated inside fix(mcp): require approval before using repo-local credentials (WALM-639) #958's MEMWAL_CREDS_DIR paragraph — where the absolute-path-outside-the-project rule and the empty-value-means-unset behaviour already are — instead of as an unqualified aside, so it cannot read as contradicting the new UntrustedCredsDirError validation.

Also replaced #958's parenthetical "the short-lived login write-ahead record is kept outside the repository either way" with the concrete location, now that the file itself is documented above it.

Checked the other claim in this PR: packages/mcp/test/logout-invalidation.test.mjs still exists on the merged tree and still asserts the pending record is gone after memwal_logout, so that claim stands.

Prose only, no code touched, so there was nothing to run and I have no test result to report.

@ducnmm ducnmm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Documents login-pending.json (location, 0600, 24h discard, per-project path). Matches the recovery behavior. Looks correct.

Issue counts by severity

  • bugs: 0
  • suggestions: 0
  • nits: 0

@harrymove-ctrl

Copy link
Copy Markdown
Collaborator Author

Re-checked against today's dev (83ae72ce). Already current — this branch merged dev at 0ab0cd8f, whose second parent is 83ae72ce, so there was nothing to merge and nothing was pushed. Approval untouched.

Still worth landing, but narrower than the body says. The gap is real: packages/mcp/README.md on today's dev never names login-pending.json. The whole of it is one parenthetical at L179 — "(The short-lived login write-ahead record is kept outside the repository either way.)" — which does not say what the file is called, where it lives, what it holds, its mode, its TTL, or when it is removed. #958 did not add any of that to the README.

Three claims in the body are now false, and should be corrected before merge.

  1. "git grep login-pending over docs/ and packages/ returned no documentation hits at all" — no longer true. fix(mcp): require approval before using repo-local credentials (WALM-639) #958 added docs/mcp/reference.md:151: "The login write-ahead record is kept in ~/.memwal/login-pending/ and never enters the repository." That names the project-case directory. It still says nothing about the filename, the global path, the contents, 0600, the 24h TTL, or the clear-on-logout, and it is in the docs site rather than the package README — so the PR still adds something, just not "the only documentation of this file anywhere".

  2. The evidence block's line references have all moved, and one of them is now describing the opposite of what the code does:

    • packages/mcp/README.md:147-153 → the Credential Storage section is L147-153 on today's dev, still accurate.
    • packages/mcp/src/auth.ts:441 pendingLoginPath() — sits beside whichever credentials file credsPath() resolves to → now auth.ts:979, and that description is exactly what fix(mcp): require approval before using repo-local credentials (WALM-639) #958 changed. It no longer sits beside credsPath(); it resolves to trustedStateDir(), and for an approved project to ~/.memwal/login-pending/<sha256 of the creds path>.json, specifically so no key material lands in the checkout.
    • packages/mcp/src/auth.ts:433 PENDING_LOGIN_TTL_MS → now auth.ts:944.
  3. "MEMWAL_MCP_TRANSPORT … was described only in docs/reference/environment-variables.md" — accurate (it is at L73 there), but it is also in packages/mcp/CHANGELOG.md:18 and docs/mcp/changelog.mdx:40. More to the point, that paragraph is unrelated to WALM-647. It is one line and it is correct against bridge.ts:548 / streamable.ts:41, so it is not harmful — but if you want this PR to be only what its title says, that hunk is the one to drop.

The diff itself is accurate against today's dev. Verified each factual claim in the new prose:

  • global path beside credentials.json in ~/.memwal — pendingLoginPath() → join(trustedStateDir(), "login-pending.json"), trustedStateDir() → credsDirOverride() ?? ~/.memwal (auth.ts:254).
  • project path ~/.memwal/login-pending/, one file per approved project — auth.ts:979-985, keyed by sha256(canonicalPath(resolution.path)).
  • holds the delegate keypair, written before the browser can register the public half — PendingLogin / savePendingLogin, auth.ts:946-1013.
  • mode 0600 — writeSecretFile, auth.ts:675.
  • 24h discard — PENDING_LOGIN_TTL_MS, auth.ts:944, enforced in loadPendingLogin at auth.ts:1063.
  • removed on completion / --logout / successful recovery — login.ts:483, index.ts:191, recovery.ts:240.
  • MEMWAL_CREDS_DIR points credentials, approval record and write-ahead record at the same directory — trustedStateDir() is the single source for all three.

Suite. Docs-only; the branch touches no code, so packages/mcp is byte-identical to dev outside the README and the suite is unchanged (dev baseline here: 207 tests, 147 pass, 60 fail, all listen EPERM 127.0.0.1 from the sandbox).

@harrymove-ctrl
harrymove-ctrl merged commit 4578ed0 into dev Sep 21, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

login-pending.json holds a second plaintext delegate key for 24h and is undocumented

3 participants