@gluecharm-lab/easyspecs-cli 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +39 -18
  2. package/commands.md +33 -16
  3. package/dist/main.cjs +24443 -17851
  4. package/dist/main.cjs.map +4 -4
  5. package/package.json +1 -1
  6. package/resources/opencode-agents/agent-ace-curator.md +3 -0
  7. package/resources/opencode-agents/agent-context-drift-compare.md +48 -0
  8. package/resources/opencode-agents/agent-list-data-model.md +4 -0
  9. package/resources/opencode-agents/agent-list-entity-fields.md +4 -0
  10. package/resources/opencode-agents/agent-list-experiences.md +4 -0
  11. package/resources/opencode-agents/agent-list-features.md +4 -0
  12. package/resources/opencode-agents/agent-list-scenarios.md +4 -0
  13. package/resources/opencode-agents/agent-list-services.md +4 -0
  14. package/resources/opencode-agents/agent-list-tech-stack.md +4 -0
  15. package/resources/opencode-agents/agent-list-use-cases.md +8 -0
  16. package/resources/opencode-agents/agent-md-method-detail.md +1 -0
  17. package/resources/opencode-agents/agent-md-tool-detail.md +2 -1
  18. package/resources/opencode-agents/agent-review-data-model-list.md +6 -0
  19. package/resources/opencode-agents/agent-review-entity-fields-list.md +6 -0
  20. package/resources/opencode-agents/agent-review-experiences-list.md +6 -0
  21. package/resources/opencode-agents/agent-review-features-list.md +8 -0
  22. package/resources/opencode-agents/agent-review-scenarios-list.md +5 -0
  23. package/resources/opencode-agents/agent-review-services-list.md +6 -0
  24. package/resources/opencode-agents/agent-review-tech-stack-list.md +6 -0
  25. package/resources/opencode-agents/agent-review-use-cases-list.md +6 -0
  26. package/resources/schemas/context-lists/data-model-list.schema.json +24 -0
  27. package/resources/schemas/context-lists/entity-fields-list.schema.json +24 -0
  28. package/resources/schemas/context-lists/experiences-list.schema.json +24 -0
  29. package/resources/schemas/context-lists/features-list.schema.json +24 -0
  30. package/resources/schemas/context-lists/repo-surface-scan.schema.json +24 -0
  31. package/resources/schemas/context-lists/scenarios-list.schema.json +24 -0
  32. package/resources/schemas/context-lists/services-list.schema.json +24 -0
  33. package/resources/schemas/context-lists/tech-stack-list.schema.json +24 -0
  34. package/resources/schemas/context-lists/use-cases-list.schema.json +24 -0
  35. package/resources/schemas/srs-46-config.schema.json +27 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gluecharm-lab/easyspecs-cli",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "EasySpecs headless CLI (synthesis, analysis, diagnose, download/upload context, auth, ACE)",
5
5
  "license": "Elastic-2.0",
6
6
  "homepage": "https://easyspecs.ai/",
@@ -29,3 +29,6 @@ Each operation’s **`sourceLessonIds`** must list the contributing **`lessonId`
29
29
  **When `operations` may stay `[]`:** every lesson is **`noise`** or redundant with an **existing** rule/overlay (same intent already present — read full playbook/overlay files if excerpts are truncated), or promoting would **duplicate** without adding clarity.
30
30
 
31
31
  **Do not** emit `append` rules that merely restate generic advice already obvious from the base agent doc; prefer lessons grounded in **this repo’s** trace.
