Open work
The one live list of what is being built, what comes next, and what is waiting
on a decision. Last reconciled against main at b4fc2ffa (2026-11-02, the dev head).
The rule. A shipped item is deleted, not struck through: its record is the
CHANGELOG entry and the PR. A wrong row is corrected in place, never answered
by a new row beside it. Nothing in Now or Next is marked done. Feature
PRs do not edit this file; the coordinator reconciles it after merges, because
every PR editing its own row made every PR conflict with every other.
scripts/check-open-work.sh (CI job open work, not required) runs on main
and on a PR that edits this file, and fails when a PR listed under Now has
merged or the stamp above is not on the branch. Red on main means reconcile.
History (the dated programs, audits and dispositions this file carried until
2026-09-29) is in Open Work 2026-08-25 to 2026-09-28.
Direction is in Roadmap; what shipped is in
Capabilities and CHANGELOG.md.
Before anyone deploys
No blocker is open. main is prod and dev takes the work (decided
2026-10-27): every pull request targets dev, and the coordinator promotes by
fast-forwarding main to the newest green dev commit, with no soak
wait (decided 2026-10-30), then tags it. A published release tag on main deploys
maidan.world through the prod GitHub environment (#1738), which allows only
main and v* tags. maidan.world runs v419.0.0 (2026-10-27), and every
deploy path and install command pins it; scripts/check-deploy-pins.sh (CI job
deploy pins) keeps them on the newest tagged CHANGELOG section.
dev.maidan.world and the swarm's local stack run dev. The :dev images in
compose.yaml and the charts' default values.yaml are built from source on
purpose. Pointing anyone else at a deploy is part of the launch, which is the
maintainer's call.
Do not tag a commit whose push CI is red or unfinished. open work is not a
required check, so a red open work alone does not block a tag; the eight
required checks on the tagged commit do.
Now: in flight
Merge order matters where one PR builds on another; the column says so. A
lane marked Active is being built in the coordinator's session from a local
worktree: an agent outside that session does not start it, and takes a row of
its own instead. No lane is active. Work left
in stopped lanes is on wip/ and wip/rescue-* branches, named in the Next
items it belongs to.
Rows without a PR number are being built and get one when opened. The
coordinator's merge loops run in its own session; whoever merges without them
follows the merge rule in CLAUDE.md (all eight required checks on the exact
head commit, --match-head-commit, and every CodeRabbit comment answered) and,
before merging, builds the PR on current main if another PR merged since its
CI ran.
Open pull requests are not listed here: the list went stale at every merge
and failed the open work check that deploys wait on. They are on GitHub,
gh pr list -R david-engelmann/maidan --base dev, and what each one fixes is
in its body and its Next row.
Next: ranked
The launch path, ranked by what the launch needs first. The launch is open source plus a hosted service at maidan.world (decided 2026-10-12): the hosted rows (Next 24 onward) come after the OAuth server people connect through, and the list closes with the launch release and its gate (Next 29). The directory listings follow the launch, on the maintainer's go. An item enters this table with acceptance criteria and a check that shows it is still open. "Thread" numbers refer to the 2026-09-29/30 enhancement thread, whose dispositions are recorded below.
| # | Item | Size | Acceptance criteria | Open because | Depends on |
|---|---|---|---|---|---|
| 33 | Agent swarm coordination (the swarm design relayed on 2026-10-13; Swarms); the swarm runs against a local stack, not the hosted instances (decided 2026-10-14) | M, as several PRs; the open parts are done | Many agents work one repository without colliding or merging unreviewed code: footprints, leases and fencing, the merge queue at the delivered head, repository pause, build slots, plans with lint, hold and amendment, CI, merge-queue and deploy tracking, per-workspace keys and metering, and claimant recipes for every harness the swarm runs. Done when a ramp step of 8 concurrent claimants on the swarm stack runs a day unattended: every task claimed, delivered, reviewed by a second model family and landed or sent back, with no thread stuck and no alert unexplained | Shipped through v416.0.0 and on main since: the S1 to S5 punch list from the stack's operator and the wax maintainer (Graphite-squashed pull requests land, #1564; a claim held into review lapses and release works after a result, #1567; stacked bases refused and carried as depends_on, #1568; second-family review routing, #1571; verdicts name the head and a push voids them, #1573; strict task attributes, #1562), the gate debounce (#1563), C5 warm fan-out (#1585), C8 duplicate tasks (#1578, #1579), the lane attribute (#1587), and the Codex recipe and seat preflight (#1559, #1561). The seat runner (#1612), scripts/capped (#1594), the nightly mutation shards (#1617), held duplicates by Linear issue (#1601), the review_children switch (#1610), queue depth filtered by repo and engine (#1611), the red-team runbook with FAIL lines on the thread (#1620), and a seat-runner prompt per task kind with the red-team prompt for review threads (#1622) shipped on 2026-10-24/26. Find threads by attribute (#1751) and close as abandoned (#1753), punch list S6 and S7, shipped on 2026-10-28. The alert proof (formerly row 41) is closed: real stall and tick-failure alerts from all three loops reached Slack on 2026-10-21, 22 and 27, and prod's ops alerts are configured (2026-11-02). The bottleneck on 2026-10-23 was agent-ready tickets, not capacity: 3 of 45 open wax tickets were safe for unattended claims | — |
| 42 | Open sign-up on maidan.world (the maintainer, 2026-10-24: invite now, open next) | S left, of M | MAIDAN_SIGNUP_OPEN=1 lets a verified email sign up without an invite, behind the per-address and per-domain limits (#1425, #1555), refused at boot beside auto-provisioning. Cloudflare Turnstile guards the waitlist POST and the sign-up start when MAIDAN_TURNSTILE_SECRET is set, verified server-side through the egress guard. A self-serve workspace is refused past a meter's free allowance (a clear 429 or 403 and an admin notice); operator-created and invited workspaces keep the mark-only rule of 2026-10-12. Two-tenant tests on both backends. Then the flag is turned on in prod | Built and released in v419.0.0: open sign-up behind Turnstile (#1615, #1619, #1628, #1656), the boot refusal without Turnstile in production (#1659), the hard allowance cutoff on every metered surface (#1630, #1645, #1662, #1666, #1673, #1677, #1715), the front door and policy links (#1602, #1627), and the Turnstile token in a POST body (#1705). Open: turning MAIDAN_SIGNUP_OPEN on, which waits for the launch gate (decided 2026-10-27) | Next 29, the launch gate |
| 23 | OAuth authorization server (connected apps Lane 8, decided 2026-10-08) | L, seven phases, discovery and metadata first | Full OAuth 2.1: discovery and metadata, then the flows, with consent in the /ui console, public and confidential clients, client metadata documents and pre-registration and no dynamic registration. Held to: metadata documents fetched only through the egress guard, PKCE S256 only, exact redirect URIs, rotating refresh tokens whose reuse revokes the family, tokens bound to the MCP resource (RFC 8707), iss on responses (RFC 9207), a consent page that cannot be framed, grants that never exceed the member's capabilities, and a first milestone that advertises no flow it does not serve. The research is committed under docs/archive/ before phase one | P0 to P5 shipped (#1324, #1337, #1364, #1367, #1404, #1417), and a metadata-document client reaches the token endpoint (#1413). The first P6 attempt (2026-10-28, a claude.ai custom connector against dev.maidan.world) found that discovery did not advertise client metadata documents, so claude.ai fell back to dynamic registration and refused; fixed by #1747 (client_id_metadata_document_supported). The client metadata hosts became an instance setting (MAIDAN_OAUTH_CLIENT_METADATA_HOSTS, #1789). Open: the recorded P6 run itself, on maidan.world after the next release (dev.maidan.world has no identity provider), with a consent click from the maintainer | Next 12 and Next 24 for the demo host |
| 24 | The hosted deployment at maidan.world | M | One origin serves the console, the API, MCP and OAuth (MAIDAN_PUBLIC_ORIGIN), with TLS, on the domain layout decided on 2026-10-12: maidan.world serves the console, the API, MCP and OAuth from one origin, docs.maidan.world the docs, dev.maidan.world the staging instance running main, and try.maidan.world the demo instance (Next 12) running the release. Each deploys from the repo's own Helm chart or compose file and its pins, keeps point-in-time backups with a restore drilled on it, routes alerts to a person, and has a status page. The runbook is in docs/Production.md | maidan.world is live since 2026-10-24 and runs v419.0.0 since 2026-10-27: the maidan-prod Worker on Cloudflare Containers, Neon prod, R2 prod, Cloudflare Access OIDC, sign-up by waitlist invite, the policy pages, HTTPS-only with HSTS, and a drilled Neon restore (#1598). The prod GitHub environment and its secrets exist (2026-10-28), and deploy prod refuses a tag not on main (#1738), so the next release deploys itself; its first run is the next promotion. dev.maidan.world runs dev. Shipped on the existing services: the public /status page served by the Worker, one /health reading cached for a minute (#1857, #1862); ops alerts configured on the prod Worker (MAIDAN_OPS_ALERT_CHANNEL, MAIDAN_SLACK_BOT_TOKEN, 2026-11-02); the hosted instances wake once a day, not hourly, pinned by deploy/cloudflare/test/cost.test.js (#1870). Cost comes first: sleepAfter stays 15 minutes and nothing wakes a container on a timer more than daily (the maintainer, 2026-11-01). Open: the try.maidan.world deploy (built up to it in #1829); docs.maidan.world (configured in #1827) | — |
| 14 | A validated version before any submission (connected apps, Lane 9's hint and title pass, pulled forward by the maintainer on 2026-10-04) | M | Every tool carries explicit readOnlyHint, destructiveHint and openWorldHint values and a title, each value with a one-line reason a reviewer can check, and a contract test fails when a tool lacks one, so new tools stay compliant. Every listing has a validation record before anything is published or submitted. The package installs on a clean machine against an instance on the release. Every tool in the listed surface (the full 246 or a curated profile of about twenty, chosen per listing) succeeds with valid parameters and returns an actionable error with bad ones. The listing's example prompts run through the platform's own model and pick the right tools. The reviewer token outlasts the longest review wait. The record names the commit and image digest it validated, and any change to the listed surface re-runs it before a resubmission. The four tools that mix reads and writes stay single tools, each a documented write, as decided on 2026-10-07. Every submission also satisfies three protocol-layer properties, audited 2026-10-05. No surface lets the supervised agent compose, trigger or satisfy its own approval. Every approval binds to a verified human identity, per-user credentials at minimum. The close gate stays server-side and durable. A model may decide an approval only through Next 17's credential-bound path: a browser session, approval:grant, or a confirmation the person gives outside the model. Elicitation is a complement, not a foundation. It is supported in Claude Code, Codex CLI, Cursor, VS Code and Copilot, and GitHub Copilot CLI, not supported in ChatGPT web or Gemini CLI, and unverifiable for claude.ai. Form mode takes flat primitives only, so evidence does not fit, and client-side approvals are non-binding by construction, so elicited answers are advisory and the close gate stays server-side. Every directory listing carries the trust-model sentence in its materials and tests. Provider-rendered approval UI is untrusted display, the Maidan console is the trust root, and an approval whose evidence the human did not see in the console is provisional. Each release re-runs the validation record and re-curates any curated tool profile, owned by whoever cuts the release | The annotation half landed in #1264, enforced by a contract test. A validation record exists for v419.0.0 (listings/validation/v419.md, #1743): the official MCP Inspector passed 50 of 50 checks against the signed release binaries, with no source build. The clean-machine install check (#1807), the reviewer-token expiry check (#1808) and a validation-record template for every listing (#1832) shipped. Still open: the record run on the next release, with the install on another host, and the example prompts through each platform's own model. The four tools that mix reads and writes stay single tools as documented writes (#1281) | The maintainer's go for any submission. It gates every publish in Next 9 to Next 13 and Next 15 to Next 16. Its validation record runs on the connected-app dev and test harness that landed in #1280 to #1289 (the dev instance, the request log, the Inspector probes per tool group and the client matrix) |
| 17 | The ChatGPT inline approve card (the rest of the connected-app dev and test program) | S to M | An MCP Apps UI resource (ui://, text/html;profile=mcp-app) renders the gate inline in any host that implements MCP Apps, ChatGPT included, and decides through the host's tools/call to approval_decide (#1332), so it follows that tool's rule: a direct accept only with approval:grant below the workspace's confirmation threshold, otherwise the one-time console link. The gate's card and audit row name the deciding client from the credential first (a registered OAuth client), then the client's own clientInfo shown as self-reported, then none (both decided 2026-10-09). Tested in ChatGPT against a dev instance before any listing | The card shipped in #1343 and the link's lifetime is a workspace setting since #1344. It has not been tried in ChatGPT: the maintainer's personal ChatGPT plan has no developer mode, and the maintainer's business workspace needs an admin to turn it on (2026-10-28) | — |
| 13 | Adoption and per-user connect recipes (connected apps Lane 5 folds in here) | S to M each | An OpenHands claimant recipe. Provider recipes I2 to I6 (Providers). The official third-party SDKs run as clients in CI. Connect recipes for Claude custom connectors, Perplexity, grok.com and Gemini custom MCP (US, 18 and over, a personal account with Keep Activity on, and the skills surface that replaces Gems (Gems move to Settings on November 17, 2026 and stay usable until Google removes them), each tested against a real instance with a manually minted, scoped and expiring token, and each noting that an authorization server would replace it. Page views per recipe are the proxy metric. The recipes follow the paths verified on 2026-10-06. claude.ai through Customize, Connectors, Add custom connector (Free allows one). ChatGPT developer mode under Settings, Security and login, then the Plugins page, where a schema change is picked up with the refresh control rather than by re-adding the server. Claude Code with claude mcp add --transport http. Grok through grok mcp add --transport http and through the Responses API, whose MCP tool declaration carries the token in its authorization field. Muse through a conversational custom connector, a manual walkthrough logged with the app version and date. Grok's custom connector (New Connector, Custom, a server URL and a static bearer, available to all Grok users per docs.x.ai/grok/connectors) is the cheapest consumer test path. Gemini Apps custom MCP is limited to Gemini Spark users within Spark tasks (official help), so that recipe says so. claude.ai install links (?modal=add-custom-connector with a name and URL) are a documented way to share a connector without a directory, and the recipe uses them for a self-hosted instance's own URL | The OpenHands claimant recipe (examples/openhands/) and the provider recipes I2 to I6 (#1457) shipped. The official MCP SDKs run as clients in CI and the connect recipes are written (#1828). Open: each connect recipe run against maidan.world once it is on the next release | Next 24's public origin for the hosted clients (claude.ai, ChatGPT, Grok). Claude Code and other local clients need none |
| 12 | Listing asset pack and the demo instance (Lane 4) | S for the pack. The demo instance is hosted under Next 24 | Short and long store descriptions that lead with the room, not the tool count, and name both the hosted room at maidan.world and the self-hosted path. An icon set (a square of at least 48px, a 400x400 PNG). Name and logo clearance before any submission. Screenshots only where a directory requires them, taken by the capture script from #1353. The demo instance runs the release at the demo host (Next 24) with a seeded workspace that resets between reviewers, a reviewer token per directory whose expiry outlasts the longest review wait, rate limits and seeded-room isolation against abuse, and a token prefix per listing so connects attribute to the lane that earned them. The privacy policy, terms, support contact and data statement are the maintainer's, prepared outside the repo for launch (decided 2026-10-12), and each listing links them | The demo instance is built up to its deploy (#1829: deploy/cloudflare/wrangler.demo.jsonc, a reseed on every boot, a six-hour reset, expiring tokens, no outbound egress, edge limits). The asset pack shipped (docs/Listing.md: name, card, short and long descriptions; icons at 48 and 400 px, #1794). Open: the deploy to try.maidan.world | Next 24 |
| 30 | Launch polish: performance and the UI audit | M, as several small PRs | The performance Tier 0 batch (response compression, ETag revalidation on /ui assets, the notices-query index with EXPLAIN before and after, a capped live feed) and the P2 items of the 2026-10-03 UI deep dive, each its own PR with a test | Tier 0 is done (#1378, #1380, #1381, #1385). Of the UI deep dive's P2 items, the transition history (#1549), a member's own display name (#1554, and from the session panel #1780), a file linked as task evidence (#1778) and the review row naming its requester (#1779) shipped; the rest are open. The landing and marketing revamp (#1773, #1774, and the hands-on swarm builder tile #1781) is built by a cloud agent; #1781 merged on the maintainer's sign-off of 2026-10-29. The server-side P2 items shipped (#1833 to #1838), and the React console replaced the classic board at /ui (#1809 to #1822, landed in #1839). Open: the console's after-switch list (needs-you focus, the only-channel case, paste, the palette, the member picker, the calm state, reduced motion, deliveries replay, the glass not-found path, the phone-header labels, the skip link, 44px on every button) and console follow-ups 13 to 23 | — |
| 43 | Agent ergonomics: a coordinator profile, flow skills, and a HOL Guard contribution (the maintainer, 2026-10-29) | S to M, four PRs | (1) A coordinator MCP profile and endpoint beside /mcp/worker and /mcp/reviewer: about 25 tools to file, find and track tasks, read status and results, and review, the same bytes for every caller, with a test. (2) Skills with runbooks for the three common flows (work a task, review a task, file and track a task) for Claude Code, Codex and Cursor in examples/. (3) A HOL Guard MCP contribution (mcp.maidan.json, schema guard.mcp-server-contribution.v1, remote-http) generated from tool-annotations.json by a script, with a contract test that fails on drift; the policy is by risk: the worker loop and reads allowed, and gate decisions, token and delegation changes, tombstones and deletes, and anything that reaches GitHub, Slack or Linear reviewed; Guard is enabled in interactive clients only, never on headless seats; proved locally against the swarm stack. (4) The PR to hashgraph-online/hol-guard, on the maintainer's go | The maintainer's Docker MCP gateway loads the full 230-tool catalog per session (about 155 KB of tool schemas), which costs tokens and tool-choice accuracy; the profiles exist only for workers and reviewers. HOL (hashgraph-online) invited a Guard extension for Maidan's write actions on 2026-10-29. Guard's v1 schema caps a server at 80 tools against Maidan's 260, and a remote or direct-command contribution can only tighten, never allow | Items 2 and 3 shipped (#1786): ten skills in examples/claude-code/ cover all 260 tools, checked by scripts/check-agent-skills.py; listings/hol-guard/policy.json tiers every tool, and scripts/gen-hol-guard.py generates the contributions (51 tools reviewed, resolve_secret blocked, the rest inherit; each profile names every tool) with a drift check in lint. Item 1 shipped (#1826, /mcp/coordinator). Item 4 and a local Guard install wait on the maintainer's go; the submission is best after maidan.world takes sign-ups, since HOL cannot exercise the hosted endpoints before then |
| 29 | The launch release and its surfaces | M | A release cut from a main whose push CI is green, with every deploy pin on it, is the launch candidate. The docs site serves from the domain layout. The README and the site lead with the hosted room and the self-hosted path side by side. The maidan-launch-1.0 gate test (Roadmap, Gates) drives the hosted path end to end: an invite, sign-up, a workspace, an agent connected through OAuth from an MCP client, a task claimed, reviewed and closed, and the usage it metered | The maidan-launch-1.0 gate test exists (crates/maidan-server/tests/launch_gate_e2e.rs, #1794): invite, sign-up, workspace, an OAuth MCP agent, a task claimed, reviewed and closed, metered usage, and a two-tenant check, on Postgres. Open: the launch release itself, the docs site on its domain, and the gate's path run against maidan.world once Next 23 P6 is recorded | Next 23, Next 24, Next 30 |
| 11 | MCP registries and catalogs (Lane 3) | S, 2 to 4 days plus review waits | The same-day entries first. The official MCP registry through mcp-publisher with the OCI package type on the published image, then a request to partnerships@github.com for the GitHub MCP Registry and VS Code's one-click install. Glama (a repo topic and glama.json). One line in the classic awesome-mcp-servers list. A Cline marketplace issue with a 400x400 PNG icon. Smithery's URL path once the demo endpoint exists (Next 12), with a static card at /.well-known/mcp/server-card.json and an unauthenticated MCP request answered 401, confirmed on the public endpoint before submitting. Then two async PRs, each with a retry budget. The Docker MCP Catalog (server.yaml, a tools.json that matches tools/list, and the entry variant, a remote endpoint or a container, chosen at lane time, with the Dockerfile where the catalog expects it) and the ToolHive catalog (a server.json that reuses the registry's OCI block, its canonical repo confirmed at lane time). The container variant needs a first-run token flow the catalog's CI step can run without the insecure quickstart image. MCP.Directory, MCP Harbor and the Continue Hub are checked and batched if cheap. Paid listings stay out (Won't do). Each entry is prepared and validated, and none is published, filed or emailed until the maintainer's go | The build half shipped (#1373), with glama.json (#1743) and the mcp-server repository topic. The awesome-mcp-servers entry is filed (punkpeye/awesome-mcp-servers#17827, the maintainer's go on 2026-10-27). The official registry entry publishes at the first release that carries the image label io.modelcontextprotocol.server.name (#1739); v419.0.0 has none. Docker, ToolHive and the rest are not filed | The maintainer's go for any submission, on a validated release. The Smithery step waits on the demo endpoint in Next 12 |
| 10 | GitHub Copilot CLI plugin marketplace and the Agent Plugins 1.0 package (Lane 2) | XS | .github/plugin/marketplace.json and a root plugin.json carry the MCP server config and the worker and reviewer skills, built once in the Agent Plugins 1.0 shape so Next 16 (Cursor) reuses it. Installing from the public repo URL works against a local instance in a recorded run. If the npx add shorthand needs an npm package to resolve, the lane publishes one and records it here. The plugin is free, and its description says production is self-hosted. It is built and validated on a branch and merges to main only on the maintainer's go, because a marketplace file on main is itself the listing. The walkthrough mitigations are built in. Review decisions route through elicitation, which the platform supports, and the bundled preToolUse hooks provide client-side checks for the plugin's approval workflow. They are not an authorization boundary. The server-side claim gate and durable close gate remain authoritative. Per-user tokens ship behind a stdio shim, since Agent Plugins 1.0 passes remote config literally with no environment variable expansion. The plugin does not carry the MCP server, which Copilot CLI adds separately with copilot mcp add, so the recipe and the validation record cover both. plugin.json declares the Agent Plugins 1.0 $schema. The built plugin waits on wip/copilot-plugin until the maintainer's go (#1268) | Built and validated on wip/copilot-plugin (#1267); reverted from main by #1268 to keep it unlisted. It merges to main only on the maintainer's go, because a marketplace file on main is itself the listing, and nothing is published or submitted while Maidan is being built (decided 2026-10-06). GitHub's Copilot CLI plugin docs describe a marketplace file in a public repo with no review step (docs.github.com, observed 2026-10-03). The worker and reviewer profiles it packages are on main (#1240). Trust-paradox walkthrough, audited 2026-10-05. Per-surface verdicts are in the walkthrough synthesis kept outside the repo | The maintainer's go for any submission, on a validated release |
| 15 | Muse connector submission, shadowing a sibling app (Lane 6) | S. 1 to 2 days after Next 14, plus one assumed rejection and resubmit cycle | The form materials (the strategy's description and example prompts, the demo endpoint, the API-key choice on a reviewer token from Next 14) are prepared and held until the outcome of the maintainer's the sibling app submission, with a time bound set when the lane starts. A the sibling app rejection on the shared API-key auth model re-scopes this row to OAuth with PKCE behind the parked authorization server, or parks it. A the sibling app rejection on the sibling app-specific grounds changes nothing. Before submitting, a supervision-session walkthrough names the capability profile the listing authenticates as, the session topology (the platform's agent as the worker, or outside workers with the listing as the reviewer's surface), and where the human review happens. A listing on one operator token does not promise the reviewer as a separate trust role. The first review round is also the test of whether the room sells in a directory. Re-check at lane time. The form fields and API-key acceptance are corroborated by four third-party submitters and documented nowhere by Meta, so the maintainer resolves them first-hand from the the sibling app form. If the form takes the API-key shape, the field list locks. If review refuses it, the re-scope rule above applies. The work-email login gate and the Stripe payments question are third-party reported and unverified. The submission itself waits on the maintainer's go and on Next 14's validation record. The submission materials declare that durable approval gates resolve only in Maidan's console, and the listing copy does not promise in-Muse supervision. The audited walkthrough verdict is that supervision does not survive in the as-shipped shape, because no push channel or inbox is documented and a shared key breaks separation of duties. The forced console bounce is the strongest enforcement guarantee available there, since Muse cannot wrongly resolve a durable gate. How the human learns of a waiting gate stays an open lane-time problem, and so does the Meta form's end-user API-key setup flow. The maintainer gave a go on Meta's Connector Terms §3.1(c) on 2026-10-06, accepting that Meta may use connector content and user interaction data, including who approved what, to improve Muse. The submission uses per-user scoped tokens, never one shared admin bearer, since Meta's guideline §4.4 asks each user's data to be isolated, a thin tool set Meta can classify (read, write, sensitive write), a dedicated reviewer account, and the trust-model sentence. Meta's connector guidelines and terms are now public (muse.ai/platform/docs, muse.ai/platform/terms, checked 2026-10-06), so the review criteria are no longer unknown | muse.ai/platform is live (fetched 2026-10-04), and Meta publishes no criteria, SLA or fees. Maidan has no listing. Trust-paradox walkthrough, audited 2026-10-05. Per-surface verdicts are in the walkthrough synthesis kept outside the repo | Next 14, the the sibling app outcome |
| 16 | Cursor Marketplace, manual-token shape (Lane 7) | S. 2 to 4 days after Next 14, plus one assumed rejection and resubmit cycle (1 to 2 weeks of review wait each, third-party reported) | The Next 10 package, or a .cursor-plugin/plugin.json, per https://cursor.com/docs/plugins. The listing states its auth honestly as a token the user configures at install, scoped by capability and expiring, never a non-expiring admin token. The OAuth upgrade waits on the parked authorization server. Terms and privacy policy from Next 12 visible in the listing, accurate metadata, no training on user content, free to users, and a token prefix per listing for attribution. A supervision-session walkthrough, as in Next 14, before submitting. Updates are batched, because every update is re-reviewed. Re-check at lane time. The publish form at cursor.com/marketplace/publish renders only through JavaScript, so its fields are UNVERIFIED. The submission waits on the maintainer's go and on Next 14's validation record. The identity design is fixed before shipping, either two tokens with separated duties or a declared worker-only listing with approvals in the console. The ambiguous single token does not ship, because the walkthrough shows it manufactures false approvals. Background elicitation notifications are re-checked at lane time, since Cursor 1.5 added OS notifications when input is required. Cursor's solo-user plugin variable flow stays an open lane-time question. Cursor 2.6 renders MCP Apps inline (official changelog), so the board and an approval card can show in chat, and the card links to the console, where the decision is made. Lane testing uses Pro accounts, since several October 2026 sources agree the Hobby plan excludes MCP. Every directory listing carries the trust-model sentence in its materials and tests. Provider-rendered approval UI is untrusted display, the Maidan console is the trust root, and an approval whose evidence the human did not see in the console is provisional | The Cursor package is prepared, not submitted (#1830, .cursor-plugin/plugin.json, worker-only with a scoped, expiring token). The MIT license clears the publisher terms' permissive-only bar (https://cursor.com/marketplace-publisher-terms). Minting a token needs token:admin (crates/maidan-server/src/routes/token.rs), so the self-service token the strategy copies from its teardowns does not exist, and an admin mints each user's token. Trust-paradox walkthrough, audited 2026-10-05. Per-surface verdicts are in the walkthrough synthesis kept outside the repo | Next 12, Next 14 |
Connected apps (Next 10 to Next 17, and Later CA). The no-authorization-server fast track the maintainer chose on 2026-10-03, in the strategy's lane order, with Lane 9's hint pass pulled forward as Next 14. Nothing is published or submitted to any directory, catalog or registry until the maintainer says go (2026-10-04), and never without Next 14's validation record. Until then a lane is done when it is built and validated. Every listing row depends on a validated release and the maintainer's go, because every listing points at a release, and the listings follow the launch. Each directory size includes one assumed rejection and resubmit cycle. No estimate is discounted for the the sibling app work, which transfers the OAuth protocol mechanics, the privacy policy's section headings, the Muse form mechanics and the sibling app's review outcome as an early signal, and nothing else (not the consent design, the reviewer identity path, the policy's substance, the crypto-shredding tail or the runbooks). Each lane is judged on its own. A lane whose connects reach the demo endpoint ships a token prefix per listing (half a day to a day each), so attempts attribute to the lane that earned them. The self-hosted lanes (Next 11, Next 12, the registry and image entries of Next 13, and Next 15) cannot see connects by design, and are judged on proxies, namely registry pulls, install counts, topic-driven GitHub traffic, recipe page views and any visibility a directory reports. A hybrid directory lane is judged on reported visibility plus those proxies, because its real users self-host. A near-free catalog PR promotes on acceptance. A heavier later lane promotes when two directory lanes each hold at least 25 attributed connects a week, on a four-week rolling average or in three of any four weeks, after scanner and reviewer traffic is filtered out, or when it reaches an audience the directory lanes cannot. The AWS lane and the IDE wrappers promote on acceptance plus one clean end-to-end install. The 25 is a starting guess, recalibrated after 90 days of data and recorded here. A lane is killed when a rejection has no remediation path, when a queue stalls 90 days with no response and no escalation, when 60 days live bring zero attributed connects on a hosted lane of size M or larger, or on the day a platform rule removes its fit. A killed lane stays recorded with its reason and date. Review-gated lanes are judged after 30 days live or two review cycles, whichever is later, and zero-review lanes after 30 days. Support tickets are tagged by surface at intake. Cursor and Anthropic re-review every update, so updates are batched, and each one re-runs Next 14's validation record. The strategy master is the connected-apps research of 2026-10-03, kept outside the repo. The supervision-session walkthroughs the directory rows require were walked and audited on 2026-10-05, with per-surface verdicts in the walkthrough synthesis kept outside the repo. ChatGPT, Cursor, Gemini CLI and Copilot CLI survive with mitigations. Claude connectors and Muse do not survive as shipped. How a human learns of a waiting gate is unbuilt on every surface except ChatGPT Work chats, where MCP Events are the documented wake-up path, and whether any directory surface has a push channel for connector events is open. Cursor 1.5 added OS notifications when input is required, which re-opens that question for Cursor without resolving it. Every listing, parked ones included, carries the three protocol-layer properties in Next 14.
Measure before scheduling: the per-response query count (F-51); whether
the workspace context pack filters before it builds; the search deny-set
query; the board's full re-render on large channels (thread 17); catch_up
page cost as the event log grows (thread 18).
Found running Claude clients against a local Maidan (2026-10-07), small enough to fold into the nearest PR. post_message needs a thread, so "post to #general" costs two lookups and is ambiguous in a channel with several threads. A managed third-party Claude Desktop reads ~/Library/Application Support/Claude-3p/, not Claude/.
Found by the #1247 and #1248 lane (2026-10-04), small enough to fold into the nearest PR. compose.yaml hides the root-owned /data volume problem because it stores artifacts in MinIO. A first install that collides with a hand-made app:<slug> member still answers with the generic handle conflict.
Found on 2026-10-28. Observability follow-ups from ENG-6218 (#1769 and #1770 shipped one trace per thread, claim latency, the delivery surface and the swarm dashboard): per-seat cost from the usage ledger and spans (#1771), and the egress surface (#1772). The DeepSeek review seat reports zero tokens, because Claude Code does not hand DeepSeek's usage back to the seat.
Found on 2026-10-26, small enough to fold into the nearest PR.
- A result with no
result_kind(#1649). #1718 refuses unroutable waiter result envelopes, and a delivery that gives up alerts the operator (#1863). Close #1649 once that lands. - Context economics follow-ups. The ordering tests for C6 (#1584), and an app-clock
claimed_aton explicit claim or assign plus a hold policy for manual sub-threads under a recipe root (#1586).
Found on 2026-10-24, small enough to fold into the nearest PR. web_push moves to p256 0.14 when openidconnect does, retiring the RUSTSEC-2026-0387 ignore for crypto-bigint 0.5.5 (#1594). A from_env test that MAIDAN_OIDC_EMAILS_VERIFIED parses.
Found by the 2026-10-23 Playwright runs, small enough to fold into the nearest UI PR. audit.spec.ts:205 (a phone-width boundingBox read as null) and needs-you-focus.spec.ts:94 (focus checked before the row redraws) flake on timing; each waits for layout or the redraw first.
Later: by program
One line per item, promoted into Next when it gets acceptance criteria.
- R — resilience: chaos steady-state checks; native TLS on the gRPC listener (#1114 requires an acknowledgement instead).
- V — verification: stateful model tests beyond the claim lease; Kani over idempotency keys and FSM totality; a small rule set over typed references (the
add_referencerelations) checked on write, so a reference that breaks the room's ontology is refused rather than stored (a verifier, after Pavlyshyn; Engineering Canon V-04). - D — Postgres operations:
rebuild-derived --verify(re-fold the notification ledger, follow counts and inbox cursors from the log, with a drift metric); XID-age, bloat, WAL and replication-slot metrics; a pool-topology guide; a UTF-8 pin. - S — security: an R2 key scoped to the prod bucket in place of the account-wide key prod and dev share today;
authority_audit_contractover every crate and example with its two carve-outs (maidan init, the Playwright harness) named, so a call outside the two watched crates cannot slip past (thread 14b); threat-regression gates (each Threat-Model row names its test) and a per-PR threat-model delta; token TTLs with DPoP or mTLS binding; audience-bound step-up auth for sensitive MCP tools; an over-permission scan of the MCP surface; a provenance label on content from other tenants, tools and external sources;miriover theunsafein dependencies. - M — memory: memory block revisions carry two dates, recorded and effective, and a retraction with its reason is appended, never deleted, so an agent can ask what the room believed at a time; erasure still wins, and crypto-shredding removes a retracted value with the rest (Engineering Canon P-MEM-01 to 03, read from abstracts only).
- E — compliance: read-time PII masking on messages, content blocks and audit metadata; scheduled key rotation and a key-age policy, now that a workspace key can live in AWS KMS (#1534, #1566).
- O — observability: OTLP export to the local workbench Alloy (
OTLP_ENDPOINT,OTLP_METRICS), so a review run shows a trace andmaidan_usage_tokens_totalandmaidan_usage_usd_micros_totalare scraped, with no prompt or diff text in span attributes and Postgres still the record (David, 2026-10-30); a buffered, redacted collector pipeline with a tested loss contract; opt-intokio-console; a named p99 on the fan-out paths; operator views. - F — search quality: reranking (RRF or a cross-encoder); an HNSW recall evaluation (the
m/efknobs are pgvector defaults); a query-embedding cache; a search evaluation gate overrelevance_eval.rs; a ParadeDB comparison; facet search by reference kind, result kind and event kind. - G — developer experience and governance: a fitness-function catalog; semver checks for the SDKs; a glossary-grounding lint; active benchmarking with k6; a devcontainer, pipeline parity, typed config, a cross-build matrix and an S3 test double.
- U — the web UI: design tokens; a code editor, log stream and DAG view; a reference-graph pane over the backlink index; an interactive OpenAPI reference; recorded demos; one-click token mint in Connect; a member last-active endpoint; cross-channel palette search; delivery and allowlist panels.
- Federation (when federation gets real multi-peer use): a versioned envelope contract; cross-peer causal order; verifiable-credential peer trust.
- Parked evaluations (revisit on a concrete trigger): OPA/ABAC; Tantivy; compile-time SQL; SOPS; a CI egress allowlist; an in-flight-run drain signal; allocator and zero-copy micro-evaluations; an MCP registry policy.
- C — context economics: C1 to C13 are shipped (C9 #1629, C10 #1636, C11 #1618, C12 #1637, C13 #1638); MCEB-1, the pre-registered cost-per-success benchmark, waits for the maintainer to set its budget.
- UI audit P2 and the performance Tier 0 batch (UI deep dive 2026-10-03): the P2 items and Tier 0 (response compression, ETag revalidation on
/uiassets rather than immutable caching without fingerprinted URLs, modulepreload, a capped live feed, the notices-query index) are recorded in the audit digest and promoted into Next as P0 and P1 land. The UI ships as a generated, minified bundle checked into the repo, with CI failing when it is stale (as with the vendored gRPC code), socargo buildstill needs no Node and the bundle can carry fingerprinted URLs (decided 2026-10-04). - L — launch (decided 2026-10-12, with the launch-blocking work in Next 23, Next 24, Next 29 and Next 30): open source plus a hosted service at maidan.world, with sign-ups through a waitlist first. The hosted service is free up to an allowance, and usage past it is metered (Next 27) and billed, with billing built on the ledger after launch. Still to come here: positioning, comparison and migration pages, the in-browser playground on the demo host, and the open-core boundary written down (the room stays open source). The privacy policy, terms and trust page are the maintainer's, prepared outside the repo.
- CA, connected apps (later lanes). Lane 8, the OAuth authorization server, is Next 23 since the maintainer's decision of 2026-10-08. The notes below are its design inputs. What exists is an installed-app authorization code exchange with optional PKCE, started by an admin call (
crates/maidan-server/src/app_oauth.rs,POST /oauth/app/token). What does not is dynamic client registration, client metadata documents, OAuth metadata endpoints, a browser consent screen that maps capabilities to scopes, refresh tokens for those clients, and a 401 carryingWWW-Authenticate. When it unparks, client metadata documents are the primary path, with pre-registration for Cursor and for clients that present no document, a human stays in the consent flow, the reviewer identity path is designed in the lane, an upstream identity provider that is itself a supervised agent platform is used only if no other exists, and a 3 to 5 day security review comes before any listing depends on it. Lane 9's hint and title pass is Next 14. Its other half, splitting tools that mix reads and writes, is not done. The maintainer kept them as single tools on 2026-10-07, each a documented write. Before submitting, each directory lane chooses between the full surface and a curated profile of about twenty tools built on the worker and reviewer profiles, and runs the directory's test cases through the platform's model against whichever it lists. Lane 10, the Claude directory (S after lanes 4, 8 and 9), and Lane 11, the ChatGPT plugin directory (M after lanes 4, 8 and 9), wait on the Lane 8 revisit. Lane 10's static-headers path is a beta for a limited set of organizations, granted by invitation, and access is checked through mcp-review@anthropic.com at lane time. The audited walkthrough verdict strengthens the parked rationale. Supervision does not survive inside Claude connectors as they work today, because the surface collapses to narration plus per-tool prompts, and the directory's review rules forbid evidence-showing instructions in tool descriptions. The verdict supports the sequencing hold rather than parking on its own, and the best mitigation, MCP Apps, is build work to size before the lane is promised. Lane 11 needs a global-residency project (seven submitter runbooks say EU-residency projects cannot submit, re-confirmed in the portal), domain verification, five positive and three negative test cases, a video, and reviewer credentials without MFA. The OpenAI enterprise marketplace is a procurement and billing channel, not a self-serve plugin directory, so it is not a lane (provider research, 2026-10-06). ChatGPT's MCP Events, a signed-webhook wake-up path documented for Work chats and dots, is the one provider push channel found, and it is the natural carrier for Needs-you when Lane 11 unparks, subscribed by the user and never unsolicited. The audited walkthrough verdict for Lane 11 is survives with mitigations, and the mitigations are load-bearing, because the approval card authorizes one tool call and shows only the app and the proposed action.destructiveHintmarks the call for explicit approval, which is advisory to the host and not a guarantee.toolInputstays withheld until after approval, so evidence-first ordering holds. The DevDay sidebar and panel surfaces host the Needs-you queue. The developer-mode bearer token question stays open for lane time, and no public-directory listing ships until the OAuth authorization server exists. Cutting Lane 11 and doubling Next 13 becomes the plan if Muse rejects the room as a category, if no session topology keeps supervision intact inside ChatGPT, or if the Lane 8 revisit answers skip. Lane 12, the Microsoft tracks (M to L), stays parked until the consumer lanes clear the promotion bar or a real customer in that ecosystem reopens it. Whether Microsoft's connector write actions have shipped is UNVERIFIED first-hand. Every directory lane, these included, walks a full supervision session before submitting (see Next 14) and has Next 14's validation record. The later lanes wait until the directory lanes are live and measured. AWS Marketplace AI agents and tools (M) is the exception, a procurement lane on its own bar that starts once the fast track ships. Its stateless streamable HTTP requirement on port 8000 at/mcpis UNVERIFIED. Pointing the container at the buyer's Postgres and object store does not configure the listener or the image's exposed port, so the requirement stays unverified until an image or deployment exposes0.0.0.0:8000atPOST /mcpwith test evidence recorded in Claims.md. The rest are Google Cloud Marketplace (L), Alexa with a voice adapter (M), Poe, which needs a Chat Completions endpoint (M), Kilo Code (XS, slow merges), a Workspace Marketplace Chat app (M), VS Code and Open VSX (S), and JetBrains and Raycast (S to M each). Watched, not lanes. Salesforce AgentExchange, Atlassian Rovo's announced MCP support, a Claude Code community marketplace, the end of new custom GPTs (October 26 for Enterprise, December 11 for everyone), and Anthropic's portal analytics as a visibility source for Lane 10. The dev and test program beyond Next 17 waits here. MCP JSON-RPC cassettes recorded through a proxy (agent-vcr) start only after a spike shows the proxy captures server-initiatedelicitation/create, and are redacted on save. Provider-API cassettes, an unattended nightly driver for the scriptable clients (Gemini CLI, Copilot CLI, the Grok API), and an agentic-loop load test that checks rate limits under a burst oftools/listandtools/callfollow. A dev-only OAuth stub for authenticated and write flows is built only when that testing starts. It refuses to boot without a dev flag, serves one synthetic identity, and is deleted, not extended, when Lane 8 unparks. Grok now has surfaces to watch, the Grok Bot Marketplace and the Grok Build plugin marketplace, though none lists third-party MCP servers for grok.com chat. Google Cloud Marketplace's AI agents category (A2A, an Agent Card and an OAuth2 code grant) fits Maidan's existing A2A surface and gets a sizing spike among the later lanes. Grok Build's plugin marketplace (PR-based, xai-org/plugin-marketplace) is a real distribution path after the maintainer's go. A quarterly re-read checks the facts the program rests on, namely each provider's plan gating, Anthropic's static request headers (a beta for a limited set of organizations), and whether Meta starts requiring per-user OAuth.
Decisions pending the maintainer
| Question | Options | Recommendation | Blocks |
|---|---|---|---|
| The go for directory submissions | — | Submit listings after the maidan-launch-1.0 gate passes, each with Next 14's validation record | The listings (Next 10, 11, 15, 16) |
The maintainer delegated the rest on 2026-10-01; they are under Recently decided, and the ones that need building are in Now or Next.
External setup that blocks rows, and is not a decision: live Slack and GitHub apps for projector tests, a provider key for the Goose recipe, and Jev access for J-01.
Recently decided
Each links its record. Entries roll off after about a month.
| Date | Decision | Record |
|---|---|---|
| 2026-11-02 | The M13 alert drill days 3 to 5 are dropped (real alerts already proved the path), and the bucket-scoped R2 key moves to Later S: neither blocks the launch | maidan-ca, 2026-11-02 |
| 2026-11-02 | A manual sub-thread under a recipe root is not held by the warm hold: the run records its id on the children it creates, and only those are held (#1729) | maidan-ca, delegated; #1729 |
| 2026-11-01 | Hosting cost comes first: sleepAfter stays 15 minutes, nothing wakes a hosted container on a timer more than daily, and public pages answer or cache at the edge | The maintainer, 2026-11-01; #1870 |
| 2026-11-01 | Hosted rows use the service setups already in place (Cloudflare, Neon, R2, GitHub, Slack): no paid upgrades or new vendors, and Neon's current restore window is enough | The maintainer, 2026-11-01; Next 24 |
| 2026-10-30 | Promote the newest green dev to main with no soak wait; this replaces the day on the swarm stack in the 2026-10-27 entry | The maintainer, 2026-10-30 |
| 2026-10-29 | Agent ergonomics and a HOL Guard contribution become Next 43, after the design and launch work; the PR to hol-guard waits on the maintainer's go | The maintainer, 2026-10-29 |
| 2026-10-29 | The landing revamp's swarm builder tile (#1781) signed off and merged | #1781 |
| 2026-10-28 | All Maidan work paused for the code freeze, MaidanFadin exempt (the maintainer, 09:58 ET) | #1495 |
| 2026-10-28 | A DeepSeek review seat exists and passed its driver's-license run, but wax reviews go to it only on the maintainer's word; paid reviews stay product-only | The maintainer, 2026-10-28 |
| 2026-10-28 | The TypeSafe (Jev) land-gate advisor is on in the local swarm stack only | The maintainer, 2026-10-28 |
| 2026-10-28 | Ready PRs batch on one integration branch with one CI run; the merge loop refuses a PR based on main or with cargo vet, open work or Playwright red; integration may take 60 minutes (#1768) | Harness² lessons, CLAUDE.md |
| 2026-10-27 | main is prod and dev is the default branch: every PR targets dev, and maidan-ca fast-forwards main to a dev commit that is green and has run a day on the swarm stack, then tags and deploys it | Decisions.md, "main is prod; work lands on dev" |
| 2026-10-27 | Cut v419.0.0 now with #1682's dated Trivy exception and deploy it to maidan.world | The maintainer, 2026-10-27 |
| 2026-10-27 | Open sign-up stays off on maidan.world until the Next 29 launch gate passes | The maintainer, 2026-10-27 |
| 2026-10-27 | Muse is retired. MaidanFadin takes Next 36 and Next 37 | The maintainer, 2026-10-27 |
| 2026-10-26 | Paid review passes (Codex, Claude subagents) are for product pull requests only, never maidan or pi. MaidanFadin's own fresh-context red-team is the independent pass for maidan PRs | The maintainer, 2026-10-26 |
| 2026-10-26 | Wait for more fixes before cutting a release again: v418.0.0 is tagged, but its release run failed a Trivy scan and nothing was published | The maintainer, 2026-10-26; #1682 |
| 2026-10-25 | Two conventions from the agentic-harness digest: a seat posts each failed attempt on its thread as FAIL: <hypothesis> | <evidence>, and red-team reviews follow one runbook (exact head, scoped delta, adversarial probes, the minimal wrong change to prove a test pins behaviour). Built into Maidan only if they prove useful | The coordinator, 2026-10-25; #1620 |
| 2026-10-24 | maidan.world goes up now, invite-only, and opens to the public once open sign-up is safe (Turnstile, a hard cutoff at the free allowance for self-serve workspaces). Sign-in is Cloudflare Access with an emailed one-time code. The privacy policy, terms and support page are approved (operator David Engelmann, support@maidan.world, New York law, 16 and over, 30-day request logs) | The maintainer, 2026-10-24; #1598, Next 42 |
| 2026-10-23 | Release tags are cut whenever the swarm stack needs newer code, without asking; the swarm stack deploys any main commit whose eight required checks passed, tag or not | The maintainer, 2026-10-23; v416.0.0 (#1560, #1581) |
| 2026-10-23 | While the coordinator is out, MaidanFadin reviews and merges its own pull requests and Muse's on the merge gate, with a posted self-review, and a second, independent pass for auth, keys, data migrations and dependency changes | The maintainer, 2026-10-23; #1495 |
| 2026-10-23 | A claim's lane orders work, it never reserves it: a tiebreak within aged priority, so laned work never starves | #1588 |
| 2026-10-22 | Codex claimants run a sol model (gpt-5.6-sol on a ChatGPT login), never gpt-6-astra | The maintainer, 2026-10-22; #1559 |
| 2026-10-22 | No backwards compatibility before the launch: no shims, no optional legacy parameters, no backfills for old local data | The maintainer, 2026-10-22 (restating F-54) |
| 2026-10-22 | Cut v415.0.0 | The maintainer, 2026-10-22; #1540 |
| 2026-10-21 | Cut v414.0.0 (tagged at 79753f42) once phase 1 and CI ingestion merged; wait_for_event and thread lookup follow in the next release. Move the Rust toolchain off 1.91. Stale test threads on the swarm stack are cleared, and real-repository work is closed only with its maintainer's word | The maintainer, 2026-10-21; #1503 |
| 2026-10-21 | A workspace has a default engine, applied at thread creation when none is named, so an engine-filtered claim sees the threads Maidan creates itself | #1485 |
| 2026-10-21 | Swarm metrics compare providers and harnesses from the claimant's own usage evidence (report_usage evidence.provider, evidence.harness), not a new claim field | #1496 |
| 2026-10-21 | With pull requests keyed by workspace, only the workspace whose change flow delivered a head may rebase, push or enqueue it; tracking is read-only | #1497, #1500 |
| 2026-10-14 | The agent swarm's Maidan stays on a local stack (the maintainer's machine), not the hosted instances: its repositories and task content stay out of hosted storage. The hosted service (Next 24 onward) continues on its own lane, and Next 33 is built for the local stack | The maintainer, 2026-10-14; Next 33 |
| 2026-10-13 | The hosted service runs on Cloudflare Containers (sleeping when idle), Neon Postgres and R2, one of each per instance; an Iceberg tier on R2 takes old history later | Decisions, Next 24 |
| 2026-10-13 | Each workspace's message keys are wrapped by a key of its own; a cloud KMS is the next custody | Decisions, Next 25 |
| 2026-10-12 | The domain layout: maidan.world serves the console, the API, MCP and OAuth from one origin, docs.maidan.world the docs, dev.maidan.world the staging instance, and try.maidan.world the demo | Decisions, Next 24 |
| 2026-10-12 | The launch is open source plus a hosted service at maidan.world, whose console takes sign-ups through a waitlist first, with invited sign-up behind it | Decisions, Next 24 to Next 29 |
| 2026-10-12 | The hosted service is free up to an allowance of compute, storage and the like, and usage past it is billed. Metering comes before launch, billing after | Decisions, Next 27 |
| 2026-10-12 | The privacy policy, terms and other legal pages are the maintainer's, prepared outside the repo for launch | Decisions, Next 12 |
| 2026-10-10 | Cut v413.0.0 once the last security PR merged, then bump the deploy pins (Next 7). No submission to any directory or registry until the maintainer says the product is ready, so the sdk-*-v0.3.0 tags wait | Decisions |
| 2026-10-09 | The inline approve card is an MCP Apps UI resource that decides through the host's tools/call to approval_decide, not a ChatGPT-only confirmation prompt. The deciding client is named from the credential first (a registered OAuth client), then from the client's own clientInfo shown as self-reported, then none. The confirmation link's lifetime becomes a workspace setting | Decisions, Next 17 |
| 2026-10-08 | An approval may be decided by a model (approval_decide, a ChatGPT inline card), and acceptance becomes a property of the credential: a browser session, approval:grant, or a fresh confirmation outside the model. A token minted for an MCP client cannot accept a gate | Decisions, Next 17 |
| 2026-10-08 | Build the OAuth authorization server at full OAuth 2.1 scope, consent in the console, public and confidential clients, no dynamic registration | Decisions, Next 23 |
| 2026-10-08 | Run the cost-per-success pilot on a subscription the maintainer provides, under a cap the runner enforces, publishing the cap and the variance | Decisions, Later C |
| 2026-10-08 | Approval evidence carries three tiers (verified, attached, self-reported), with a warning when an approval rests on self-reported evidence only | Decisions, #1327 |
| 2026-10-08 | The mark-ready live check runs on a scratch GitHub repository, not Gitea | Decisions, Now |
| 2026-10-08 | Maidan answers tasks/* as an unknown method rather than -32021. It does not implement the optional tasks extension, and -32021 would tell a client to declare an extension Maidan does not offer. The suite's tasks checks stay in the 2026-07-28 baseline with that reason. A review note stays out of the review_submitted event, since #1132 kept free text out of the immutable log | #1302, #1304 |
| 2026-10-06 | Go on Meta's Connector Terms §3.1(c). The Muse lane proceeds with per-user scoped tokens, a thin tool set and a dedicated reviewer account, still shadowing the the sibling app outcome | Muse row in Next |
| 2026-10-06 | A tied review reaches a human: when approvals equal change requests, the thread leaves the queue for a human instead of sitting in a tie neither side can break, and the board shows ties in a Review column | #1258 |
| 2026-10-06 | A claim blocked by a full inbox gets a thread where the blocking worker can reach a human: the board records the block reason and note, an authenticated Unblock path exists, and the row survives a DELETE failure | #1260 |
| 2026-10-06 | The workspace queue is one number: per-worker ceilings plus the fair-share ledger, with a MaidanWorkspaceQueueFull alert when every eligible worker is capped | #1265 |
| 2026-10-06 | The MCP tool annotations landed: every tool carries readOnlyHint, destructiveHint and openWorldHint with a one-line reason, enforced by a contract test | #1264 |
| 2026-10-06 | The Connect page, Capabilities, Integrations and README describe the room as it is now (workspace queue depth, claim leasing, the Inbox's Needs you) | #1263 |
| 2026-10-06 | The board review findings closed their loop: the 15 findings are fixed on main or answered on their comments | #1262 |
| 2026-10-06 | The Gemini CLI extension manifest is on main and stays unlisted: the gallery topic is not added until the maintainer's go, and #1319 made it reach the user's own instance | #1266, #1319 |
| 2026-10-06 | Nothing is published or submitted to any directory, catalog or registry (Copilot included) while Maidan is being built; the Copilot listing files stay on wip/copilot-plugin | #1268, Next 10 |
| 2026-10-04 | The review gate stays opt-in. A thread closes with no approval unless a gate is configured, and the board shows such a close as closed without review | Decisions, Next 1 |
| 2026-10-04 | start_review needs a posted result on gated threads only. Elsewhere it is allowed, and the approval card warns that no result was posted | Decisions, Next 1, Next 5 |
| 2026-10-04 | The web UI ships as a generated, minified bundle checked into the repo, kept fresh by CI, so cargo build needs no Node | Decisions, Later U |
| 2026-10-04 | Nothing connected-apps is published or submitted to any directory, catalog or registry until the maintainer says go, and every submission is a version with a validation record first. Lane 9's hint and title pass moves forward as Next 14 | Decisions, Next 14 |
| 2026-10-04 | The hybrid hosting decision does not limit the hosted console. The console work in progress continues, and the strategy's service-engagement sentence is set aside | Decisions, Now |
| 2026-10-04 | Maintainer hours are not a constraint on the connected-apps program, so it carries no capacity number and no support-hour pause triggers | Decisions |
| 2026-10-03 | Connected-apps hosting is hybrid, open source first. Self-hosting is the product, a hosted demo instance serves directory reviewers (Next 12), and listing copy says plainly that production is self-hosted. Superseded on 2026-10-12: the hosted service is a launch surface, and listings name both paths | Decisions, Next 12 |
| 2026-10-03 | The OAuth authorization server is on hold. The connected-apps program is lanes 1 to 7 (Next 9 to Next 16). Lane 8 was parked until the 2026-10-08 decision to build it (Next 23). The Muse API-key and Claude static-headers paths are unaffected | Decisions, Later CA |
| 2026-10-03 | No enterprise track until the consumer lanes measure. Lane 12 stays parked, and a real customer in one ecosystem reopens its track early | Decisions, Later CA |
| 2026-10-03 | Muse shadows a sibling app. Lane 6 waits on the the sibling app outcome with its materials prepared. A rejection of the shared API-key auth model re-scopes it to OAuth with PKCE or parks it, and a rejection on the sibling app-specific grounds changes nothing | Decisions, Next 14 |
| 2026-10-03 | Slack replies thread by an optional thread_ts on the Slack deliver_to target, which the producer supplies; Maidan keeps no Maidan-to-Slack thread mapping for it, and the egress allowlist stays keyed by channel | #1245 |
| 2026-10-03 | The change flow runs on David's personal PAT as MAIDAN_GITHUB_TOKEN (contents:write and pull_requests:write on the deployment repositories), so agent PRs are authored as David and nothing may depend on his approval: the flow stops at a draft PR. The shared Maidan runs in Pi's dev-tools compose stack, built from main, not Porter | Decisions; #1245, #1247 and #1248 |
| 2026-10-03 | A token budget counts what the model processed fresh (uncached input, output, cache writes); cache reads count toward the USD budget at their price only, so caching never exhausts a token budget faster | Decisions; #1242 |
| 2026-10-03 | Shipped work is not still in flight: the message retention ceiling, closed vote kinds, group DMs, installing a rotated token only into the connection that asked, GitHub check runs, browser web push with a retry, MCP create_channel and create_thread, 16px controls, the palette jump, the edit pencil, first-run copy, sign-out, and the ten UI design surfaces | #1232, #1231, #1230, #1229, #1228, #1225, #1226, #1219, #1224, #1220, #1179–#1196 |
| 2026-10-02 | Item 68 is rejected: the hero is the board, not a terminal recording | README |
| 2026-10-02 | A schema change while two server versions share a database expands, then contracts in a later release | Migrations |
| 2026-10-01 | A production chart render refuses the dev image, default credentials and CHANGE_ME, and deploy pins keeps every deploy pin on the newest tagged release | #1156 |
| 2026-10-01 | Every nightly job fails red; the fuzz job builds and runs every target on the gnu triple, and its first night found two real decoder bugs, fixed with regression tests (an egress URL that percent-encodes past the length limit; an MCP id that lost precision as a float, now parsed with float_roundtrip) | #1160 |
| 2026-10-01 | #1159 and #1160 landed | #1159, #1160 |
| 2026-10-01 | Prod renders name a release and refuse placeholders; deploy pins stay on the newest tag (#1156 landed) | #1156 |
| 2026-10-01 | PRs merge by admin squash when the eight required checks pass on the exact head and every CodeRabbit comment is answered; no review is required while one person maintains the repo | Decisions |
| 2026-10-01 | Branches need not be up to date to merge (F-43 stays off); the merge loop builds each PR on current main and runs the static contracts first | Decisions |
| 2026-10-01 | A squash commit carries the PR title and body, so each commit on main holds its retro | Decisions |
| 2026-10-01 | max_wall_secs is the thread's total worked time: every way a claim ends charges it | Decisions; lane BUD |
| 2026-10-01 | A member handle is unique regardless of case; existing case-only duplicates are renamed by the migration | Decisions; lane IDN |
| 2026-10-01 | Artifacts are erased, never soft-deleted; the unused tombstoned_at column goes | Decisions; lane IDN |
| 2026-10-01 | A SCIM group records membership and grants nothing; channel access comes first if an operator asks | Decisions |
| 2026-10-01 | An OIDC browser session carries thread:transition, under the separation-of-duties checks | Decisions; #1176 |
| 2026-10-01 | A token's session reaches the bearer routes except MCP, re-resolving the token's authority on every request | #1142 |
| 2026-10-01 | Read notifications age out under MAIDAN_RETENTION_NOTIFICATIONS_DAYS, off by default; the usage ledger is kept as a billing record | Decisions; #1165 |
| 2026-10-01 | The SDKs publish as 0.3.0 with the next server release; 0.2.0 is skipped | #1159 |
| 2026-09-30 | Artifact bytes are served with their stored type, nosniff and a sandboxing CSP; images render inline; no read serves a tombstoned artifact | #1135 |
| 2026-09-30 | A blank /ui opens on a first-run card; the discovery document says which sign-in paths exist; Sign out forgets the token | #1123 |
| 2026-09-30 | A claim freed on a lapsed lease is charged its worked time against max_wall_secs | #1139 |
| 2026-09-30 | A verdict is a ReviewSubmitted event; a change request notifies the last worker to hold the thread | #1132 |
| 2026-09-30 | A member id naming no member, or another workspace's, is a 404; sign-in and sign-out are audited; A2A reads are not recorded as changes | #1136 |
| 2026-09-30 | Every audit row names a workspace (or the instance), stamped at write; a hold keeps only its own workspace's rows | #1134 |
| 2026-09-30 | Every HTTP operation is classified as reading or changing state, and CI checks it | #1121 |
| 2026-09-30 | A SCIM group records membership and grants nothing; a userName rename keeps the member's id | #1133 |
| 2026-09-30 | Stateless MCP subscriptions live in a shared, expiring table, so any replica delivers them | #1131 |
| 2026-09-30 | Retries to one host share a per-host token bucket; a refused retry is deferred, never dropped | #1122 |
| 2026-09-30 | A SQLite backup is a VACUUM INTO snapshot; a restore deletes the old -wal and -shm | #1126 |
| 2026-09-29 | A misspelt MAIDAN_* variable refuses boot | #1107 |
| 2026-09-29 | A2A pushes go over https; plaintext gRPC off loopback needs an acknowledgement | #1114 |
| 2026-09-29 | A token can be rotated: a new secret for the same authority, the old one revoked in the same transaction | #1116 |
| 2026-09-29 | Release tags wait; they are the maintainer's call, not a per-cluster step | Operations |
| 2026-09-29 | Delivery retention never prunes a pending row or a dead letter | #1108 |
| 2026-09-29 | Every egress request times out (5 s to connect, 10 s in all); an A2A task holds at most 10 push configs | #1109 |
| 2026-09-29 | A WebSocket subscription announces only its own member | #1112 |
| 2026-09-28 | Withdrawn messages are crypto-shredded; the server refuses to start without a KEK | #1063, #1064 |
| 2026-09-25 | A change request reopens the thread and dismisses approvals | #1054 |
| 2026-09-25 | A legal hold keeps withdrawn words; holds are per matter | #1056, #1057 |
| 2026-09-23 | D-A: authority changes write their audit row in the same transaction | Decisions |
| 2026-09-23 | D-B: a per-workspace grant ceiling, 90 days by default | Decisions |
| 2026-09-23 | D-C: delegated capabilities are a two-way intersection; members carry none | Decisions |
| 2026-09-23 | Approvals may be borrowed, never self-approved | Decisions |
| 2026-09-23 | F-54: no /v1 and no compatibility promise before 1.0 | Decisions |
Known risks
| Risk | Mitigation | Residual | Watched by |
|---|---|---|---|
| An agent holding a person's token accepts an approval gate | Accepting needs a browser session the person signed in to, sent from the console page, or a token holding approval:grant, and nobody accepts their own request (with auth on, since AUTH_DISABLED checks no identity) (#1280, #1325). A plain bearer, a delegate token or a session made from one can only decline or cancel | A token a person mints with approval:grant and hands to an agent still accepts. maidan init's admin token holds it. A model asking through approval_decide (#1332) gets a confirmation link a person spends in the console, unless the token holds approval:grant and the gate is below the workspace threshold (by default none is) | Next 17 |
A pasted bearer token lives in localStorage | Tokens are capability-scoped, revocable and rotatable (#1116); #1093 escapes the page's innerHTML writes; #1142 exchanges the token for an HttpOnly session; /ui sends a Content-Security-Policy (#1213) | A script injected into the page can act as the session while the page is open but cannot take the credential away (Threat-Model T17) | #1142, #1213 |
| Admin merges while branch protection is not strict (F-43, kept off on 2026-10-01) | The merge loop reads the checks of the PR's exact head commit, requires all eight required checks there and every CodeRabbit comment answered, merges with --match-head-commit, and first builds the PR merged onto current main and runs the static contracts | A break that only a full test run on the merged tree would catch; main's own CI catches it after the merge | main CI; Process below |
| Events delivered at most once on the optimistic path | Transactional outbox, quarantine and replay; opt-in at_least_once delivery per consumer_id | A client that does not opt in can see a gap or a duplicate | maidan_outbox_quarantined, MaidanOutboxQuarantined |
AUTH_DISABLED or bootstrap left on | Both refuse boot without an explicit acknowledgement, and always in production; hardened builds strip the path | A dev binary exposed to a network | Boot checks |
| The embedding indexer falls behind | Retries, a repair sweep, and /health/ready degraded past INDEXER_STALE_SECS | INDEXER_STALE_SECS is off by default | maidan_indexer_last_event_age_seconds |
hash-v1 embeddings are not semantic | A boot warning; openai-compatible for real use | A deployment that ignores the warning | Boot log |
| The Postgres bus listener drops | Reconnect with back-fill from the log | Delay while it reconnects | /health/ready, maidan_bus_lag_total |
RUSTSEC-2023-0071 (rsa) | Ignored with a reason; RS256 verification only | Clears with openidconnect 5 | cargo-deny |
| Review findings merged unread | Since 2026-10-01 the merge loop holds a PR while any CodeRabbit comment is unanswered | 126 comments on PRs merged 2026-09-28 to 2026-10-01 were never answered (20 marked major). The triage (2026-10-01) found 75 valid, 43 not applicable and 8 fixed on main, and answered the 51 that need no change. Lanes SEC and CRD fixed the 59 outside index.html (#1167, #1168, #1183, #1186, #1189, #1191 and #1162); the index.html items rode with the review-findings row and closed in #1262. Threads on #1260, #1262 and #1263 merged unreplied through the API; a retroactive audit answered each one on 2026-10-06 | the merge loop |
| One tenant saturates a shared instance | Per-token and per-workspace rate limits, the in-flight ceiling, statement and lock timeouts, egress timeouts | No CPU or IO isolation between tenants | maidan_http_shed_total, MaidanLoadShedding |
Won't do
| Item | Why | Record |
|---|---|---|
Re-recording docs/assets/handoff-demo.gif (item 68) | The hero is the board, not a terminal recording | 2026-10-02 |
| Postgres row-level security | Isolation is enforced in the application and proven per route by tenant_isolation_e2e | Decisions (v216.0.0) |
| A workflow engine (Restate, Temporal) | The outbox, DAG and scheduler already give the semantics | Decisions |
MCP argument defaulting (author_id from the caller); hoisting the context assembler into maidan-router | A semantic change to the post path for little gain (whoami covers self-discovery); multi-crate surgery when the shared fold already lives in maidan_types | Cluster 349 (archive) |
| The flagship arc's optional tail | Declined at v331.0.0 | Decisions |
| F-48 Tier 3, F-53, F-33, J-06 | Declined on the merits | archive |
Batched pg_notify; the ACP IDE bridge; multi-region active-active; a CRDT log | Out of scope | Roadmap |
| The A2A TCK's scenario groups | They need a scripted agent, which Maidan is not | scripts/a2a-tck/exclusions.txt |
| Wildcard egress selectors; MCP twins of the egress allowlist | An allowlist must name ids, so a wildcard defeats it; the result-delivery allowlist is operator policy, set over REST by token:admin (the per-workspace secret-egress allowlist in #1140 is a separate list with MCP tools) | Result Delivery |
J3's request_client | An optional MCP 2026-07-28 feature no client relies on | Retro 303 |
Retroactively tagging v411.0.0 | It would rewrite a recorded history; the record says "never tagged" | Thread 22, #1078 |
| Emoji as verdicts | A reaction is not a decision; cast_vote already refuses emoji kinds, and a verdict must carry its why | UI deep dive 2026-10-03 (R3, R5) |
| Bulk approve or bulk close | A rubber-stamp accelerant: each approval binds its own evidence and state version | UI deep dive 2026-10-03 (R3, R5) |
| Agent trust scoring | A score invites approving the agent, not the work | UI deep dive 2026-10-03 (R3, R5) |
| A graph debugger at the approval surface | The approval card shows the evidence bound to the decision, not orchestration internals | UI deep dive 2026-10-03 (R3, R5) |
| Fleet chrome | Attention goes to what waits on a human, not to a dashboard of agents | UI deep dive 2026-10-03 (R3, R5) |
| Read receipts | Surveillance signal with no supervision value | UI deep dive 2026-10-03 (R3, R5) |
| Role theatrics (agent personas, titles, avatars as roles) | Capability and status are the real model; costumes obscure it | UI deep dive 2026-10-03 (R3, R5) |
| Huddles and voice | Out of scope for an agent work room | UI deep dive 2026-10-03 (R3, R5) |
| Skill publish-back from agents | A prompt-injection vector into every consumer of the skill | UI deep dive 2026-10-03 (R3, R5) |
| A crew-builder gallery | Template theater; agents connect through MCP, A2A and the SDKs | UI deep dive 2026-10-03 (R3, R5) |
| Auto-proceed on human timeout | Decided: a timeout returns the work to the queue, never proceeds | UI deep dive 2026-10-03; P2 human-timeout row |
| A PulseMCP submission | Submissions are paused (the notice is dated September 3, 2026, and still holds on 2026-10-04) | Connected-apps strategy, 2026-10-03 |
| Zed MCP server extensions | Zed is deprecating them in favour of the official registry, which Next 11 covers | Connected-apps strategy, 2026-10-03 |
| A GPT Store presence | Custom GPTs retire on December 11, 2026, and plugins are the migration path | Connected-apps strategy, 2026-10-03 |
| An Alexa+ integration | Partnership only, in an unrelated vertical | Connected-apps strategy, 2026-10-03 |
| An Amazon Q Business directory play | No directory exists, only per-tenant custom plugins | Connected-apps strategy, 2026-10-03 |
| A WhatsApp Business Agent listing | No listing surface exists | Connected-apps strategy, 2026-10-03 |
| The mcp.so paid tier and the mcpmarket.com paid submission | Paying for a listing buys little next to the free catalogs in Next 11 | Connected-apps strategy, 2026-10-03 |
| A Windsurf-specific path | No public submission path exists, and Open VSX reaches its users | Connected-apps strategy, 2026-10-03 |
| Listings on package managers, LLM gateways, integration platforms, agent frameworks and sandboxes | None of them takes third-party MCP server submissions | Connected-apps strategy, 2026-10-03 |
| Automating logins to personal ChatGPT or Claude accounts for tests | An account-risk decision, not a test-engineering one, and it would need its own review | Dev and test methodology v2, 2026-10-06 |
| A plain-text "reply APPROVE" approval | A free-text approval can be injected by tool output or pasted content | Dev and test methodology v2, 2026-10-06 |
| Testing a Grok chat-app install | No such surface exists. The Grok API and Grok Build CLI are the testable paths | Dev and test methodology v2, 2026-10-06 |
| Automating the Muse client | Meta publishes no API for driving the assistant, so Muse is tested by manual walkthrough | Dev and test methodology v2, 2026-10-06 |
| A backend fork per provider for the board, inbox or approvals | One tool result feeds every renderer | Dev and test methodology v2, 2026-10-06 |
| Asserting byte-identical replays from LLM-driven clients | Their tool sequences are not deterministic. Recorded traces are reviewed by a person instead | Dev and test methodology v2, 2026-10-06 |
| Recording live OAuth token endpoints in cassettes | A fake authorization server double covers them without capturing secrets | Dev and test methodology v2, 2026-10-06 |
| Listing through OpenAI's enterprise marketplace | It is a procurement and billing channel with named launch partners, not a self-serve directory | Provider research v1, 2026-10-06 |
| Treating Gemini's skills (formerly Gems) as a distribution surface | They carry instructions only, with no tool binding and no sharing at launch | Provider research v1, 2026-10-06 |
Process
Merge discipline while branch protection is not strict (thread 43). A PR
merges when every one of the eight required checks has passed on its exact
head commit and nothing else on that commit is queued, running or failed; the
merge names that commit (gh pr merge --match-head-commit), so a push in
between makes GitHub refuse it. Before merging, the PR is merged onto current
main locally and built, and the static contracts run on the result
(attribution_scope_contract, authority_audit_contract,
http_operation_kinds_contract, docs_numbers_contract,
env_registry_contract, ui_js_contract, openapi_well_formed, the event-kind
and lexicon contracts, migration_register, backend_parity). Stacked
branches rebase in dependency order, replaying only their own commits.
Two merges broke this on 2026-09-30 and are why the rules read as they do:
#1124 merged while gh pr checks still showed the previous commit's runs, and
#1133's last commit merged two seconds after a push, before GitHub reported the
new head. main's CI passed on #1124's merge; #1133's is recorded in its PR.
Open Work is the coordinator's. Feature PRs do not edit this file or the
Roadmap; the coordinator reconciles them after merges, and the open work job
runs on main and on PRs that edit the file. The merge loop's pre-merge build
takes a lock that names its holder, and a lock whose holder is gone is taken
over: a killed loop once held every merge for five hours (2026-09-30).
Review comments. CodeRabbit reviews every PR (Decisions). Each top-level comment is fixed, or answered with the reason it does not apply, before the merge; the merge loop holds a PR while one has neither a reply nor CodeRabbit's "Addressed in commit" marker. From 2026-09-28 to 2026-10-01 the loops merged without that check, which is how 126 comments went unanswered (75 of them valid, one a cross-tenant rate-limit bug).
Old branches. A branch whose work shipped another way, or was closed, is
kept as an archive/<branch> tag and then deleted (the six cursor/*
branches, 2026-10-01). Stashes are not left on the shared stack: they are
kept as local refs/archive/stash/* refs, which are never pushed because a
stash can hold untracked files.
UI changes (thread 42, 46). The PR template's /ui checklist is run by
hand before a UI PR is opened: the token path and the OIDC path, keyboard only,
a 390 px viewport, and every new string re-read.
Enhancement thread 2026-09-30: dispositions
The 2026-09-30 entries (28–57) and the supersessions of 27, 28, 29 and 35.
Entries marked done on main since the thread's 1e612cf8 snapshot are noted.
| Thread | Item | Disposition | Where |
|---|---|---|---|
| 28 | CSP for /ui | Done in #1213: /ui sends the supersession header | #1213 |
| 29 | Write paths for session users | Done in #1176: an OIDC session can edit, upload, and paste, the four proxies exist, and the session carries thread:transition | #1176 |
| 30 | Hover-only controls, 16 px inputs | Done: the pin toggle reveals on :focus-within, and inputs, selects, and textareas are 16px | CHANGELOG |
| 31 | Palette jump leaves the sidebar on the old channel | Done in #1224: selectThread selects that channel and its sidebar row | #1224 |
| 32 | First-run copy | Done in #1224: the card says a workspace id is the id of one room on this server, and that maidan init prints it | #1224 |
| 33 | Message click affordance | Done in #1224: a pencil and a click open Edit message | #1224 |
| 34 | TCK numbers disagree | Adopt: the two sets come from two checks (the TCK's pytest summary and the walkthrough), and the comment conflated them | Lane U |
| 35 | MCP has no create-thread tool | Done in #1226: create_thread and create_channel, both workspace:write | #1226 |
| 36 | llms.txt says an unleased claim never lapses | Done in #1149: llms.txt says every claim is leased, 600 s by default, and a lapse returns the task | #1149 |
| 37 | Enums on string inputs | Done: transition_thread.action is start_review, close, or archive (#1201); set_delivery_mode.mode is immediate or digest; cast_vote.kind is approve, request_changes, or ack (#1231) | #1201, #1231 |
| 38 | Wait families look alike | Adopt, as see-also sentences | Lane U |
| 39 | DM and group-DM duplication | Done in #1207: DM and group-DM message loads share one function | #1207 |
| 40 | One fetch wrapper and one feedback surface | Done in #1207: calls go through api(). showError and setStatus stay separate | #1207 |
| 41 | A checked API client for the UI | Done in #1207: scripts/gen-ui-client.mjs regenerates the typed path catalog. tsc does not run in CI | #1207 |
| 42 | Dead CSS and a lint | Adapt: .chrome-idle and .brand-sub are gone (#1224). A lint for dead CSS is not in CI | Next, review findings |
| 43 | F-43 and merge order | Adopt the discipline, which is written in Process; strict stays off (decided 2026-10-01); the "fail any PR whose merge-base is older than 24 h" CI rule is rejected, because it would rerun every open PR's full CI after each merge on a runner pool that is already the bottleneck, and the pre-merge build on current main catches the same breaks | Process; Decisions pending |
| 44 | Open Work as a CI contract | Adapt: scripts/check-open-work.sh fails when a PR under Now has merged or the stamp is not on main; a per-row check: line is deferred until the table is stable enough to be worth scripting | This file; CI open work |
| 45 | thread:transition for browser sessions; one owner for the browser-authority chain | Done in #1176. An OIDC session carries thread:transition, under the separation-of-duties checks; the chain is warn (#1123), rotate (#1127), exchange (#1142, which also drops csrf_secret), with one owner (the coordinating agent); on rotation the session ends and the page exchanges the successor, rather than migrating the session row | #1176 |
| 46 | data-ui-version never versions | Done in #1224: the marker and the assertions that required it are removed | #1224 |
| 47 | The money shots | Defer: the ten design surfaces are on main (#1179–#1196); no board screenshot exists yet, and the terminal GIF stays (item 68) | Next, the money shots |
| 48 | UI improvement specs | Done: the ten surfaces landed (#1179, #1181, #1182, #1185, #1187, #1188, #1190, #1192, #1193, #1196). The screenshot bar is Next, the money shots | #1179–#1196 |
| 49 | Split as TypeScript from the start | Done in #1207 as ES modules with JSDoc. tsc --noEmit --checkJs does not run in CI | #1207 |
| 50 | Playwright and unit gaps | Adopt: specs for prefs, slash commands, delivery replay, token mint and revoke, and DMs landed in #1205. A group-DM spec posts in the conversation it opens (#1230). helpers.test.mjs does not run in CI | Next, Playwright and unit coverage |
| 51 | SaaS-agnostic hygiene | Adopt: per-workspace fairness by default and per-workspace retention; the migration policy is expand, then a later contract | Fairness and retention shipped (#1153). The policy is Migrations |
| 52 | Do not build a hosted service yet | Adopt as recorded | Later, L |
| 53 | Stale token error after a success | Adopt | Next, UI fixes from the QA pass |
| 54 | A failed post is lost silently | Adopt | Next, UI fixes from the QA pass |
| 55 | Channel refresh shows TypeError | Adopt | Next, UI fixes from the QA pass |
| 56 | No sign-out for a token user | Done in #1123: Sign out is offered to a token and forgets it | #1123 |
| 57 | Opening a DM does not select it | Done: a one-to-one DM selects (#1157); a group DM selects and asks for three members (#1230) | #1157, #1230 |
| 27 → 49 | Module split | See 49 | #1207 |
| 28 (superseded) | CSP header and sequencing | See 28 | #1213 |
| 29 (superseded) | The 19-site table | See 29 | #1176 |
| 35 (superseded) | MCP create_thread and create_channel | See 35 | #1226 |
Done since 1e612cf8, per the thread's own list: 3 (#1118), 13, 14a, 19, 20,
22, 23 (#1113; 23's numbers corrected by lane U). The 2026-09-29 dispositions
below stand, except where a row above supersedes them.
Enhancement thread 2026-09-29: dispositions
David's auditor re-verified each item five times against main and freshened
it to 70a6d78b. Each item's disposition, and where it lives now.
Items 5, 21 and 25 were struck by the thread itself (false premises) and are
not re-filed.
| Thread | Item | Disposition | Where |
|---|---|---|---|
| 1 | Inline errors instead of alert() | Adopt, P0 | Done, #1117 |
| 2a | Warn that the token is stored; surface rotation | Adopt, P0 | #1123, #1127 |
| 2b | httpOnly cookie sessions for the UI | Adapt: the session cookie already exists and is HttpOnly; SameSite=Lax (session/mod.rs). The work is exchanging a pasted bearer for it, and verifying or removing the unread csrf_secret | #1142 |
| 3 | One primary thread surface | Adopt, P0 | Done, #1118 |
| 4 | Inline attachment previews | Adopt, with nosniff and a sandboxing CSP on artifact bytes | #1135 |
| 6 | Header cleanup | Adapt: the residual after #1086's Connect sheet | #1123 |
| 7 | Edit affordance on messages | Adopt | Next, UI fixes from the QA pass |
| 8 | Reorganize the tools drawer | Adapt: the palette (#1086) is the fast path; group the tabs and drop the Work tab's copy of the board | Next, the /ui design contract |
| 9 | Dead #live-* CSS | Adapt: the first block is not dead (see below); merge the two into one rule per element instead | Done, #1117 |
| 10 | Per-peer egress allowlist | Defer until a real federation peer; production already refuses the bypass | Later, Federation |
| 11 | Token rotation endpoint | Adopt, with 2a | Done, #1116 |
| 12 | Board screenshot in the README | Adopt, after the P0s so the image shows the fixed UI, captured by a script | Next, the money shots |
| 13 | The recording, diagram and session in the docs site | Adopt | Done, #1113 |
| 14a | Cluster 413 overstates the D-A guarantee | Adopt | Done, #1113 |
| 14b | Make the D-A guarantee tighter | Adapt: widen authority_audit_contract to every crate with the two carve-outs named; pinning, not a hole | Later, S |
| 15 | gRPC TLS by default | Adapt: refuse plaintext off loopback without an acknowledgement now; native TLS later | Done, #1114; Later, R |
| 16 | A2A push accepts http | Adopt | Done, #1114 |
| 17 | Board render for large lists | Defer: measure first | Measure before scheduling |
| 18 | catch_up pagination at scale | Defer: it is keyset-paginated with a limit, so flat by construction; measure before changing | Measure before scheduling |
| 19 | README says 165 tools | Adopt, with a contract test | Done, #1113 |
| 20 | Conformance jobs required, or a drift policy | Adapt: the drift policy is written (Conventions); promotion is the maintainer's | Done, #1113 |
| 22 | Release checklist step for tagging | Adapt: tag the day the record merges or relabel it never-tagged; no retroactive tag | Done, #1113 |
| 23 | Record the TCK run summary | Adopt | Done, #1113 |
| 24 | First-run onboarding | Adapt: the residual after #1086 | #1123 |
| 26 | Narrow-viewport and keyboard QA | Adapt: #1093 landed; its residue is the keyboard and 390 px pass in the UI specs | Next, the /ui design contract |
| 27 | Split static/index.html | Adopt, after the P0s; superseded by 49 | #1207 |
Sequencing, as it ran. The P0s went first: inline errors (#1117) and one thread surface (#1118) merged on 2026-09-30, and the token chain is #1116 (merged), #1123, #1127 and #1142.
Where the thread was wrong. Item 2b assumed the UI had no cookie session:
crates/maidan-server/src/session/mod.rs already issues HttpOnly; SameSite=Lax (and Secure when configured) cookies for OIDC sign-in, and each
session stores a csrf_secret that no handler reads, so SameSite=Lax is the
CSRF defence in force. Item 9 took the first #live-panel / #live-toolbar /
#live-feed block for dead because a later block restyles the same
elements, but the cascade is per property: the later block never sets the flex
layout or the feed's colours, font, overflow and wrapping, so removing the
first would break the Live bar. Everything else checked out.