up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Symbols Server CI / symbols-smoke (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Symbols Server CI / symbols-smoke (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: StellaOps Graph Gateway (draft)
|
||||
version: 0.0.2-pre
|
||||
version: 0.0.3-pre
|
||||
description: |
|
||||
Draft API surface for graph search/query/paths/diff/export with streaming tiles,
|
||||
cost budgets, overlays, and RBAC headers. Aligns with sprint 0207 Wave 1 outline
|
||||
@@ -42,6 +42,28 @@ paths:
|
||||
'400': { $ref: '#/components/responses/ValidationError' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'429': { $ref: '#/components/responses/BudgetExceeded' }
|
||||
responses:
|
||||
'200':
|
||||
description: Stream of search tiles (NDJSON)
|
||||
content:
|
||||
application/x-ndjson:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TileEnvelope'
|
||||
examples:
|
||||
sample:
|
||||
summary: Node + cursor tiles
|
||||
value: |
|
||||
{"type":"node","seq":0,"data":{"id":"gn:tenant:component:abc","kind":"component","tenant":"acme","attributes":{"purl":"pkg:npm/lodash@4.17.21"}},"cost":{"limit":1000,"remaining":999,"consumed":1}}
|
||||
{"type":"cursor","seq":1,"data":{"token":"cursor-123","resumeUrl":"https://gateway.local/api/graph/search?cursor=cursor-123"}}
|
||||
headers:
|
||||
X-RateLimit-Remaining:
|
||||
description: Remaining request budget within the window.
|
||||
schema:
|
||||
type: integer
|
||||
Retry-After:
|
||||
description: Seconds until next request is allowed when rate limited.
|
||||
schema:
|
||||
type: integer
|
||||
|
||||
/graph/query:
|
||||
post:
|
||||
@@ -74,6 +96,29 @@ paths:
|
||||
'400': { $ref: '#/components/responses/ValidationError' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'429': { $ref: '#/components/responses/BudgetExceeded' }
|
||||
responses:
|
||||
'200':
|
||||
description: Stream of query tiles (NDJSON)
|
||||
content:
|
||||
application/x-ndjson:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TileEnvelope'
|
||||
examples:
|
||||
mixedTiles:
|
||||
summary: Node + edge + stats tiles
|
||||
value: |
|
||||
{"type":"node","seq":0,"data":{"id":"gn:tenant:artifact:sha256:...","tenant":"acme","kind":"artifact","attributes":{"sbom_digest":"sha256:abc"}}}
|
||||
{"type":"edge","seq":1,"data":{"id":"ge:tenant:CONTAINS:...","sourceId":"gn:tenant:artifact:...","targetId":"gn:tenant:component:...","kind":"CONTAINS"}}
|
||||
{"type":"stats","seq":2,"data":{"nodesEmitted":1,"edgesEmitted":1,"depthReached":2,"cacheHitRatio":0.8}}
|
||||
headers:
|
||||
X-RateLimit-Remaining:
|
||||
description: Remaining request budget within the window.
|
||||
schema:
|
||||
type: integer
|
||||
Retry-After:
|
||||
description: Seconds until next request is allowed when rate limited.
|
||||
schema:
|
||||
type: integer
|
||||
|
||||
/graph/paths:
|
||||
post:
|
||||
@@ -106,6 +151,20 @@ paths:
|
||||
'400': { $ref: '#/components/responses/ValidationError' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'429': { $ref: '#/components/responses/BudgetExceeded' }
|
||||
responses:
|
||||
'200':
|
||||
description: Stream of path tiles ordered by hop
|
||||
content:
|
||||
application/x-ndjson:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TileEnvelope'
|
||||
examples:
|
||||
pathTiles:
|
||||
summary: Path tiles grouped by hop
|
||||
value: |
|
||||
{"type":"node","seq":0,"data":{"id":"gn:tenant:component:src","kind":"component","tenant":"acme","attributes":{"purl":"pkg:npm/demo@1.0.0"},"pathHop":0}}
|
||||
{"type":"edge","seq":1,"data":{"id":"ge:tenant:DEPENDS_ON:1","sourceId":"gn:tenant:component:src","targetId":"gn:tenant:component:dst","kind":"DEPENDS_ON","pathHop":1}}
|
||||
{"type":"stats","seq":2,"data":{"nodesEmitted":2,"edgesEmitted":1,"depthReached":1}}
|
||||
|
||||
/graph/diff:
|
||||
post:
|
||||
@@ -136,6 +195,7 @@ paths:
|
||||
{"type":"diagnostic","seq":1,"data":{"level":"info","message":"snapshot diff complete"}}
|
||||
'400': { $ref: '#/components/responses/ValidationError' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
'429': { $ref: '#/components/responses/BudgetExceeded' }
|
||||
|
||||
/graph/export/{jobId}/manifest:
|
||||
get:
|
||||
@@ -244,6 +304,21 @@ components:
|
||||
description: Optional caller-provided correlation id, echoed in responses.
|
||||
|
||||
schemas:
|
||||
OverlayPayload:
|
||||
type: object
|
||||
description: Overlay content injected into node/edge tiles when requested (policy/vex/advisory).
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
enum: [policy, vex, advisory]
|
||||
version:
|
||||
type: string
|
||||
description: Contract version of the overlay payload.
|
||||
data:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required: [kind, version, data]
|
||||
|
||||
CostBudget:
|
||||
type: object
|
||||
properties:
|
||||
@@ -290,9 +365,14 @@ components:
|
||||
kind: { type: string }
|
||||
tenant: { type: string }
|
||||
attributes: { type: object }
|
||||
pathHop:
|
||||
type: integer
|
||||
description: Hop depth for path streaming responses.
|
||||
overlays:
|
||||
type: object
|
||||
description: Optional overlay payloads (policy/vex/advisory) keyed by overlay kind.
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/OverlayPayload'
|
||||
required: [id, kind, tenant]
|
||||
|
||||
EdgeTile:
|
||||
@@ -304,8 +384,13 @@ components:
|
||||
targetId: { type: string }
|
||||
tenant: { type: string }
|
||||
attributes: { type: object }
|
||||
pathHop:
|
||||
type: integer
|
||||
description: Hop depth for path streaming responses.
|
||||
overlays:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/OverlayPayload'
|
||||
required: [id, kind, sourceId, targetId, tenant]
|
||||
|
||||
StatsTile:
|
||||
@@ -352,6 +437,9 @@ components:
|
||||
ordering:
|
||||
type: string
|
||||
enum: [relevance, id]
|
||||
cursor:
|
||||
type: string
|
||||
description: Resume token from prior search response.
|
||||
required: [kinds]
|
||||
|
||||
QueryRequest:
|
||||
@@ -378,6 +466,9 @@ components:
|
||||
type: string
|
||||
enum: [none, minimal, full]
|
||||
default: none
|
||||
cursor:
|
||||
type: string
|
||||
description: Resume token from prior query response.
|
||||
anyOf:
|
||||
- required: [dsl]
|
||||
- required: [filter]
|
||||
@@ -418,6 +509,9 @@ components:
|
||||
filters:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
cursor:
|
||||
type: string
|
||||
description: Resume token from prior diff stream.
|
||||
required: [snapshotA, snapshotB]
|
||||
|
||||
ExportRequest:
|
||||
@@ -450,6 +544,7 @@ components:
|
||||
createdAt: { type: string, format: date-time }
|
||||
updatedAt: { type: string, format: date-time }
|
||||
message: { type: string }
|
||||
expiresAt: { type: string, format: date-time, description: "Optional expiry for download links." }
|
||||
required: [jobId, status]
|
||||
|
||||
Error:
|
||||
@@ -485,3 +580,8 @@ components:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
headers:
|
||||
Retry-After:
|
||||
description: Seconds until budgets refresh.
|
||||
schema:
|
||||
type: integer
|
||||
|
||||
Reference in New Issue
Block a user