32
+
33
+ ## Referenced implementation files
34
+ - architecture.md:1-12
@@ -0,0 +1,48 @@
1
+ # Agent: Context drift comparison
2
+
3
+ | Field | Value |
4
+ | ----- | ----- |
5
+ | **AGENT_ID** | `ctx-context-drift-compare` |
6
+ | **Display name** | Context drift comparison |
7
+ | **SRS-56** | Compare reference docs to repository evidence; emit JSON payload |
8
+
9
+ ## Responsibility
10
+
11
+ **`.opencode/` exclusion:** Do not cite `.opencode/` paths as product evidence.
12
+
13
+ The prompt file gives **absolute paths** to:
14
+
15
+ 1. A **manifest JSON** (reference excerpts + evidence snippets/paths).
16
+ 2. The **output JSON path** you **must write**.
17
+
18
+ Read the manifest, explore the worktree as needed (`grep`, `read`, `glob`) to ground claims, then write **only** valid JSON to the output path.
19
+
20
+ ## Output JSON (mandatory)
21
+
22
+ Write **only** this object shape (no markdown wrapper, no commentary):
23
+
24
+ ```json
25
+ {
26
+ "summary": "2-6 sentences: overall drift picture.",
27
+ "findings": [
28
+ {
29
+ "severity": "warn",
30
+ "title": "Short label",
31
+ "detail": "What diverges and why it matters.",
32
+ "referenceRefs": "optional: SRS § or doc path",
33
+ "evidenceRefs": "optional: src/ path or test"
34
+ }
35
+ ],
36
+ "unverifiable": ["item the manifest could not confirm"],
37
+ "truncationAck": true
38
+ }
39
+ ```
40
+
41
+ - **severity** must be **`info`**, **`warn`**, or **`error`**.
42
+ - **findings** may be empty if the reference fully matches evidence.
43
+ - **truncationAck** must be **`true`** if the manifest indicates truncation; otherwise **`false`**.
44
+ - **unverifiable** may be empty.
45
+
46
+ ## Failure modes
47
+
48
+ If you cannot produce valid JSON, still write a minimal object with **`summary`** explaining failure, **`findings: []`**, **`unverifiable: ["…"]`**, **`truncationAck: false`**.
@@ -23,6 +23,10 @@ Emit **entities only** (`DM-*` with **`name`** and **`slug`** for **`DM-<nn>-<sl
23
23
 
24
24
  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.
25
25
 
26
+ ## SRS-50 — Stable coordination writes
27
+
28
+ 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.
29
+
26
30
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
27
31
 
28
32
  Derive **entity-level** persistent/domain concepts from schema, migrations, ORM models, or types **only where they exist** in the worktree. Each entity row: **`code`**, **`name`**, **`slug`**, optional **`description`**, optional **`order`**, and **required** **`sourceReferences`** with **`minItems: 1`** (`path`, `startLine`, `endLine`, optional `note`). Any inline **`fields`** / **`relationships`** rows (if present) **must** also include non-empty **`sourceReferences`**. **`path`** is always a **single file**, never a folder.
@@ -23,6 +23,10 @@ For **one entity** already fixed in `data-model-list.json`, emit all **fields**
23
23
 
24
24
  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.
25
25
 
26
+ ## SRS-50 — Stable coordination writes
27
+
28
+ 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.
29
+
26
30
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
27
31
 
28
32
  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`**.
@@ -65,6 +65,10 @@ Assign stable **`code`** values per srs-4 Experience scope, fill **`sourceRefere
65
65
 
66
66
  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.
67
67
 
68
+ ## SRS-50 — Stable coordination writes
69
+
70
+ 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.
71
+
68
72
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
69
73
 
70
74
  Run the **reasoning workflow**, then discover **only** user-facing surfaces and interactions **evidenced in the repo**. Assign stable **`code`** values consistent with srs-4 Experience scope.
@@ -23,6 +23,10 @@ Emit the **canonical registry of features**: stable **`code`** (`FE-01` …), hu
23
23
 
24
24
  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.
25
25
 
26
+ ## SRS-50 — Stable coordination writes
27
+
28
+ 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.
29
+
26
30
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
27
31
 
28
32
  Produce **`features-list.json`** by **discovering every meaningful feature or capability** this repository implements—not a quick skim of `README.md`. Each row must be suitable for driving downstream use-case and scenario work. Do **not** write markdown lists; output **one JSON file** only.
@@ -25,6 +25,10 @@ For one **use case**, emit all **scenarios** (`SC-*`). Barrier for parallel **`F
25
25
 
26
26
  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.
27
27
 
28
+ ## SRS-50 — Stable coordination writes
29
+
30
+ 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.
31
+
28
32
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
29
33
 
30
34
  List concrete scenarios (flows, test-like paths, edge cases) for **feature {{FE_CODE}}**, **use case {{UC_CODE}}**. Do not alter parent codes. Aim for **multiple** scenarios when the implementation or tests support distinct paths (see **Cardinality** under Responsibility). Each scenario **must** include **`sourceReferences`** with **`minItems: 1`** (`path`, `startLine`, `endLine`, optional `note`). **`path`** is always one **file**, never a folder; split folder evidence across multiple entries.
@@ -23,6 +23,10 @@ Emit **services** (`SV-*`) and **methods** (`ME-*`) as a structured list (method
23
23
 
24
24
  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.
25
25
 
26
+ ## SRS-50 — Stable coordination writes
27
+
28
+ 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.
29
+
26
30
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
27
31
 
28
32
  Identify bounded contexts, APIs, backend services, or modules that expose 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.
@@ -23,6 +23,10 @@ Emit **tools** (`TS-*`): languages, frameworks, infra, key libraries. Usually on
23
23
 
24
24
  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.
25
25
 
26
+ ## SRS-50 — Stable coordination writes
27
+
28
+ 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.
29
+
26
30
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
27
31
 
28
32
  Inventory the technology stack from manifest files, configs, and repo structure. Each tool gets a stable **`TS-<nn>`** code and **`name`**. Each tool **must** include **`sourceReferences`**: a non-empty array (`minItems: 1`) of `{ path, startLine, endLine, note? }` — **`path`** must name a **file** (e.g. `package.json`, `pnpm-lock.yaml`), never a directory; use several entries if evidence spans multiple files.
@@ -25,6 +25,10 @@ For a **single feature** already fixed in `features-list.json`, emit all **use c
25
25
 
26
26
  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.
27
27
 
28
+ ## SRS-50 — Stable coordination writes
29
+
30
+ 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.
31
+
28
32
  ## Task (for `{{LIST_TASK_DESCRIPTION}}`)
29
33
 
30
34
  Enumerate goals or user journeys that belong to **feature {{FE_CODE}}** only. Do not change the feature code. Aim for **multiple** use cases whenever the codebase exposes more than one coherent goal or path under this feature (see **Cardinality** under Responsibility). Each use case row **must** include **`sourceReferences`** with **`minItems: 1`** (`path`, `startLine`, `endLine`, optional `note`). **`path`** must be a **single file** (never a directory); use multiple objects for multiple files under a folder.
@@ -176,4 +180,8 @@ Valid **`features-list.json`**; orchestration passes **`{{FE_CODE}}`** in the pa
176
180
 
177
181
  ## OpenCode wiring
178
182
 
183
+ ## Referenced implementation files
184
+ - .gluecharm/context/architecture.md:1-136
185
+
186
+
179
187
  One JSON file per feature invocation. §3.5.2 with **`{{PARENT_CONTEXT_BLOCK}}`**.
@@ -70,6 +70,7 @@ Basename **`SV-<nn>_ME-<mm>-<slug>.md`**.
70
70
 
71
71
  ## Evidence index
72
72
 
73
+ - `architecture.md:1-138`: Contains the overall application architecture, relevant for understanding method context.
73
74
  - <!-- At least one substantive bullet: `path:line` or honest grounding note per Non-empty chapters — never empty; never `readme.md` basenames. -->
74
75
  ```
75
76
 
@@ -66,7 +66,8 @@ Basename **`TS-<nn>-<slug>.md`**.
66
66
 
67
67
  ## Evidence index
68
68
 
69
- - <!-- At least one substantive bullet: `path:line` or honest grounding note per Non-empty chapters never empty; never `readme.md` basenames. -->
69
+ - `.gluecharm/context/architecture.md:1-139`: Application architecture overview and component breakdown.
70
+ - <!-- At least one substantive bullet: \`path:line\` or honest grounding note per Non-empty chapters — never empty; never \`readme.md\` basenames. -->
70
71
  ```
71
72
 
72
73
  ## Evidence (**R21**)
@@ -17,6 +17,12 @@ mode: primary
17
17
 
18
18
  Read **data-model-list.json**. Normalize entity rows: duplicates, vague entities, split/merge; each **entity** (and any inline **fields** / **relationships** rows) **must** have **`sourceReferences`** with **`minItems: 1`**. Stable **DM-*** codes.
19
19
 
20
+ ## SRS-50 (stable coordination list writes)
21
+
22
+ - **Append-only** — net-new `DM-*` and nested `FD-*` / `RL-*` only **after** existing rows; **do not reorder** survivors.
23
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** for every removed `code`.
24
+ - **Slug rename auth** — **`revisionLog[].slugRenames`** when changing entity `slug` for a fixed `code`.
25
+
20
26
  ## Task
21
27
 
22
28
  Valid JSON at **`{{OUTPUT_FILE_ABSOLUTE}}`** per **`{{LIST_SCHEMA_REF}}`**.
@@ -17,6 +17,12 @@ mode: primary
17
17
 
18
18
  Read **DM-*-fields-list.json**. Normalize FD rows: duplicates, false fields, split/merge; each row must keep valid **sourceReferences**; stable **FD-*** codes and slugs; **entityCode** must match.
19
19
 
20
+ ## SRS-50 (stable coordination list writes)
21
+
22
+ - **Append-only** — net-new `FD-*` only **after** existing rows; **do not reorder** survivors.
23
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** for every removed `code`.
24
+ - **Slug rename auth** — **`revisionLog[].slugRenames`** when changing `slug` for a fixed `code`.
25
+
20
26
  ## Task
21
27
 
22
28
  Valid JSON at **`{{OUTPUT_FILE_ABSOLUTE}}`** per **`{{LIST_SCHEMA_REF}}`**.
@@ -19,6 +19,12 @@ Read the existing **experiences-list.json** (schema-valid from **listExperiences
19
19
 
20
20
  **Critical:** A **view** is any **user-facing surface** the product exposes for interaction—not only full graphical windows. Treat **command-line usage** (subcommands, REPLs, prompts, stdin/stdout flows) and **terminal UIs** (TUI) as first-class views when the repo implements them. **Do not assume** the project is a web app or a single-page stack.
21
21
 
22
+ ## SRS-50 (stable coordination list writes)
23
+
24
+ - **Append-only** — net-new `XP-*` rows (and nested `BH-*`) only **after** existing rows at each level; **do not reorder** surviving rows.
25
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** must list every removed `code` (exact strings).
26
+ - **Slug rename auth** — **`revisionLog[].slugRenames`** `{ code, from, to }` when changing `slug` without changing `code`.
27
+
22
28
  ## Reasoning workflow (mandatory order)
23
29
 
24
30
  Work through these steps **explicitly** (brief notes in your own trace are fine; the **deliverable** remains the JSON file only). Skipping classification and jumping to “pages/routes” causes **hallucinated views**.
@@ -29,6 +29,14 @@ mode: primary
29
29
  8. **`sourceReferences`** — Every surviving feature row **must** have **`minItems: 1`** valid evidence; add from manifests/code if missing. Drop or fix entries that violate schema (no directories, no `.gluecharm/` paths, no `.opencode/` paths, no README basenames).
30
30
  9. **`revisionLog`** — **Append** at least one entry for this review pass (`summary` required; `at` ISO-8601 optional). **Never delete** prior `revisionLog` entries.
31
31
 
32
+ ## SRS-50 (stable coordination list writes)
33
+
34
+ Prefer output that already respects EasySpecs merge rules (the extension post-processes the file):
35
+
36
+ - **Append-only** — net-new `FE-*` rows only **after** all existing rows; **do not reorder** surviving rows.
37
+ - **Logged deletes** — every removed `code` must appear in **`revisionLog[].droppedCodes`** (exact strings) in the same entry as the explanatory **`summary`**.
38
+ - **Slug rename auth** — changing `slug` without changing `code` requires **`revisionLog[].slugRenames`** entries `{ "code", "from", "to" }`.
39
+
32
40
  ## Stable codes
33
41
 
34
42
  - When **merging** duplicates: keep **one** `FE-*` code (prefer the row with stronger evidence).
@@ -19,6 +19,11 @@ Read the scenarios list for the scoped feature/use case. Merge duplicates, remov
19
19
 
20
20
  **Cardinality:** After normalization, **one** remaining scenario is **suspicious** for a non-trivial use case—re-check that error paths, permission denials, boundary data, and alternate success paths were not folded into one overly broad SC. If the use case is genuinely a single path with no variants, note that in **`revisionLog`**; otherwise add or split scenarios.
21
21
 
22
+ ## SRS-50 (stable coordination list writes)
23
+
24
+ - **Append-only** — net-new `SC-*` only **after** existing rows; **do not reorder** survivors.
25
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** for every removed `code`.
26
+
22
27
  ## Task
23
28
 
24
29
  Valid JSON at **`{{OUTPUT_FILE_ABSOLUTE}}`** per **`{{LIST_SCHEMA_REF}}`**.
@@ -17,6 +17,12 @@ mode: primary
17
17
 
18
18
  Read **services-list.json** from **listServices**. Normalize: merge duplicate services/methods, remove false SV/ME rows, fix granularity; each **service** and **method** row **must** have **`sourceReferences`** with **`minItems: 1`**. Stable **SV-*** / **ME-*** codes. **revisionLog** if supported.
19
19
 
20
+ ## SRS-50 (stable coordination list writes)
21
+
22
+ - **Append-only** — net-new `SV-*` / nested `ME-*` only **after** existing rows; **do not reorder** survivors.
23
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** for every removed `code`.
24
+ - **Slug rename auth** — **`revisionLog[].slugRenames`** when changing `slug` for a fixed `code`.
25
+
20
26
  ## Task
21
27
 
22
28
  Output valid JSON at **`{{OUTPUT_FILE_ABSOLUTE}}`** per **`{{LIST_SCHEMA_REF}}`**.
@@ -17,6 +17,12 @@ mode: primary
17
17
 
18
18
  Read **tech-stack-list.json**. Normalize tool rows: duplicates, false tools; stable **TS-*** codes and slugs. **Every** surviving tool **must** keep valid **`sourceReferences`** with **`minItems: 1`** (schema-required). **Drop** tools you cannot ground with at least one allowed file+line span, or **add** evidence from manifests/configs before writing — empty/missing **`sourceReferences`** fails validation.
19
19
 
20
+ ## SRS-50 (stable coordination list writes)
21
+
22
+ - **Append-only** — net-new `TS-*` only **after** existing rows; **do not reorder** survivors.
23
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** for every removed `code`.
24
+ - **Slug rename auth** — **`revisionLog[].slugRenames`** when changing `slug` for a fixed `code`.
25
+
20
26
  ## Task
21
27
 
22
28
  Valid JSON at **`{{OUTPUT_FILE_ABSOLUTE}}`** per **`{{LIST_SCHEMA_REF}}`**.
@@ -19,6 +19,12 @@ Read the use-cases list for the scoped feature. Merge duplicate UCs, remove fals
19
19
 
20
20
  **Cardinality:** After normalization, **one** remaining UC is **suspicious** for a non-trivial feature—re-check that distinct goals or entry paths were not over-merged. If the feature truly has a single linear journey, note that in **`revisionLog`**; otherwise split or add UCs so the list reflects multiple meaningful journeys.
21
21
 
22
+ ## SRS-50 (stable coordination list writes)
23
+
24
+ - **Append-only** — net-new `UC-*` only **after** existing rows; **do not reorder** survivors.
25
+ - **Logged deletes** — **`revisionLog[].droppedCodes`** for every removed `code`.
26
+ - **Slug rename auth** — **`revisionLog[].slugRenames`** when changing `slug` for a fixed `code`.
27
+
22
28
  ## Task
23
29
 
24
30
  Valid JSON at **`{{OUTPUT_FILE_ABSOLUTE}}`** per **`{{LIST_SCHEMA_REF}}`**.
@@ -149,6 +149,30 @@
149
149
  "minLength": 1,
150
150
  "maxLength": 2000,
151
151
  "description": "What was added, changed, or refined in this write."
152
+ },
153
+ "droppedCodes": {
154
+ "type": "array",
155
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
156
+ "items": { "type": "string", "minLength": 1 }
157
+ },
158
+ "slugRenames": {
159
+ "type": "array",
160
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
161
+ "items": {
162
+ "type": "object",
163
+ "additionalProperties": false,
164
+ "required": ["code", "from", "to"],
165
+ "properties": {
166
+ "code": { "type": "string", "minLength": 1 },
167
+ "from": { "type": "string", "minLength": 1 },
168
+ "to": { "type": "string", "minLength": 1 }
169
+ }
170
+ }
171
+ },
172
+ "stableWriteDiff": {
173
+ "type": "object",
174
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
175
+ "additionalProperties": true
152
176
  }
153
177
  }
154
178
  }
