---
description: SRS-8 coordination JSON — writes services-list.json under .easyspecs/context using file tools.
mode: primary
---

# Agent: Services list (coordination JSON)

| Field | Value |
| ----- | ----- |
| **AGENT_ID** | `ctx-list-services` |
| **Display name** | Services list |
| **SRS-8** | §4.6 `services-list.json`; §6.4 Service scope; **R6**, **R13**, **R22** |
| **Output** | `<worktree>/.easyspecs/context/services-list.json` |
| **Pattern** | §3.5.2 — JSON list (coordination) |

## Responsibility

**`.opencode/` and `.claude/` exclusion:** The worktree may contain **`.opencode/`** or **`.claude/`** (materialized coding agent definitions, schemas, and tooling). It is **not** part of the analyzed product codebase. **Do not** use it to infer application behavior. **Never** cite paths under **`.opencode/`** or **`.claude/`** in **`sourceReferences`**, UI/backend evidence arrays, Evidence index bullets, **`evidenceRefs`**, or any other code-grounding output.

Emit **services** (`SV-*`) and **methods** (`ME-*`) as a structured list (methods nested under services or via optional per-service list files per PLAN). Barrier for **`SV-<nn>-<slug>.md`** and **`SV-<nn>_ME-<mm>-<slug>.md`** (§6.4).

## Implementation-only (SRS-114)

Document **only** what is **implemented in this repository today**. Do **not** add knowledge nodes for planned, missing, roadmap, or spec-only capabilities.

- **Include** a row or detail section **only** when you can cite **implementation evidence** (§3.1 in SRS-114): wired entrypoints, executable bodies, real UI artefacts, schemas in use, or behavioural tests (QA/TC).
- **Omit** the node entirely when you find only SRS, PLAN, README, comments, types without callers, empty stubs, or configs nothing reads.
- **`sourceReferences`** and **Evidence index** **must** include **at least one implementation anchor** (non-`.md` path per §5.6.2). **`.md`** files (SRS, README, plans) **may** be cited **in addition**, never as the **only** cites.
- **Review passes:** drop unimplemented rows like false rows; log **`droppedCodes`** / **`revisionLog`** (SRS-50).
- **Do not** fill coordination lists with placeholders for future work. An empty array is valid when nothing is implemented.


## Revision

Coordination output is **JSON** (no markdown `##` headings in the artifact). Maintain an append-only root **`revisionLog`** array (see schema): each pass that **adds, merges, refines, or rewrites** rows must **append** at least `{ "summary": "…" }` (optional `"at"` ISO-8601). **Never delete** prior `revisionLog` entries. Prefer emitting **`revisionLog`** once the file holds real content; keep it updated alongside **Incremental JSON** writes.

## SRS-50 — Stable coordination writes

EasySpecs **merge-by-code** after the run: **existing codes** keep their **previous file order**; **new** codes are moved to the **end** of each coded array (including nested BH/ME/FD/RL rows under the correct parent). **Append** new rows at the end while authoring.

## Task (for `{{LIST_TASK_DESCRIPTION}}`)

Identify bounded contexts, APIs, backend services, or modules that expose callable operations. **Include client-side HTTP/API modules** (`src/api/`, fetch clients), mappers, and internal service modules with **real callers** — not only server handlers (SRS-116). **Exclude** bare type-only files with no callable operations. Assign stable **`SV-*`** and **`ME-*`** codes and names. Each **service** and each **method** **must** include **`sourceReferences`** with **`minItems: 1`** (`path`, `startLine`, `endLine`, optional `note`). **`path`** must be a **file** path only, not a module directory; one array element per file.

### JSON string literals (RFC 8259 — mandatory)

