Skip to content

Commit 2111cf2

Browse files
ifahimrezaclaude
andcommitted
docs: STATUS — the four pillars, Mark's handshake bug, and the PR backlog cleared
Session log per the repo's own end-of-session rule. Records what the eleven merges actually decided rather than that they happened: the 202 that was answering 200-null between connected and tools/list, the dispatch()-vs-wire false negative that hid a 404 behind a passing test, the 1.1.0 bump reverted in four places (one of which was not a conflict and would have shipped), and the bind kept as sha256-over-key-sorted rather than truncated md5. Next up rewritten against reality: Mark needs a build and two caveats, Pro and Mailyard still owe the context-seam migration, and the three surviving branches are all superseded or contradict current policy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GkZr73cqaSesHRDG89Yy8S
1 parent 0e079ac commit 2111cf2

1 file changed

Lines changed: 25 additions & 18 deletions

File tree

STATUS.md

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
## Last session
2+
2026-08-16 (**the four pillars swept, Mark's ChatGPT bug root-caused and fixed, and every open PR resolved**) — Fahim's ask opened as "context, guardrails, tools and a system must work smoothly", turned into Mark Roach's ChatGPT report mid-session, and ended with "merge now" on the whole open-PR backlog. Eleven PRs merged (#90, #92, #94, #96, #98, #99, #66, #68, #69, #100, #101, #102); #70 closed as already-landed; **zero open PRs**. 575 tests, 0 lint errors.
3+
4+
**Mark's bug is fixed, and it was ours.** His two-client experiment isolated it: Claude Desktop via mcp-remote worked end to end against staging.kesuk.net while ChatGPT completed OAuth and then reported no callable actions. That rules out abilities, tiers, OAuth and the endpoint, leaving the handshake. `Saddle_MCP` violated three Streamable-HTTP MUSTs, and one sits between "connected" and `tools/list`: a notification must be answered **202 with no body**, and Saddle answered `200` with the JSON literal `null`. mcp-remote shrugs; a strict client treats the handshake as unfinished and never asks what tools exist. Also fixed: GET now 405 (was 404), DELETE 405, unsupported `MCP-Protocol-Version` 400, unparseable body 400, and `resources/*`/`prompts/list` answer empty lists instead of Method-not-found. **This was never only Mark** — since `bff1a99` the .org zip has no adapter, so that transport is the only one a .org install will ever have.
5+
6+
**A trap worth remembering:** leaving GET unregistered LOOKS conformant, because `WP_REST_Server::dispatch()` answers a method mismatch with 405 — so a test written against `dispatch()` passes while real clients get 404. I wrote that test, concluded "already correct", and only caught it by curling a Playground install running the built wporg zip. The suite cannot route to this transport at all (the dev tree carries the adapter), so the handler is unit-tested and the routing is verified on the wire.
7+
8+
**The four pillars.** Guardrails: wrapped destructive tools passed no `bind`, so a confirm could carry different arguments than its preview — the two-step confirm doing the opposite of its job. Tools: `tools/list` advertised everything regardless of tier; a default read-tier install showed 30 tools that are refused on every call. Now filtered at dispatch (never at registration — that runs pre-auth), with the withheld count stated in prose so an agent can name the setting instead of reporting the site can't do it. Context: `Saddle_Context_Bundle::summary_lines()` was dead code, the steering still described the five calls `context-bundle` replaced, and recent-changes stuttered six lines for one post. System: `build-page` was gated on `wp_is_block_theme()`, so classic themes got no playbook; now gated on "no foreign builder", plus a new `fix-page`.
9+
10+
**#86 closed.** The adapter's undeclared second endpoint is disabled, and disabling it let three test files drop the `_doing_it_wrong` workaround they carried. There is now a test asserting every MCP route is one of Saddle's own — verified to fail when the filter is removed.
11+
12+
**The vendored lib was hand-edited, and now is not.** 147 text domains rewritten across 18 files, existing only as edits that a re-vendor would silently drop. Recorded as `scripts/revendor-wp-mcp.php`, verified by reverting the library and reproducing main byte-for-byte. Only the text-domain *argument* is rewritten; `'mcp-adapter'` also appears 5 times as an ability category and server id, which are identifiers.
13+
14+
**Merging the July stack.** #67 auto-closed when #66's base branch was deleted, and GitHub won't reopen a PR whose base is gone — recreated as #99, then retargeted #68/#69 to `main` BEFORE merging their parents. Three real decisions in those merges: #69's **1.1.0 version bump reverted in four places** (readme's `Stable tag` was NOT a conflict and would have shipped silently); the wrapper bind kept as sha256-over-key-sorted rather than truncated md5 (without sorting, a client reordering its JSON has a legitimate confirm refused); and one of my own tests corrected, having asserted a precedence `permission()` does not use.
15+
16+
**Branch cleanup.** 27 local / 19 remote → 5 local / 4 remote. Every merged branch deleted, including 9 squash-merged local-only ones verified upstream with `git cherry`.
17+
18+
## Previous session
219
2026-08-12 (**CLAUDE.md rewritten from scratch; positioning + direction set; self-hosted update channel built and SHIPPED LIVE; Mark's remaining ChatGPT bug diagnosed but NOT fixed**) — Fahim's asks, in order: read Brian Coords' agent-first block-theme post and find what applies to Saddle; audit Novamira (free repo + local `novamira-pro` 1.5.0); rewrite `CLAUDE.md` clean with the old roadmap and issue links dropped; discuss what Saddle stands for; then "focus Saddle free: make sure it updates from here" → "clean just an updater" → "recreate all" → "live now".
320

421
**Positioning landed (now the Direction section of CLAUDE.md).** Transport is table stakes — WP 7.0 shipped the Abilities API + AI Client + Connectors, and 7.1 (**Aug 19**) adds granular AI permissions and connector filtering, i.e. core is building Saddle's tier layer from the other end. The product is the layer *above*: understand the design system → commit constraints → build → verify. Buyer = developers/agencies running WordPress from Claude Code/Codex. Scope locked to **Gutenberg (free) + Divi (Pro)**; no third builder, no chat UI, no screenshot engine (the buyer arrives with eyes — Saddle makes the page judgeable, `get-preview-url` + honest coverage caveats, and lets the agent judge).
@@ -246,24 +263,14 @@ Earlier 2026-07-12 — **Audit-backlog execution (P0–P4)**. Cleared the audit
246263
- Earlier same day: the Closed-Loop Quality Engine free half (epic #22, PRs #28#32, 300 green) — see git history.
247264

248265
## Next up
249-
- **Reply to Mark Roach** (support thread "Findings from testing Loggle & Saddle…", not asked for this session so not drafted): free's fixes ride in the refreshed `dist/saddle-1.0.0.zip` and Pro 1.2.2 removes the version demand — his three Saddle screenshots are all addressed. **Ask him to rotate the mrr.org.uk credentials he emailed in plaintext.** His offer of a live 20i test site stands if Fahim wants real-StackProtect confirmation of the `?rest_route=` fallback.
250-
- **Ship Loggle's own fallback** — its `src/admin/api.js` WAF+nonce work is still **uncommitted** in the loggle working tree, and the customer's installed 1.0.0 lacks it (his "log out then log in again" workaround is the stale-nonce gap). Commit + release from the loggle repo.
251-
- **Delete the v1.1.0 GitHub release + tag (Fahim, one command):** `gh release delete v1.1.0 --repo plugpressco/saddle --cleanup-tag --yes && git tag -d v1.1.0`. The code-side rollback to 1.0.0 is already committed (`f448d74`); this is the only piece left, blocked for the agent by the permission classifier.
252-
- **Write meta descriptions for the 11 posts/pages that lack them — this is the actual lever on the 86/100.** `meta_coverage` scores 3/10 and counts posts + pages only (15 items), so the 38 docs done on 2026-08-02 cannot move it. Use `waggle/generate-seo-meta` for drafts, approve, then `waggle/update-seo-meta`. Same rules: 140–160 chars, unique, focus keyword must appear verbatim in the title or description or the lint warns.
253-
- **Set the share-card default** in wp-admin → SEO → Social. Unreachable from the MCP side (see last session); needs a real 1200×630 branded card — none of the 21 uploaded screenshots is one. Clears the `og_image` warning on every doc at once; the per-post `featured_image` error stays open by decision.
254-
- **Eight Waggle docs need an FAQ section and H3s:** `waggle-aeo-score`, `waggle-how-ai-bots-find-markdown-pages`, and the six `waggle-troubleshooting-*` pages. `waggle-troubleshooting-machine-files` also has only 2 internal links. Coordinate first — these were being edited by someone else on 2026-08-01.
255-
- **Purge the page cache** after any docs change; plugpress.co serves stale HTML for a while otherwise.
256-
- **Docs follow-ups (small):** capture the OAuth consent screen and a deletion-preview-as-a-client-renders-it, and drop them into `/docs/oauth-sign-in/` and `/docs/safe-deletions/` — both were skipped because the local Studio site has neither state. Optionally re-shoot the Permissions access-levels figure so both figures in that doc come from the same site.
257-
- **[saddle#59](https://github.com/plugpressco/saddle/issues/59)** — Integrations screen ignores plugins that self-enrol via `saddle_integrations`; derive the category from the live catalog instead of the hardcoded prefix list at `class-saddle-rest.php:788`. One-file fix.
258-
- **Live ChatGPT round-trip on plugpress.co — the real gate for the OAuth work, not yet run.** Turn on Settings → "Sign-in for ChatGPT", confirm the readiness strip says discoverable, then in ChatGPT (Developer Mode → Settings → Connectors → Create) paste the MCP address, pick OAuth, leave client ID/secret blank. Watch for: discovery found, consent screen renders, code exchange succeeds, `tools/list` returns, a read tool call works, then Revoke and confirm the connector dies immediately. Worth knowing before testing: **ChatGPT restricts write-capable custom connectors to Business/Enterprise/Edu** — on Plus or Pro it will be read-only regardless of the granted scope, which is ChatGPT's limit, not Saddle's.
259-
- **Uncertainty this test resolves:** whether ChatGPT honours `resource_metadata` from the 401 challenge, or only probes `/.well-known/*` at the host root. If only the root, OAuth needs WordPress at the domain root and the Settings readiness strip should say so more bluntly.
260-
- **Then rebuild the zip** (`npm run build && npx grunt build` — never `grunt release`, it bumps the version) and re-upload.
261-
- **SUBMIT to WordPress.org — everything code-side is done (2026-07-23 audit: zero blockers).** Fahim's three steps, all in `WPORG-SUBMISSION.md`: (1) confirm `badhonrocks` is the submitting wp.org username (it's the readme `Contributors:` value), (2) upload `dist/saddle-1.0.0.zip` at wordpress.org/plugins/developers/add/, (3) after approval: screenshots ×4 + banner/icon into SVN `assets/`, then the first public GitHub tag/release (rolled-back v1.0.0 tag rule — tag only AFTER approval). Reviewer-pushback answers are pre-written in `WPORG-SUBMISSION.md`.
262-
- **If HEAD moves before upload:** rebuild with `npm run build && npx grunt build` (never `grunt release` — it bumps the version).
263-
- **Final visual pass in wp-admin** (fix-forward): topbar under admin bar at 32px/46px, status pill flips with tier/pause, Memory drawer, Permissions chip tooltips, 960 column everywhere, <782px icon rail; Unsplash demo-key round-trip (search → import → re-import reuse → force → Media filter → remove key), then close #60 + #61 on the board.
264-
- **Feature backlog:** free has none open; Pro: #1 Rank Math / #2 CF7 / #3 Elementor all deferred by decision, #4 hygiene tail.
265-
- Consider a free minor release (0.10.0) bundling the UI migration; Pro's min-free constant bump to match is still pending in Pro.
266-
- CI PHPUnit still red on GitHub Actions (no WP core in the runner) — fix as its own PR so future PRs get a real green.
266+
- **Reply to Mark Roach with a build to test.** The handshake fix is in `main` and unreleased. Two things to tell him beyond "try this": at the read tier he is now offered 36 tools rather than 66 (the new filter working as designed — and relevant because **ChatGPT restricts write-capable connectors to Business/Enterprise/Edu**, so on Plus or Pro his connector is read-only whatever scope he approved); and if it still shows nothing, **Connections → Connection details & health → Client traffic** is the next diagnostic. A `tools/list` row with status 200 and a non-zero count means Saddle is conformant and the tools are being dropped inside ChatGPT — a [documented](https://community.openai.com/t/mcp-connected-but-not-invokable/1384847) connector bug. **Still ask him to rotate the mrr.org.uk credentials he emailed in plaintext.**
267+
- **Migrate saddle-pro and mailyard onto `saddle_context_sections`.** Free's half shipped in #102 and both still append through the old string filter, so Pro's `##` heading and Mailyard's floating "For email delivery problems:" sentence are still in the live context. Pro's tree currently has uncommitted release prep in it (a 1.4.0 → 1.4.1 bump), which is why it was left alone. Nothing breaks meanwhile — the compat path is tested.
268+
- **The three surviving branches are all superseded or dead — decide and delete.** `feat/admin-header` (9 commits) and `feat/ui-plugpress-ui-v0.6.0` (a strict subset of it) targeted `@plugpress/ui` v0.8.2; `main` is on **v0.11.3**, TopBar and `Saddle_Log::record_action()` are both there, and every file they add exists on main in restructured form. `feat/freemius-parent` puts Freemius in FREE, which contradicts both CLAUDE.md ("no licensing or upsell in free") and the decision that free ships on WP.org with no Freemius.
269+
- **Delete the v1.1.0 GitHub release + tag (one command):** `gh release delete v1.1.0 --repo plugpressco/saddle --cleanup-tag --yes && git tag -d v1.1.0`. Still outstanding, and #69 tried to reintroduce 1.1.0 this session — reverted in four places, including a `Stable tag` that was not a conflict and would have shipped silently.
270+
- **Run `php scripts/revendor-wp-mcp.php --check` before any release.** New pre-release guard: it exits non-zero if the vendored library was refreshed without re-applying Saddle's text domain.
271+
- **SUBMIT to WordPress.org.** Everything code-side is done and this session removed one of the reviewer-facing surfaces (#86). Fahim's three steps are in `WPORG-SUBMISSION.md`. Rebuild first: `npm run build && npx grunt build` — never `grunt release`, it bumps the version.
272+
- **Live ChatGPT round-trip on plugpress.co** — still the real gate for the OAuth work, and now also the confirmation that the handshake fix holds against the client that exposed it.
273+
- **CI PHPUnit still red on GitHub Actions** (no WP core in the runner). Worth its own PR so future PRs get a real green; "green" currently means someone ran the suite locally and said so.
267274

268275
## Blockers / open questions
269276
- Old work tickets #4#6 remain from the previous scope — #5 (design-system unify) partially overlaps the shipped brief/bundle; triage against the new scope when convenient. (#8 closed 2026-07-11.)

0 commit comments

Comments
 (0)