gstack-brain-context-load shells out to `gbrain list_pages`, which is an MCP tool name and not a CLI verb — brain context is always 0 bytes
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Summary
`bin/gstack-brain-context-load.ts` builds its argv as `["list_pages", "--limit", ...]` and calls `spawnSync("gbrain", cliArgs)`. **`list_pages` is the MCP tool name; the CLI verb is `list`.** Every invocation exits non-zero with `Unknown command: list_pages`, the dispatch returns `{ ok: false, bytes: 0 }`, and **no brain context is ever loaded into any skill**.
It fails silently: the caller degrades to Grep with no user-visible error.
## Reproduction
```
$ gbrain list_pages --limit 3
Unknown command: list_pages
Run gbrain --help for available commands.
$ gbrain list --limit 3
<3 rows>
```
Measured end-to-end with the loader's own `--explain`:
```
$ gstack-brain-context-load --skill investigate --repo --explain
[brain-context-load] mode=manifest queries=3
SKIP prior-investigations kind=list bytes=0 (gbrain list_pages exited 1)
SKIP project-learnings kind=filesystem bytes=0 (no matches)
SKIP recent-eureka kind=filesystem bytes=0 (no matches)
[brain-context-load] total bytes=0
$ gstack-brain-context-load --skill review --repo --explain
[brain-context-load] mode=default queries=3
SKIP recent-transcripts kind=list bytes=0 (gbrain list_pages exited 1)
SKIP recent-curated kind=list bytes=0 (gbrain list_pages exited 1)
SKIP skill-name-events kind=list bytes=0 (gbrain list_pages exited 1)
[brain-context-load] total bytes=0
```
Note the second case: a skill with **no** `gbrain:` manifest falls back to Layer 1, and that fallback is **also** all-`kind: list`, so it fails identically.
## Source
`bin/gstack-brain-context-load.ts`, line 263 on current `origin/main`:
```ts
const cliArgs: string[] = ["list_pages", "--limit", String(limit)];
if (q.sort) cliArgs.push("--sort", q.sort);
if (q.filter) {
for (const [k, v] of Object.entries(q.filter)) {
cliArgs.push("--filter", `${k}=${rv}`);
}
}
const result = spawnSync("gbrain", cliArgs, ...);
```
## Impact
Every brain-backed query in the shipped skills is `kind: list` -- there are **zero `kind: vector`** queries -- and the Layer-1 fallback is all-`list` too. Net effect is **0 bytes of brain context in every skill, for every user with gbrain installed**.
## Verified independently on two machines
| | Machine A | Machine B |
| --- | --- | --- |
| gbrain | 0.42.67.0 | 0.50.2.0 |
| gstack | 1.84.1.0 | 1.84.x |
| `gbrain list_pages` | Unknown command | Unknown command |
| loader `--explain` | total bytes=0 | total bytes=0 |
So it is **not** a gbrain-version artifact. On both machines the local gstack copy was unmodified (`git diff origin/main -- bin/gstack-brain-context-load.ts` empty) and within a few commits of `origin/main`.
## Likely root cause, and a docs half
`gbrain list --help` itself says *"use list_pages with sort=updated_desc"* -- gbrain's CLI help refers to its own **MCP tool name**. Anyone writing a CLI caller from that help text lands exactly here. Worth fixing on the gbrain side too, or having the CLI accept `list_pages` as an alias.
## Secondary mismatches (CONFIRMED on 0.50.2.0)
Initially filed as unverified leads; both are now confirmed directly:
```
$ gbrain list --limit 5 --filter type=timeline
gbrain list: unknown flag --filter for 'gbrain list'
Run: gbrain list --help
```
- **`--filter` does not exist.** The real flags are `--type` and `--tag`. The string `--filter` appears nowhere in gbrain 0.50's `src/cli.ts`.
- **`--sort` value is wrong.** The loader sends `updated_at_desc`; the CLI accepts `updated_desc`, `updated_asc`, `created_desc`, `slug`.
So fixing the verb alone is **not** sufficient -- the sort value and the filter flags need translating too.
Worth noting for anyone fixing this: on gbrain **<=0.42** unknown flags were *silently ignored*, and **0.50** made them a hard error (a deliberate upstream break, per its release notes). A verb-only fix would therefore surface these two immediately on 0.50+ rather than degrading quietly.
## Related but distinct
#1687 covers `filter:` blocks being dropped by `parseSkillManifest`, so `kind: list` queries ran **unfiltered** (reported fixed in #2264). That bug assumes the query *executes*. This one is upstream of it: with the wrong verb the command never runs at all, so correct filter parsing still yields 0 bytes.
Contributor guide
Research direction
Start in bin/gstack-brain-context-load.ts around line 263 and compare the constructed arguments with the output of gbrain list --help. Check the --explain reproductions for investigate and review, including the verb, sort, and filter arguments. Done means supported gbrain commands execute and the loader reports nonzero context bytes instead of silently skipping every query.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100