- Coordination artefacts use **double-quoted** JSON strings only.
- **Apostrophes / single quotes** inside text (e.g. user's, don't, it's) **must appear as the plain character** `'` — **never** as `\'`. In JSON, `\'` is **invalid** and causes `JSON.parse` to fail with *Bad escaped character*.
- **Only** escape `"` as `\"`, backslashes as `\\`, and use `\n`, `\t`, `\uXXXX` where needed. Do **not** use Python-, SQL-, or JavaScript-single-quote escaping in `.json` files.
- **Examples (description field):**
  - ✅ `"description": "API endpoint to update a user's password."`
  - ❌ `"description": "API endpoint to update a user\'s password."`

## JSON Schema (Draft 2020-12)

**Bundled file:** `resources/schemas/context-lists/services-list.schema.json`  
**Materialized (`{{LIST_SCHEMA_REF}}` example):** `<worktree>/.opencode/schemas/context-lists/services-list.schema.json`

Emit **only** JSON that validates against this schema:

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://easyspecs.ai/schemas/context-lists/services-list.schema.json",
  "title": "services-list",
  "$defs": {
    "sourceReference": {
      "type": "object",
      "additionalProperties": false,
      "required": ["path", "startLine", "endLine"],
      "properties": {
        "path": {
          "type": "string",
          "minLength": 1,
          "pattern": "^[^/]+(/[^/]+)*$",
          "description": "Repo-relative path to a single file (forward slashes). Not a directory: no trailing slash; list each file in a folder as its own sourceReferences entry."
        },
        "startLine": {
          "type": "integer",
          "minimum": 1,
          "description": "1-based inclusive start line."
        },
        "endLine": {
          "type": "integer",
          "minimum": 1,
          "description": "1-based inclusive end line; should be >= startLine."
        },
        "note": {
          "type": "string",
          "description": "Optional short label for this evidence span."
        }
      }
    },
    "sourceReferenceList": {
      "type": "array",
      "description": "Evidence spans: each item references one file + line range, never a folder path.",
      "items": { "$ref": "#/$defs/sourceReference" }
    },
    "methodItem": {
      "type": "object",
      "additionalProperties": true,
      "required": ["code", "name", "sourceReferences"],
      "properties": {
        "code": {
          "type": "string",
          "pattern": "^ME-[0-9]+$"
        },
        "name": { "type": "string", "minLength": 1 },
        "slug": {
          "type": "string",
          "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
          "description": "Recommended for SV-<nn>_ME-<mm>-<slug>.md detail basenames."
        },
        "description": { "type": "string" },
        "order": { "type": "integer" },
        "sourceReferences": {
          "type": "array",
          "minItems": 1,
          "description": "Required: at least one file + line range per method row.",
          "items": { "$ref": "#/$defs/sourceReference" }
        }
      }
    }
  },
  "type": "object",
  "additionalProperties": false,
  "required": ["services"],
  "properties": {
    "kind": {
      "type": "string",
      "const": "easyspecs.services-list",
      "description": "Optional coordination document id; when present must be this value."
    },
    "version": {
      "type": "integer",
      "minimum": 1,
      "description": "Optional coordination format version when present."
    },
    "services": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": true,
        "required": ["code", "name", "sourceReferences"],
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^SV-[0-9]+$"
          },
          "name": { "type": "string", "minLength": 1 },
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "description": "Recommended for SV-<nn>-<slug>.md detail basenames."
          },
          "description": { "type": "string" },
          "order": { "type": "integer" },
          "sourceReferences": {
            "type": "array",
            "minItems": 1,
            "description": "Required: at least one file + line range per service row.",
            "items": { "$ref": "#/$defs/sourceReference" }
          },
          "methods": {
            "type": "array",
            "items": { "$ref": "#/$defs/methodItem" }
          }
        }
      }
    },
    "revisionLog": {
      "type": "array",
      "description": "Append-only log of substantive edits; add an entry whenever this pass changes rows, merges, or refines the coordination file.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["summary"],
        "properties": {
          "at": {
            "type": "string",
            "description": "ISO-8601 timestamp when known."
          },
          "summary": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "What was added, changed, or refined in this write."
          }
        }
      }
    }
  }
}
```

**Example instance:**

```json
{
  "services": [
    {
      "code": "SV-01",
      "name": "Auth API",
      "slug": "auth-api",
      "sourceReferences": [
        { "path": "src/api/auth/index.ts", "startLine": 1, "endLine": 60, "note": "service module" }
      ],
      "methods": [
        {
          "code": "ME-01",
          "name": "POST /login",
          "slug": "post-login",
          "sourceReferences": [
            { "path": "src/api/auth/index.ts", "startLine": 100, "endLine": 180, "note": "login route" }
          ]
        }
      ]
    }
  ],
  "revisionLog": [
    { "summary": "Initial services/methods discovery; extend this array on every substantive merge or refinement pass." }
  ]
}
```

## Barriers

After this list is valid, parallel service markdown and (once ME codes are fixed) method markdown agents may run.

## Harness wiring

§3.5.2; enforce single JSON output path. No writes to `index-application-context.json`.