@@ -96,6 +96,30 @@
96
96
  "minLength": 1,
97
97
  "maxLength": 2000,
98
98
  "description": "What was added, changed, or refined in this write."
99
+ },
100
+ "droppedCodes": {
101
+ "type": "array",
102
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
103
+ "items": { "type": "string", "minLength": 1 }
104
+ },
105
+ "slugRenames": {
106
+ "type": "array",
107
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
108
+ "items": {
109
+ "type": "object",
110
+ "additionalProperties": false,
111
+ "required": ["code", "from", "to"],
112
+ "properties": {
113
+ "code": { "type": "string", "minLength": 1 },
114
+ "from": { "type": "string", "minLength": 1 },
115
+ "to": { "type": "string", "minLength": 1 }
116
+ }
117
+ }
118
+ },
119
+ "stableWriteDiff": {
120
+ "type": "object",
121
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
122
+ "additionalProperties": true
99
123
  }
100
124
  }
101
125
  }
@@ -124,6 +124,30 @@
124
124
  "minLength": 1,
125
125
  "maxLength": 2000,
126
126
  "description": "What was added, changed, or refined in this write."
127
+ },
128
+ "droppedCodes": {
129
+ "type": "array",
130
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
131
+ "items": { "type": "string", "minLength": 1 }
132
+ },
133
+ "slugRenames": {
134
+ "type": "array",
135
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
136
+ "items": {
137
+ "type": "object",
138
+ "additionalProperties": false,
139
+ "required": ["code", "from", "to"],
140
+ "properties": {
141
+ "code": { "type": "string", "minLength": 1 },
142
+ "from": { "type": "string", "minLength": 1 },
143
+ "to": { "type": "string", "minLength": 1 }
144
+ }
145
+ }
146
+ },
147
+ "stableWriteDiff": {
148
+ "type": "object",
149
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
150
+ "additionalProperties": true
127
151
  }
