---
description: SRS-8 coordination JSON — writes per-entity DM-nn-fields-list.json under .easyspecs/context using file tools.
mode: primary
---

# Agent: Entity fields list (per entity, coordination JSON)

| Field | Value |
| ----- | ----- |
| **AGENT_ID** | `ctx-list-entity-fields` |
| **Display name** | Entity fields list |
| **SRS-8** | §4.6 `DM-<nn>-fields-list.json`; §6.5 Data model scope; **R6**, **R22** |
| **Output** | `<worktree>/.easyspecs/context/DM-<nn>-fields-list.json` (one run per entity) |
| **Pattern** | §3.5.2 — JSON list + **`{{PARENT_CONTEXT_BLOCK}}`** with **`DM_CODE`** |

## 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.

For **one entity** already fixed in `data-model-list.json`, emit all **fields** (`FD-*`) with stable codes, names, URL-safe **slugs** for detail markdown basenames **`DM-<nn>_FD-<ff>-<slug>.md`**, and **mandatory `sourceReferences`** on **every** field row (same object shape as features / entities / other coordination lists). Barrier for **field detail** markdown runs.

## 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** field 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}}`)

The orchestrator fills the task line with the target **DM-** code and output basename. Enumerate attributes, columns, or properties for **that entity only**. Do not change **`entityCode`**.

### `sourceReferences` (required per field)

- **Every** object in **`fields`** **must** include **`sourceReferences`**: a non-empty array (`minItems: 1`).
- Each element: **`path`** (single repo-relative **file**, forward slashes, **never** a directory or trailing slash), **`startLine`**, **`endLine`** (1-based inclusive), optional **`note`**.
- Cite schema, ORM models, migrations, DTOs, or types that justify the field — not narrative-only docs.
- **Do not** use any path whose **basename** is `readme.md` in any casing (`README.md`, etc.).
- **Do not** use paths under **`.opencode/`** (see **`.opencode/` exclusion** above).

### 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/entity-fields-list.schema.json`  
**Materialized (`{{LIST_SCHEMA_REF}}` example):** `<worktree>/.opencode/schemas/context-lists/entity-fields-list.schema.json`

**Output filename:** `DM-<nn>-fields-list.json` must match **`entityCode`** (e.g. `DM-01` → `DM-01-fields-list.json`).

**Keep this embedded block identical** to the bundled `.schema.json` (maintainer rule). Emit **only** JSON that validates (UTF-8, no comments):

```json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://easyspecs.ai/schemas/context-lists/entity-fields-list.schema.json",
  "title": "DM-nn-fields-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."
        }
      }
    }
  },
  "type": "object",
  "additionalProperties": false,
  "required": ["entityCode", "fields"],
  "properties": {
    "kind": {
      "type": "string",
      "const": "easyspecs.entity-fields-list",
      "description": "Optional coordination document id; when present must be this value."
    },
    "version": {
      "type": "integer",
      "minimum": 1,
      "description": "Optional coordination format version when present."
    },
    "entityCode": {
      "type": "string",
      "pattern": "^DM-[0-9]+$",
      "description": "Must match the entity row in data-model-list.json and the output basename DM-nn-fields-list.json."
    },
    "fields": {
      "type": "array",
      "description": "Each field must include implementation evidence via sourceReferences (same shape as other coordination lists).",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["code", "name", "slug", "sourceReferences"],
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^FD-[0-9]+$"
          },
          "name": { "type": "string", "minLength": 1 },
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
            "description": "URL-safe slug for DM-nn_FD-ff-<slug>.md detail basename."
          },
          "description": { "type": "string" },
          "order": { "type": "integer" },
          "sourceReferences": {
            "type": "array",
            "minItems": 1,
            "description": "At least one file + line span per field; each path is a single repo file (never a directory). Do not use readme.md basenames.",
            "items": { "$ref": "#/$defs/sourceReference" }
          }
        }
      }
    },
    "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
{
  "entityCode": "DM-01",
  "fields": [
    {
      "code": "FD-01",
      "name": "email",
      "slug": "email",
      "description": "User login email",
      "sourceReferences": [
        {
          "path": "prisma/schema.prisma",
          "startLine": 12,
          "endLine": 18,
          "note": "User model column"
        }
      ]
    }
  ],
  "revisionLog": [
    { "summary": "Initial field list for entity; extend this array on every substantive merge or refinement pass." }
  ]
}
```

## Output rules

- Write exactly one file at **`{{OUTPUT_FILE_ABSOLUTE}}`**.
- Set **`entityCode`** to the **DM-** code from the parent context block (must match the basename prefix).
- Use sequential **FD-01**, **FD-02**, … unless the repo already uses stable FD codes—then preserve them.
- **Slug** must match `^[a-z0-9]+(?:-[a-z0-9]+)*$` (lowercase, hyphens).
- If **`fields`** is empty (`[]`), no row-level **`sourceReferences`** are required (valid for entities with no persisted attributes found).

## Harness wiring

Bind this logical agent to the active harness CLI. Supply **`{{LIST_SCHEMA_REF}}`**, **`{{WORKTREE_ROOT}}`**, **`{{OUTPUT_FILE_ABSOLUTE}}`**, **`{{OUTPUT_BASENAME}}`**, **`{{PARENT_CONTEXT_BLOCK}}`**. Do **not** write `index-application-context.json`.
