@uoyo/mvtt 2.0.0-beta.3 → 2.0.0-beta.4

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 (32) hide show
  1. package/dist/fs/materialize.d.ts.map +1 -1
  2. package/dist/fs/materialize.js +7 -4
  3. package/dist/fs/materialize.js.map +1 -1
  4. package/dist/fs/registry-merge.d.ts +19 -0
  5. package/dist/fs/registry-merge.d.ts.map +1 -0
  6. package/dist/fs/registry-merge.js +177 -0
  7. package/dist/fs/registry-merge.js.map +1 -0
  8. package/dist/scripts/plan-update.cjs +7563 -0
  9. package/install-manifest.yaml +6 -2
  10. package/package.json +1 -1
  11. package/sources/scripts/plan-update.js +353 -0
  12. package/sources/sections/output-format-constraint.md +14 -0
  13. package/sources/sections/project-context-profile.md +29 -0
  14. package/sources/skills/mvt-analyze/manifest.yaml +3 -0
  15. package/sources/skills/mvt-analyze-code/manifest.yaml +6 -0
  16. package/sources/skills/mvt-cleanup/manifest.yaml +3 -0
  17. package/sources/skills/mvt-create-skill/manifest.yaml +3 -0
  18. package/sources/skills/mvt-design/manifest.yaml +3 -0
  19. package/sources/skills/mvt-fix/manifest.yaml +3 -0
  20. package/sources/skills/mvt-implement/business.md +9 -5
  21. package/sources/skills/mvt-implement/manifest.yaml +3 -0
  22. package/sources/skills/mvt-init/manifest.yaml +3 -0
  23. package/sources/skills/mvt-manage-context/manifest.yaml +6 -0
  24. package/sources/skills/mvt-plan-dev/manifest.yaml +3 -0
  25. package/sources/skills/mvt-quick-dev/manifest.yaml +3 -0
  26. package/sources/skills/mvt-refactor/manifest.yaml +3 -0
  27. package/sources/skills/mvt-review/manifest.yaml +3 -0
  28. package/sources/skills/mvt-sync-context/business.md +58 -29
  29. package/sources/skills/mvt-sync-context/manifest.yaml +6 -0
  30. package/sources/skills/mvt-test/manifest.yaml +3 -0
  31. package/sources/skills/mvt-update-plan/business.md +30 -28
  32. package/sources/skills/mvt-update-plan/manifest.yaml +3 -0
@@ -4,8 +4,8 @@
4
4
  - **What**: produce a candidate list of change-ids whose artifacts will be aggregated.
5
5
  - **How**:
6
6
  1. Read `session.yaml`. Collect `changes[]` entries with `status: done`.
7
- 2. For each candidate, verify `.ai-agents/workspace/artifacts/{change-id}/` exists AND contains at least one of `analysis.md` or `design.md`. Drop entries with only `plan.yaml`.
8
- 3. (Fallback) If `changes[]` is empty, scan `.ai-agents/workspace/artifacts/*/` directly; offer those with `analysis.md` or `design.md`, marked `unindexed`.
7
+ 2. For each candidate, verify `.ai-agents/workspace/artifacts/{change-id}/` exists AND contains at least one of `analysis.md` or `implementation.md`. Drop entries with only `plan.yaml`, or with only `design.md` (design artifacts are not aggregated -- see Step 3).
8
+ 3. (Fallback) If `changes[]` is empty, scan `.ai-agents/workspace/artifacts/*/` directly; offer those with `analysis.md` or `implementation.md`, marked `unindexed`.
9
9
  4. Exclude already-archived or irrelevant changes:
10
10
  - **Indexed changes**: exclude any `changes[]` entry with `status: abandoned`. For `status: done` entries, Step 1.2's directory existence check already filters out those whose artifacts have been moved to `artifacts/_archived/` by `/mvt-cleanup`.
11
11
  - **Fallback scan**: when scanning `artifacts/*/` directly, skip any path under `artifacts/_archived/` (the unified archive directory managed by `/mvt-cleanup`).
@@ -32,57 +32,85 @@ This step establishes the **target structure** that aggregated content must fit
32
32
  2. Parse the current `.md` into a section map:
33
33
  - Each top-level `##` heading -> one section anchor.
34
34
  - Record: section title (verbatim), byte range, and a 1-line semantic summary derived from the section's content (e.g., "lists domain terms with definitions" or "describes module dependencies").