128
152
  }
129
153
  }
@@ -101,6 +101,30 @@
101
101
  "minLength": 1,
102
102
  "maxLength": 2000,
103
103
  "description": "What was added, changed, or refined in this write."
104
+ },
105
+ "droppedCodes": {
106
+ "type": "array",
107
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
108
+ "items": { "type": "string", "minLength": 1 }
109
+ },
110
+ "slugRenames": {
111
+ "type": "array",
112
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
113
+ "items": {
114
+ "type": "object",
115
+ "additionalProperties": false,
116
+ "required": ["code", "from", "to"],
117
+ "properties": {
118
+ "code": { "type": "string", "minLength": 1 },
119
+ "from": { "type": "string", "minLength": 1 },
120
+ "to": { "type": "string", "minLength": 1 }
121
+ }
122
+ }
123
+ },
124
+ "stableWriteDiff": {
125
+ "type": "object",
126
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
127
+ "additionalProperties": true
104
128
  }
105
129
  }
106
130
  }
@@ -82,6 +82,30 @@
82
82
  "minLength": 1,
83
83
  "maxLength": 2000,
84
84
  "description": "What was added, changed, or refined in this write."
85
+ },
86
+ "droppedCodes": {
87
+ "type": "array",
88
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
89
+ "items": { "type": "string", "minLength": 1 }
90
+ },
91
+ "slugRenames": {
92
+ "type": "array",
93
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
94
+ "items": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "required": ["code", "from", "to"],
98
+ "properties": {
99
+ "code": { "type": "string", "minLength": 1 },
100
+ "from": { "type": "string", "minLength": 1 },
101
+ "to": { "type": "string", "minLength": 1 }
102
+ }
103
+ }
104
+ },
105
+ "stableWriteDiff": {
106
+ "type": "object",
107
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
108
+ "additionalProperties": true
85
109
  }
