# Context Graph Schema

Reference for the graph JSON structure stored at `flydocs/context/graph.json`.

## Top-Level Structure

```json
{
  "version": 1,
  "updated": "ISO-8601 timestamp",
  "nodes": { "<id>": { ... } },
  "edges": [ { ... } ]
}
```

## Node Schema

```json
{
  "type": "skill | decision | issue | module | session | concept",
  "label": "Human-readable name",
  "path": "Relative file path (optional)",
  "status": "Node-specific status (optional)",
  "date": "ISO date for temporal nodes (optional)",
  "tier": "Skill tier: behavioral | mechanism | premium (optional)",
  "manual": true
}
```

**ID conventions:**

| Type     | Pattern                     | Example                          |
| -------- | --------------------------- | -------------------------------- |
| skill    | `skill:{directory-name}`    | `skill:typescript-strict`        |
| decision | `decision:{3-digit-number}` | `decision:001`                   |
| issue    | `issue:{identifier}`        | `issue:FLY-56`                   |
| module   | `module:{kebab-name}`       | `module:install-script`          |
| session  | `session:{YYYY-MM-DD-seq}`  | `session:2026-02-03-a`           |
| concept  | `concept:{kebab-name}`      | `concept:progressive-disclosure` |
| repo     | `repo:{owner/name}`         | `repo:plastrlab/flydocs-app`     |

## Edge Schema

```json
{
  "from": "source node ID",
  "to": "target node ID",
  "rel": "RELATIONSHIP_TYPE",
  "weight": 0.0-1.0,
  "manual": true
}
```

**Weight guidelines:**

| Weight  | Meaning                     |
| ------- | --------------------------- |
| 1.0     | Direct, strong relationship |
| 0.7-0.9 | Strong but indirect         |
| 0.4-0.6 | Moderate association        |
| 0.1-0.3 | Weak or tangential          |

**Edges with `"manual": true`** are preserved when `graph_build.py` rebuilds
the graph from sources. Auto-derived edges are regenerated on each build.

## Relationship Types

| Relationship   | Direction                      | Example                                   |
| -------------- | ------------------------------ | ----------------------------------------- |
| `EXTENDS`      | A extends B                    | ADR-004 extends ADR-001                   |
| `IMPLEMENTS`   | A implements B                 | Issue implements a decision               |
| `DELEGATES_TO` | A delegates to B               | Workflow delegates to mechanism           |
| `PRECEDES`     | A should load before B         | typescript-strict precedes implementation |
| `MODIFIES`     | A modifies B                   | Issue modifies a module                   |
| `WORKED_ON`    | A worked on B                  | Session worked on an issue                |
| `PRODUCED`     | A produced B                   | Session produced a decision               |
| `RELATES_TO`   | A relates to B                 | General association                       |
| `SUPERSEDES`   | A supersedes B                 | New decision replaces old                 |
| `BLOCKS`       | A blocks B                     | Issue blocks another issue                |
| `PROVIDES`     | A exposes interface B consumes | Repo provides REST API to sibling         |
| `CONSUMES`     | A depends on B's interface     | Repo consumes another's API               |

These twelve are the whole vocabulary — `graph.query` and the `graph.add-edge` /
`graph.remove-edge` operations reject anything else. Inverses are not stored:
ask for them with `--direction in`. "What blocks FLY-2?" is
`flydocs run graph.query --node FLY-2 --rel BLOCKS --direction in`, never
`--rel BLOCKED_BY`.

### Cross-Repo Edge Properties

Edges of type `PROVIDES` and `CONSUMES` carry additional properties:

```json
{
  "from": "repo:plastrlab/flydocs-core",
  "to": "repo:plastrlab/flydocs-app",
  "rel": "PROVIDES",
  "weight": 1.0,
  "interface": "REST API /api/relay/*",
  "description": "Core CLI pushes config and descriptors to relay endpoints"
}
```

| Property      | Type   | Description                                            |
| ------------- | ------ | ------------------------------------------------------ |
| `interface`   | string | What is exposed or consumed (endpoint, event, package) |
| `description` | string | Brief context about the relationship                   |

## Repo Node Schema

Repo nodes are derived from `flydocs/context/service.json` by `graph_build.py`.
See `service-descriptor-schema.md` for the full ServiceDescriptor interface.

```json
{
  "type": "repo",
  "label": "flydocs-app",
  "path": "flydocs/context/service.json",
  "purpose": "Web dashboard and relay API for FlyDocs cloud tier",
  "stack": ["next", "convex", "typescript"]
}
```
