nebari-dev / nebari-dev/nebari-frames
Resolved Frame content is unbounded even though stored content is capped
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 2
- Forks
- 1
- Avg merge
- 10h 55m
- Merged PRs (30d)
- 9
Description
Problem
#51 implemented the 512KB cap the design doc promised, but it applies to a single version's stored document (frames.MaxContentBytes, checked in the shared publish path). The resolved form is still unbounded: Resolve merges every ancestor's slots, so a Frame that inherits from a chain of near-limit parents can compose to far more than 512KB.
The design doc originally claimed "A Frame with 100MB of inherited content is rejected at publish time, not at MCP-read time." That is still not true - the note in docs/design/2026-05-21-mcp-endpoint-design.md §6 was updated in #51 to say so honestly rather than leave the claim standing.
Why it matters
The resolved form is what actually gets served and held in memory:
ResolveDocwalks the whole ancestor graph on everyGetFrame,ResolveFrame,get_frame, and MCP resource read.- Nothing caches it, so the cost is per request.
- With
replicaCount: 1and SQLite, a handful of concurrent reads of a deeply-inherited Frame is a memory and latency problem on a single pod.
Inheritance depth is not otherwise limited either - only cycles are rejected (CycleError), not depth or fan-out.
Suggested direction
Options, roughly in order of cost:
- Cap resolved size at publish time: resolve the document as part of
publishand reject when the composed form exceeds a limit. Catches it at write time, but makes a publish's validity depend on its ancestors, so a parent growing can retroactively invalidate a child's next publish. - Cap at read time: return a clear error rather than serving an enormous payload. Simple, but the failure surfaces to a reader who cannot fix it.
- Limit inheritance depth and total ancestor count, which bounds the blast radius without a byte-level rule.
A decision is needed on which limit is the real contract before implementing; that is the substance of this issue.
Context
Raised by review of #51. The per-version cap landed there; this is the remaining half.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with docs/design/2026-05-21-mcp-endpoint-design.md §6 and trace ResolveDoc through publish, GetFrame, ResolveFrame, get_frame, and MCP resource reads. First settle whether the contract is a resolved-byte, depth, or ancestor-count limit; done means the chosen behavior is documented and its affected publish/read paths are covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sqlite
- Domain
- api, backend, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100