86
110
  }
87
111
  }
@@ -99,6 +99,30 @@
99
99
  "minLength": 1,
100
100
  "maxLength": 2000,
101
101
  "description": "What was added, changed, or refined in this write."
102
+ },
103
+ "droppedCodes": {
104
+ "type": "array",
105
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
106
+ "items": { "type": "string", "minLength": 1 }
107
+ },
108
+ "slugRenames": {
109
+ "type": "array",
110
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
111
+ "items": {
112
+ "type": "object",
113
+ "additionalProperties": false,
114
+ "required": ["code", "from", "to"],
115
+ "properties": {
116
+ "code": { "type": "string", "minLength": 1 },
117
+ "from": { "type": "string", "minLength": 1 },
118
+ "to": { "type": "string", "minLength": 1 }
119
+ }
120
+ }
121
+ },
122
+ "stableWriteDiff": {
123
+ "type": "object",
124
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
125
+ "additionalProperties": true
102
126
  }
103
127
  }
104
128
  }
@@ -124,6 +124,30 @@
124
124
  "minLength": 1,
125
125
  "maxLength": 2000,
126
126
  "description": "What was added, changed, or refined in this write."
127
+ },
128
+ "droppedCodes": {
129
+ "type": "array",
130
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
131
+ "items": { "type": "string", "minLength": 1 }
132
+ },
133
+ "slugRenames": {
134
+ "type": "array",
135
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
136
+ "items": {
137
+ "type": "object",
138
+ "additionalProperties": false,
139
+ "required": ["code", "from", "to"],
140
+ "properties": {
141
+ "code": { "type": "string", "minLength": 1 },
142
+ "from": { "type": "string", "minLength": 1 },
143
+ "to": { "type": "string", "minLength": 1 }
144
+ }
145
+ }
146
+ },
147
+ "stableWriteDiff": {
148
+ "type": "object",
149
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
150
+ "additionalProperties": true
127
151
  }