35
- - The summary is what enables matching in Step 3 -- section titles may be in any language and may not match conventional names (Terms / Modules / etc.).
35
+ - The summary is what enables matching in Step 5 -- section titles may be in any language and may not match conventional names (Terms / Modules / etc.).
36
36
  3. If the document has zero `##` sections (single block) -> STOP. Recommend `/mvt-analyze-code` to establish a sectioned baseline first.
37
- 4. Read `.ai-agents/workspace/project-context.yaml`. Record current `projects[].source_paths`, `modules`, and `tech_stack` for diff comparison in Step 4d.
37
+ 4. Read `.ai-agents/workspace/project-context.yaml`. Record current `projects[].source_paths`, `modules`, and `tech_stack` for diff comparison in Step 5d.
38
38
 
39
- ### Step 3: Extract and Classify Artifact Content
39
+ ### Step 3: Extract Artifact Content
40
40
 
41
- - **What**: from each selected change-id, extract atomic knowledge items and classify them against the section map from Step 2.
41
+ - **What**: from each selected change-id, extract atomic knowledge items (do not classify yet).
42
42
  - **How**:
43
- 1. For each selected change-id, read available artifacts (`analysis.md`, `implementation.md`).
43
+ 1. For each selected change-id, read available artifacts (`analysis.md`, `implementation.md`). Do NOT read `design.md` -- design artifacts are not aggregated by this skill.
44
44
  2. Extract atomic items. Typical sources:
45
45
  - `analysis.md` -> domain terms, actors, business rules, constraints
46
46
  - `implementation.md` -> files added/changed (informs `.yaml` source_paths), realized vs deviated design points
47
- 3. For each item, match to a section from the Step 2 map:
47
+
48
+ ### Step 4: Normalize Extracted Content
49
+
50
+ Before classifying extracted items against the section map, normalize each item per the **Document Profile: project-context.md** section loaded above. This step strips intra-artifact cross-references -- meaningful in their source document but noise in project-context.md -- before they enter the merge pipeline.
51
+
52
+ 1. For each extracted item, apply the normalization rules below (the governing principle lives in the Document Profile; this table lists concrete patterns, non-exhaustive):
53
+
54
+ | Pattern | Example | Normalization |
55
+ |---------|---------|---------------|
56
+ | ADR reference with section number | `(ADR-06, §12.4)` | Remove the reference; keep the substantive content it annotates |
57
+ | Bare ADR reference | `per ADR-06`, `(ADR-06)` | Remove entirely |
58
+ | Section number reference | `§12.4`, `§3.2.1` | Remove entirely |
59
+ | Design rule label prefix | `B-1:`, `D-7:`, `C-3:` | Remove the prefix; keep the rule text |
60
+ | Parenthesized design label | `(D-7)`, `(B-4)` | Remove entirely |
61
+ | Cross-artifact link phrase | `see §X`, `refer to ADR-N` | Remove the link phrase |
62
+ | Other reference pointing outside project-context.md | Any pattern not listed above | Apply the governing principle: if understanding requires an external document, strip the reference marker |
63
+
64
+ **Critical**: strip only the *reference marker*, never the *substantive content* it annotates.
65
+
66
+ 2. After normalization, re-evaluate each item:
67
+ - Still contains substantive content -> keep for classification in Step 5.
68
+ - Was entirely a cross-reference with no independent semantic value -> drop it (it is a pointer, not knowledge).
69
+ 3. Any normalization that removes content from a `modify` item (where the item modifies an existing entry) must be flagged in the update plan (Step 6, Table 6b) so the user can verify the substantive meaning was preserved.
70
+
71
+ ### Step 5: Classify Artifact Content
72
+
73
+ - **What**: classify each normalized item against the section map from Step 2.
74
+ - **How**:
75
+ 1. For each item, match to a section from the Step 2 map:
48
76
  - Match by semantic similarity to **section title + 1-line summary**, not by exact string.
49
77
  - Confidence levels:
50
78
  - **mapped**: exactly one section matches with high confidence
51
79
  - **ambiguous**: 2+ sections plausibly match
52
80
  - **orphan**: no section matches; propose a new section name
53
- 4. For each item, also detect change type relative to current section content:
81
+ 2. For each item, also detect change type relative to current section content:
54
82
  - `new` -- target section does not contain this entity
55
83
  - `modify` -- target section mentions the entity but artifact provides a different value
56
84
  - `redundant` -- already present, no change (will be filtered out, not shown to user)
57
85
 
