garrytan / garrytan/gstack

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

Open Beginner friendly
#2,883 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.