@osovv/vv-opencode 1.3.6-rc.6 → 1.3.6-rc.7
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.
- package/CHANGELOG.md +8 -0
- package/README.md +32 -2
- package/dist/cli.js +5 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/lint.d.ts +74 -0
- package/dist/commands/lint.js +269 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/opencode.js +3 -2
- package/dist/lib/opencode.js.map +1 -1
- package/dist/lib/plugin-toggle-config.d.ts +13 -1
- package/dist/lib/plugin-toggle-config.js +38 -4
- package/dist/lib/plugin-toggle-config.js.map +1 -1
- package/dist/lib/spec-lint-cache.d.ts +34 -0
- package/dist/lib/spec-lint-cache.js +140 -0
- package/dist/lib/spec-lint-cache.js.map +1 -0
- package/dist/lib/spec-lint.d.ts +57 -0
- package/dist/lib/spec-lint.js +963 -0
- package/dist/lib/spec-lint.js.map +1 -0
- package/dist/lib/vvoc-config.d.ts +25 -0
- package/dist/lib/vvoc-config.js +9 -0
- package/dist/lib/vvoc-config.js.map +1 -1
- package/dist/lib/vvoc-paths.d.ts +1 -0
- package/dist/lib/vvoc-paths.js +15 -5
- package/dist/lib/vvoc-paths.js.map +1 -1
- package/dist/plugins/spec-guard/index.d.ts +39 -0
- package/dist/plugins/spec-guard/index.js +251 -0
- package/dist/plugins/spec-guard/index.js.map +1 -0
- package/package.json +6 -2
- package/schemas/vvoc/v3.json +23 -6
- package/templates/skills/vv-execute/SKILL.md +8 -3
- package/templates/skills/vv-plan/SKILL.md +7 -7
- package/templates/skills/vv-plan/references/plan-template.xml +11 -6
- package/templates/skills/vv-spec/SKILL.md +5 -3
- package/templates/skills/vv-spec/references/design-context-template.xml +2 -2
- package/templates/skills/vv-spec/references/spec-template.xml +17 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osovv/vv-opencode",
|
|
3
|
-
"version": "1.3.6-rc.
|
|
3
|
+
"version": "1.3.6-rc.7",
|
|
4
4
|
"description": "An opinionated agentic development layer for OpenCode — spec-first when it matters, review-driven execution, portable model roles, safer tools, and long-run safety.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -85,6 +85,10 @@
|
|
|
85
85
|
"./plugins/peak-hours": {
|
|
86
86
|
"types": "./dist/plugins/peak-hours/index.d.ts",
|
|
87
87
|
"import": "./dist/plugins/peak-hours/index.js"
|
|
88
|
+
},
|
|
89
|
+
"./plugins/spec-guard": {
|
|
90
|
+
"types": "./dist/plugins/spec-guard/index.d.ts",
|
|
91
|
+
"import": "./dist/plugins/spec-guard/index.js"
|
|
88
92
|
}
|
|
89
93
|
},
|
|
90
94
|
"scripts": {
|
|
@@ -97,7 +101,7 @@
|
|
|
97
101
|
"grace:check": "bun scripts/check-grace-markup.ts",
|
|
98
102
|
"test": "bun test",
|
|
99
103
|
"check": "bun run typecheck && bun run lint && bun run fmt:check && bun run grace:check && bun test",
|
|
100
|
-
"pack:check": "bun run build && bun -e \"const root = await import('./dist/index.js'); if (!('GuardianPlugin' in root)) throw new Error('dist root export missing GuardianPlugin'); if (!('HashlineEditPlugin' in root)) throw new Error('dist root export missing HashlineEditPlugin'); if (!('ModelRolesPlugin' in root)) throw new Error('dist root export missing ModelRolesPlugin'); if (!('SystemContextInjectionPlugin' in root)) throw new Error('dist root export missing SystemContextInjectionPlugin'); if (!('WorkflowPlugin' in root)) throw new Error('dist root export missing WorkflowPlugin'); if (!('SecretsRedactionPlugin' in root)) throw new Error('dist root export missing SecretsRedactionPlugin'); if (!('WebToolsPlugin' in root)) throw new Error('dist root export missing WebToolsPlugin'); if (!('AnalyticsPlugin' in root)) throw new Error('dist root export missing AnalyticsPlugin'); if (!('PeakHoursPlugin' in root)) throw new Error('dist root export missing PeakHoursPlugin'); const tui = await import('./dist/tui.js'); if (!tui.default || typeof tui.default.tui !== 'function') throw new Error('dist TUI export missing default tui module'); await import('./dist/plugins/guardian/index.js'); await import('./dist/plugins/hashline-edit/index.js'); await import('./dist/plugins/model-roles/index.js'); await import('./dist/plugins/system-context-injection/index.js'); await import('./dist/plugins/workflow/index.js'); await import('./dist/plugins/secrets-redaction/index.js'); await import('./dist/plugins/web-tools/index.js'); await import('./dist/plugins/analytics/index.js'); await import('./dist/plugins/peak-hours/index.js')\" && npm pack --dry-run",
|
|
104
|
+
"pack:check": "bun run build && bun -e \"const root = await import('./dist/index.js'); if (!('GuardianPlugin' in root)) throw new Error('dist root export missing GuardianPlugin'); if (!('HashlineEditPlugin' in root)) throw new Error('dist root export missing HashlineEditPlugin'); if (!('ModelRolesPlugin' in root)) throw new Error('dist root export missing ModelRolesPlugin'); if (!('SystemContextInjectionPlugin' in root)) throw new Error('dist root export missing SystemContextInjectionPlugin'); if (!('WorkflowPlugin' in root)) throw new Error('dist root export missing WorkflowPlugin'); if (!('SecretsRedactionPlugin' in root)) throw new Error('dist root export missing SecretsRedactionPlugin'); if (!('WebToolsPlugin' in root)) throw new Error('dist root export missing WebToolsPlugin'); if (!('AnalyticsPlugin' in root)) throw new Error('dist root export missing AnalyticsPlugin'); if (!('PeakHoursPlugin' in root)) throw new Error('dist root export missing PeakHoursPlugin'); if (!('SpecGuardPlugin' in root)) throw new Error('dist root export missing SpecGuardPlugin'); const tui = await import('./dist/tui.js'); if (!tui.default || typeof tui.default.tui !== 'function') throw new Error('dist TUI export missing default tui module'); await import('./dist/plugins/guardian/index.js'); await import('./dist/plugins/hashline-edit/index.js'); await import('./dist/plugins/model-roles/index.js'); await import('./dist/plugins/system-context-injection/index.js'); await import('./dist/plugins/workflow/index.js'); await import('./dist/plugins/secrets-redaction/index.js'); await import('./dist/plugins/web-tools/index.js'); await import('./dist/plugins/analytics/index.js'); await import('./dist/plugins/peak-hours/index.js'); await import('./dist/plugins/spec-guard/index.js')\" && npm pack --dry-run",
|
|
101
105
|
"tui:local": "bun scripts/tui-local.ts",
|
|
102
106
|
"release:check": "bun scripts/release-check.ts",
|
|
103
107
|
"release:bump": "bun scripts/release-bump.ts",
|
package/schemas/vvoc/v3.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://cdn.jsdelivr.net/npm/@osovv/vv-opencode@1.3.6-rc.
|
|
3
|
+
"$id": "https://cdn.jsdelivr.net/npm/@osovv/vv-opencode@1.3.6-rc.7/schemas/vvoc/v3.json",
|
|
4
4
|
"title": "vvoc config",
|
|
5
5
|
"description": "Canonical vvoc configuration document.",
|
|
6
6
|
"type": "object",
|
|
@@ -393,11 +393,28 @@
|
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
},
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
396
|
+
"required": [
|
|
397
|
+
"windows"
|
|
398
|
+
],
|
|
399
|
+
"additionalProperties": false
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
"additionalProperties": false
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
"type": "object",
|
|
407
|
+
"description": "spec-guard plugin entry: enabled plus lint enforcement mode warn or enforce.",
|
|
408
|
+
"properties": {
|
|
409
|
+
"enabled": {
|
|
410
|
+
"type": "boolean"
|
|
411
|
+
},
|
|
412
|
+
"mode": {
|
|
413
|
+
"type": "string",
|
|
414
|
+
"enum": [
|
|
415
|
+
"warn",
|
|
416
|
+
"enforce"
|
|
417
|
+
]
|
|
401
418
|
}
|
|
402
419
|
},
|
|
403
420
|
"additionalProperties": false
|
|
@@ -38,11 +38,15 @@ Do not mutate files until the execution mode is explicit. In classic mode, deleg
|
|
|
38
38
|
</helper>
|
|
39
39
|
<helper name="architecture">
|
|
40
40
|
<command>sed -n '/<architecture>/,/<\/architecture>/p' PLAN_PATH</command>
|
|
41
|
-
<purpose>Extract full architecture section with
|
|
41
|
+
<purpose>Extract full architecture section with components, files, contracts</purpose>
|
|
42
42
|
</helper>
|
|
43
43
|
<helper name="module-list">
|
|
44
|
-
<command>
|
|
45
|
-
<purpose>List all
|
|
44
|
+
<command>grep '<COMPONENT-' PLAN_PATH</command>
|
|
45
|
+
<purpose>List all architecture component identities (COMPONENT-UPPER-SLUG element names, mirrored from spec.xml)</purpose>
|
|
46
|
+
</helper>
|
|
47
|
+
<helper name="extract-component">
|
|
48
|
+
<command>sed -n '/<COMPONENT-UPPER-SLUG>/,/<\/COMPONENT-UPPER-SLUG>/p' PLAN_PATH</command>
|
|
49
|
+
<purpose>Extract one full architecture component by slug (replace COMPONENT-UPPER-SLUG with the actual element name, e.g. COMPONENT-CACHE-STORE)</purpose>
|
|
46
50
|
</helper>
|
|
47
51
|
<helper name="list-tasks">
|
|
48
52
|
<command>grep '<TASK-T-' PLAN_PATH</command>
|
|
@@ -107,6 +111,7 @@ Do not mutate files until the execution mode is explicit. In classic mode, deleg
|
|
|
107
111
|
<check>Each task element name matches the TASK-T-NNN pattern and the task has non-empty <title> and <file>. There is no child id element — identity lives in the element name.</check>
|
|
108
112
|
<check>Each task has <snippet> (may be empty but must exist)</check>
|
|
109
113
|
<check>Each task has <acceptance> with at least one <criterion></check>
|
|
114
|
+
<check>Plan architecture components use COMPONENT-UPPER-SLUG element names and every component exists in the linked spec's components section — plan components are a subset of spec components</check>
|
|
110
115
|
<action>If any check fails, stop and report the issue with line numbers. Do not proceed with broken plan.</action>
|
|
111
116
|
</step>
|
|
112
117
|
<step name="assess-complexity">
|
|
@@ -34,13 +34,13 @@ You are the vv-plan skill. Your job is to take an approved spec and write an imp
|
|
|
34
34
|
<rule>Load the plan template from references/plan-template.xml. Fill every element.</rule>
|
|
35
35
|
<rule>The top-level <status> element is the plan lifecycle status and MUST be one of: draft, approved, applied.</rule>
|
|
36
36
|
<rule>When first saving the plan, set the top-level status to <status>draft</status>. Only change it to approved after the user explicitly reads/reviews and approves the final plan. Never set the top-level status to applied yourself; applied is reserved for vv-execute after successful execution.</rule>
|
|
37
|
-
<rule>The plan contains two major sections: architecture (
|
|
38
|
-
<rule>Architecture
|
|
37
|
+
<rule>The plan contains two major sections: architecture (components, contracts, dependencies) and tasks (implementation steps with code snippets).</rule>
|
|
38
|
+
<rule>Architecture maps the spec's components. Each architecture element reuses the exact COMPONENT-UPPER-SLUG identity declared in spec.xml: <COMPONENT-CACHE-STORE>…</COMPONENT-CACHE-STORE>. Plan components are always a subset of spec components — a plan module without a spec component does not exist. Architecture child tags: name (display name from the spec), purpose, file (path, role), contract, depends_on (bare component slug). Do NOT add a child id element.</rule>
|
|
39
39
|
<rule>Tasks are grouped into wave elements whose identity is the element name: <WAVE-1>, <WAVE-2>, … Each wave contains a <goal> and its tasks.</rule>
|
|
40
40
|
<rule>A task's identity is its element name in the TASK-T-NNN pattern: <TASK-T-001>…</TASK-T-001>. The identity repeats on both boundaries so long blocks stay addressable. Tasks use child tags: title, file, status, description, depends_on (task_id), snippet (CDATA), acceptance (criterion), verification (command). Do NOT add a child id element — the element name is the single authoritative identity. Task-level <status> values are separate from the top-level plan lifecycle status and may remain pending until execution updates them.</rule>
|
|
41
|
-
<rule>Every XML element is named for grep extraction. Use: `grep '<TASK-T-' plan.xml` to list tasks, `grep '<criterion>' plan.xml` for all criteria, `grep '<task_id>' plan.xml` for dependency graph.</rule>
|
|
41
|
+
<rule>Every XML element is named for grep extraction. Use: `grep '<TASK-T-' plan.xml` to list tasks, `grep '<criterion>' plan.xml` for all criteria, `grep '<task_id>' plan.xml` for dependency graph, `grep '<COMPONENT-' plan.xml` for the component map.</rule>
|
|
42
42
|
<rule>Populate the <spec> element with the path to the spec.xml this plan implements.</rule>
|
|
43
|
-
<rule>If a design-context.xml was found and read as explanatory context, populate the <
|
|
43
|
+
<rule>If a design-context.xml was found and read as explanatory context, populate the <design_context> element with the path to design-context.xml so execution tools and reviewers can locate it.</rule>
|
|
44
44
|
<location>Save plan.xml as a sibling of spec.xml in the same spec package directory: .vvoc/specs/<id>/plan.xml</location>
|
|
45
45
|
</plan_document_format>
|
|
46
46
|
|
|
@@ -142,7 +142,7 @@ export type CacheStoreOptions = {
|
|
|
142
142
|
<forbidden>XML attributes in any tag — use child elements only</forbidden>
|
|
143
143
|
<forbidden>Code outside CDATA — all snippets must be wrapped in CDATA sections</forbidden>
|
|
144
144
|
<forbidden>Numbered criterion tags — use plain <criterion>, not numbered variants</forbidden>
|
|
145
|
-
<forbidden>Generic <task> or <
|
|
145
|
+
<forbidden>Generic <task>, <wave>, or <module> elements with child id/num elements — identity belongs in the element name: <TASK-T-NNN>, <WAVE-N>, <COMPONENT-UPPER-SLUG></forbidden>
|
|
146
146
|
</no_placeholders>
|
|
147
147
|
|
|
148
148
|
<self_review>
|
|
@@ -152,7 +152,7 @@ export type CacheStoreOptions = {
|
|
|
152
152
|
<check>Type consistency: Do types, signatures, and property names match across tasks? A function called `clearLayers()` in Task 3 but `clearFullLayers()` in Task 7 is a bug.</check>
|
|
153
153
|
<rule>Fix issues inline as you find them. No second review pass needed — just fix and continue.</rule>
|
|
154
154
|
<check>Format compliance: Are there zero XML attributes? Is every snippet in CDATA? Is every task a <TASK-T-NNN> element with identity in the element name and no child id element?</check>
|
|
155
|
-
<check>Architecture presence: Does the plan have an architecture section with
|
|
155
|
+
<check>Architecture presence: Does the plan have an architecture section with components, contracts, and dependency graph? Does every <COMPONENT-UPPER-SLUG> element exist in the spec's components section — plan components are a subset of spec components?</check>
|
|
156
156
|
</self_review>
|
|
157
157
|
|
|
158
158
|
<execution_handoff>
|
|
@@ -167,6 +167,6 @@ export type CacheStoreOptions = {
|
|
|
167
167
|
</execution_handoff>
|
|
168
168
|
|
|
169
169
|
<task>
|
|
170
|
-
Your current task is the ongoing user request. Read the approved spec at .vvoc/specs/<id>/spec.xml and verify its top-level status is approved. Check whether a sibling design-context.xml exists; if so, read it as explanatory context only (it does NOT override spec.xml). Load the plan template from references/plan-template.xml, populate <spec> and optionally <
|
|
170
|
+
Your current task is the ongoing user request. Read the approved spec at .vvoc/specs/<id>/spec.xml and verify its top-level status is approved. Check whether a sibling design-context.xml exists; if so, read it as explanatory context only (it does NOT override spec.xml). Load the plan template from references/plan-template.xml, populate <spec> and optionally <design_context> paths, map the architecture (spec components as COMPONENT-UPPER-SLUG elements, contracts, dependencies), write detailed tasks with code snippets in CDATA, apply self-review, save the plan as .vvoc/specs/<id>/plan.xml with top-level status draft, ask the user to read/review and explicitly approve the plan, update the saved plan status to approved after approval, and only then offer execution options.
|
|
171
171
|
</task>
|
|
172
172
|
</skill>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<plan>
|
|
2
2
|
<spec></spec>
|
|
3
|
-
<
|
|
3
|
+
<design_context></design_context> <!-- optional, populated when sibling file exists -->
|
|
4
4
|
<created></created>
|
|
5
5
|
<status>draft</status>
|
|
6
6
|
|
|
@@ -12,7 +12,14 @@
|
|
|
12
12
|
</meta>
|
|
13
13
|
|
|
14
14
|
<architecture>
|
|
15
|
-
|
|
15
|
+
<!--
|
|
16
|
+
Architecture maps the spec's components. Each element reuses the
|
|
17
|
+
exact COMPONENT-UPPER-SLUG identity declared in spec.xml — plan
|
|
18
|
+
components are always a subset of spec components. The child
|
|
19
|
+
<name> element repeats the spec's display name. depends_on holds
|
|
20
|
+
bare component slugs declared in this plan or the spec.
|
|
21
|
+
-->
|
|
22
|
+
<COMPONENT-EXAMPLE>
|
|
16
23
|
<name></name>
|
|
17
24
|
<purpose></purpose>
|
|
18
25
|
<file>
|
|
@@ -21,10 +28,8 @@
|
|
|
21
28
|
</file>
|
|
22
29
|
<contract>
|
|
23
30
|
</contract>
|
|
24
|
-
<depends_on>
|
|
25
|
-
|
|
26
|
-
</depends_on>
|
|
27
|
-
</module>
|
|
31
|
+
<depends_on></depends_on>
|
|
32
|
+
</COMPONENT-EXAMPLE>
|
|
28
33
|
</architecture>
|
|
29
34
|
|
|
30
35
|
<tasks>
|
|
@@ -25,11 +25,11 @@ UX cues (roadmap, progress markers, depth estimates, checkpoints) are TRANSPAREN
|
|
|
25
25
|
<principle>Understand the full landscape: purpose, constraints, success criteria, non-goals, edge cases, existing code patterns.</principle>
|
|
26
26
|
<principle>When the decision tree reaches a fork (2-3 viable approaches), present all options with trade-offs. Lead with your recommendation and explain why. The user picks one — that closes the fork and the tree continues from that branch.</principle>
|
|
27
27
|
<principle>When presenting design sections, do it one section at a time. After each section: "Does this look right?" If yes, move to the next. If no, resolve concerns before continuing.</principle>
|
|
28
|
-
<principle>Cover every section of the spec template: goal, architecture,
|
|
28
|
+
<principle>Cover every section of the spec template: goal, architecture, tech_stack, components, data_flow, error_handling, testing, non_goals. The roadmap shown at the start IS the coverage checklist. A section is "closed" only when its template element is fully decidable.</principle>
|
|
29
29
|
<principle>YAGNI ruthlessly: prune dead branches — remove unnecessary features from every approach.</principle>
|
|
30
30
|
<principle>After design is confirmed, synthesize the spec yourself. You are the expensive model — deep analysis and architectural design are your responsibility, not a subagent's.</principle>
|
|
31
31
|
<principle>Maintain a structured internal decision/rationale ledger during the interview. For each decision point, track: the decision, options considered, chosen option, rationale, rejected alternatives (with reasons), and any assumptions, deferred decisions, or revisit triggers. This ledger is the raw material for design-context.xml — it is synthesized from curated decisions, not reconstructed from conversation memory.</principle>
|
|
32
|
-
<principle>Open the interview with a DECISION-TREE ROADMAP: show the spec template sections (goal, architecture,
|
|
32
|
+
<principle>Open the interview with a DECISION-TREE ROADMAP: show the spec template sections (goal, architecture, tech_stack, components, data_flow, error_handling, testing, non_goals) AND the major forks that may arise within each. State traversal order (highest-impact first). The purpose is predictability of the full landscape, not brevity — the user is working, so a large honest surface is welcome. Note the tree is dynamic: the branch actually taken depends on answers, but every reachable fork is shown up front.</principle>
|
|
33
33
|
<principle>Mark the CURRENT SECTION on every question message (a short header). The user must always know their location in the tree. This reduces disorientation in long interviews; it does not skip content.</principle>
|
|
34
34
|
<principle>After the first substantive exchange, give an HONEST DEPTH ESTIMATE (approximate decision points remaining). If the estimate is high (roughly 12–15+), do NOT shorten the interview. Surface it as a signal that the prompt/context needs upgrading: offer the user ways to provide richer context up front (existing PRD, requirements doc, reference project, voice description), or propose decomposition into sub-projects. A large estimate means MORE context, not fewer questions.</principle>
|
|
35
35
|
<principle>After closing each section, post a ONE-LINE RECAP of the decisions made in it, then show what sections remain. This is a coherence checkpoint — every branch inside the section was already walked to its leaf, so the recap confirms fixation rather than skipping deliberation. It lets the user catch a misunderstanding immediately instead of discovering it in the final spec.</principle>
|
|
@@ -46,7 +46,9 @@ UX cues (roadmap, progress markers, depth estimates, checkpoints) are TRANSPAREN
|
|
|
46
46
|
|
|
47
47
|
<spec_document_format>
|
|
48
48
|
<rule>Load the spec template from references/spec-template.xml. Fill every element with the decisions confirmed during the interview.</rule>
|
|
49
|
-
<rule>Do not invent new elements beyond what the template defines. The template IS the contract.</rule>
|
|
49
|
+
<rule>Do not invent new elements beyond what the template defines. The template IS the contract. Field names use snake_case only.</rule>
|
|
50
|
+
<rule>A component's identity is its element name in the COMPONENT-UPPER-SLUG pattern: <COMPONENT-CACHE-STORE>…</COMPONENT-CACHE-STORE>. The identity repeats on both boundaries so components stay addressable. Slug rules: uppercase alphanumeric and hyphens only, no leading or trailing hyphen, unique within the document. Derive the slug from the component's display name. The child <name> element holds the human-readable display name. Do NOT add a child id element — the element name is the single authoritative identity.</rule>
|
|
51
|
+
<rule>Component references use bare slugs: each <depends_on> element contains exactly one component slug declared elsewhere in the same components section. Never reference a component by prose name.</rule>
|
|
50
52
|
<rule>The top-level <status> element is the document lifecycle status and MUST be one of: draft, approved, applied.</rule>
|
|
51
53
|
<rule>When first saving the spec, set <status>draft</status>. Only change it to approved after the user explicitly approves the final spec. Never set applied yourself; applied is reserved for vv-execute after the approved plan has been fully executed.</rule>
|
|
52
54
|
<location>Canonical layout — all artifacts for one feature live in a single spec package directory:</location>
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
</assumption>
|
|
41
41
|
</assumptions>
|
|
42
42
|
<deferred>
|
|
43
|
-
<
|
|
43
|
+
<deferred_decision>
|
|
44
44
|
<decision></decision>
|
|
45
45
|
<why_deferred></why_deferred>
|
|
46
46
|
<revisit_trigger></revisit_trigger>
|
|
47
|
-
</
|
|
47
|
+
</deferred_decision>
|
|
48
48
|
</deferred>
|
|
49
49
|
<scenarios>
|
|
50
50
|
<scenario>
|
|
@@ -2,21 +2,29 @@
|
|
|
2
2
|
<status>draft</status>
|
|
3
3
|
<goal></goal>
|
|
4
4
|
<architecture></architecture>
|
|
5
|
-
<
|
|
5
|
+
<tech_stack></tech_stack>
|
|
6
6
|
<components>
|
|
7
|
-
|
|
7
|
+
<!--
|
|
8
|
+
Each component's identity is its element name: COMPONENT-UPPER-SLUG.
|
|
9
|
+
Slug rules: uppercase alphanumeric and hyphens only, must not start
|
|
10
|
+
or end with a hyphen, unique within this document. Derive the slug
|
|
11
|
+
from the component's display name (for example "Cache Store" ->
|
|
12
|
+
COMPONENT-CACHE-STORE). References (depends_on) use the bare slug.
|
|
13
|
+
Keep the child <name> element as the human-readable display name.
|
|
14
|
+
-->
|
|
15
|
+
<COMPONENT-EXAMPLE>
|
|
8
16
|
<name></name>
|
|
9
17
|
<responsibility></responsibility>
|
|
10
|
-
<
|
|
11
|
-
</
|
|
18
|
+
<depends_on></depends_on>
|
|
19
|
+
</COMPONENT-EXAMPLE>
|
|
12
20
|
</components>
|
|
13
|
-
<
|
|
14
|
-
<
|
|
21
|
+
<data_flow></data_flow>
|
|
22
|
+
<error_handling></error_handling>
|
|
15
23
|
<testing>
|
|
16
24
|
<strategy></strategy>
|
|
17
25
|
<coverage></coverage>
|
|
18
26
|
</testing>
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
</
|
|
27
|
+
<non_goals>
|
|
28
|
+
<non_goal></non_goal>
|
|
29
|
+
</non_goals>
|
|
22
30
|
</spec>
|