128
152
  }
129
153
  }
@@ -100,6 +100,30 @@
100
100
  "minLength": 1,
101
101
  "maxLength": 2000,
102
102
  "description": "What was added, changed, or refined in this write."
103
+ },
104
+ "droppedCodes": {
105
+ "type": "array",
106
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
107
+ "items": { "type": "string", "minLength": 1 }
108
+ },
109
+ "slugRenames": {
110
+ "type": "array",
111
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
112
+ "items": {
113
+ "type": "object",
114
+ "additionalProperties": false,
115
+ "required": ["code", "from", "to"],
116
+ "properties": {
117
+ "code": { "type": "string", "minLength": 1 },
118
+ "from": { "type": "string", "minLength": 1 },
119
+ "to": { "type": "string", "minLength": 1 }
120
+ }
121
+ }
122
+ },
123
+ "stableWriteDiff": {
124
+ "type": "object",
125
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
126
+ "additionalProperties": true
103
127
  }
104
128
  }
105
129
  }
@@ -100,6 +100,30 @@
100
100
  "minLength": 1,
101
101
  "maxLength": 2000,
102
102
  "description": "What was added, changed, or refined in this write."
103
+ },
104
+ "droppedCodes": {
105
+ "type": "array",
106
+ "description": "SRS-50: coordination row codes removed in this pass (explicit intent).",
107
+ "items": { "type": "string", "minLength": 1 }
108
+ },
109
+ "slugRenames": {
110
+ "type": "array",
111
+ "description": "SRS-50: authorized slug changes for stable detail markdown basenames.",
112
+ "items": {
113
+ "type": "object",
114
+ "additionalProperties": false,
115
+ "required": ["code", "from", "to"],
116
+ "properties": {
117
+ "code": { "type": "string", "minLength": 1 },
118
+ "from": { "type": "string", "minLength": 1 },
119
+ "to": { "type": "string", "minLength": 1 }
120
+ }
121
+ }
122
+ },
123
+ "stableWriteDiff": {
124
+ "type": "object",
125
+ "description": "SRS-50: machine-readable summary of merge-by-code pass (EasySpecs extension).",
126
+ "additionalProperties": true
103
127
  }
104
128
  }
105
129
  }
@@ -20,6 +20,33 @@
20
20
  },
21
21
  "upload": {
22
22
  "$ref": "#/$defs/srs46Upload"
23
+ },
24
+ "factory": {
25
+ "type": "object",
26
+ "description": "SRS-53 optional canonical block; when `cloudContextAnalyzed` / `cloudContextAnalyzedAt` are set here they override the same keys under `analysis` after merge.",
27
+ "additionalProperties": true,
28
+ "properties": {
29
+ "debug": { "type": "boolean" },
30
+ "cloudContextAnalyzed": { "type": "boolean" },
31
+ "cloudContextAnalyzedAt": {
32
+ "oneOf": [{ "type": "null" }, { "type": "string", "format": "date-time", "minLength": 1 }]
33
+ },
34
+ "updateContext": {
35
+ "type": "object",
36
+ "additionalProperties": true,
37
+ "properties": {
38
+ "lastRunAt": { "type": "string", "format": "date-time", "minLength": 1 }
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "workstations": {
44
+ "type": "object",
45
+ "additionalProperties": true
46
+ },
47
+ "pipelines": {
48
+ "type": "object",
49
+ "additionalProperties": true
23
50
  }
24
51
  }
25
52
  }