agentleFS
EtanHeyEtanHey/golems/skills/golem-powers/research-lifecycle/SKILL.md

research-lifecycle

Skill0 starsChanged 15 days agoApache-2.0View on GitHub

Research corpus: stale context, R-number, research docs link (Google Docs/Deep Research report URL). NOT drive-filing.

  • Reads credentials

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. About 0 are common, 12 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈12

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every research dispatch — fleet-fired OR Etan-fired in his own Gemini/NotebookLM UI (standing fire=Etan rule) — MUST carry these fields at …

    line 16
  2. Distinctive:

    Research without all three = PARKED: Do not mark done, do not brain_store conclusions, do not close the collab row until harvest completes …

    line 24
  3. Distinctive:

    After a sprint that implements research findings, create a new context file:

    line 71
  4. Distinctive:

    Naming: Use sequential numbers (91-, 92-, 93-...) to preserve ordering.

    line 95
  5. Distinctive:

    When context files accumulate (>10 files or >50KB total), condense older ones:

    line 101
  6. Distinctive:

    Update claims to current state (remove "FTS5 is broken" if it's fixed)

    line 119
  7. Distinctive:

    Keep timeless content as-is (references, architecture decisions with rationale)

    line 120
  8. Distinctive:

    Remove redundant context (if 3 files say "BrainBar is Swift", keep it in one place)

    line 121
  9. Distinctive:

    ALL findings from the research are implemented (check PRs)

    line 166
  10. Distinctive:

    Verify the replacements are indexed and readable, then delete the stale sources:

    line 202
  11. Very specific:

    Before emitting any Gemini research prompt, require exactly one # Grounding block.

    line 223
  12. Distinctive:

    Run the executable gate against the prompt file.

    line 225
  13. Distinctive:

    Write the verification evidence to a receipt, then run the same executable gate:

    line 239
  14. Very specific:

    NEWEST: Create 95-R75-sprint-results.md with: FTS5 3.1%→100%, entity detection implemented, search hybrid mode live

    line 342

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Research Lifecycle — Context Freshness Management

Anti-pattern: R75 says "FTS5 is 96.9% desynced" — but it's been fixed for days. Without lifecycle management, R76 starts from wrong assumptions.

Research context files live at docs.local/claude-web/projects/<project>/. After a sprint implements research findings, these files go STALE. The local corpus is the source; Google Drive is the grounding corpus Gemini reads. This skill refreshes both so the next research round starts from truth, not assumptions.


HARVEST GATE — research without a harvest path is PARKED, not done

Every research dispatch — fleet-fired OR Etan-fired in his own Gemini/NotebookLM UI (standing fire=Etan rule) — MUST carry these fields at dispatch time:

FieldRequired content
harvest_ownerNamed agent/LEAD who owns pulling results back into the fleet
harvest_triggerWhat event starts harvest (report complete, Drive export lands, cron poll, Etan says "it's done", etc.)
export_routeWhere results land for the fleet: Drive path, docs.local/research/, collab ack, brain_store digest — adapters must name this explicitly

Research without all three = PARKED. Do not mark done, do not brain_store conclusions, do not close the collab row until harvest completes and VERIFY BEFORE STORE passes for those conclusions, or Etan explicitly parks it.

Applies to /gemini-research, /claude-desktop-research, and orc W5 research dispatches. The E07 integrity gate catches bad claims; this gate catches throughput — results sitting unharvested since morning.


INCOMING RESEARCH DOC LINK — harvest before closing

When research links arrive, the receiver's FIRST dispatch is ONE coordinator child for the whole batch, including already-filed reports. Use delegate_task with role: "research", target.providerInstanceId: "codex-worker", high effort/default tier, and label its brief codex.research.coordinator. Pass the workflow, all links and the verifier parameter. Omit isolation (shared checkout). Then end the turn. The receiver does no harvesting, splitting, verifying or filing. A non-research link does not take this route. Children briefed by a coordinator (the coordinator itself and its Drive harvest child) skip this route.

The coordinator skips intake dispatch. Per /agent-routing § Execution capability, delegate harvest/readback/filing/NotebookLM to a Drive-write-capable child; wait for its receipt while orchestrating verification. The workflow preserves R{NN}-<slug>-result, readback/export_route and PARKED-not-guessed associations.

VERIFY BEFORE STORE — coordinator-owned

Verifier parameter: VERIFIER_ROLE=claude.research.verifier (API key); one override to codex.research.verifier selects subscription dispatch.

  1. Freeze numbered checkable claims per section (exact report quotes, locations, code/corpus revision). Fan out section verifiers using the verifier rubric. For the Claude family, use the API-key launcher, never a subscription delegate_task. Expect ~$0.21/section or ~$0.66/100 claims for verifiers; post the batch projection before fan-out.
  2. Send all WRONG/HALLUCINATED verdicts, a random audit of 85 VERIFIED claims (all if fewer), and a separate decision-critical UNVERIFIABLE queue to ONE adjudicator using its rubric. Default adjudicator role: codex.research.adjudicator, effort high, service tier default. Use the other model family; Codex verifiers therefore switch it to claude.judgment (high, never fast). Only the lead named as step owner in the brief can override the cross-family rule, in which case double the VERIFIED audit to 170 (all if fewer).
  3. Write VERIFY-SUMMARY.md beside each report, with coverage, final verdict counts, hallucination/error rates and denominators, audit seed/IDs and evidence. Store only VERIFIED facts from completed audited sections or adjudication-resolved VERIFIED claims; WRONG/HALLUCINATED only as evidenced corrections. Never store UNVERIFIABLE as fact or report-authored PROPOSAL-OK as established fact. Partial work releases only the eligible subset; pending claims remain pending.

Resolve roles from standards/model-roles.json; dispatch per /agent-routing. This gate applies to research conclusions, not ordinary non-research notes.

THE LIFECYCLE

SPRINT COMPLETES (findings implemented)
  │
  ├─ 1. NEWEST: Add sprint results as new context file
  │     (what changed, benchmark numbers, PRs merged)
  │
  ├─ 2. CONDENSED: Compress older context files
  │     (files 01-50 → one condensed file)
  │
  ├─ 3. UPDATED: Refresh description.md with current state
  │     (facts first, narrative second)
  │
  ├─ 4. ARCHIVED: Move implemented research results
  │     (R-numbers whose findings are now in code)
  │
  └─ 5. MIRRORED: Update Drive AND NotebookLM
        (Drive required; NotebookLM only when a project notebook exists)

STEP 1: NEWEST — Add Sprint Results

After a sprint that implements research findings, create a new context file:

# File: research-context/NN-sprint-results-{date}.md

## Sprint: {description}
- Date: {date}
- PRs merged: #{N}, #{N}, #{N}

## What Changed
- {specific change 1}: {before state} → {after state}
- {specific change 2}: {before} → {after}

## Benchmark Numbers
- {metric}: {old value} → {new value}
- {metric}: {old} → {new}

## What's Still Open
- {remaining issue 1}
- {remaining issue 2}

Key: Include BEFORE and AFTER states. The researcher needs to know what was the problem AND what's the current state.

Naming: Use sequential numbers (91-, 92-, 93-...) to preserve ordering. Prefix with the topic.


STEP 2: CONDENSED — Compress Stale Context

When context files accumulate (>10 files or >50KB total), condense older ones:

BEFORE:
  91-swift-python-root-cause.md     (from 2 weeks ago, findings implemented)
  92-brainbar-ux-current-state.md   (from 1 week ago, partially stale)
  93-inspiration-references.md       (timeless, keep as-is)
  94-search-improvement-collab.md   (from yesterday, still current)

AFTER:
  condensed-pre-R75.md              (91 + 92 merged, updated to current state)
  93-inspiration-references.md       (unchanged — timeless content)
  94-search-improvement-collab.md   (unchanged — still current)
  95-R75-sprint-results.md          (NEW — what the sprint changed)

Condensation rules:

  • Merge files about the SAME topic into one
  • Update claims to current state (remove "FTS5 is broken" if it's fixed)
  • Keep timeless content as-is (references, architecture decisions with rationale)
  • Remove redundant context (if 3 files say "BrainBar is Swift", keep it in one place)

STEP 3: UPDATED — Refresh description.md

The project description file tells the researcher what the project IS. It must reflect current state.

Location: docs.local/claude-web/projects/<project>/description.md

Refresh checklist:

  • Architecture claims match current code (check recent PRs)
  • Stats are current (chunk count, entity count, test count)
  • Open issues are actually still open (not fixed in latest sprint)
  • "Known limitations" haven't been resolved
  • No claims about features that are stubs (check with /never-fabricate)

Format: Facts first, narrative second. Lead with numbers, follow with explanation.

## Current State (as of {date})
- Chunks: 299,972 (FTS5: 100% synced ← was 3.1% before R75 sprint)
- Entities: 166 (0.055% coverage ← needs improvement)
- Tests: 675 passing
- MCP: BrainBar (Swift daemon), 5 working tools + 3 stubs

## Architecture
{current architecture, verified against code}

STEP 4: ARCHIVED — Move Implemented Research

Research results (R-number files) whose findings are fully implemented should move to archived:

# Move completed research
mv docs.local/claude-web/projects/brainlayer/R38-knowledge-graph.md \
   docs.local/claude-web/projects/archived/brainlayer/

Archive criteria:

  • ALL findings from the research are implemented (check PRs)
  • Benchmark improvements are captured in a sprint results file
  • The research is >1 sprint old (keep recent research active for reference)

DON'T archive:

  • Research with partially-implemented findings (keep, mark which are done)
  • Timeless architectural decisions (keep in main project)
  • The LATEST research result (always keep the most recent R-number)

STEP 5: MIRRORED — Drive AND NotebookLM

The local corpus is the source to push. Drive is where Gemini grounds, so the Drive refresh is blocking; NotebookLM mirroring is conditional on a project notebook existing.

  1. Prove Drive auth and account identity with real calls. "MCP connected" is NOT evidence of Drive auth. Call authGetStatus; continue only when the real call succeeds and returns authed. Tool discovery or a connected-tool count does not pass this gate. Then verify the active account before any upload, replacement, or deletion:
    # Project has a NotebookLM notebook: verify both identities.
    bash skills/golem-powers/_shared/research/verify-account.sh
    
    # No project notebook: verify Drive without requiring NotebookLM auth state.
    bash skills/golem-powers/_shared/research/verify-account.sh --drive-only
    The expected account is RESEARCH_ACCOUNT if set, else the RESEARCH_ACCOUNT=<address> line in ~/.config/research-lifecycle/research.env (outside every repo; the completion gate reads the same source). If neither is set, verification and DRIVE_ACCOUNT fail and name that file. Save the successful JSON output in the lifecycle receipt. A call failure or account mismatch is blocking; switch profiles and rerun verification instead of reconciling the wrong Drive corpus.
  2. Resolve the canonical destination. Use /drive-filing for the correct numbered folder and naming convention (its folder model and decision tree own the Drive paths; this skill does not restate them). Use /braindrive to resolve current folder IDs and the Gemini-facing corpus; do not trust stale hard-coded IDs.
  3. Reconcile the managed Drive corpus to local truth. Upload or replace every current local context file under the canonical project corpus, keeping local and Drive relative names identical. Upload with mcp__google-drive__uploadFile(localPath, name, parentFolderId, mimeType) and set mimeType from the extension: .md → text/markdown, .txt → text/plain, .json → application/json. Without it, a markdown file whose first bytes are <!-- lands as text/html. Do not use createTextFile or updateTextFile here: they take no mimeType. Track the complete lifecycle-managed file set. Delete only previously managed Drive files that are absent locally; never delete unrelated Drive documents. Unexpected duplicate managed names fail the gate.
  4. Verify the refresh with a real Drive read. List/search and download/read the destination after upload. Record every local and Drive relative name, modifiedTime, and SHA-256 content digest in a receipt. The completion command independently walks --local-root, hashes every regular file, and rejects a receipt that omits or changes any canonical local entry. DRIVE_FILESET=PASS requires the Drive names to equal that derived inventory with no duplicates. DRIVE_FRESHNESS=PASS requires every Drive digest to match its local source and every Drive modifiedTime to be at least as new. Missing or unverifiable content is FAIL.
  5. If the project has a NotebookLM notebook (see /gemini-research), add updated replacement files first:
    source_add(notebook_id, source_type="file", file_path="updated-context.md", wait=True)
  6. Verify the replacements are indexed and readable, then delete the stale sources:
    source_delete(source_id=stale_source, confirm=True)
    source_list_drive(notebook_id)
    Record the replacement IDs returned by source_add, the stale source IDs, and the final indexed source IDs returned by readback. NOTEBOOKLM_FRESHNESS=PASS requires every expected replacement ID to exist and every stale source ID to be absent; a bare fresh: true claim does not pass.
  7. Update notebook instructions:
    chat_configure(notebook_id, goal="custom",
      custom_prompt="Context files have been updated as of {date}. Previous findings about {X} are now implemented.")

Remember NP3: .py/.json/.swift/.yaml files must be renamed to .txt for NotebookLM upload.


GEMINI RESEARCH PROMPT PREFLIGHT — BLOCKING

Prepare the next prompt with /gemini-research's template and its structural pre-fire gate.

Before emitting any Gemini research prompt, require exactly one # Grounding block. That block must contain either a Drive document referenced by name or the exact line None — web-only research. Never instruct Etan to attach or upload Drive documents; his connected Drive workspace pulls named documents itself.

Run the executable gate against the prompt file. It checks the block structure and invokes the shared no-attach gate:

PROMPT=/path/to/R{NN}-prompt.md
node skills/golem-powers/research-lifecycle/scripts/lifecycle-gate.mjs \
  preflight --prompt "$PROMPT"

Any non-zero result means GEMINI_PREFLIGHT=FAIL: do not emit or fire the prompt. Add the missing named-document grounding or the explicit web-only line, then rerun the checks.


LIFECYCLE COMPLETION GATE — BLOCKING

Write the verification evidence to a receipt, then run the same executable gate:

{
  "driveRoute": {"canonical": true, "resolvedWith": ["/drive-filing", "/braindrive"]},
  "driveAuth": {"callSucceeded": true, "authed": true},
  "accountVerification": {
    "callSucceeded": true,
    "drive_account": "<resolved research account>",
    "notebooklm_account": "<resolved research account>",
    "expected": "<resolved research account>",
    "match": true,
    "drive_only": false
  },
  "localFiles": [
    {"name": "01-context.md", "sha256": "<64 hex chars>", "modifiedTime": "<ISO-8601>"}
  ],
  "driveFiles": [
    {"name": "01-context.md", "sha256": "<64 hex chars>", "modifiedTime": "<ISO-8601>"}
  ],
  "notebooklm": {
    "exists": true,
    "expectedReplacementIds": ["source-new"],
    "indexedSourceIds": ["source-new"],
    "staleSourceIds": ["source-old"]
  }
}
LOCAL_ROOT=docs.local/claude-web/projects/PROJECT
node skills/golem-powers/research-lifecycle/scripts/lifecycle-gate.mjs \
  completion --receipt /path/to/lifecycle-receipt.json --prompt "$PROMPT" \
  --local-root "$LOCAL_ROOT"

The lifecycle may be marked complete only when the command exits 0 and every row passes:

CheckPASS criterion
DRIVE_ROUTEReceipt names the canonical destination resolved through /drive-filing and /braindrive
DRIVE_AUTHA real authGetStatus call succeeds and returns authed
DRIVE_ACCOUNTverify-account.sh succeeds and records the active Drive identity, equal to RESEARCH_ACCOUNT or the account in ~/.config/research-lifecycle/research.env
LOCAL_INVENTORYReceipt local names/digests/timestamps exactly equal the inventory derived from --local-root
DRIVE_FILESETManaged Drive names exactly equal the derived local inventory; no missing, extra, or duplicate managed file
DRIVE_FRESHNESSEvery Drive SHA-256 matches local content and every Drive modifiedTime is at least as new
NOTEBOOKLM_FRESHNESSExplicitly not applicable, or source-ID readback proves expected replacements exist and stale sources are absent
GEMINI_PREFLIGHTThe next Gemini prompt passes the executable grounding/no-attach preflight

If the Drive corpus is older than the local context, the lifecycle is NOT complete. Auth failure, account mismatch, missing files, or unverifiable Drive freshness also fail the lifecycle; report the failing row instead of silently skipping it.


WHEN TO TRIGGER

TriggerAction
Research docs link arrives (Google Docs / Deep Research report URL)Gatherer locates the R-number prompt; the report is filed in the sibling results/ and read back
Sprint merged PRs that address research findingsRun full lifecycle (Steps 1-5)
Before writing a new R-number research promptRun Steps 2-5, then the Gemini prompt preflight
Nightly/project maintenance runsCheck if context files are stale (Step 3 at minimum)
Context file count > 10Run Step 2 (condense)
Local context changedRun Step 5 (Drive refresh is blocking)
NotebookLM notebook existsRun the NotebookLM portion of Step 5

STALENESS DETECTION

A context file is STALE when:

  1. It describes a problem that's been fixed — e.g., "FTS5 is 96.9% desynced" after PR fixing it
  2. Its benchmark numbers are outdated — e.g., "675 tests" when there are now 720
  3. Its architecture claims are wrong — e.g., "Python MCP" when it's now Swift BrainBar
  4. It references PRs as "open" that are merged — check via gh pr view
  5. It's >2 sprints old and never updated — age alone signals staleness

Quick staleness check:

# Find context files older than 7 days with no updates
find docs.local/claude-web/projects/PROJECT/research-context/ -name "*.md" -mtime +7

INTEGRATION

SkillHow Research Lifecycle Uses It
Claude/Gemini research runsCreate research results → lifecycle manages them afterward
/drive-filingSelect the canonical Drive folder and stable artifact names; archive heavy originals; docs.local lifecycle
/braindriveResolve current Drive corpus locations and verify Gemini-facing files
/gemini-researchEnforce Drive grounding preflight and NotebookLM mirroring rules
Nightly/project maintenanceShould check research context staleness during sweeps
/never-fabricateVerify claims in description.md against actual code before updating
/orc W5Claude Web research prompts consume these context files

EXAMPLE: Post-R75 Lifecycle

R75 sprint fixed FTS5 sync, implemented detect_entities_in_prompt, improved search.

  1. NEWEST: Create 95-R75-sprint-results.md with: FTS5 3.1%→100%, entity detection implemented, search hybrid mode live
  2. CONDENSED: Merge 91-swift-python-root-cause.md + 92-brainbar-ux-current-state.md → condensed-pre-R75.md (update "FTS5 broken" → "FTS5 fixed in PR #198")
  3. UPDATED: Refresh description.md — chunk count, entity count, test count, remove "FTS5 broken" from known issues
  4. ARCHIVED: Move R38-knowledge-graph.md (fully implemented) to archived/brainlayer/
  5. MIRRORED: Push the current local corpus to Drive, verify Drive freshness, then replace stale NLM sources

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.