58
- ### Step 4: Render the Update Plan (Four Tables)
86
+ ### Step 6: Render the Update Plan (Four Tables)
59
87
 
60
- #### 4a. Section-mapped items
88
+ #### 6a. Section-mapped items
61
89
  | # | change-id | item | type | target section | classification |
62
90
  |---|-----------|------|------|----------------|----------------|
63
91
 
64
- #### 4b. Conflicts requiring resolution (every `modify` item)
92
+ #### 6b. Conflicts requiring resolution (every `modify` item)
65
93
  | # | item | section | current value | proposed value (from {change-id}) |
66
94
  |---|------|---------|---------------|-----------------------------------|
67
95
 
68
- #### 4c. Ambiguous and orphan items
96
+ #### 6c. Ambiguous and orphan items
69
97
  | # | item | reason | candidate sections (or proposed new section) |
70
98
  |---|------|--------|----------------------------------------------|
71
99
 
72
- #### 4d. Implied yaml changes
100
+ #### 6d. Implied yaml changes
73
101
  | # | yaml field | current | proposed |
74
102
  |---|------------|---------|----------|
75
103
 
76
- ### Step 5: User Confirmation (Per-Table)
104
+ ### Step 7: User Confirmation (Per-Table)
77
105
 
78
- - **4a**: default = accept all. User input: indices to drop, or `e <n>` to edit a single item's target section.
79
- - **4b**: **explicit per-row decision required**. Format `<index>:<keep|replace|edit>`. Example: `1:replace,2:keep,3:edit`. No default.
80
- - **4c**: per row, user picks an existing section, types a new section name, or `skip`.
81
- - **4d**: default = accept; user can drop indices.
106
+ - **6a**: default = accept all. User input: indices to drop, or `e <n>` to edit a single item's target section.
107
+ - **6b**: **explicit per-row decision required**. Format `<index>:<keep|replace|edit>`. Example: `1:replace,2:keep,3:edit`. No default.
108
+ - **6c**: per row, user picks an existing section, types a new section name, or `skip`.
109
+ - **6d**: default = accept; user can drop indices.
82
110
 
83
111
  Then ask: **"Run optional read-only code verification before applying? (y/n)"**
84
112
 
85
- ### Step 6: (Optional) Read-only Code Verification
113
+ ### Step 8: (Optional) Read-only Code Verification
86
114
 
87
115
  This step catches artifacts claiming entities never actually delivered. It is **read-only** -- it never writes anything to `.md` or `.yaml`.
88
116
 
@@ -101,9 +129,9 @@ If user opts in:
101
129
 
102
130
  3. Re-render the apply list with `verified` / `unverified` markers; final confirmation.
103
131
 
104
- If user skips verification: proceed directly to Step 7 with Step 5 selections.
132
+ If user skips verification: proceed directly to Step 9 with Step 7 selections.
105
133
 
106
- ### Step 7: Apply Updates (Merge Mode)
134
+ ### Step 9: Apply Updates (Merge Mode)
107
135
 
108
136
  - **Pre-write**:
109
137
  1. Backup: `project-context.md` -> `project-context.md.bak`; `project-context.yaml` -> `project-context.yaml.bak`. Overwrite any prior `.bak`.
@@ -114,15 +142,16 @@ If user skips verification: proceed directly to Step 7 with Step 5 selections.
114
142
  2. Each `modify` item with `replace`: replace the matching line in place. Smallest possible diff.
115
143
  3. Each `orphan` item with new-section choice: append a new `##` section at end of file.
116
144
  4. **Never delete** any existing line. **Never reorder** existing sections.
145
+ 5. All merged content must already be normalized per Step 4 rules. Do not re-introduce stripped references during inline replacement or append operations.
117
146
 
118
147
  - **Update `project-context.yaml`** (structured merge):
119
- 1. Apply accepted entries from Table 4d.
148
+ 1. Apply accepted entries from Table 6d.
120
149
  2. Add new `source_paths` to matching project entry; add new modules to `modules[]`.
121
150
  3. **Never delete** an existing yaml entry in this skill.
122
151
 
123
152
  - **Atomicity**: temp + rename per file. If `.md` write succeeds but `.yaml` fails (or vice versa) -> restore the failed one from `.bak`, keep the other; report partial success.
124
153
 
125
- ### Step 8: Report
154
+ ### Step 10: Report
126
155
 
127
156
  1. **Applied summary** -- counts: items added / modified / skipped / orphaned-into-new-section
