Plan 019: Design the research publication lifecycle surface (list, status, rotate, unpublish) — design/spike, not build
Executor instructions: This is a DESIGN plan. The deliverable is a
written design document plus open questions — no production code. Follow
the steps, honor STOP conditions, and update this plan's status row in
plans/README.md when done — unless a reviewer dispatched you and told you
they maintain the index.
Drift check (run first): Written against commit b8836b8 with the
research-publication feature uncommitted in the working tree. Confirm
the cited files exist and the quoted strings below still appear.
Status
- Risk: LOW — document only.
- Depends on: none (informed by 010–012 outcomes if they landed)
- Category: direction
- Planned at: commit
b8836b8, 2026-07-15 (feature files uncommitted in working tree)
- Issue: (filled after publication)
Why this matters
The CLI can now publish research (/publish-research, and the post-turn
offer after /deep-research), but publishing is the only lifecycle verb it
has. The feature's own UI text points users at operations that do not exist
in the CLI:
src/research/TerminalResearchPublicationPrompts.ts:65 — "This code is
shown once. If it is lost, rotate it through the authenticated owner
workflow."
src/research/ResearchPublicationService.ts:140 — "…Rotate it through the
authenticated owner workflow." (shown on retries where the code is gone)
grep -rn "rotate" src/commands/ confirms no such workflow is reachable from
the CLI. There is also no way to list what you've published, check a
publication's state, or unpublish. Users who publish a private report and
lose the code hit a dead end inside the product that created the situation.
The client/receipt/contract architecture (attempt status endpoint, opaque
report IDs, revoked state in publicationContract.ts) suggests the server
contract already anticipates management operations.
Current state
- Publication flow:
src/research/OpenResearchClient.ts (attempt lifecycle,
recovery receipts <report>.publication.json),
src/research/publicationContract.ts (v1 contract; note the revoked
attempt state and or_-prefixed report IDs),
src/research/ResearchPublicationService.ts (consent flow),
src/commands/publish-research.ts (slash command),
src/core/agent/PostTurnActionCoordinator.ts (post-turn offer gate).
- Receipts already persist
reportId, url, and visibility locally after
a successful commit — a local index of published reports exists implicitly.
- Command conventions: see
src/commands/README.md and any simple
metadata-exporting command (e.g. src/commands/publish-research.ts) for
the metadata + handler pattern; interactive-only commands are listed in
INTERACTIVE_ONLY in src/core/slashCommandHandler.ts:38-42.
Commands you will need
| Purpose |
Command |
Expected on success |
| Search |
grep -rn "<term>" src/ |
read-only exploration |
No build/test gates — this plan produces a document.
Scope
In scope: one design document at docs/plans/research-publication-lifecycle.md
(the docs/plans/ directory already exists).
Out of scope: ANY change to src/. Any server-side implementation (the
design may propose contract additions, clearly marked as requiring the
Open Research service team).
Git workflow
- Branch:
advisor/019-publication-lifecycle-design
- One commit adding the design doc; imperative sentence, no prefixes.
- Do not add any Co-authored-by trailer.
- Do NOT push or open a PR unless the operator instructed it.
Steps
Step 1: Inventory what the contract and receipts already support
Read publicationContract.ts and the receipt schema in
OpenResearchClient.ts. List which lifecycle operations are already
expressible (status by receipt), which need new v1 endpoints (list-by-owner,
rotate code, unpublish/revoke), and what identity/auth each requires.
Step 2: Draft the design document
Cover, with the trade-offs stated:
/publish-research list (or /research list) — sources: local
receipts (offline, workspace-scoped) vs server list endpoint
(account-scoped); recommend starting with receipts and say what that
misses (publications from other machines).
- Status — reuse the existing attempt-status endpoint via stored
receipts; define output for committed/expired/revoked.
- Rotate access code — requires a server endpoint; specify the CLI UX
(consent prompt, shown-once display reusing
TerminalResearchPublicationPrompts), and the contract addition needed.
- Unpublish — map to the
revoked state; define local receipt handling
afterward (plan 010 made revoked terminal — the design must keep that
coherent).
- Command-surface decision: extend
/publish-research with subcommands vs a
new /research namespace — check src/completions/index.ts and the
existing multi-word commands (/skills install) for precedent, and
recommend one.
- Open questions for the maintainer (numbered, each with your recommended
answer) — including whether the server team owns contract v2 or v1
extensions.
Step 3: Ground every claim
Every "the contract supports X" claim in the doc must cite file:line from
this repo. Anything about server behavior beyond the contract file is an
assumption — label it as such.
Verify: grep -c ":[0-9]" docs/plans/research-publication-lifecycle.md
shows citations exist; every section from Step 2 present.
Test plan
None — design document.
Done criteria
STOP conditions
- The Open Research server contract source of truth turns out to live in
another repo you can access — read it first and cite it; if you cannot
access it, note every dependent decision as blocked on it.
- You find an existing design doc for this surface (search
docs/ and prd/
for "open research" / "publication") — reconcile with it instead of
writing a competing one.
Maintenance notes
- The two UI strings quoted above should be revisited by whichever plan
implements rotation — they currently promise a workflow that doesn't exist;
the design doc should propose replacement wording if rotation is deferred.
Plan 019: Design the research publication lifecycle surface (list, status, rotate, unpublish) — design/spike, not build
Status
b8836b8, 2026-07-15 (feature files uncommitted in working tree)Why this matters
The CLI can now publish research (
/publish-research, and the post-turnoffer after
/deep-research), but publishing is the only lifecycle verb ithas. The feature's own UI text points users at operations that do not exist
in the CLI:
src/research/TerminalResearchPublicationPrompts.ts:65— "This code isshown once. If it is lost, rotate it through the authenticated owner
workflow."
src/research/ResearchPublicationService.ts:140— "…Rotate it through theauthenticated owner workflow." (shown on retries where the code is gone)
grep -rn "rotate" src/commands/confirms no such workflow is reachable fromthe CLI. There is also no way to list what you've published, check a
publication's state, or unpublish. Users who publish a private report and
lose the code hit a dead end inside the product that created the situation.
The client/receipt/contract architecture (attempt status endpoint, opaque
report IDs,
revokedstate inpublicationContract.ts) suggests the servercontract already anticipates management operations.
Current state
src/research/OpenResearchClient.ts(attempt lifecycle,recovery receipts
<report>.publication.json),src/research/publicationContract.ts(v1 contract; note therevokedattempt state and
or_-prefixed report IDs),src/research/ResearchPublicationService.ts(consent flow),src/commands/publish-research.ts(slash command),src/core/agent/PostTurnActionCoordinator.ts(post-turn offer gate).reportId,url, andvisibilitylocally aftera successful commit — a local index of published reports exists implicitly.
src/commands/README.mdand any simplemetadata-exporting command (e.g.
src/commands/publish-research.ts) forthe
metadata+ handler pattern; interactive-only commands are listed inINTERACTIVE_ONLYinsrc/core/slashCommandHandler.ts:38-42.Commands you will need
grep -rn "<term>" src/No build/test gates — this plan produces a document.
Scope
In scope: one design document at
docs/plans/research-publication-lifecycle.md(the
docs/plans/directory already exists).Out of scope: ANY change to
src/. Any server-side implementation (thedesign may propose contract additions, clearly marked as requiring the
Open Research service team).
Git workflow
advisor/019-publication-lifecycle-designSteps
Step 1: Inventory what the contract and receipts already support
Read
publicationContract.tsand the receipt schema inOpenResearchClient.ts. List which lifecycle operations are alreadyexpressible (status by receipt), which need new v1 endpoints (list-by-owner,
rotate code, unpublish/revoke), and what identity/auth each requires.
Step 2: Draft the design document
Cover, with the trade-offs stated:
/publish-research list(or/research list) — sources: localreceipts (offline, workspace-scoped) vs server list endpoint
(account-scoped); recommend starting with receipts and say what that
misses (publications from other machines).
receipts; define output for
committed/expired/revoked.(consent prompt, shown-once display reusing
TerminalResearchPublicationPrompts), and the contract addition needed.revokedstate; define local receipt handlingafterward (plan 010 made
revokedterminal — the design must keep thatcoherent).
/publish-researchwith subcommands vs anew
/researchnamespace — checksrc/completions/index.tsand theexisting multi-word commands (
/skills install) for precedent, andrecommend one.
answer) — including whether the server team owns contract v2 or v1
extensions.
Step 3: Ground every claim
Every "the contract supports X" claim in the doc must cite file:line from
this repo. Anything about server behavior beyond the contract file is an
assumption — label it as such.
Verify:
grep -c ":[0-9]" docs/plans/research-publication-lifecycle.mdshows citations exist; every section from Step 2 present.
Test plan
None — design document.
Done criteria
docs/plans/research-publication-lifecycle.mdexists covering the six Step 2 itemssrc/files modified (git status)plans/README.mdstatus row updatedSTOP conditions
another repo you can access — read it first and cite it; if you cannot
access it, note every dependent decision as blocked on it.
docs/andprd/for "open research" / "publication") — reconcile with it instead of
writing a competing one.
Maintenance notes
implements rotation — they currently promise a workflow that doesn't exist;
the design doc should propose replacement wording if rotation is deferred.