feat(graphs): subgraph write-surface gates + durable-bytes storage accounting - #1079
Merged
Conversation
This was referenced Aug 7, 2026
jfrench9
added a commit
to RoboFinSystems/robosystems-python-client
that referenced
this pull request
Aug 7, 2026
…es (#173) ## Summary Regeneration picking up two API changes: the byte-precision subgraph size fields already merged on the API's `main`, and the storage-item documentation from RoboFinSystems/robosystems#1079 (`transient`/`orphan` item types, enforcement semantics for `usage_percentage`). Generated against the local stack at #1079's tip; if that PR changes in review, this regen will be refreshed. ## Changes - **Regenerated `models/` only** — no `api/` or facade changes; sync and async paths unaffected. - `SubgraphResponse`, `SubgraphSummary`: new optional `size_bytes`; `ListSubgraphsResponse`: new optional `total_size_bytes`. `size_mb` remains, documented as derived. - `StorageItem`, `InstanceUsage`: docstring updates only — the new `transient` (blue-green build artifact) and `orphan` (unregistered leftover) item type values, and a note that `usage_percentage` derives from durable bytes. `type` was and remains a plain `str`, so the new values are shape-compatible. ## Compatibility ADDITIVE. All new fields are optional (`| None | Unset = UNSET`); no removals, renames, signature changes, or requiredness flips — verified by reading the full emitted diff, not assumed from the regeneration. Rides the next minor. ## Testing `just test-all` run this session: 519 passed, 17 skipped; ruff format, lint, and basedpyright clean. No packaging changes, so `just build-package` was not needed.
jfrench9
added a commit
to RoboFinSystems/robosystems-typescript-client
that referenced
this pull request
Aug 7, 2026
…180) ## Summary Regeneration picking up two API changes: the byte-precision subgraph size fields already merged on the API's `main`, and the storage-item documentation from RoboFinSystems/robosystems#1079 (`transient`/`orphan` item types, enforcement semantics for `usage_percentage`). Generated against the local stack at #1079's tip; if that PR changes in review, this regen will be refreshed. ## Changes - **Regenerated `sdk/types.gen.ts` only** — no hand-written extensions or tooling touched. - `SubgraphResponse`, `SubgraphSummary`: new optional `size_bytes`; `ListSubgraphsResponse`: new optional `total_size_bytes`. `size_mb` remains, documented as derived. - `StorageItem`, `InstanceUsage`: doc-comment updates only — the new `transient` (blue-green build artifact) and `orphan` (unregistered leftover) item type values, and a note that `usage_percentage` derives from durable bytes. `type` was and remains `string`, so the new values are shape-compatible. ## Compatibility ADDITIVE. All new fields are optional (`?: number | null`); no removals, renames, or narrowed types — verified by reading the full emitted diff, not assumed from the regeneration. Rides the next minor. ## Testing `npm run test:all` run this session: validate (prettier, eslint, tsc), 295 tests across 10 files passed, and the build completed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the storage breakdown account for everything actually on disk — blue-green build artifacts and leftovers of deleted subgraphs get their own item types instead of masquerading as (or hiding from) the subgraph footprint — and enforces the storage cap on durable bytes only, so an in-flight rebuild can't block the very operation that reclaims it. Separately, closes the surfaces a subgraph must not have: the staging pipeline, materialization, and semantic-memory writes, on both REST and the MCP connector.
Changes
Storage accounting (
graph_api/core/storage_breakdown.py,middleware/graph/ingestion_limits.py)transientitem type for blue-green-wip/-prevartifacts. Previously a subgraph's build artifact was classified as a subgraph, while the parent's own{id}-wip(hyphenated) escaped the ownership test and went uncounted entirely.orphanitem type, applied by the platform layer:{parent}_*items with no live row in the graph registry. Covers a deleted subgraph's whole estate — database, vector index, and staging file — with the{parent}_memoryindex explicitly protected from mislabelling. This is what made/usage(sums by type) and the subgraphs page (sums by registered id) agree again.enforced_storage_gbfigure that excludestransientbytes: a rebuild briefly holds a copy the size of the database, and a crashed build's leftover would otherwise block the materialize that rebuilds and reclaims it. Orphans stay counted — they're durable, and blocking on them surfaces registry drift instead of hiding it.total_storage_gbremains the full real-disk figure (metering truth; the itemized list sums to it)./limits'approaching_limitflag uses the same durable-bytes basis. Registry lookups ignore soft-deleted rows.total_storage_gbandcurrent_usage_gbreport at byte level instead of 2-decimal GB (a 0.01 GB quantum erased small tenants' footprints and contradicted the itemized bytes beneath them);size_mblikewise.Subgraph surface gating (
routers/graphs/operations.py,routers/graphs/content_ops.py,middleware/mcp/tools/manager.py)materialize,create-file-upload, andingest-filenow 403 on subgraphs.rememberandupdate-memoryare refused on subgraphs. The exits stay open deliberately —forgetanddelete-filestill work so anything stored before the gate remains removable.materialize,get-graph-sync-status,remember,update-memorywithheld), since MCP dispatch bypasses FastAPI dependencies.sync-connectionis withheld alongside its read half: connections belong to the parent, and a sync feeds the staging pipeline the subgraph doesn't have.Reviewer notes
check_instance_storage.-wipleft by a crashed build other than the next materialize; a GC follow-up may be worth filing.Breaking Changes
None.
StorageItem.typeis a plain string in the schema, so the newtransient/orphanvalues are shape-compatible;enforced_storage_gbis internal and not exposed in the response models. Description-text updates can ride the next SDK regen — no coordinated release needed.Testing
Full gate run this session:
just test-all— 12,249 passed, 0 failed (plus dbt, ruff, format, basedpyright, cf-lint all clean). New coverage includes: transient classification and the parent's own artifacts counting; orphan labelling across the estate (and the memory-index exclusion); enforcement excluding transient while keeping orphans and genuine overages blocking; registry-failure fail-open for labelling; REST and MCP subgraph gates firing before any command runs, with the parent unaffected.