128
157
  2. **Files changed** -- paths + byte deltas
@@ -136,7 +165,7 @@ If user skips verification: proceed directly to Step 7 with Step 5 selections.
136
165
  - Aggregated >= 1 change -> "Run `/mvt-cleanup` to archive these completed changes."
137
166
  - Verification flagged code-only entities -> "Run `/mvt-analyze-code` to capture missing entities."
138
167
 
139
- ### Step 9: State Update
168
+ ### Step 11: State Update
140
169
  Apply the State Update rules defined in the **State Update** section below.
141
170
  - The `--set-synced` parameter updates `session.last_synced_at`.
142
171
 
@@ -149,7 +178,7 @@ Apply the State Update rules defined in the **State Update** section below.
149
178
  | Selected change-id has only `plan.yaml` | Filtered in Step 1; will not appear |
150
179
  | `modify` with `replace` but the existing line cannot be located deterministically | Fall back to append + flag as duplicate-needs-manual-edit; do NOT silently overwrite the wrong line |
151
180
  | `.md.bak` already exists | Overwrite (only the most recent backup matters) |
152
- | User aborts at Step 5 | Do not write; report "no changes applied" |
153
- | Step 6 verification finds zero matches for everything | Strong warning; require explicit confirm before proceeding (artifacts likely describe planned, not delivered, work) |
154
- | Two artifacts contradict each other (design says layer A, implementation says layer B) | Surface in Table 4b as cross-artifact conflict; user picks |
155
- | change-id was archived between Step 1 and Step 7 | Skip with note; do not error the run |
181
+ | User aborts at Step 7 | Do not write; report "no changes applied" |
182
+ | Step 8 verification finds zero matches for everything | Strong warning; require explicit confirm before proceeding (artifacts likely describe planned, not delivered, work) |
183
+ | Two artifacts contradict each other (analysis claims rule X, implementation realizes rule Y) | Surface in Table 6b as cross-artifact conflict; user picks |
184
+ | change-id was archived between Step 1 and Step 9 | Skip with note; do not error the run |
@@ -60,6 +60,9 @@ sections:
60
60
  - type: shared
61
61
  source: sections/output-language-constraint.md
62
62
 
63
+ - type: shared
64
+ source: sections/output-format-constraint.md
65
+
63
66
  - type: shared
64
67
  source: sections/activation-preflight.md
65
68
  params:
@@ -73,6 +76,9 @@ sections:
73
76
  level: "BLOCK"
74
77
  message: "project-context.md not found. Run `/mvt-analyze-code` to create the initial document; this skill only handles incremental updates."
75
78
 
79
+ - type: shared
80
+ source: sections/project-context-profile.md
81
+
76
82
  - type: file
77
83
  source: ./business.md
78
84
 
@@ -57,6 +57,9 @@ sections:
57
57
  - type: shared
58
58
  source: sections/output-language-constraint.md
59
59
 
60
+ - type: shared
61
+ source: sections/output-format-constraint.md
62
+
60
63
  - type: shared
61
64
  source: sections/activation-preflight.md
62
65
  params:
@@ -23,43 +23,45 @@ Resolution rules:
23
23
  2. Parse YAML; if parse fails or schema is invalid -> stop and report. Do not attempt to repair silently.
24
24
  3. Verify the target `task_id` exists in `tasks[]`. If not, list valid ids and stop.
25
25
 
26
- ### Step 3: Apply the Update
26
+ ### Step 3: Apply the Update, Recompute, Validate, and Write (via script)
27
27
 
28
- Mutate the in-memory plan:
28
+ The mechanical work — mutating the task, recomputing `current_task` via the DAG
29
+ rules, validating the result, and writing back atomically — is performed by a
30
+ deterministic script. Do NOT hand-edit `plan.yaml` or reason through the
31
+ `current_task` selection yourself; call the script with the resolved arguments
32
+ from Step 1–2:
29
33
 
30
- 1. Find the target task; capture `old_status` for the report.
31
- 2. Set `tasks[i].status = new_status`.
32
- 3. If `artifacts` provided -> append to `tasks[i].artifacts` (de-duplicate).
33
- 4. If `notes` provided -> overwrite `tasks[i].notes`.
34
- 5. Update `plan.updated_at` to current ISO 8601 timestamp.
34
+ ```bash
35
+ node .ai-agents/scripts/plan-update.cjs --plan "<active_change.plan_path>" --task <task_id> --status <new_status> [--artifacts "<comma,separated,paths>"] [--notes "<note text>"]
36
+ ```
35
37
 
