aw-spec-cli 0.1.19 → 0.1.21
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/assets/.appweaver/DESIGN-FORMAT.md +17 -9
- package/assets/.appweaver/ORCH-DIALECT.md +8 -3
- package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +26 -3
- package/assets/.appweaver/orchestrator/orchestrator.py +65 -3
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +4 -2
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +121 -42
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan-delta.orch.yaml +7 -7
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-plan.orch.yaml +145 -52
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice-delta.orch.yaml +18 -10
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +306 -28
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +4 -4
- package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +114 -30
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +140 -36
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +385 -61
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +217 -174
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +407 -107
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-plan.orch.yaml +49 -11
- package/assets/.appweaver/orchestrator/workflows/aw-spec-recall-delta.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +1 -1
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +29 -23
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +47 -23
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +19 -11
- package/assets/.appweaver/scripts/bash/aw-inventory.sh +15 -0
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +683 -92
- package/assets/.appweaver/scripts/bash/aw-xref.sh +3 -0
- package/assets/.appweaver/scripts/powershell/aw-inventory.ps1 +15 -0
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +625 -64
- package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +3 -0
- package/assets/.appweaver/scripts/python/aw-crstate.py +194 -0
- package/assets/.appweaver/scripts/python/aw-foundation.py +151 -0
- package/assets/.appweaver/scripts/python/aw-inventory.py +1829 -63
- package/assets/.appweaver/scripts/python/aw-payload-parity.py +3 -0
- package/assets/.appweaver/scripts/python/aw-plan-coverage.py +423 -0
- package/assets/.appweaver/scripts/python/aw-stack.py +251 -28
- package/assets/.appweaver/scripts/python/aw-testlog.py +148 -0
- package/assets/.appweaver/scripts/python/aw-xref.py +500 -81
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +1 -0
- package/assets/.appweaver/stack-profiles/java-spring.json +1 -0
- package/assets/.appweaver/stack-profiles/node-express.json +1 -0
- package/assets/.appweaver/stack-profiles/python-fastapi.json +1 -0
- package/assets/.appweaver/templates/constitution-domain-template.md +17 -2
- package/assets/.appweaver/templates/delta-design-template.md +1 -1
- package/assets/.appweaver/templates/delta-domain-model-template.md +1 -1
- package/assets/.appweaver/templates/delta-spec-template.md +4 -3
- package/assets/.appweaver/templates/design-template.md +16 -11
- package/assets/.appweaver/templates/okf-concept-template.md +11 -1
- package/assets/.appweaver/templates/proposed-inventory-template.md +127 -0
- package/assets/.appweaver/templates/source-map-template.md +5 -3
- package/assets/.appweaver/templates/spec-template.md +17 -17
- package/assets/.appweaver/templates/ui-delta-design-template.md +1 -1
- package/assets/.appweaver/templates/ui-design-template.md +4 -4
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +4489 -361
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +2274 -125
- package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +10 -6
- package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +4 -0
- package/assets/guardrails/technology/dotnet-webapi/auditing.md +3 -1
- package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +5 -3
- package/assets/guardrails/technology/dotnet-webapi/cqrs.md +5 -1
- package/assets/guardrails/technology/dotnet-webapi/domain-driven-design.md +13 -5
- package/assets/guardrails/technology/dotnet-webapi/examples/cqrs.md +2 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/domain-driven-design.md +6 -2
- package/assets/guardrails/technology/dotnet-webapi/framework-api-map.md +70 -0
- package/assets/guardrails/technology/dotnet-webapi/technology-constitution.md +3 -0
- package/assets/guardrails/technology/dotnet-webapi/testing.md +10 -0
- package/assets/guardrails/technology/nextjs/ui-constitution.md +8 -1
- package/package.json +1 -1
- package/assets/.appweaver/orchestrator/.state/smoke.state.json +0 -32
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
project reverse-engineered by `onboard` that map points at the project's OWN generated
|
|
8
8
|
domain rule files and its own charter, both derived from the code — same partition, a
|
|
9
9
|
different corpus. It carries ONLY domain-specific material:
|
|
10
|
-
the domain principles, domain identifiers/terminology, regulatory
|
|
11
|
-
interoperability surfaces, and domain governance overrides.
|
|
10
|
+
the project identity, the domain principles, domain identifiers/terminology, regulatory
|
|
11
|
+
regime, interoperability surfaces, and domain governance overrides.
|
|
12
12
|
|
|
13
13
|
══ THIS FILE IS SHAPE. THE MAPPED CORPUS IS CONTENT. ═════════════════════════════
|
|
14
14
|
This template is part of the kit and governs projects in any industry. It therefore
|
|
@@ -35,6 +35,21 @@
|
|
|
35
35
|
the detail. That keeps the authority/detail overlap to one line.
|
|
36
36
|
-->
|
|
37
37
|
|
|
38
|
+
## Project Identity
|
|
39
|
+
|
|
40
|
+
[PROJECT_IDENTITY_CONTENT]
|
|
41
|
+
<!--
|
|
42
|
+
Form: what this project IS in its domain — the regulated role it plays, the bounded
|
|
43
|
+
contexts it is organised into, and who consumes it and through what surface — each as a
|
|
44
|
+
short labelled line. Take them from the mapped charter's own identity section. Where the
|
|
45
|
+
project's domain-requirements states a different value (a different context list, a
|
|
46
|
+
narrower role), the project value is a DEVIATION: ratify it here, naming the charter line
|
|
47
|
+
it departs from and who approved it.
|
|
48
|
+
|
|
49
|
+
This section exists because specify loads THIS file and not the charter, so it is the
|
|
50
|
+
only way the project's contexts and consumers reach specify.
|
|
51
|
+
-->
|
|
52
|
+
|
|
38
53
|
## Adopted Modelling Standard
|
|
39
54
|
|
|
40
55
|
[MODELLING_STANDARD_STATEMENT]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Bounded context**: `[Context]`
|
|
4
4
|
|
|
5
|
-
**Feature
|
|
5
|
+
**Feature**: `[Feature]` <!-- the feature whose change this is; the aggregates it changes are listed under "Aggregates touched" -->
|
|
6
6
|
|
|
7
7
|
**Wave**: [N] <!-- script-stamped; same wave = developable in parallel, higher wave = after -->
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Delta Spec — [CR-ID]: [TITLE]
|
|
2
2
|
|
|
3
|
-
**Feature
|
|
3
|
+
**Feature**: [Feature]
|
|
4
4
|
|
|
5
5
|
**Change type**: [new-requirement | changed-requirement | defect | refactor]
|
|
6
6
|
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
Standards (UX-n). A CR that changes a retention/audit rule, a data-exposure rule, an
|
|
22
22
|
interop obligation or a project-wide experience standard is a CN-/DC-/IC-/UX- delta, not
|
|
23
23
|
a smuggled code change. A UX- delta states the standard only — never a screen, page or
|
|
24
|
-
component, which the prototype and frontend-plan.md settle. Adding a command
|
|
25
|
-
UpdateOrder to
|
|
24
|
+
component, which the prototype and frontend-plan.md settle. Adding a command to THIS
|
|
25
|
+
feature (e.g. UpdateOrder to Order) is a new user story (US-n). Whether a capability is
|
|
26
|
+
a feature of its own is the developer's decision, made when they select the feature.
|
|
26
27
|
|
|
27
28
|
MODEL CHANGES DO NOT BELONG HERE. A new entity, a changed aggregate boundary or a new
|
|
28
29
|
or amended invariant (BR-n) goes in this change's domain-model delta — the "Model delta"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Backend Plan: [
|
|
1
|
+
# Backend Plan: [FEATURE]
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Feature**: `[Feature]` <!-- the capability scope the developer chose; the aggregate(s) it acts on are the spec's "Acts on aggregate(s)" line -->
|
|
4
4
|
|
|
5
|
-
**Plan home**: `specs/[
|
|
5
|
+
**Plan home**: `specs/[Context]/[Feature]/backend-plan.md`
|
|
6
6
|
|
|
7
|
-
**Source spec**: `specs/[
|
|
7
|
+
**Source spec**: `specs/[Context]/[Feature]/spec.md` <!-- behaviour: what the system must DO -->
|
|
8
8
|
|
|
9
9
|
**Source model**: `specs/[Context]/domain-model.md` <!-- structure: what the domain IS -->
|
|
10
10
|
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
<!--
|
|
16
16
|
WHAT THIS DOCUMENT IS
|
|
17
17
|
=====================
|
|
18
|
-
The single, living High-Level Design (HLD) for ONE
|
|
18
|
+
The single, living High-Level Design (HLD) for ONE feature — the capability scope
|
|
19
|
+
the developer chose, over the aggregate(s) its spec says it acts on. It is the
|
|
19
20
|
MEDIATOR between spec.md (WHAT/WHY, tech-agnostic) and the generated code
|
|
20
21
|
(HOW, tech-specific). It is NOT code: it carries structure, contracts,
|
|
21
22
|
behaviour, and decisions — enough for ANY capable LLM to generate correct,
|
|
@@ -41,9 +42,13 @@
|
|
|
41
42
|
one of the two (BR- in the model; CN-/DC-/IC- in the spec). Realise each of those;
|
|
42
43
|
invent no entity, value object or rule that neither states (if one seems missing,
|
|
43
44
|
record it as an Assumption in §7, never smuggle it in).
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
- One feature = one backend-plan.md. A feature is the capability scope the developer
|
|
46
|
+
chose: it may act on several aggregates, and several features may act on one. Its
|
|
47
|
+
operations (CreateOrder, UpdateOrder…) are USER STORIES here, and a later requirement
|
|
48
|
+
on this feature is a delta on THIS doc, never a new one. An aggregate's shared code
|
|
49
|
+
(its root, entities, value objects, repository) is realised by every plan whose
|
|
50
|
+
feature acts on it: each plan names only the members its feature needs, and the
|
|
51
|
+
code extends the shared file instead of regenerating it.
|
|
47
52
|
|
|
48
53
|
WHAT LIVES ELSEWHERE (do NOT repeat it here — it is identical for every feature)
|
|
49
54
|
- The clean-architecture layering + dependency rule (API → Application → Domain
|
|
@@ -76,13 +81,13 @@
|
|
|
76
81
|
## 0. Design Overview
|
|
77
82
|
|
|
78
83
|
<!--
|
|
79
|
-
One paragraph: the architectural shape of this
|
|
84
|
+
One paragraph: the architectural shape of this feature and the 3–5 decisions
|
|
80
85
|
that matter most (why this boundary, the lifecycle model, the hardest trade-off).
|
|
81
86
|
This is the orientation a reviewer or an LLM reads first. The standing layering /
|
|
82
87
|
dependency rule is NOT restated here — it is the project architecture standard.
|
|
83
88
|
-->
|
|
84
89
|
|
|
85
|
-
[The architectural essence of this
|
|
90
|
+
[The architectural essence of this feature in 3–6 sentences: its purpose, its
|
|
86
91
|
lifecycle spine, the key structural choices specific to it, and the single biggest
|
|
87
92
|
trade-off. Layering follows the project architecture standard (constitution).]
|
|
88
93
|
|
|
@@ -298,7 +303,7 @@ text, and do not add a rule the model does not carry)*
|
|
|
298
303
|
|
|
299
304
|
### 4.3 Wiring & migrations
|
|
300
305
|
|
|
301
|
-
- **Composition**: bind `[Port] → [Adapter]` for this
|
|
306
|
+
- **Composition**: bind `[Port] → [Adapter]` for this feature.
|
|
302
307
|
- **Migrations needed**: [yes → what changes conceptually / no]. The Run phase applies them.
|
|
303
308
|
|
|
304
309
|
## 5. Cross-Cutting Concerns
|
|
@@ -3,6 +3,8 @@ type: aggregate
|
|
|
3
3
|
title: [Aggregate]
|
|
4
4
|
description: [one line — what this aggregate is and the invariant/boundary it guards]
|
|
5
5
|
origin: greenfield
|
|
6
|
+
bounded_context:
|
|
7
|
+
features:
|
|
6
8
|
source_files:
|
|
7
9
|
ui_source_files:
|
|
8
10
|
---
|
|
@@ -17,8 +19,16 @@ ui_source_files:
|
|
|
17
19
|
as it generates the aggregate's code;
|
|
18
20
|
• brownfield — `inventory` seeds it and `adopt` enriches it.
|
|
19
21
|
|
|
22
|
+
A CONCEPT IS AN AGGREGATE, NEVER A FEATURE. A feature is a capability scope the
|
|
23
|
+
developer chose; it may act on several aggregates, and several features may act on
|
|
24
|
+
one. `features:` lists every feature known to act on this aggregate — implement and
|
|
25
|
+
adopt add their feature, and a feature is never removed from it by a later write.
|
|
26
|
+
`bounded_context:` names the context the aggregate belongs to.
|
|
27
|
+
|
|
20
28
|
WHO WRITES WHAT (do not cross these lanes):
|
|
21
|
-
• Frontmatter, Overview, Depends-On →
|
|
29
|
+
• Frontmatter, Overview, Depends-On → the implement/adopt of every feature that
|
|
30
|
+
acts on this aggregate. Depends-On is the
|
|
31
|
+
union over all of them.
|
|
22
32
|
• Cross-References → the OTHER aggregates that USE this one; each
|
|
23
33
|
writes its own row (never hand-edit them here).
|
|
24
34
|
One addition inside the first lane: `analyze-slice` MERGES (never replaces) the files its
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Proposed Inventory
|
|
2
|
+
|
|
3
|
+
<!-- TEMPLATE-NOTE
|
|
4
|
+
This is the TEMPLATE for the document `/appweaver inventory` generates at
|
|
5
|
+
specs/proposed-inventory.md. Every TEMPLATE-NOTE block is stripped on generation,
|
|
6
|
+
so nothing in here reaches the produced file.
|
|
7
|
+
|
|
8
|
+
UNLIKE EVERY OTHER TEMPLATE IN THIS DIRECTORY, THIS ONE IS FILLED BY A SCRIPT,
|
|
9
|
+
NOT BY AN AGENT. aw-inventory.py substitutes each token below with the result of
|
|
10
|
+
its scan. There are no [PLACEHOLDER] tokens for an author to complete — a token
|
|
11
|
+
left in the output is a bug, not an unfinished section.
|
|
12
|
+
|
|
13
|
+
Override it per project at
|
|
14
|
+
.appweaver/templates/overrides/proposed-inventory-template.md to change the
|
|
15
|
+
wording, the ordering or the guidance. Keep every token you want filled; drop
|
|
16
|
+
one and that section simply does not appear.
|
|
17
|
+
|
|
18
|
+
Tokens, each written in single braces:
|
|
19
|
+
root · head · date · strategy · reason · files · code · coverage
|
|
20
|
+
probe_table · context_table · feature_table
|
|
21
|
+
splits_section · cycles_section
|
|
22
|
+
-->
|
|
23
|
+
<!-- Generated by `/appweaver inventory`. Edit freely, then run
|
|
24
|
+
`/appweaver inventory apply`. -->
|
|
25
|
+
|
|
26
|
+
**Repository:** `{root}` · **Commit:** `{head}` · **Generated:** {date}
|
|
27
|
+
**Pass A strategy:** `{strategy}` — {reason}
|
|
28
|
+
**Scanned:** {files} files, {code} source files · **Coverage:** {coverage}%
|
|
29
|
+
|
|
30
|
+
This file is the **boundary map for this codebase, and it is yours to change.** Nothing
|
|
31
|
+
below was decided by a person yet — it is what a deterministic scan of the source
|
|
32
|
+
proposes. Read it, correct it, then run `/appweaver inventory apply`, which validates
|
|
33
|
+
your edits and regenerates the machine map that `/appweaver onboard` reads.
|
|
34
|
+
|
|
35
|
+
## How to edit this file
|
|
36
|
+
|
|
37
|
+
- **Rename** a feature or a bounded context by editing its cell. Names are the
|
|
38
|
+
identity — renaming a feature here renames the slice onboard will create.
|
|
39
|
+
- **Move** a feature to another context by editing its Bounded Context cell.
|
|
40
|
+
A feature lives in exactly one context.
|
|
41
|
+
- **Merge** two features by giving them the same name; their files combine, and the
|
|
42
|
+
merged feature acts on every aggregate its rows name — that is how one feature spans
|
|
43
|
+
several aggregates. Keep those rows in the same Bounded Context.
|
|
44
|
+
- **Split** a feature by adding a row with the same Aggregate and a different
|
|
45
|
+
Feature name. Name the split from the capability, not the noun —
|
|
46
|
+
`PatientRegistration`, not a second `Patient`.
|
|
47
|
+
- **Reorder** by editing Depends On. Waves are recomputed on apply, so you do
|
|
48
|
+
not maintain wave numbers by hand.
|
|
49
|
+
- Rows you delete are dropped from the map and never onboarded.
|
|
50
|
+
|
|
51
|
+
The Aggregate column must name an aggregate the scan found; everything else is
|
|
52
|
+
yours. `apply` reports anything it cannot resolve rather than guessing.
|
|
53
|
+
|
|
54
|
+
## How these boundaries were found
|
|
55
|
+
|
|
56
|
+
Three passes over the source. None of them reads a specification, a rule file or an
|
|
57
|
+
exemplar from another project — the code is the only evidence.
|
|
58
|
+
|
|
59
|
+
**Pass A — what must stay consistent together.** Groups the source into candidate
|
|
60
|
+
aggregates. Three strategies can do this, and only those the evidence supports are
|
|
61
|
+
offered:
|
|
62
|
+
|
|
63
|
+
| strategy | the evidence it reads | available when |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `structure` | the repo's own organising axis — a vertical slice, a layer folder under a module, a layer carried as a project-name suffix, or a layer at the top with the module repeated as a noun | always |
|
|
66
|
+
| `reference` | the `using` / `import` / `require` graph, clustered after removing the high-fan-in nodes that are shared kernel rather than features | enough import-parseable source |
|
|
67
|
+
| `persistence` | the schema itself — `DbSet<T>`, `[Table]`, JPA `@Entity`, `schema.prisma`, `CREATE TABLE` — with roots derived by ownership: an entity that owns others' lifecycles and is referenced from outside by id | ORM / schema / migration evidence found |
|
|
68
|
+
|
|
69
|
+
`structure` always runs whichever strategy is chosen, because the other two produce
|
|
70
|
+
unnamed clusters and need it to give each one a directory and a human name.
|
|
71
|
+
|
|
72
|
+
**Pass B — what can be cut over together.** Reads the application, API and UI surface
|
|
73
|
+
only, and emits *signals*, never decisions: route families (`[Route("orders")]`,
|
|
74
|
+
`@RequestMapping`, `app.get('/orders/…')`), command/handler groups, UI router segments,
|
|
75
|
+
and rates of change from git history. **Two distinct route families on one aggregate is
|
|
76
|
+
a split candidate** — proposed below, never applied.
|
|
77
|
+
|
|
78
|
+
Three of the five tests for a feature boundary are computable — one cutover seam,
|
|
79
|
+
stable file ownership, one bounded context — and two are not: whether it serves one
|
|
80
|
+
business need, and whether it can be demonstrated independently. Those two are why this
|
|
81
|
+
file is editable.
|
|
82
|
+
|
|
83
|
+
**Pass C — the proposal.** One aggregate becomes one feature with the same name. That
|
|
84
|
+
is the default and not a failure. A split is proposed only where Pass B found the
|
|
85
|
+
evidence, and is shown with that evidence for you to accept or ignore. One endpoint is
|
|
86
|
+
never a feature; neither is one whole bounded context.
|
|
87
|
+
|
|
88
|
+
**Bounded contexts** are derived above Pass A and voted from where each candidate's
|
|
89
|
+
files actually live. A feature belongs to exactly one context — the context of the
|
|
90
|
+
primary aggregate it acts on. A feature that needs another context's aggregate
|
|
91
|
+
references it by id and stays a separate feature over there.
|
|
92
|
+
|
|
93
|
+
## Strategy probe
|
|
94
|
+
|
|
95
|
+
The clustering each available strategy produced on this tree. The chosen one is
|
|
96
|
+
marked; re-run with `--strategy <name>` to pick another.
|
|
97
|
+
|
|
98
|
+
{probe_table}
|
|
99
|
+
|
|
100
|
+
## Bounded Contexts
|
|
101
|
+
|
|
102
|
+
Onboard one context at a time, in this order. A context is ready when every context it
|
|
103
|
+
depends on has been onboarded.
|
|
104
|
+
|
|
105
|
+
{context_table}
|
|
106
|
+
|
|
107
|
+
## Features
|
|
108
|
+
|
|
109
|
+
Dependency order. **Wave 0 depends on nothing** and can be onboarded first; a feature in
|
|
110
|
+
wave N depends only on features in earlier waves. Edit any cell except Wave, which is
|
|
111
|
+
recomputed.
|
|
112
|
+
|
|
113
|
+
{feature_table}
|
|
114
|
+
{splits_section}{cycles_section}
|
|
115
|
+
## What happens after you apply this
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
/appweaver inventory apply validates these edits, regenerates the machine map
|
|
119
|
+
/appweaver onboard <Context> once per context, in the order above:
|
|
120
|
+
reverse-engineers the governance and creates
|
|
121
|
+
specs/<Context>/<Feature>/ for each feature
|
|
122
|
+
/appweaver adopt <Feature> just-in-time, per feature: reverse-engineers its
|
|
123
|
+
spec, plans and domain-model section
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Re-running `/appweaver inventory` re-derives this file from the code and **discards
|
|
127
|
+
your edits** — apply them first. Re-running `apply` is safe and idempotent.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
# Source Map: [
|
|
1
|
+
# Source Map: [FEATURE]
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Feature**: `[Feature]` <!-- the capability scope confirmed in the boundary map, e.g. MedicinalProduct or PatientRegistration -->
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Acts on aggregate(s)**: `[Aggregate]` <!-- the same names the spec's Domain Model Reference gives -->
|
|
6
|
+
|
|
7
|
+
**Source home**: `specs/[Context]/[Feature]/source-map.md`
|
|
6
8
|
|
|
7
9
|
**Origin**: `reverse-engineered` <!-- greenfield | reverse-engineered | migrated -->
|
|
8
10
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Specification: [
|
|
1
|
+
# Specification: [FEATURE]
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Feature**: `[Feature]` <!-- the capability scope the developer chose, e.g. Order or PatientRegistration; the aggregate(s) it acts on are named under Domain Model Reference -->
|
|
4
4
|
|
|
5
|
-
**Spec home**: `specs/[
|
|
5
|
+
**Spec home**: `specs/[Context]/[Feature]/`
|
|
6
6
|
|
|
7
7
|
**Version**: v1.0 <!-- living truth; every applied change request bumps this — see Change History -->
|
|
8
8
|
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
and is referenced from here by name and id. That split is what lets one aggregate be
|
|
18
18
|
acted on by several specs without any of them owning its definition.
|
|
19
19
|
|
|
20
|
-
Every operation
|
|
21
|
-
|
|
20
|
+
Every operation within this feature's scope (CreateOrder, UpdateOrder, …) is a USER
|
|
21
|
+
STORY below. A later requirement on this feature is a new US-n added as a delta (see
|
|
22
22
|
delta-spec-template.md), never a new spec folder. One spec + one plan per declared
|
|
23
23
|
lane — the PLAN derives from this document and the domain model together.
|
|
24
24
|
|
|
25
25
|
Section order is intentional: establish the business need and scope, then the stable
|
|
26
|
-
core the
|
|
26
|
+
core the feature's BEHAVIOUR is (requirements → constraints → data classification →
|
|
27
27
|
integration contracts → experience standards → edge cases), then the prioritized user
|
|
28
28
|
journeys that exercise it, then measurable success.
|
|
29
29
|
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
## Business Need
|
|
40
40
|
|
|
41
41
|
<!--
|
|
42
|
-
ACTION REQUIRED: Why this
|
|
42
|
+
ACTION REQUIRED: Why this feature exists — the problem, the affected users,
|
|
43
43
|
and the value delivered. Business-facing; no implementation detail.
|
|
44
44
|
-->
|
|
45
45
|
|
|
46
|
-
[The problem this
|
|
46
|
+
[The problem this feature solves, who it serves, and the value it delivers.]
|
|
47
47
|
|
|
48
48
|
## Scope & Assumptions
|
|
49
49
|
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
### Experience Scope
|
|
84
84
|
|
|
85
85
|
<!--
|
|
86
|
-
The experience envelope this
|
|
86
|
+
The experience envelope this feature is specified against: WHO reaches it through a
|
|
87
87
|
UI, THROUGH WHAT, and the floor the frontend lane has to hold. Scope, not requirement —
|
|
88
88
|
it bounds what the Experience Standards and the prototype are held to, and it is the
|
|
89
89
|
only place the spec describes the delivery surface at all.
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
surface to bound: write "None (as of vX.Y)" — never delete the section.
|
|
98
98
|
-->
|
|
99
99
|
|
|
100
|
-
- **Actors**: [the user roles that reach this
|
|
100
|
+
- **Actors**: [the user roles that reach this feature through a UI — e.g. clinician, scheduler; distinct from a system/API caller]
|
|
101
101
|
- **Channels**: [where the experience is delivered — e.g. responsive web; internal back-office only]
|
|
102
102
|
- **Device / viewport floor**: [the smallest supported surface — e.g. 360 px wide]
|
|
103
103
|
- **Browser / platform floor**: [the oldest supported targets — e.g. the last two major versions of evergreen browsers]
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
|
|
131
131
|
<!--
|
|
132
132
|
ACTION REQUIRED (when the domain applies; else "None (as of vX.Y)"). Constraints the
|
|
133
|
-
|
|
133
|
+
feature MUST satisfy that are NEITHER functional behaviour (those are FR) NOR
|
|
134
134
|
always-true business invariants (those are BR): the regulatory, retention,
|
|
135
135
|
immutability, audit-mandate, and performance-as-a-limit rules. Many are LIFTED here
|
|
136
136
|
by specify from the domain rule files (e.g. persistence.domain, auditing.domain,
|
|
@@ -147,8 +147,8 @@
|
|
|
147
147
|
## Data Classification *(domain lift — DC)*
|
|
148
148
|
|
|
149
149
|
<!--
|
|
150
|
-
ACTION REQUIRED (when the
|
|
151
|
-
The sensitivity taxonomy for this
|
|
150
|
+
ACTION REQUIRED (when the feature handles sensitive data; else "None (as of vX.Y)").
|
|
151
|
+
The sensitivity taxonomy for this feature's data and the exposure rules that follow:
|
|
152
152
|
which categories exist, which Key-Entity fields fall in each, and where each category
|
|
153
153
|
MAY / MUST NOT appear (public API surface, logs, metrics, traces, external projections).
|
|
154
154
|
Lifted by specify from the domain data-classification rules. Design enforces these; the
|
|
@@ -165,8 +165,8 @@
|
|
|
165
165
|
## Integration Contracts *(domain lift — IC)*
|
|
166
166
|
|
|
167
167
|
<!--
|
|
168
|
-
ACTION REQUIRED (when the
|
|
169
|
-
external contracts this
|
|
168
|
+
ACTION REQUIRED (when the feature interoperates; else "None (as of vX.Y)"). The
|
|
169
|
+
external contracts this feature MUST satisfy — interoperability obligations lifted by
|
|
170
170
|
specify from the domain interop rules (e.g. FHIR/HL7/DICOM projections, terminology
|
|
171
171
|
services, inbound feeds). State each at CONTRACT level: which standard, which resources,
|
|
172
172
|
direction (inbound/outbound), projection vs system-of-record — NOT the adapter design
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
|
|
183
183
|
<!--
|
|
184
184
|
ACTION REQUIRED (when the frontend lane's rules apply; else "None (as of vX.Y)").
|
|
185
|
-
The PROJECT-WIDE experience standards this
|
|
185
|
+
The PROJECT-WIDE experience standards this feature's UI must satisfy, lifted here by
|
|
186
186
|
specify out of the frontend lane's constitution (constitution.ui.md — the UX-* principle
|
|
187
187
|
series) and the mapped ux/ rule files, exactly as CN-/DC-/IC- lift the domain rules.
|
|
188
188
|
The lift is what makes them binding: the prototype phase and the FRONTEND LANES of plan
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
- **UX-001**: [Accessibility conformance — e.g. every user-facing surface MUST meet [standard, level]; every task in the User Stories is completable keyboard-only. — lifted from UX-II, ux/accessibility-standards.md]
|
|
209
209
|
- **UX-002**: [Interaction states — e.g. every asynchronous operation MUST present its loading, empty, partial-failure, recovery and success states; no state leaves the user without a next action. — lifted from UX-IV, ux/interaction-states.md]
|
|
210
210
|
- **UX-003**: [Content and language — e.g. user-facing text uses the context's ubiquitous language; every error names what happened and what to do next; regulated wording is reproduced verbatim. — lifted from UX-V, ux/content-design.md]
|
|
211
|
-
- **UX-004**: [Journey integrity — e.g. each US-n is completable without leaving this
|
|
211
|
+
- **UX-004**: [Journey integrity — e.g. each US-n is completable without leaving this feature's surface; destructive actions are confirmed and reversible. — lifted from ux/journey-mapping.md]
|
|
212
212
|
- **UX-005**: [Responsiveness-as-a-limit — e.g. an interaction acknowledges input within [n] ms and shows progress past [n] s. A front-end bound; the server-side budget it depends on is CN-nnn.]
|
|
213
213
|
|
|
214
214
|
## Edge Cases & Exceptional Scenarios
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Frontend Plan: [
|
|
1
|
+
# Frontend Plan: [FEATURE]
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Feature**: `[Feature]` <!-- the capability scope the developer chose; the aggregate(s) it acts on are the spec's "Acts on aggregate(s)" line -->
|
|
4
4
|
|
|
5
|
-
**Plan home**: `specs/[
|
|
5
|
+
**Plan home**: `specs/[Context]/[Feature]/frontend-plan.md`
|
|
6
6
|
|
|
7
|
-
**Source spec**: `specs/[
|
|
7
|
+
**Source spec**: `specs/[Context]/[Feature]/spec.md`
|
|
8
8
|
|
|
9
9
|
**Lane**: `[lane id]` — the frontend lane declared in `.appweaver/stacks.json`
|
|
10
10
|
|