Spaces

A Space is a live selection over the Step catalog, and planning inside it considers only the Steps it selects.

Scoped Planning

A Space names a subset of the catalog with a label selector. Planning inside a Space follows Attribute dependencies through the selected Steps alone, so a Space with a risk selector reaches its Goals using Risk Steps even when another team publishes a Step producing the same Attribute.

A Space carries an ID, a display name, an optional description, and its selector:

{
  "id": "risk",
  "name": "Risk",
  "description": "Steps owned by the risk domain",
  "selector": {
    "match_labels": {
      "domain": "risk"
    }
  }
}

Label Steps for Membership

A Step declares labels alongside its Attributes:

{
  "id": "score-customer",
  "type": "sync",
  "labels": {
    "domain": "risk",
    "tier": "gold"
  },
  "attributes": {
    "customer_id": {"role": "required", "type": "string"},
    "risk_score": {"role": "output", "type": "number"}
  }
}

A Step belongs to a Space when every entry in the selector matches the Step’s label of the same key. The selector above selects score-customer because its domain label is risk. Adding tier: gold to the selector keeps it selected, while tier: silver selects a different set. A Space carries at least one selector entry, so every Space names the labels it scopes to.

Argyll resolves the selector whenever a Step or a Space changes and keeps the resulting Step list in the catalog, so planning reads a Space’s Steps rather than re-matching the whole catalog. Registering a Step with matching labels adds it to every Space that selects it, and updating a Step’s labels moves it between Spaces, both without touching the Space itself.

Start a Flow in a Space

Pass space_id when starting a Flow to plan within that Space:

curl -X POST http://localhost:8080/engine/flows \
  -H "Content-Type: application/json" \
  -d '{
    "id": "risk-run-1",
    "space_id": "risk",
    "goals": ["score-customer"],
    "init": {"customer_id": ["cust-123"]}
  }'

POST /engine/plan accepts the same field, so a preview reflects the Space the Flow will run in. A Flow Step accepts flow.space_id to scope its child Flow, described in Flows.

Manage Spaces

RequestResult
GET /engine/spacesEvery registered Space
POST /engine/spacesRegister a Space
GET /engine/spaces/{space_id}One Space definition
GET /engine/spaces/{space_id}/stepsThe Steps the Space selects right now
PUT /engine/spaces/{space_id}Replace a Space definition
DELETE /engine/spaces/{space_id}Remove a Space

GET /engine/spaces/{space_id}/steps answers membership questions directly, which makes it the quickest way to confirm a selector before a Flow depends on it.

Referential Integrity

A Flow Step that names a Space anchors the definitions it depends on. While that reference exists, Argyll keeps the arrangement consistent:

  • Deleting the Space returns 409 Conflict and names the Flow Step holding it
  • Deleting a Step used as one of that Flow Step’s Goals returns 409 Conflict
  • Replacing the Space with a selector that would drop one of those Goals returns 409 Conflict
  • Relabelling such a Goal so it leaves the Space returns 400 Bad Request

A Step therefore keeps its Space membership for as long as a Flow Step depends on it being a Goal there.