36
- ### Step 4: Recompute current_task
38
+ Include `--artifacts` only if artifacts were provided, and `--notes` only if a note was provided; omit each flag otherwise.
37
39
 
38
- Selection logic, in order:
40
+ | Argument | Value source |
41
+ |----------|-------------|
42
+ | `--plan` | `active_change.plan_path` resolved from session.yaml |
43
+ | `--task` | the `task_id` resolved in Step 1 |
44
+ | `--status` | the `new_status` resolved in Step 1 (`pending`/`in_progress`/`done`/`blocked`/`skipped`) |
45
+ | `--artifacts` | optional; comma-separated paths to append (the script de-duplicates) |
46
+ | `--notes` | optional; overwrites the task's `notes` |
39
47
 
40
- 1. If any task has status `in_progress` AND it is **not** the task we just changed to a terminal status (done/blocked/skipped) -> `current_task` = that task's id.
41
- 2. Otherwise pick the first task (by array order) where:
42
- - `status == pending`
43
- - All ids in `depends_on` reference tasks with status `done`
44
- 3. If no such task exists AND every task is `done` -> set `plan.status = done`, `current_task = null`.
45
- 4. If no such task exists but some tasks are still `pending` (because their dependencies are not done -- e.g., everything reachable is blocked) -> set `current_task = null`, leave `plan.status = in_progress`. Surface a warning in the output ("All remaining tasks are blocked by dependencies; resolve a blocker before continuing").
48
+ The script performs, deterministically:
46
49
 
47
- If the selected next task is currently `pending` -> promote it to `in_progress` (so the plan accurately reflects the active focus). Skip this promotion if `plan.status` just transitioned to `done`.
50
+ 1. **Apply**: sets the task status; appends + de-duplicates `--artifacts` (handles `artifacts: null`); overwrites `--notes`; sets `completed_at` to now when status is `done`, else `null`; refreshes `plan.updated_at`.
51
+ 2. **Recompute `current_task`** (same rules as before): an `in_progress` task that is not the one just moved to terminal wins; else the first `pending` task whose `depends_on` are all `done` (promoted to `in_progress`); else if all tasks are `done` set `plan.status = done` and `current_task = null`; else `current_task = null` with a blocked-by-dependencies warning.
52
+ 3. **Validate** the mutated plan (unique ids, valid `depends_on` references, DAG/no-cycle, ≤1 `in_progress`, every task has acceptance, `completed_at` consistency, `current_task` validity).
53
+ 4. **Write atomically** (temp + rename) only if validation passes.
48
54
 
49
- ### Step 5: Validate and Write
55
+ **Interpreting the result:**
50
56
 
51
- 1. Run the plan validator on the mutated structure.
52
- 2. If validation fails -> abort the write, report the validation errors, leave the original file untouched.
53
- 3. Otherwise, write back to `active_change.plan_path`.
57
+ - **Exit 0**: success. stdout is a single-line JSON object:
58
+ ```json
59
+ {"ok":true,"task":{"id":"t1","title":"...","old_status":"in_progress","new_status":"done"},"current_task":"t2","plan_status":"in_progress","progress":{"done":1,"total":4},"warning":null}
60
+ ```
61
+ Use these fields directly to render the Output Format block. The file is already written — do NOT read it back to verify. If `warning` is non-null, surface it.
62
+ - **Exit 1**: failure. stderr carries the error (invalid status, task not found, validation failure, parse/write error). The file was **not** modified. Report the error to the user and do not fabricate a success summary.
54
63
 
55
- ### Step 6: Update Session State
56
-
57
- Apply the State Update rules defined in the **State Update** section below, AND the update-plan-specific updates:
58
-
59
- - Refresh the matching entry in `changes[]`: `updated_at` -> current ISO 8601 timestamp.
60
- - Do NOT touch `active_change.plan_path`.
61
-
62
- ### Step 7: Output
64
+ ### Step 4: Output
63
65
 
64
66
  Emit the Plan Update summary block defined in the Output Format section. Include:
65
67
 
@@ -46,6 +46,9 @@ sections:
46
46
  - type: shared
47
47
  source: sections/output-language-constraint.md
48
48
 
49
+ - type: shared
50
+ source: sections/output-format-constraint.md
51
+
49
52
  - type: shared
50
53
  source: sections/activation-preflight.md
51
54
  params: