-
Notifications
You must be signed in to change notification settings - Fork 1
Add tool-agnostic rate-limit workaround for wiki workflow #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,8 @@ wiki/ | |
|
|
||
| Don't free-hand it — call **`workflow({ kind: "wiki" })`** and follow the phased, STOP-gated guide. It auto-detects mode: a stubbed `OVERVIEW.md` (empty `source_commit`) → **generate** (survey → overview → architecture → modules → flows → concepts → link-graph audit); a stamped `source_commit` → **refresh** (diff `source_commit..HEAD`, update only affected pages, re-stamp). | ||
|
|
||
| **Persist incrementally (MUST).** Wiki generation is multi-page and tool-call-heavy — host platforms (Factory, Cursor, Claude, etc.) may rate-limit or end sessions mid-run. Write each page immediately after reading its source; never hold finished module write-ups in context for a trailing batch. The workflow guide carries the full crash-safe + resume rules; re-invoking `workflow({ kind: "wiki" })` picks up from partial pages already in `wiki/`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Existing projects will not be offered this updated persistence guidance because the bundled Useful? React with 👍 / 👎. |
||
|
|
||
| **Two toolsets.** Read source code with NATIVE tools (`Read`/`Grep`/`Glob`/`Bash`) — OK MCP does not index non-markdown source. Author and audit the wiki with OK MCP verbs (`write`/`edit` for pages, `links`/`search` for the graph). Never hand-write wiki markdown with native `Write`/`Edit`. | ||
|
|
||
| ## The two knobs | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import { describe, expect, test } from 'bun:test'; | ||
| import { | ||
| buildSessionInterruptRecoverySection, | ||
| buildWikiCheckpointTasksSection, | ||
| buildWikiPersistAsYouGoSection, | ||
| hostTaskSystemPhrase, | ||
| } from './workflow-persistence.ts'; | ||
|
|
||
| describe('workflow-persistence — tool-agnostic durability fragments', () => { | ||
| test('hostTaskSystemPhrase names multiple hosts without picking one', () => { | ||
| const phrase = hostTaskSystemPhrase(); | ||
| expect(phrase).toContain('Factory'); | ||
| expect(phrase).toContain('Cursor'); | ||
| expect(phrase).toContain('Claude'); | ||
| }); | ||
|
|
||
| test('buildWikiPersistAsYouGoSection stresses one-page-at-a-time writes', () => { | ||
| const section = buildWikiPersistAsYouGoSection('content'); | ||
| expect(section).toContain('PERSIST AS YOU GO'); | ||
| expect(section).toContain('`write` each page immediately after reading its source'); | ||
| expect(section).toContain('content/wiki'); | ||
| }); | ||
|
|
||
| test('buildWikiCheckpointTasksSection lists phased tasks for GENERATE', () => { | ||
| const section = buildWikiCheckpointTasksSection(); | ||
| expect(section).toContain('Phase 0'); | ||
| expect(section).toContain('Phase 7'); | ||
| expect(section).toContain('REFRESH mode'); | ||
| }); | ||
|
|
||
| test('buildSessionInterruptRecoverySection forbids native write bypass', () => { | ||
| const section = buildSessionInterruptRecoverySection('resume hint here'); | ||
| expect(section).toContain('rate-limit'); | ||
| expect(section).toContain('Never bypass OK'); | ||
| expect(section).toContain('resume hint here'); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| /** | ||
| * Shared procedural fragments for MCP workflow bodies. | ||
| * | ||
| * Tool-agnostic guidance for crash-safe persistence and host rate-limit / | ||
| * session-interrupt recovery. Workflow bodies interpolate these into their | ||
| * markdown plans so agents on Factory, Cursor, Claude, or any other host get | ||
| * the same durability rules without host-specific code paths. | ||
| */ | ||
|
|
||
| /** How to refer to the host's durable task/todo system without requiring a single host product. */ | ||
| export function hostTaskSystemPhrase(): string { | ||
| return 'your host\'s task system (`TaskCreate` in Claude; equivalent task/todo APIs elsewhere — Cursor, Factory, etc.)'; | ||
| } | ||
|
|
||
| /** | ||
| * Generic rate-limit / session-interrupt recovery block. Callers pass a | ||
| * resume hint that tells the agent how to pick up where it left off. | ||
| */ | ||
| export function buildSessionInterruptRecoverySection(resumeHint: string): string { | ||
| return `## Host rate limits + session interrupts — exit cleanly, resume cheaply | ||
|
|
||
| Host platforms may rate-limit tool calls, exhaust a session budget, or compact context mid-run. **This is normal for large wiki generation — design for it, don't fight it.** | ||
|
|
||
| When the host signals rate limiting, tool-call budget exhaustion, context pressure, or an imminent session end: | ||
|
|
||
| 1. **Stop cleanly** — do NOT burst remaining work into a trailing batch held only in context. Finished units belong in the KB; unfinished units wait for the next session. | ||
| 2. **Never bypass OK for wiki markdown** — native \`Write\`/\`Edit\` on in-scope wiki pages is still forbidden (loses attribution, backlinks, live preview). Rate limits are a pause signal, not an excuse to bypass MCP. | ||
| 3. **Optional snapshot** — if you wrote substantial content this session, \`checkpoint({ summary: "Wiki partial — <last completed page>" })\` before exiting gives the user a named restore point in \`history\`. | ||
| 4. **Tell the user what's done** — list pages written, what's next, and that re-invoking resumes without redoing finished pages. | ||
| 5. **Resume** — ${resumeHint}`; | ||
| } | ||
|
|
||
| /** | ||
| * Wiki-specific persist-as-you-go rules. Multi-page generation is the primary | ||
| * failure mode when hosts rate-limit mid-session. | ||
| */ | ||
| export function buildWikiPersistAsYouGoSection(contentDir: string): string { | ||
| return `## Persist as you go — the wiki IS your checkpoint | ||
|
|
||
| ⛔ **PERSIST AS YOU GO — crash-safe checkpoint rule.** Wiki generation is multi-page and tool-call-heavy. Host platforms may rate-limit or terminate sessions mid-run. The most expensive failure is completed analysis held in context, never written — discarded when the session died. The knowledge base is the checkpoint; these rules make every phase crash-safe: | ||
|
|
||
| - **Create \`wiki/OVERVIEW.md\` skeleton early (Phase 2)** — stamp \`profile\` + \`source_commit\` + a nav map (placeholder links are fine) before module pages. Fill sections as you go; don't defer the whole hub to the end. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When generation is interrupted after Phase 2, this instruction has already stamped Useful? React with 👍 / 👎. |
||
| - **\`write\` each page immediately after reading its source** — one page at a time: read source → \`write\`/\`edit\` page → next. Never batch-survey the whole repo and write all pages in one trailing burst. | ||
| - **Interleave read work with writes** — read a module's source, write its page, then move on. Holding five module write-ups in context while still reading is the anti-pattern (see the platform skill's cadence note: durability beats batching). | ||
| - **After each page lands, update OVERVIEW nav links if needed** — don't defer all hub updates to Phase 7. | ||
| - **Structured notes that live only in your context are not persisted work** — if a section is worth keeping, it belongs in a wiki page via \`write\`/\`edit\`, not in chat or memory. | ||
|
|
||
| On resume after any interrupt: re-invoke \`workflow({ kind: "wiki" })\`, inventory partial progress with \`exec("find ${contentDir}/wiki -name '*.md'")\` (or \`exec("ls -R ${contentDir}/wiki")\`), read each partial page via \`exec("cat ${contentDir}/wiki/modules/<module>.md")\` (substitute the actual path), skip completed pages, continue from the first gap in phase order.`; | ||
| } | ||
|
|
||
| /** Step 0 task list for wiki GENERATE mode — persists across context compaction on hosts that support tasks. */ | ||
| export function buildWikiCheckpointTasksSection(): string { | ||
| const taskPhrase = hostTaskSystemPhrase(); | ||
| return `## Step 0 — Create workflow checkpoint tasks (GENERATE mode) | ||
|
|
||
| ⛔ **ALWAYS THE FIRST ACTION** after mode detection confirms GENERATE (stub \`source_commit\`). Before any survey read or wiki write — create tasks via ${taskPhrase}. They persist across context compaction, make skipped phases visible, and show progress to the user. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On an MCP client without a durable task/todo API, GENERATE cannot perform this mandatory “ALWAYS THE FIRST ACTION” step: the only concrete operation shown is Claude's Useful? React with 👍 / 👎. |
||
|
|
||
| \`\`\` | ||
| TaskCreate: "Wiki: Resolve profile + scope (Phase 0)" → in_progress | ||
| TaskCreate: "Wiki: Survey codebase (Phase 1)" → pending, blocked by #1 | ||
| TaskCreate: "Wiki: Author OVERVIEW hub (Phase 2)" → pending, blocked by #2 | ||
| TaskCreate: "Wiki: Architecture pages (Phase 3)" → pending, blocked by #3 | ||
| TaskCreate: "Wiki: Module pages (Phase 4)" → pending, blocked by #4 | ||
| TaskCreate: "Wiki: Flow pages (Phase 5)" → pending, blocked by #5 | ||
| TaskCreate: "Wiki: Concept pages (Phase 6)" → pending, blocked by #6 | ||
| TaskCreate: "Wiki: Link-graph audit + log (Phase 7)" → pending, blocked by #7 | ||
| \`\`\` | ||
|
|
||
| Use \`addBlockedBy\` (or equivalent) to enforce ordering. Mark each task \`completed\` as its phase finishes; mark the next \`in_progress\`. | ||
|
|
||
| **REFRESH mode:** skip this step — jump to the *Refresh mode* section; create at most one task per affected page cluster if the host supports tasks. | ||
|
|
||
| **Rate-limit interrupt:** mark the current phase task still \`in_progress\` (not \`completed\`) so the next session knows where to resume.`; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes the installed Codebase Wiki skill and the runtime guidance returned by
workflow({ kind: "wiki" }), but the commit contains no.changesetfile. Add the required patch changeset so the user-visible behavior is versioned and included in release notes.AGENTS.md reference: AGENTS.md:L167-L172
Useful? React with 👍 / 👎.