aw-spec-cli 0.1.8 → 0.1.9
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 +200 -0
- package/assets/.appweaver/ORCH-DIALECT.md +156 -0
- package/assets/.appweaver/RULE-PARTITION.md +175 -0
- package/assets/.appweaver/STACK-PROFILES.md +461 -0
- package/assets/.appweaver/ai-rules.md +180 -0
- package/assets/.appweaver/domain.json +1 -0
- package/assets/.appweaver/extensions/.registry +19 -0
- package/assets/.appweaver/extensions/agent-context/README.md +57 -0
- package/assets/.appweaver/extensions/agent-context/agent-context-config.yml +4 -0
- package/assets/.appweaver/extensions/agent-context/commands/aw-spec.agent-context.update.md +26 -0
- package/assets/.appweaver/extensions/agent-context/extension.yml +37 -0
- package/assets/.appweaver/extensions/agent-context/scripts/bash/update-agent-context.sh +201 -0
- package/assets/.appweaver/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +237 -0
- package/assets/.appweaver/extensions.yml +16 -0
- package/assets/.appweaver/feature.json +3 -0
- package/assets/.appweaver/init-options.json +9 -0
- package/assets/.appweaver/integration.json +15 -0
- package/assets/.appweaver/integrations/aw-spec.manifest.json +9 -0
- package/assets/.appweaver/interpreter/run-skill.py +1176 -0
- package/assets/.appweaver/memory/constitution.md +50 -0
- package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +6 -0
- package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +94 -0
- package/assets/.appweaver/orchestrator/README.md +300 -0
- package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +74 -0
- package/assets/.appweaver/orchestrator/adapters/google_antigravity.py +74 -0
- package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +105 -0
- package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +101 -0
- package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +90 -0
- package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +126 -0
- package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +123 -0
- package/assets/.appweaver/orchestrator/orchestrator.py +1721 -0
- package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +40 -0
- package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +101 -0
- package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +245 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +63 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +59 -0
- package/assets/.appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
- package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +63 -0
- package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +116 -0
- package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
- package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
- package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +125 -0
- package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +123 -0
- package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +294 -0
- package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +160 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +270 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +934 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +251 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +265 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +437 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +197 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +475 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +727 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +100 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +386 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +462 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +265 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +253 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +267 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +287 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +238 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1822 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +194 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +83 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +296 -0
- package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +439 -0
- package/assets/.appweaver/scripts/bash/aw-inventory.sh +17 -0
- package/assets/.appweaver/scripts/bash/aw-parity.sh +13 -0
- package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +13 -0
- package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2626 -0
- package/assets/.appweaver/scripts/bash/aw-xref.sh +15 -0
- package/assets/.appweaver/scripts/bash/common.sh +533 -0
- package/assets/.appweaver/scripts/powershell/aw-inventory.ps1 +17 -0
- package/assets/.appweaver/scripts/powershell/aw-parity.ps1 +13 -0
- package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +13 -0
- package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +2232 -0
- package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +15 -0
- package/assets/.appweaver/scripts/python/aw-component-catalog.py +121 -0
- package/assets/.appweaver/scripts/python/aw-inventory.py +1180 -0
- package/assets/.appweaver/scripts/python/aw-parity.py +380 -0
- package/assets/.appweaver/scripts/python/aw-rev-constitution.py +329 -0
- package/assets/.appweaver/scripts/python/aw-stack.py +1251 -0
- package/assets/.appweaver/scripts/python/aw-xref.py +1330 -0
- package/assets/.appweaver/scripts/python/validate_okf.py +352 -0
- package/assets/.appweaver/stack-profiles/angular.json +16 -0
- package/assets/.appweaver/stack-profiles/blazor-wasm.json +17 -0
- package/assets/.appweaver/stack-profiles/dotnet-webapi.json +15 -0
- package/assets/.appweaver/stack-profiles/go-chi.json +14 -0
- package/assets/.appweaver/stack-profiles/java-spring.json +16 -0
- package/assets/.appweaver/stack-profiles/nextjs.json +16 -0
- package/assets/.appweaver/stack-profiles/node-express.json +15 -0
- package/assets/.appweaver/stack-profiles/python-fastapi.json +16 -0
- package/assets/.appweaver/stack-profiles/react-vite.json +17 -0
- package/assets/.appweaver/stack-profiles/sveltekit.json +16 -0
- package/assets/.appweaver/stack-profiles/vue-vite.json +17 -0
- package/assets/.appweaver/stacks.json +3 -0
- package/assets/.appweaver/templates/constitution-domain-template.md +116 -0
- package/assets/.appweaver/templates/constitution-technical-template.md +108 -0
- package/assets/.appweaver/templates/constitution-ui-template.md +116 -0
- package/assets/.appweaver/templates/delta-design-template.md +69 -0
- package/assets/.appweaver/templates/delta-spec-template.md +63 -0
- package/assets/.appweaver/templates/design-template.md +383 -0
- package/assets/.appweaver/templates/okf-concept-template.md +114 -0
- package/assets/.appweaver/templates/parity-manifest-template.json +49 -0
- package/assets/.appweaver/templates/source-map-template.md +85 -0
- package/assets/.appweaver/templates/spec-template.md +309 -0
- package/assets/.appweaver/templates/ui-design-template.md +273 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.pack.txt +25248 -0
- package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +5726 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-foundation.ps1 +145 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-foundation.sh +196 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.ps1 +157 -0
- package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.sh +209 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.ps1 +126 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.sh +217 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.ps1 +129 -0
- package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.sh +218 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.pack.txt +19318 -0
- package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +2833 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-foundation.ps1 +145 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-foundation.sh +196 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.ps1 +157 -0
- package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.sh +209 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.ps1 +126 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.sh +217 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.ps1 +129 -0
- package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.sh +218 -0
- package/assets/foundations/dotnet/components/Email/README.md +119 -0
- package/assets/foundations/dotnet/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +84 -0
- package/assets/foundations/dotnet/components/Email/integration.md +300 -0
- package/assets/foundations/dotnet/components/Jobs/README.md +113 -0
- package/assets/foundations/dotnet/components/Jobs/integration.md +259 -0
- package/assets/foundations/dotnet/components/QrGenerator/README.md +85 -0
- package/assets/foundations/dotnet/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +57 -0
- package/assets/foundations/dotnet/components/QrGenerator/integration.md +230 -0
- package/assets/foundations/dotnet/components/README.md +74 -0
- package/assets/guardrails/README.md +222 -0
- package/assets/guardrails/domain/healthcare/ai-rules.domain.md +34 -0
- package/assets/guardrails/domain/healthcare/api-versioning.domain.md +17 -0
- package/assets/guardrails/domain/healthcare/auditing.domain.md +97 -0
- package/assets/guardrails/domain/healthcare/authorization.domain.md +26 -0
- package/assets/guardrails/domain/healthcare/clinical-terms.md +20 -0
- package/assets/guardrails/domain/healthcare/coding-standards.domain.md +26 -0
- package/assets/guardrails/domain/healthcare/consent.md +19 -0
- package/assets/guardrails/domain/healthcare/cqrs.domain.md +12 -0
- package/assets/guardrails/domain/healthcare/data-classification.domain.md +28 -0
- package/assets/guardrails/domain/healthcare/dependency-policy.domain.md +11 -0
- package/assets/guardrails/domain/healthcare/dicom.md +15 -0
- package/assets/guardrails/domain/healthcare/domain-constitution.md +119 -0
- package/assets/guardrails/domain/healthcare/domain-driven-design.domain.md +28 -0
- package/assets/guardrails/domain/healthcare/eventing.domain.md +18 -0
- package/assets/guardrails/domain/healthcare/fhir.md +36 -0
- package/assets/guardrails/domain/healthcare/folder-structure.domain.md +25 -0
- package/assets/guardrails/domain/healthcare/hipaa.md +34 -0
- package/assets/guardrails/domain/healthcare/hl7.md +15 -0
- package/assets/guardrails/domain/healthcare/ihe-conformance.md +31 -0
- package/assets/guardrails/domain/healthcare/integration-terms.md +21 -0
- package/assets/guardrails/domain/healthcare/persistence.domain.md +20 -0
- package/assets/guardrails/domain/healthcare/terminology.md +30 -0
- package/assets/guardrails/domain/healthcare/testing.domain.md +15 -0
- package/assets/guardrails/domain/healthcare/ux/accessibility-standards.md +36 -0
- package/assets/guardrails/domain/healthcare/ux/content-design.md +32 -0
- package/assets/guardrails/domain/healthcare/ux/interaction-states.md +44 -0
- package/assets/guardrails/domain/healthcare/ux/journey-mapping.md +40 -0
- package/assets/guardrails/domain/healthcare/vertical-slices.domain.md +18 -0
- package/assets/guardrails/domain/healthcare/zero-trust.domain.md +12 -0
- package/assets/guardrails/domain/pharma/ai-rules.domain.md +32 -0
- package/assets/guardrails/domain/pharma/api-versioning.domain.md +20 -0
- package/assets/guardrails/domain/pharma/atc.md +22 -0
- package/assets/guardrails/domain/pharma/auditing.domain.md +90 -0
- package/assets/guardrails/domain/pharma/authorization.domain.md +25 -0
- package/assets/guardrails/domain/pharma/coding-standards.domain.md +28 -0
- package/assets/guardrails/domain/pharma/cqrs.domain.md +16 -0
- package/assets/guardrails/domain/pharma/data-classification.domain.md +24 -0
- package/assets/guardrails/domain/pharma/data-provenance.md +21 -0
- package/assets/guardrails/domain/pharma/dependency-policy.domain.md +11 -0
- package/assets/guardrails/domain/pharma/domain-constitution.md +113 -0
- package/assets/guardrails/domain/pharma/domain-driven-design.domain.md +36 -0
- package/assets/guardrails/domain/pharma/domain-requirements.sample.md +103 -0
- package/assets/guardrails/domain/pharma/eventing.domain.md +18 -0
- package/assets/guardrails/domain/pharma/fhir.md +31 -0
- package/assets/guardrails/domain/pharma/folder-structure.domain.md +26 -0
- package/assets/guardrails/domain/pharma/hl7.md +17 -0
- package/assets/guardrails/domain/pharma/idmp.md +26 -0
- package/assets/guardrails/domain/pharma/integration-terms.md +21 -0
- package/assets/guardrails/domain/pharma/ndc.md +28 -0
- package/assets/guardrails/domain/pharma/persistence.domain.md +23 -0
- package/assets/guardrails/domain/pharma/pharma-terms.md +27 -0
- package/assets/guardrails/domain/pharma/product-lifecycle.domain.md +30 -0
- package/assets/guardrails/domain/pharma/regulatory-compliance.md +19 -0
- package/assets/guardrails/domain/pharma/terminology.md +32 -0
- package/assets/guardrails/domain/pharma/testing.domain.md +19 -0
- package/assets/guardrails/domain/pharma/vertical-slices.domain.md +17 -0
- package/assets/guardrails/domain/pharma/zero-trust.domain.md +12 -0
- package/assets/guardrails/projects/dotnet-default-project/domain/domain-requirements.md +58 -0
- package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +113 -0
- package/assets/guardrails/projects/dotnet-default-project/frontend/ui-requirements.md +43 -0
- package/assets/guardrails/projects/dotnet-default-project/service/technical-requirements.md +40 -0
- package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +263 -0
- package/assets/guardrails/requirement-spec.txt +27 -0
- package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +184 -0
- package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +44 -0
- package/assets/guardrails/technology/dotnet-webapi/auditing.md +96 -0
- package/assets/guardrails/technology/dotnet-webapi/authorization-matrix.md +14 -0
- package/assets/guardrails/technology/dotnet-webapi/authorization.md +39 -0
- package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +54 -0
- package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +87 -0
- package/assets/guardrails/technology/dotnet-webapi/cqrs.md +63 -0
- package/assets/guardrails/technology/dotnet-webapi/data-classification.md +38 -0
- package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +40 -0
- package/assets/guardrails/technology/dotnet-webapi/domain-driven-design.md +91 -0
- package/assets/guardrails/technology/dotnet-webapi/eventing.md +57 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/api-versioning.md +75 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/auditing.md +84 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/authorization.md +68 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/clean-architecture.md +37 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/cqrs.md +97 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/domain-driven-design.md +141 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/eventing.md +46 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/persistence.md +207 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/vertical-slices.md +151 -0
- package/assets/guardrails/technology/dotnet-webapi/examples/zero-trust.md +48 -0
- package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +61 -0
- package/assets/guardrails/technology/dotnet-webapi/modular-monolith.md +47 -0
- package/assets/guardrails/technology/dotnet-webapi/persistence.md +82 -0
- package/assets/guardrails/technology/dotnet-webapi/technology-constitution.md +162 -0
- package/assets/guardrails/technology/dotnet-webapi/testing.md +55 -0
- package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +70 -0
- package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +48 -0
- package/assets/guardrails/technology/java-spring/README.md +62 -0
- package/assets/guardrails/technology/nextjs/accessibility-implementation.md +56 -0
- package/assets/guardrails/technology/nextjs/api-client.md +56 -0
- package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +174 -0
- package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +203 -0
- package/assets/guardrails/technology/nextjs/auth-session.md +68 -0
- package/assets/guardrails/technology/nextjs/client-security.md +69 -0
- package/assets/guardrails/technology/nextjs/component-architecture.md +60 -0
- package/assets/guardrails/technology/nextjs/component-conventions.md +58 -0
- package/assets/guardrails/technology/nextjs/design-system.md +60 -0
- package/assets/guardrails/technology/nextjs/error-handling.md +72 -0
- package/assets/guardrails/technology/nextjs/forms-and-validation.md +75 -0
- package/assets/guardrails/technology/nextjs/frontend-testing.md +94 -0
- package/assets/guardrails/technology/nextjs/i18n.md +57 -0
- package/assets/guardrails/technology/nextjs/observability.md +67 -0
- package/assets/guardrails/technology/nextjs/performance-budgets.md +66 -0
- package/assets/guardrails/technology/nextjs/routing-navigation.md +52 -0
- package/assets/guardrails/technology/nextjs/state-management.md +70 -0
- package/assets/guardrails/technology/nextjs/ui-constitution.md +166 -0
- package/package.json +1 -1
- package/assets/docs/pharma-constitution.my-ref.md +0 -86
|
@@ -0,0 +1,1822 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# aw-spec-onboard (orchestrator) — the entry step of the Brownfield DEVELOPMENT flow
|
|
3
|
+
#
|
|
4
|
+
# Onboard an EXISTING codebase into aw-spec so it can be DEVELOPED (evolved, not
|
|
5
|
+
# migrated) governed exactly like greenfield and as lightly as OpenSpec. Runs ONCE
|
|
6
|
+
# per repo, over the WHOLE codebase (project-level, not per-slice). It does two
|
|
7
|
+
# things, both from a single deterministic whole-repo scan — no slice is adopted yet:
|
|
8
|
+
#
|
|
9
|
+
# 1. FEATURE MAP — a HIGH-LEVEL OKF discovery index of the features/aggregates the
|
|
10
|
+
# code contains (folders/concepts + a bounded-context map + the tech stack). It
|
|
11
|
+
# is a shallow map to pick from, NOT a deep reverse — the deep per-feature
|
|
12
|
+
# reverse (spec.md + design.md) is /appweaver adopt, done just-in-time when
|
|
13
|
+
# you are about to develop that feature.
|
|
14
|
+
#
|
|
15
|
+
# 2. GOVERNANCE SCAFFOLD — the PROJECT-level governing tier, established once from
|
|
16
|
+
# the whole-repo vantage so forward development is consistent from the first
|
|
17
|
+
# change: the split constitution (technical + domain), the guardrails/projects/
|
|
18
|
+
# brf-<domain>/domain/ rule-file set (+ domain-rule-bindings), the domain charter
|
|
19
|
+
# that set is headed by, and the activated domain. Because nothing is adopted yet, this tier is
|
|
20
|
+
# a PROVISIONAL scaffold evidenced by the SCAN (project identity + bounded-context
|
|
21
|
+
# map are firm; principles/rules are marked provisional). adopt then RECONCILES
|
|
22
|
+
# each with the slice's own evidence (BR-/CN-/DC-/IC- ids) when that feature is
|
|
23
|
+
# developed — the "created here, updated when taking each slice" contract.
|
|
24
|
+
#
|
|
25
|
+
# ONBOARD → adopt <Feature> (JIT) → specify → design → analyze-delta-design → implement-delta → build → finalize-delta → analyze-slice → close-delta ← you are here
|
|
26
|
+
#
|
|
27
|
+
# Establishing the PROJECT-scoped constitution here (whole-repo vantage) — not from a
|
|
28
|
+
# single adopted slice — is deliberate: it keeps governance project-scoped from day
|
|
29
|
+
# one and stops a first-adopted feature from biasing it (adopt only ADDS evidence).
|
|
30
|
+
#
|
|
31
|
+
# This is the DEVELOPMENT flow — there is NO migration content: no migration backlog,
|
|
32
|
+
# no seams/adopt-order, no strangler, no parity, no cutover. Modernization/migration
|
|
33
|
+
# is a separate, later phase. Reuses proven machinery unchanged (the scan, the
|
|
34
|
+
# constitution scripts, the neutral rev-templates skeletons); the new agent PROMPTS read
|
|
35
|
+
# the SCAN + representative SOURCE, not adopted docs. It also REVERSE-ENGINEERS the repo's
|
|
36
|
+
# own technical structure into a project-specific design + delta-design template pair
|
|
37
|
+
# (installed as the project template overrides), so forward development follows the
|
|
38
|
+
# as-built architecture, not the greenfield four-layer layout.
|
|
39
|
+
#
|
|
40
|
+
# ONE ORACLE — THE CODE. Every artifact this workflow writes is evidenced from source, and
|
|
41
|
+
# the discipline is structural rather than instructional: no greenfield constitution, rule
|
|
42
|
+
# file or document template is ever placed in a step's context. Where a shape reference is
|
|
43
|
+
# needed, the step reads a NEUTRAL SKELETON from rev-templates/ that carries the format and
|
|
44
|
+
# deliberately carries no principle set, no rule, no layering and no technology. That is
|
|
45
|
+
# why "do not copy the exemplar" never has to be trusted — there is no exemplar present.
|
|
46
|
+
#
|
|
47
|
+
# CODE-DERIVED RULE SETS + MAPS (both tiers): onboard authors, from the code ALONE
|
|
48
|
+
# (never a greenfield rule file), BOTH the DOMAIN rule-file set
|
|
49
|
+
# (guardrails/projects/brf-<domain>/domain/*.domain.md +
|
|
50
|
+
# domain-rule-bindings.md) AND the TECHNICAL rule-file set (guardrails/projects/brf-<domain>/service/*.md
|
|
51
|
+
# + tech-rule-bindings.md), then WIRES each per-workflow. This is what makes the WHOLE
|
|
52
|
+
# forward pipeline AND adopt govern against THIS codebase's rules — resolve-domain /
|
|
53
|
+
# resolve-tech read the activated brf-<domain>'s maps, so no workflow ever falls back to a
|
|
54
|
+
# rule file from another project. Both sets are evidenced-only (a rule
|
|
55
|
+
# is written only for a concern the code exhibits) and may be seeded with an optional list
|
|
56
|
+
# of concerns to look for (onboard still DECIDES presence + implementation from the code).
|
|
57
|
+
# The technical set carries ONE file for /specify — service/domain-modelling.md, the AS-BUILT
|
|
58
|
+
# modelling METHODOLOGY (how this code expresses a domain model: what marks an aggregate
|
|
59
|
+
# root, entity vs value object, where invariants live, the context boundary). It is the
|
|
60
|
+
# code-derived analog of the greenfield corpus's technology/<stack>/domain-driven-design.md, and the only
|
|
61
|
+
# thing this tier is ever allowed to put under `## /aw-spec-specify`. WHAT the model is
|
|
62
|
+
# stays in the domain set (its domain-model file); HOW to model lives here.
|
|
63
|
+
#
|
|
64
|
+
# THE FRONTEND LANE (only where the CODE has one). A repo with a user interface gets the
|
|
65
|
+
# lane's governance reverse-engineered on the same terms as the other two tiers — from the
|
|
66
|
+
# code and nothing else:
|
|
67
|
+
# .appweaver/memory/constitution.ui.md — the lane's UX-* base, authored from the UI
|
|
68
|
+
# source (never from a greenfield UI template's content), then linted like the other
|
|
69
|
+
# halves and composed in. Parallel to the technical base, so its numbering is its own.
|
|
70
|
+
# guardrails/projects/brf-<domain>/frontend/*.md — the code-derived lane rule set, the detail
|
|
71
|
+
# layer under those UX-* principles, plus `## /aw-spec-ui-constitution` appended to
|
|
72
|
+
# tech-rule-bindings.md so a later /appweaver constitution re-ratifies from THIS
|
|
73
|
+
# project's lane rules.
|
|
74
|
+
# .appweaver/templates/overrides/ui-design-template.md + ui-delta-design-template.md — the
|
|
75
|
+
# lane's own document pair, reverse-engineered from the UI source the same way the
|
|
76
|
+
# service pair is reverse-engineered from the service code. The lane is governed by a
|
|
77
|
+
# different constitution half and implemented by different commands, so it gets its own
|
|
78
|
+
# design document rather than a section inside the service design; the only thing that
|
|
79
|
+
# crosses between them is the design contract. Their consumers (⌛ ui-design,
|
|
80
|
+
# ui-implement) are not built yet — the templates are written now because the
|
|
81
|
+
# whole-repo evidence for them exists exactly once, at onboard.
|
|
82
|
+
# RUN /appweaver select-stack FIRST. It is the first command of the brownfield
|
|
83
|
+
# sequence and this workflow REFUSES to run without it, because it needs to be told three
|
|
84
|
+
# things before it can start: which lanes this project has, where each lane's source is,
|
|
85
|
+
# and what each lane's stack is. Those decide which constitution halves and rule sets get
|
|
86
|
+
# generated, which subtrees are scanned, and what technology the derived rules name.
|
|
87
|
+
# select-stack detects all three from the repo's own files and proposes them, so answering
|
|
88
|
+
# it on an existing codebase is mostly confirmation — but it is a person's confirmation,
|
|
89
|
+
# which is exactly what detection on a legacy repo needs. A declared source path that is
|
|
90
|
+
# not a directory stops this run with the fix named rather than producing a scaffold
|
|
91
|
+
# reverse-engineered from nothing.
|
|
92
|
+
#
|
|
93
|
+
# WHICH LANES EXIST is therefore the DECLARATION's answer, and it answers in both
|
|
94
|
+
# directions — a project that declared `(none)` for the UI lane gets no UI half, no
|
|
95
|
+
# frontend rule files and no `## /aw-spec-ui-*` mapping, and one that declared `(none)`
|
|
96
|
+
# for the service lane gets no technical half and no service rules. The deterministic
|
|
97
|
+
# scan is still what reads the code, now pointed AT the declared subtree: it decides what
|
|
98
|
+
# the governance SAYS, and the declaration decides what there is to govern. A declared
|
|
99
|
+
# lane whose source path holds nothing recognisable is reported, because the governance
|
|
100
|
+
# derived from it will be thin.
|
|
101
|
+
#
|
|
102
|
+
# ONE ORACLE, UNCHANGED. Nothing about where the CONTENT comes from has moved. Every
|
|
103
|
+
# constitution half, rule file and design template below is derived from this repository's
|
|
104
|
+
# own source plus a NEUTRAL skeleton, with no greenfield corpus, filled constitution or
|
|
105
|
+
# kit template in context. The declaration selects the subtree; it supplies no governance.
|
|
106
|
+
#
|
|
107
|
+
# THIS WORKFLOW NEVER WRITES .appweaver/stacks.json. It used to, back when a repo could
|
|
108
|
+
# reach onboard undeclared: it ran its own detection pass, recorded what it found marked
|
|
109
|
+
# `origin: reverse-engineered`, and was gated never to overwrite a lane a person had
|
|
110
|
+
# confirmed. With the declaration required at the top, that gate can never open and the
|
|
111
|
+
# pass was re-deriving an answer the run already had. `lane-declare` has one caller again
|
|
112
|
+
# — select-stack — and this workflow only reads.
|
|
113
|
+
#
|
|
114
|
+
# Never modifies source — every write lands in the OKF bundle, the specs governance dir,
|
|
115
|
+
# guardrails/projects/ (domain/ + service/ + frontend/ rule sets + both maps), or the
|
|
116
|
+
# .appweaver/templates/overrides/ design templates.
|
|
117
|
+
#
|
|
118
|
+
# Launch: /appweaver onboard [domain-name / scope hint] [; concerns: a, b, c]
|
|
119
|
+
# e.g. /appweaver onboard Pharma
|
|
120
|
+
# e.g. /appweaver onboard "Pharma; concerns: auditing, concurrency, authorization"
|
|
121
|
+
# =============================================================================
|
|
122
|
+
|
|
123
|
+
name: aw-spec-onboard
|
|
124
|
+
description: Onboard an existing codebase for brownfield DEVELOPMENT — a deterministic whole-repo scan produces a high-level OKF feature map (folders/concepts) PLUS the project-level governance scaffold (split constitution + guardrails/projects/brf-<domain>/ with its DOMAIN rule files at domain/ + domain-rule-bindings + code-derived TECHNICAL rule files at service/ + tech-rule-bindings + activated domain), all provisional-from-scan and refined per slice by adopt. Where the scan finds a frontend lane in the CODE, it also authors that lane's half — constitution.ui.md (UX-*) — and its code-derived rule files at brf-<domain>/frontend/, mapped under `## /aw-spec-ui-constitution`; a backend-only repo gets none of it. Every rule tier is reverse-engineered from the CODE alone (never a greenfield rule file), evidenced-only, and WIRED per-workflow so the whole forward pipeline AND adopt govern against THIS codebase — never a greenfield fallback. It also reverse-engineers the repo's own technical structure into a project-specific design + delta-design template pair, installed as the project template overrides, and — where the lane exists — the frontend lane's own pair from the UI source. Every authoring step is shaped by a NEUTRAL rev-templates skeleton; no greenfield constitution, rule file or document template is ever placed in context. Accepts an optional concerns list to look for (onboard decides which are actually present). Reads any declared lane, never writes one. No migration content; never modifies source.
|
|
125
|
+
version: 1.6.0
|
|
126
|
+
agent_agnostic: true
|
|
127
|
+
dialect: aw-spec.orchestrator/v1
|
|
128
|
+
|
|
129
|
+
inputs:
|
|
130
|
+
user_input:
|
|
131
|
+
description: >-
|
|
132
|
+
Optional free-text hint. May carry (a) a domain name for the governance project
|
|
133
|
+
(e.g. Pharma → guardrails/projects/brf-pharma/); (b) a scope/focus hint for the
|
|
134
|
+
feature map; and/or (c) a CONCERNS LIST to look for, as a "concerns: a, b, c"
|
|
135
|
+
clause (e.g. "Pharma; concerns: auditing, concurrency, authorization"). The
|
|
136
|
+
concerns are a SEARCH HINT only — both rule-set authors still DECIDE which
|
|
137
|
+
concerns are actually present from the code, and are never limited to the list.
|
|
138
|
+
When omitted, the domain defaults to the PROJECT name from the OKF overview,
|
|
139
|
+
then the repo basename; concerns are auto-discovered from the code.
|
|
140
|
+
required: false
|
|
141
|
+
bind: USER_INPUT
|
|
142
|
+
|
|
143
|
+
scripts:
|
|
144
|
+
inventory:
|
|
145
|
+
sh: .appweaver/scripts/bash/aw-inventory.sh
|
|
146
|
+
ps1: .appweaver/scripts/powershell/aw-inventory.ps1
|
|
147
|
+
revcon:
|
|
148
|
+
sh: .appweaver/scripts/bash/aw-rev-constitution.sh
|
|
149
|
+
ps1: .appweaver/scripts/powershell/aw-rev-constitution.ps1
|
|
150
|
+
actions:
|
|
151
|
+
sh: .appweaver/scripts/bash/aw-spec-actions.sh
|
|
152
|
+
ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
|
|
153
|
+
|
|
154
|
+
# The sticky set carries the kit's universal operating rules and NOTHING project-shaped.
|
|
155
|
+
# agent_generate ALWAYS injects the standards set (it cannot opt out), so keeping it to
|
|
156
|
+
# behaviour-only guarantees no governance skeleton or exemplar from another project leaks
|
|
157
|
+
# into the feature-map agent. Every step is fed EXACTLY what it needs via build_context;
|
|
158
|
+
# the technical-half author gets its neutral shape skeleton through context, not here.
|
|
159
|
+
standards:
|
|
160
|
+
- { path: .appweaver/ai-rules.md } # kit-resident: the universal operating rules, every flow
|
|
161
|
+
|
|
162
|
+
vars:
|
|
163
|
+
bundle_present: "false" # inventory bundle_guard driver
|
|
164
|
+
conformant: "false" # OKF conformance-gate driver
|
|
165
|
+
pack_present: "false" # project anti-clobber driver
|
|
166
|
+
technical_ok: "false" # technical-half lint guard
|
|
167
|
+
domain_ok: "false" # domain-half lint guard
|
|
168
|
+
ui_ok: "false" # UI-half lint guard
|
|
169
|
+
ui_lane: "false" # set from the DECLARATION below; gates the whole frontend block
|
|
170
|
+
svc_lane: "false" # set from the DECLARATION below; gates the whole service block
|
|
171
|
+
|
|
172
|
+
workflow:
|
|
173
|
+
|
|
174
|
+
# ═══════════════════ PART 1 — FEATURE MAP (high-level discovery) ═════════════
|
|
175
|
+
# A deterministic scan + one enrichment agent, mirroring inventory's shape but
|
|
176
|
+
# producing a SHALLOW discovery index (drop the migration backlog / seams /
|
|
177
|
+
# adopt-order — this is development, not migration).
|
|
178
|
+
|
|
179
|
+
# 0. WHICH LANES, AND WHERE IS THEIR SOURCE. select-stack is the first command of
|
|
180
|
+
# the brownfield sequence, and this is why: onboard reverse-engineers governance
|
|
181
|
+
# OUT of a subtree, so it has to be told which subtree before it starts. The
|
|
182
|
+
# declaration answers three questions at once — which lanes exist (so which
|
|
183
|
+
# constitution halves and rule sets to generate), where each lane's source is (so
|
|
184
|
+
# what to scan), and what each lane's stack is (so the derived rules name the
|
|
185
|
+
# right technology).
|
|
186
|
+
#
|
|
187
|
+
# The on-disk check is ON here, unlike in constitution: this run is about to READ
|
|
188
|
+
# those directories. A declared path that is not there stops the run with the fix
|
|
189
|
+
# named, rather than producing a governance scaffold reverse-engineered from
|
|
190
|
+
# nothing.
|
|
191
|
+
- id: lane_model
|
|
192
|
+
action: execute_script
|
|
193
|
+
script: { ref: actions }
|
|
194
|
+
subcommand: lane-verify
|
|
195
|
+
args: ["--command", "/appweaver onboard"]
|
|
196
|
+
outputs:
|
|
197
|
+
- { name: lane_model_ok, from: "$.ok" }
|
|
198
|
+
- { name: lane_model_issues, from: "$.message" }
|
|
199
|
+
- { name: lane_kinds, from: "$.kinds" }
|
|
200
|
+
- { name: be_declared, from: "$.backend_declared" }
|
|
201
|
+
- { name: be_lane_id, from: "$.backend_lane_id" }
|
|
202
|
+
- { name: be_profile, from: "$.backend_profile" }
|
|
203
|
+
- { name: be_root, from: "$.backend_source_path" }
|
|
204
|
+
- { name: fe_declared, from: "$.frontend_declared" }
|
|
205
|
+
- { name: fe_lane_id, from: "$.frontend_lane_id" }
|
|
206
|
+
- { name: fe_profile, from: "$.frontend_profile" }
|
|
207
|
+
- { name: fe_root, from: "$.frontend_source_path" }
|
|
208
|
+
|
|
209
|
+
- id: lane_model_gate
|
|
210
|
+
action: verify_context
|
|
211
|
+
require_true: lane_model_ok
|
|
212
|
+
on_false: stop
|
|
213
|
+
on_false_message: >
|
|
214
|
+
/appweaver onboard cannot run: {{lane_model_issues}}
|
|
215
|
+
onboard reverse-engineers this repository's governance out of its source, so it
|
|
216
|
+
has to be told which subtrees hold which lane before it starts scanning. Run
|
|
217
|
+
/appweaver select-stack first — it detects what this repo already is, proposes
|
|
218
|
+
the stack and the source path for each lane, and lets you correct both.
|
|
219
|
+
|
|
220
|
+
- id: lane_kinds_gate
|
|
221
|
+
action: verify_context
|
|
222
|
+
require_non_empty: lane_kinds
|
|
223
|
+
on_empty: stop
|
|
224
|
+
on_empty_message: >
|
|
225
|
+
No lane is declared — .appweaver/stacks.json exists but declares neither a service
|
|
226
|
+
nor a UI lane, so onboard has no source to reverse-engineer. Re-run
|
|
227
|
+
/appweaver select-stack and declare at least one lane.
|
|
228
|
+
|
|
229
|
+
# 1. DETERMINISTIC scan of the current codebase → JSON substrate (files, churn,
|
|
230
|
+
# categories, aggregate_signals = candidate feature roots), and reports whether
|
|
231
|
+
# a bundle already holds curation.
|
|
232
|
+
#
|
|
233
|
+
# SCOPED BY THE DECLARATION. Backend signals come from outside the UI lane's
|
|
234
|
+
# subtree (and inside the service lane's); frontend signals come from the UI
|
|
235
|
+
# lane's subtree alone. This substrate is inlined verbatim into every agent
|
|
236
|
+
# request this run makes, so an unscoped scan puts the whole frontend file list in
|
|
237
|
+
# front of the step deriving the SERVICE rules and every backend aggregate in front
|
|
238
|
+
# of the steps deriving the UI's — while each prompt tells the model to ignore what
|
|
239
|
+
# it has just been handed. Scoping removes the material instead of arguing with it,
|
|
240
|
+
# and shrinks six payloads at the same time.
|
|
241
|
+
- id: scan
|
|
242
|
+
action: execute_script
|
|
243
|
+
script: { ref: inventory }
|
|
244
|
+
subcommand: scan
|
|
245
|
+
args: ["--service-root", "{{be_root}}", "--ui-root", "{{fe_root}}"]
|
|
246
|
+
outputs:
|
|
247
|
+
- { name: inventory_json, from: "$.inventory_json" }
|
|
248
|
+
- { name: root, from: "$.root" }
|
|
249
|
+
- { name: head, from: "$.head" }
|
|
250
|
+
- { name: file_count, from: "$.file_count" }
|
|
251
|
+
- { name: aggregate_count, from: "$.aggregate_count" }
|
|
252
|
+
- { name: bundle_dir, from: "$.bundle_dir" }
|
|
253
|
+
- { name: bundle_present, from: "$.bundle_present" }
|
|
254
|
+
- { name: bundle_md_count, from: "$.bundle_md_count" }
|
|
255
|
+
# The frontend lane, as the CODE evidences it. `frontend_present` is true only
|
|
256
|
+
# where a candidate root reached lane strength (a frontend build config, or a
|
|
257
|
+
# real set of component/view files) — loose scripts and stylesheets under a
|
|
258
|
+
# wwwroot/ are reported in the substrate but are NOT a lane.
|
|
259
|
+
- { name: frontend_present, from: "$.frontend_present" }
|
|
260
|
+
- { name: frontend_separable, from: "$.frontend_separable" }
|
|
261
|
+
- { name: frontend_roots, from: "$.frontend_roots" }
|
|
262
|
+
- { name: frontend_root_count, from: "$.frontend_root_count" }
|
|
263
|
+
# The PRIMARY root / kind / stack — the single values the lane declaration needs.
|
|
264
|
+
- { name: frontend_root, from: "$.frontend_root" }
|
|
265
|
+
- { name: frontend_kind, from: "$.frontend_kind" }
|
|
266
|
+
- { name: frontend_stack, from: "$.frontend_stack" }
|
|
267
|
+
# Did the DECLARED UI subtree actually contain UI? A declared lane is a lane
|
|
268
|
+
# either way — this is what separates governance reverse-engineered from real
|
|
269
|
+
# source from governance derived from an empty directory.
|
|
270
|
+
- { name: ui_evidence_found, from: "$.ui_evidence_found" }
|
|
271
|
+
- { name: backend_file_count, from: "$.backend_file_count" }
|
|
272
|
+
- { name: frontend_file_count, from: "$.frontend_file_count" }
|
|
273
|
+
- { name: scoped_service_root, from: "$.declared_service_root" }
|
|
274
|
+
- { name: scoped_ui_root, from: "$.declared_ui_root" }
|
|
275
|
+
|
|
276
|
+
# 1b. Substance gate: no candidate features → nothing to map.
|
|
277
|
+
- id: require_aggregates
|
|
278
|
+
action: verify_context
|
|
279
|
+
require_true: aggregate_count
|
|
280
|
+
on_false: stop
|
|
281
|
+
on_false_message: "Scan found no candidate features in {{root}} (file_count={{file_count}}). Point /appweaver onboard at a codebase with a recognizable domain/vertical-slice layout, or scan a subtree that contains one."
|
|
282
|
+
|
|
283
|
+
# 1c. Curation guard (OKF rule): a bundle that already has concept files is
|
|
284
|
+
# curation — regenerating from scratch would destroy it.
|
|
285
|
+
- id: bundle_guard
|
|
286
|
+
action: verify_context
|
|
287
|
+
require_value: bundle_present
|
|
288
|
+
equals: "false"
|
|
289
|
+
on_mismatch: stop
|
|
290
|
+
on_mismatch_message: "The OKF feature-map bundle at {{bundle_dir}} already holds {{bundle_md_count}} concept file(s) — onboard would overwrite that curation. Back up or remove {{bundle_dir}} to re-onboard from scratch."
|
|
291
|
+
|
|
292
|
+
# 1d. FRONTEND LANE — the DECLARATION decides that it exists, and the CODE decides
|
|
293
|
+
# what its governance says. Those are two different questions and they used to be
|
|
294
|
+
# answered by one signal.
|
|
295
|
+
#
|
|
296
|
+
# Before, the scan's own strength test (a frontend build config, or UI_STRONG_MIN
|
|
297
|
+
# component files) both found the lane and supplied its evidence. That test exists
|
|
298
|
+
# to stop a scan INVENTING a lane out of a wwwroot/ of loose scripts, which is the
|
|
299
|
+
# right instinct and the wrong authority: it also meant a real lane the heuristic
|
|
300
|
+
# scored one file short simply did not exist, and no amount of declaring it helped.
|
|
301
|
+
# Now the project says which lanes it has and where their source is, and the scan
|
|
302
|
+
# — pointed at that subtree — says what is in there.
|
|
303
|
+
#
|
|
304
|
+
# ONE ORACLE, UNCHANGED. Nothing about where the CONTENT comes from has moved:
|
|
305
|
+
# every rule, principle and template below is still derived from this repository's
|
|
306
|
+
# own source and from a neutral skeleton, with no greenfield corpus in context.
|
|
307
|
+
# The declaration selects the subtree; it never supplies a word of the governance.
|
|
308
|
+
# No service lane ⇒ the technical lint loop has nothing to check, so its guard is
|
|
309
|
+
# satisfied rather than left at its "not yet verified" default; a declared lane
|
|
310
|
+
# restores it, because that half does get authored and does get linted.
|
|
311
|
+
- id: svc_lane_absent
|
|
312
|
+
action: set
|
|
313
|
+
vars: { svc_lane: "false", technical_ok: "true", setup_tech_flag: "--no-technical" }
|
|
314
|
+
- id: svc_lane_declared
|
|
315
|
+
action: set
|
|
316
|
+
condition: "{{be_declared}}"
|
|
317
|
+
vars: { svc_lane: "true", technical_ok: "false", setup_tech_flag: "" }
|
|
318
|
+
|
|
319
|
+
# A repo with no service lane. Rare in brownfield and real — a static site, a
|
|
320
|
+
# component library, a front end whose API lives in another repository. The
|
|
321
|
+
# technical half, the service rule set and the service design templates are all the
|
|
322
|
+
# SERVICE lane's, so none of them is authored, and saying so is better than leaving
|
|
323
|
+
# someone to notice that guardrails/projects/<p>/service/ is empty.
|
|
324
|
+
- id: svc_lane_warning
|
|
325
|
+
action: verify_context
|
|
326
|
+
require_true: svc_lane
|
|
327
|
+
on_false: continue
|
|
328
|
+
on_false_message: >
|
|
329
|
+
No service lane in .appweaver/stacks.json — skipping the TECHNICAL constitution
|
|
330
|
+
half, the service rule set (the project's own service/ folder) and the
|
|
331
|
+
service design/delta-design template overrides. All three are the service lane's,
|
|
332
|
+
and this project declared it has none. The domain rule set, the domain half and —
|
|
333
|
+
where a UI lane is declared — the whole frontend tier are authored as usual. If
|
|
334
|
+
this repo does have backend source, run /appweaver select-stack, declare it and
|
|
335
|
+
re-run onboard.
|
|
336
|
+
|
|
337
|
+
- id: ui_lane_absent
|
|
338
|
+
action: set
|
|
339
|
+
vars:
|
|
340
|
+
ui_lane: "false"
|
|
341
|
+
ui_evidence: ""
|
|
342
|
+
ui_declaration_note: "no frontend lane is declared in .appweaver/stacks.json — this repo is governed as backend-only"
|
|
343
|
+
- id: ui_lane_declared
|
|
344
|
+
action: set
|
|
345
|
+
condition: "{{fe_declared}}"
|
|
346
|
+
vars:
|
|
347
|
+
ui_lane: "true"
|
|
348
|
+
ui_evidence: "lane '{{fe_lane_id}}' ({{fe_profile}}) is declared at the source path {{fe_root}}; the scan found UI source there — {{frontend_roots}}"
|
|
349
|
+
ui_declaration_note: "lane '{{fe_lane_id}}' ({{fe_profile}}) at {{fe_root}} — the declared source path this run reverse-engineered the UI governance out of"
|
|
350
|
+
|
|
351
|
+
# A declared UI lane whose source path holds nothing a scan recognises as UI. The
|
|
352
|
+
# path exists — lane-verify already refused the run otherwise — so this is not a
|
|
353
|
+
# broken declaration, it is an empty one: a lane scaffolded but not yet built, or a
|
|
354
|
+
# source path one directory too high. Announce and continue rather than stop: the
|
|
355
|
+
# declaration is a person's statement and is left exactly as it stands, but the UI
|
|
356
|
+
# governance below will be thin, and it is better to say why now than to let someone
|
|
357
|
+
# discover a UX base derived from an empty directory.
|
|
358
|
+
- id: ui_evidence_warning
|
|
359
|
+
action: verify_context
|
|
360
|
+
condition: "{{ui_lane}} == true"
|
|
361
|
+
require_true: ui_evidence_found
|
|
362
|
+
on_false: continue
|
|
363
|
+
on_false_message: >
|
|
364
|
+
Frontend lane '{{fe_lane_id}}' is declared at {{fe_root}}, but the scan found no
|
|
365
|
+
component, view or build-config files under that path ({{frontend_file_count}}
|
|
366
|
+
file(s) there in total). The UI governance authored below is reverse-engineered
|
|
367
|
+
from that subtree, so it will be thin or empty. Check that the source path points
|
|
368
|
+
at the directory holding the UI — /appweaver select-stack can move it — or
|
|
369
|
+
retire the lane there with (none) if this repo has no UI yet.
|
|
370
|
+
|
|
371
|
+
# 2. Pre-execution hooks.
|
|
372
|
+
- id: resolve_pre_hooks
|
|
373
|
+
action: execute_script
|
|
374
|
+
script: { ref: actions }
|
|
375
|
+
subcommand: resolve-hooks
|
|
376
|
+
args: ["--phase", "before_onboard"]
|
|
377
|
+
outputs:
|
|
378
|
+
- { name: before_hooks, from: "$.hooks" }
|
|
379
|
+
- id: dispatch_pre_hooks
|
|
380
|
+
action: dispatch_hooks
|
|
381
|
+
hooks_from_variable: before_hooks
|
|
382
|
+
|
|
383
|
+
# 3. ENRICHMENT — turn the substrate into a HIGH-LEVEL OKF feature map. Context via
|
|
384
|
+
# build_context (agent_generate reads the envelope): the factual substrate, the
|
|
385
|
+
# OKF format authority, and an OPTIONAL DDD vocabulary aid for naming (no
|
|
386
|
+
# migration/pipeline reference — this is development).
|
|
387
|
+
- id: ctx_author
|
|
388
|
+
action: build_context
|
|
389
|
+
context:
|
|
390
|
+
- { path: "{{inventory_json}}" } # the deterministic substrate (aggregate_signals etc.)
|
|
391
|
+
- { path: .appweaver/templates/okf-concept-template.md } # OKF v0.1 format authority (frontmatter, index, log, rules) — format only, zero project content
|
|
392
|
+
- id: author_bundle
|
|
393
|
+
action: agent_generate
|
|
394
|
+
tools: "Read,Write,Edit"
|
|
395
|
+
permission_mode: acceptEdits
|
|
396
|
+
task: |
|
|
397
|
+
Act as the OKF enrichment agent for the Brownfield DEVELOPMENT onboard step.
|
|
398
|
+
Produce a CONFORMANT OKF v0.1 knowledge bundle at {{bundle_dir}} that is a
|
|
399
|
+
HIGH-LEVEL FEATURE MAP — a discovery index of the features/aggregates this
|
|
400
|
+
codebase contains, organized BY AGGREGATE ROOT — from the deterministic
|
|
401
|
+
substrate {{inventory_json}} (in context). Follow the OKF concept template in
|
|
402
|
+
context for format (frontmatter, index.md/log.md rules, cross-linking, hard rules).
|
|
403
|
+
Domain/scope hint (optional): {{USER_INPUT}}
|
|
404
|
+
|
|
405
|
+
THIS IS A MAP, NOT A DEEP REVERSE. Keep every feature concept SHALLOW — enough
|
|
406
|
+
to recognize and pick the feature to develop next. The deep per-feature reverse
|
|
407
|
+
(spec.md + design.md) is /appweaver adopt, run just-in-time when a feature is
|
|
408
|
+
about to be developed. Do NOT deep-model invariants/behaviour here.
|
|
409
|
+
|
|
410
|
+
Read the substrate first. Its `aggregate_signals` are CANDIDATE feature roots,
|
|
411
|
+
each with its files grouped by layer plus detected entities; `ui_attribution`
|
|
412
|
+
says which FRONTEND files serve which of those roots (and which serve none);
|
|
413
|
+
`git.history.churn` ranks significance; the category lists and `top_level_dirs`
|
|
414
|
+
fill in the rest.
|
|
415
|
+
Signals are input, not decisions — YOU draw the real feature boundaries:
|
|
416
|
+
- Merge a src module and its mirror test module into ONE feature (e.g.
|
|
417
|
+
src/.../MedicinalProducts + tests/.../MedicinalProducts → MedicinalProduct).
|
|
418
|
+
- Treat service-level / shared infrastructure (a shared persistence context,
|
|
419
|
+
cross-cutting adapters, host / service-defaults projects) as a Platform/Shared
|
|
420
|
+
concept, NOT a feature.
|
|
421
|
+
- Fold value objects, entities, domain events, commands and endpoints into the
|
|
422
|
+
feature that OWNS them — one feature concept, not one per type.
|
|
423
|
+
NAME EVERY CONCEPT IN THE CODE'S OWN VOCABULARY — read the identifiers the source
|
|
424
|
+
actually uses. "Aggregate", "entity" and "value object" are how aw-spec ORGANIZES a
|
|
425
|
+
feature map; they are not a claim that this codebase is modelled that way. Where the
|
|
426
|
+
code expresses its model differently, record what it does and keep the aw-spec
|
|
427
|
+
grouping around it.
|
|
428
|
+
|
|
429
|
+
Write the bundle (all paths under {{bundle_dir}}; bundle-relative links begin
|
|
430
|
+
with "/", per OKF §5.1):
|
|
431
|
+
- `index.md` (bundle root) — frontmatter EXACTLY `okf_version: "0.1"` and nothing
|
|
432
|
+
else; body = sections of bulleted links reusing each concept's `description`.
|
|
433
|
+
- `architecture/overview.md` (type: Reference) — the system at a glance. Its
|
|
434
|
+
`## Purpose` section MUST open with the whole solution/product name in bold
|
|
435
|
+
followed by "is a …" (e.g. "**Medicinal.Healthcare** is a …") — this bold token
|
|
436
|
+
is the PROJECT NAME the governance tier is named after, so get it right. Then:
|
|
437
|
+
the FEATURE MAP (each feature + one-line responsibility — NO seam/clean-torn
|
|
438
|
+
column, NO adopt-order), the tech stack, named external references / integration
|
|
439
|
+
points, and links to every other concept.
|
|
440
|
+
- `architecture/platform.md` (type: Reference) — the SHARED / cross-cutting
|
|
441
|
+
TECHNICAL note: the actual technology base (language, framework, persistence,
|
|
442
|
+
eventing, hosting), the shared infrastructure (persistence context, host /
|
|
443
|
+
service-defaults),
|
|
444
|
+
cross-cutting concerns (auth posture, concurrency, observability) AS-BUILT. This
|
|
445
|
+
is the evidence the technical constitution is scaffolded from — describe what the
|
|
446
|
+
code ACTUALLY does, mark anything stubbed/optional/inactive as such.
|
|
447
|
+
- `architecture/frontend.md` (type: Reference) — WRITE THIS ONLY IF the substrate's
|
|
448
|
+
`frontend_signals.present` is true; omit the file entirely otherwise (a backend-only
|
|
449
|
+
repo must not get one). It is the UI counterpart of the platform note and the
|
|
450
|
+
evidence the frontend lane's constitution is scaffolded from. Read the candidate
|
|
451
|
+
roots in `frontend_signals` and then READ REPRESENTATIVE UI SOURCE from their
|
|
452
|
+
component/route/store file lists, and record AS-BUILT: the lane root(s) and whether
|
|
453
|
+
the UI is separable or rendered inside the service tree; what it is built with (name
|
|
454
|
+
it from the code — the `framework_markers` are markers, not conclusions); how
|
|
455
|
+
components are organized and named; routing/navigation; where client state and
|
|
456
|
+
server data-fetching live; styling and any design-system or component library in
|
|
457
|
+
use; the accessibility, internationalization and error/loading-state handling the
|
|
458
|
+
code ACTUALLY exhibits; and the lane's build, lint and test tooling. State
|
|
459
|
+
inconsistency as inconsistency and absence as absence — an app with no
|
|
460
|
+
accessibility attributes is recorded as having none, never as needing them.
|
|
461
|
+
This note is also where the SHARED UI surface is recorded — `ui_attribution.
|
|
462
|
+
unattributed` lists the files serving no single aggregate (app shell, layout,
|
|
463
|
+
design system, global styles). Describe what they provide; they belong here
|
|
464
|
+
precisely because no slice owns them.
|
|
465
|
+
- `aggregates/<feature>.md` (type: Aggregate) — ONE per feature root, SHALLOW:
|
|
466
|
+
Responsibilities; the entities / value objects / domain events / commands / API
|
|
467
|
+
endpoints / persistence it OWNS (named at a glance from the signal's layer
|
|
468
|
+
files — a list, not a deep model); and the candidate `specs/<Feature>/` slice
|
|
469
|
+
name (feature = aggregate). Set `source_files` to the module's files, grouped
|
|
470
|
+
with YAML comment headers by each file's OWN folder — the path segment that
|
|
471
|
+
VARIES across the files after their shared parent (the layer folder in a
|
|
472
|
+
vertical slice; the tier project in an n-tier app; tests → a single `tests`
|
|
473
|
+
group). Do NOT impose a fixed Domain/Application/UI taxonomy — the CODE's
|
|
474
|
+
folders ARE the grouping. Set `timestamp` to the latest commit time across them.
|
|
475
|
+
Then set `ui_source_files` to the FRONTEND files that serve this aggregate,
|
|
476
|
+
grouped the same way. The substrate's `ui_attribution` proposes them per
|
|
477
|
+
aggregate — it is a NAME match, so confirm each against what the file actually
|
|
478
|
+
is and move or drop one it got wrong. Keep the key and leave it EMPTY where the
|
|
479
|
+
aggregate has no UI (and on a backend-only repo, where every concept has none);
|
|
480
|
+
never fold these paths into `source_files`, which stays the service surface.
|
|
481
|
+
- `aggregates/index.md` — the bounded-context / feature map (no frontmatter beyond
|
|
482
|
+
OKF index rules) linking every feature concept.
|
|
483
|
+
- An `index.md` in EVERY subdirectory (no frontmatter).
|
|
484
|
+
- `log.md` (bundle root) — first line under a `## <today's date>` heading must be
|
|
485
|
+
`Commit: ` + backtick + `{{head}}` + backtick (validator rule E4), then a
|
|
486
|
+
one-line Initialization entry noting the concept count.
|
|
487
|
+
Do NOT write a migration-backlog, a seam/clean-torn analysis, or an adopt-order —
|
|
488
|
+
those are migration artifacts and are out of scope for the development flow.
|
|
489
|
+
|
|
490
|
+
Provenance + safety (OKF hard rules):
|
|
491
|
+
- Stamp every concept `origin: reverse-engineered` and `generated_by:
|
|
492
|
+
aw-spec-onboard/1.6.0` in frontmatter.
|
|
493
|
+
- The CODE is the source of truth; capture what IS (quirks included), not what
|
|
494
|
+
SHOULD be. Where intent is unclear from code + git history, add a concrete
|
|
495
|
+
`open_questions` entry rather than inventing one.
|
|
496
|
+
- NEVER fabricate facts, and NEVER emit secrets/tokens/credentials/internal
|
|
497
|
+
hostnames — describe shape, never values.
|
|
498
|
+
- Write ONLY inside {{bundle_dir}}; do NOT modify any source file.
|
|
499
|
+
Report the bundle tree and the concept count by type.
|
|
500
|
+
outputs:
|
|
501
|
+
- { name: bundle_files, from: "$.files" }
|
|
502
|
+
|
|
503
|
+
- id: verify_authored
|
|
504
|
+
action: verify_context
|
|
505
|
+
require_non_empty: bundle_files
|
|
506
|
+
on_empty: stop
|
|
507
|
+
on_empty_message: "No feature-map files were written to {{bundle_dir}}. Ensure the substrate {{inventory_json}} has aggregate_signals and re-run."
|
|
508
|
+
|
|
509
|
+
# 4. CONFORMANCE gate — OKF v0.1 validator (errors block; warnings noted).
|
|
510
|
+
- id: validate_bundle
|
|
511
|
+
action: execute_script
|
|
512
|
+
script: { ref: inventory }
|
|
513
|
+
subcommand: validate
|
|
514
|
+
args: ["--bundle", "{{bundle_dir}}", "--repo-root", "{{root}}"]
|
|
515
|
+
outputs:
|
|
516
|
+
- { name: conformant, from: "$.conformant" }
|
|
517
|
+
- { name: okf_errors, from: "$.errors" }
|
|
518
|
+
- { name: okf_warnings, from: "$.warnings" }
|
|
519
|
+
- { name: concepts, from: "$.concepts" }
|
|
520
|
+
|
|
521
|
+
- id: conformance_gate
|
|
522
|
+
action: verify_context
|
|
523
|
+
require_true: conformant
|
|
524
|
+
on_false: stop
|
|
525
|
+
on_false_message: "The OKF feature map at {{bundle_dir}} is NON-CONFORMANT (errors: {{okf_errors}}). Fix the reported ERRORs (unparseable frontmatter, missing `type`, malformed index.md/log.md) and re-run."
|
|
526
|
+
|
|
527
|
+
# ═══════════════ PART 2 — GOVERNANCE SCAFFOLD (project-level) ════════════════
|
|
528
|
+
# Establish the governing tier ONCE, from the feature map just written (the whole-
|
|
529
|
+
# repo vantage). No slice is adopted, so list-adopted returns slice_count=0 but STILL
|
|
530
|
+
# yields project_name / overview / project_context (domain evidence) and
|
|
531
|
+
# design_context (= overview + platform: the technical evidence) from the bundle.
|
|
532
|
+
# There is NO require_adopted gate here — that is the whole point of onboarding first.
|
|
533
|
+
|
|
534
|
+
- id: project_ctx
|
|
535
|
+
action: execute_script
|
|
536
|
+
script: { ref: revcon }
|
|
537
|
+
subcommand: list-adopted
|
|
538
|
+
outputs:
|
|
539
|
+
- { name: slice_count, from: "$.slice_count" }
|
|
540
|
+
- { name: spec_context, from: "$.spec_context" } # at onboard = project_context (no specs yet)
|
|
541
|
+
- { name: design_context, from: "$.design_context" } # at onboard = overview + platform (the tech evidence)
|
|
542
|
+
- { name: project_context, from: "$.project_context" } # overview + aggregates/index + platform + index
|
|
543
|
+
- { name: project_name, from: "$.project_name" }
|
|
544
|
+
- { name: overview, from: "$.overview" }
|
|
545
|
+
|
|
546
|
+
# Slugify + `brf-` prefix the domain name and create guardrails/projects/brf-<domain>/.
|
|
547
|
+
# Name: explicit arg → PROJECT name from the OKF overview → repo basename. Guarded
|
|
548
|
+
# against clobbering a project that already holds .md files.
|
|
549
|
+
- id: pack_setup
|
|
550
|
+
action: execute_script
|
|
551
|
+
script: { ref: revcon }
|
|
552
|
+
subcommand: project-setup
|
|
553
|
+
args: ["--name", "{{USER_INPUT}}", "--fallback", "{{project_name}}"]
|
|
554
|
+
outputs:
|
|
555
|
+
- { name: domain_slug, from: "$.domain_slug" }
|
|
556
|
+
- { name: pack_dir, from: "$.pack_dir" }
|
|
557
|
+
- { name: domain_rule_bindings, from: "$.domain_rule_bindings" }
|
|
558
|
+
- { name: domain_constitution_source, from: "$.domain_constitution_source" }
|
|
559
|
+
- { name: pack_present, from: "$.pack_present" }
|
|
560
|
+
|
|
561
|
+
- id: pack_guard
|
|
562
|
+
action: verify_context
|
|
563
|
+
require_value: pack_present
|
|
564
|
+
equals: "false"
|
|
565
|
+
on_mismatch: stop
|
|
566
|
+
on_mismatch_message: "The project guardrails/projects/{{domain_slug}}/ already holds curated rule files — onboard would overwrite them. Back up or remove that folder to re-onboard, or amend it via /appweaver constitution."
|
|
567
|
+
|
|
568
|
+
# ── DOMAIN RULE SET (provisional, evidenced by the SCAN) ────────────────────
|
|
569
|
+
# Feed NEUTRAL shape skeletons (rev-templates/, zero content to leak) + the rule-
|
|
570
|
+
# partition authority + the project context (the feature map). NO adopted specs
|
|
571
|
+
# exist — the evidence is the OKF overview + aggregates/index + platform.
|
|
572
|
+
- id: ctx_pack
|
|
573
|
+
action: build_context
|
|
574
|
+
context:
|
|
575
|
+
- { path: "{{inventory_json}}" } # the COMPLETE deterministic scan substrate — read representative SOURCE from its file lists (the OKF map only SUMMARISES this)
|
|
576
|
+
- { path: .appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md, optional: true }
|
|
577
|
+
- { path: .appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md, optional: true }
|
|
578
|
+
- { path: .appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md, optional: true }
|
|
579
|
+
- { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
|
|
580
|
+
context_from: project_context
|
|
581
|
+
- id: author_pack
|
|
582
|
+
action: agent_generate
|
|
583
|
+
tools: "Read,Write,Edit"
|
|
584
|
+
permission_mode: acceptEdits
|
|
585
|
+
task: |
|
|
586
|
+
Scaffold the PROJECT-level DOMAIN RULE SET for **{{project_name}}** (domain
|
|
587
|
+
{{domain_slug}}) into guardrails/projects/{{domain_slug}}/domain/ (the dir exists),
|
|
588
|
+
plus the domain map guardrails/projects/{{domain_slug}}/domain-rule-bindings.md at the
|
|
589
|
+
project root. A project keeps its three rule classes in domain/ · service/ · frontend/
|
|
590
|
+
and both maps at its root; adopt reconciles this set in place, so a file written
|
|
591
|
+
anywhere else is unreachable.
|
|
592
|
+
|
|
593
|
+
EVIDENCE = THE CODE ITSELF (deep read), NOT the shallow map. The OKF FEATURE MAP in
|
|
594
|
+
context (architecture/overview.md, aggregates/index.md, architecture/platform.md)
|
|
595
|
+
only SUMMARISES the codebase. READ REPRESENTATIVE SOURCE to extract the real domain
|
|
596
|
+
rules: use {{inventory_json}} (in context) to locate the domain-carrying files —
|
|
597
|
+
entities, value objects, aggregates, domain events, invariant checks, validation —
|
|
598
|
+
across the aggregate_signals, and Read enough of them to state each rule from what
|
|
599
|
+
the code ACTUALLY enforces. Do NOT invent a rule the code does not evidence, and do
|
|
600
|
+
NOT rely on the map alone. There are NO adopted specs yet; this is the whole-repo
|
|
601
|
+
vantage — describe the domain / bounded context AS A WHOLE, so any feature later
|
|
602
|
+
slots in without a rewrite.
|
|
603
|
+
|
|
604
|
+
CONCERNS HINT: {{USER_INPUT}} may carry a "concerns: a, b, c" clause. Treat any listed
|
|
605
|
+
concern as a SEARCH HINT — go look for it in the code — but you still DECIDE presence
|
|
606
|
+
from evidence: include a concern's rule file ONLY if the code exhibits it, drop a
|
|
607
|
+
listed concern the code shows none of, and ADD an unlisted concern the code clearly
|
|
608
|
+
evidences. Ignore any non-concerns text (the domain name / scope hint).
|
|
609
|
+
|
|
610
|
+
PROVISIONAL BY CONSTRUCTION. Because no slice is adopted, you have the domain's
|
|
611
|
+
SHAPE (its features, ubiquitous language, bounded-context map, evident concerns)
|
|
612
|
+
but not yet its enumerated rule ids. Write each rule at the level the feature map
|
|
613
|
+
evidences and mark unresolved specifics `PROVISIONAL — reconciled at adopt`
|
|
614
|
+
(adopt fills the exact BR-/CN-/DC-/IC- ids when the feature is developed). NEVER
|
|
615
|
+
invent a rule the code/feature-map does not evidence.
|
|
616
|
+
|
|
617
|
+
SKELETONS ARE SHAPE ONLY. The *.skeleton.md files (rev-templates/) show HEADINGS,
|
|
618
|
+
frontmatter, the rule-partition and tone — and carry NO domain content. Copy the
|
|
619
|
+
SHAPE; never treat a bracketed [TOKEN] or example marker as a value to assert.
|
|
620
|
+
|
|
621
|
+
EVIDENCED-ONLY (lean): write a `<concern>.domain.md` ONLY for a concern the
|
|
622
|
+
feature map / platform note actually exhibits. NAME EACH FILE AFTER THE CONCERN THE
|
|
623
|
+
CODE EXHIBITS, never after a methodology the code may not follow — a filename is an
|
|
624
|
+
assertion too. Consider, include only if evidenced:
|
|
625
|
+
- domain-model.domain.md — the ubiquitous language + bounded-context /
|
|
626
|
+
feature map, WHAT this codebase's model is. Written wherever the code carries a
|
|
627
|
+
discernible domain model; omitted where it carries none (a pure script/ETL repo).
|
|
628
|
+
This is the domain tier's authority for /specify.
|
|
629
|
+
- data-classification.domain.md — only if the overview shows classified data.
|
|
630
|
+
- auditing.domain.md — only if the platform note shows audit/immutability.
|
|
631
|
+
- authorization.domain.md — only if an auth posture is evident.
|
|
632
|
+
- persistence.domain.md — only if retention/immutability/no-hard-delete is evident.
|
|
633
|
+
- cqrs.domain.md — only if the platform note shows a command/query split.
|
|
634
|
+
- eventing.domain.md — only if domain events are evident.
|
|
635
|
+
- api-versioning.domain.md — only if the API surface is versioned.
|
|
636
|
+
Plus, as needed:
|
|
637
|
+
- a domain reference file per distinct domain identifier/standard the overview names.
|
|
638
|
+
- domain-requirements.md — the PROJECT overview: open with a
|
|
639
|
+
`[DOMAIN: Bounded Contexts / Modules]` map (from the overview + aggregates
|
|
640
|
+
index), then per-subsection pointers, platform topology, governance overrides.
|
|
641
|
+
Stamp every file `origin: reverse-engineered`, `generated_by: aw-spec-onboard/1.6.0`,
|
|
642
|
+
and note the project is a provisional scaffold reconciled per slice at adopt.
|
|
643
|
+
|
|
644
|
+
domain-rule-bindings.md (MANDATORY — /specify's resolve-domain reads this exact filename).
|
|
645
|
+
Wire ONLY the files you generated, preserving the RULE PARTITION:
|
|
646
|
+
- `## /aw-spec-constitution` — `domain/domain-constitution.md` FIRST (the project's
|
|
647
|
+
charter; a later step in this same run authors it, so wire the bullet now), then the
|
|
648
|
+
domain identity/regulatory/interop files → domain principles.
|
|
649
|
+
- `## /aw-spec-specify` — the FULL domain set (specify models the domain, lifts CN-/DC-/IC-).
|
|
650
|
+
- `## /aw-spec-design` — `_None — design loads no domain file. Domain reaches design only through the spec._`
|
|
651
|
+
- `## /aw-spec-implement` — `_None — implement loads no domain file. Domain reaches implement only through design.md._`
|
|
652
|
+
- `## /aw-spec-gate` — the conformance-checklist set (the *.domain.md files).
|
|
653
|
+
Each bullet is a workspace-relative path `- guardrails/projects/{{domain_slug}}/domain/<file>`.
|
|
654
|
+
Write ONLY inside guardrails/projects/{{domain_slug}}/ (domain/ + the map). Report the
|
|
655
|
+
files written.
|
|
656
|
+
outputs:
|
|
657
|
+
- { name: pack_files, from: "$.files" }
|
|
658
|
+
|
|
659
|
+
- id: verify_pack
|
|
660
|
+
action: verify_context
|
|
661
|
+
require_non_empty: pack_files
|
|
662
|
+
on_empty: stop
|
|
663
|
+
on_empty_message: "No domain rule files were written to guardrails/projects/{{domain_slug}}/domain/. Ensure the feature map carries a modellable domain (a feature map + ubiquitous language) and re-run."
|
|
664
|
+
- id: require_domain_rule_bindings
|
|
665
|
+
action: verify_context
|
|
666
|
+
required_files: ["{{domain_rule_bindings}}"]
|
|
667
|
+
|
|
668
|
+
# ── DOMAIN CONSTITUTION SOURCE — <project>/domain/domain-constitution.md ────────────
|
|
669
|
+
# Named and placed exactly as a greenfield industry corpus names and places its charter,
|
|
670
|
+
# and already wired as the first `## /aw-spec-constitution` bullet by the step above.
|
|
671
|
+
- id: ctx_domain_source
|
|
672
|
+
action: build_context
|
|
673
|
+
context:
|
|
674
|
+
- { path: "{{domain_rule_bindings}}" }
|
|
675
|
+
- { path: .appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md, optional: true }
|
|
676
|
+
context_from: project_context
|
|
677
|
+
- id: author_domain_source
|
|
678
|
+
action: agent_author
|
|
679
|
+
include_standards: false
|
|
680
|
+
output_target: { type: file, path: "{{domain_constitution_source}}" }
|
|
681
|
+
task: |
|
|
682
|
+
Author the DOMAIN CONSTITUTION SOURCE (the output target) — the human-readable
|
|
683
|
+
charter for the WHOLE PROJECT **{{project_name}}** (domain {{domain_slug}}),
|
|
684
|
+
scaffolded from the OKF feature map (architecture/overview.md, aggregates/index.md
|
|
685
|
+
— in context) and the generated project's domain-rule-bindings.md. Follow the SHAPE of the
|
|
686
|
+
neutral skeleton domain-constitution.skeleton.md (in context) — its Project-Identity
|
|
687
|
+
+ Domain-Principle structure — so the normal /appweaver constitution can
|
|
688
|
+
re-derive the domain half later. The skeleton carries NO content; every value
|
|
689
|
+
comes from the feature-map evidence.
|
|
690
|
+
|
|
691
|
+
PROJECT CHARTER, NOT AN AGGREGATE SPEC, and PROVISIONAL (no slice adopted yet).
|
|
692
|
+
Structure:
|
|
693
|
+
- Title `# {{project_name}} Domain Constitution (as-built, provisional)` and a
|
|
694
|
+
one-line origin note (`origin: reverse-engineered`, today's date).
|
|
695
|
+
- `## Project Identity` — project name = {{project_name}}; mission (from the
|
|
696
|
+
overview Purpose); bounded-context / feature map (from the overview feature map +
|
|
697
|
+
aggregates/index.md — list the features AND named external references as
|
|
698
|
+
contexts); architecture posture (from platform.md).
|
|
699
|
+
- `## Domain Principles` — principles the domain embodies, TITLED by DOMAIN CONCERN
|
|
700
|
+
(not by a feature name), each a declarative rule that would hold across features.
|
|
701
|
+
Number with a stable "D1, D2, …" convention (the composed constitution assigns
|
|
702
|
+
exact roman numerals after the technology base). Cite the feature-map evidence;
|
|
703
|
+
mark any principle whose exact rule ids are not yet enumerable `PROVISIONAL —
|
|
704
|
+
reconciled at adopt`.
|
|
705
|
+
- AS-BUILT: state the rule the code evidences; do NOT prescribe an ideal it does
|
|
706
|
+
not meet, and do NOT create a debt/backlog (migration is a later phase) — simply
|
|
707
|
+
omit an aspiration the code shows none of.
|
|
708
|
+
- Reference (do not restate) the technology base and the project's rule files.
|
|
709
|
+
Return the charter markdown only.
|
|
710
|
+
|
|
711
|
+
# ── SPLIT CONSTITUTION — scaffold the two memory halves ──────────────────────
|
|
712
|
+
# Create the halves this project's LANES call for. The domain half is always created
|
|
713
|
+
# — domain is not a lane, it addends whichever halves exist — and the technical half
|
|
714
|
+
# only where a service lane is declared. `setup_tech_flag` carries that decision to
|
|
715
|
+
# EVERY setup-constitution call in this workflow, the UI one included: this command
|
|
716
|
+
# creates the always-present halves as a side effect of whatever else it is asked to
|
|
717
|
+
# do, so a later call without the flag silently recreates the half an earlier call
|
|
718
|
+
# was told to skip.
|
|
719
|
+
- id: setup_constitution
|
|
720
|
+
action: execute_script
|
|
721
|
+
script: { ref: actions }
|
|
722
|
+
subcommand: setup-constitution
|
|
723
|
+
args: ["{{setup_tech_flag}}"]
|
|
724
|
+
outputs:
|
|
725
|
+
- { name: constitution_technical_file, from: "$.constitution_technical_file" }
|
|
726
|
+
- { name: constitution_domain_file, from: "$.constitution_domain_file" }
|
|
727
|
+
|
|
728
|
+
# TECHNICAL HALF — from the OKF overview + platform note (design_context), DOMAIN-FREE.
|
|
729
|
+
# The neutral technical shape skeleton is fed via CONTEXT (not the sticky standards
|
|
730
|
+
# set, which is empty), so nothing leaks into the Part-1 feature-map agent.
|
|
731
|
+
- id: ctx_technical
|
|
732
|
+
action: build_context
|
|
733
|
+
condition: "{{svc_lane}} == true"
|
|
734
|
+
context:
|
|
735
|
+
- { path: "{{constitution_technical_file}}" }
|
|
736
|
+
- { path: .appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md, optional: true }
|
|
737
|
+
- { path: .appweaver/orchestrator/rev-templates/ai-rules.reference.md, optional: true }
|
|
738
|
+
context_from: design_context
|
|
739
|
+
- id: author_technical
|
|
740
|
+
action: agent_author
|
|
741
|
+
condition: "{{svc_lane}} == true"
|
|
742
|
+
include_standards: false
|
|
743
|
+
output_target: { type: file, path: "{{constitution_technical_file}}" }
|
|
744
|
+
task: |
|
|
745
|
+
Scaffold the TECHNICAL project constitution (the target file in context) —
|
|
746
|
+
AS-BUILT, from the OKF architecture overview + platform note (in context) that
|
|
747
|
+
describe this codebase's ACTUAL technology base. It is a TEMPLATE with [ALL_CAPS]
|
|
748
|
+
tokens; this is the domain-AGNOSTIC half. No slice is adopted, so the evidence is
|
|
749
|
+
the SCAN (overview stack + platform note), and principles are PROVISIONAL —
|
|
750
|
+
reconciled with real code coordinates when features are adopted.
|
|
751
|
+
|
|
752
|
+
EVIDENCE-FIRST — DISCOVER the principle set; do NOT inherit it. The skeleton
|
|
753
|
+
(technical-constitution.skeleton.md, in context) is a NEUTRAL SHAPE REFERENCE ONLY
|
|
754
|
+
— heading style, Sync-Impact-Report shape, evidence-line pattern — and carries NO
|
|
755
|
+
principle set. Author a principle ONLY for a technology trait the platform note /
|
|
756
|
+
overview actually evidences (the framework, persistence, eventing, concurrency,
|
|
757
|
+
hosting, testing, auth posture that ARE there). Cite the evidence on every
|
|
758
|
+
principle (e.g. "(evidence: platform.md persistence; overview stack)"); mark it
|
|
759
|
+
`PROVISIONAL — code coordinate reconciled at adopt` where the exact file/type is
|
|
760
|
+
not yet pinned.
|
|
761
|
+
- State PARTIAL / STUBBED / OPTIONAL traits AT THE LEVEL THE CODE REACHES, never a
|
|
762
|
+
template ideal (e.g. permissive-stub auth is not "Security by Default").
|
|
763
|
+
- OMIT pure-aspiration traits the platform note shows ZERO of. Do NOT create an
|
|
764
|
+
as-built-debt/backlog sink — migration is a separate later phase; an unmet ideal
|
|
765
|
+
is simply not asserted here.
|
|
766
|
+
- The project name is **{{project_name}}** — use it for the title / any
|
|
767
|
+
[PROJECT_NAME] token so this half, the domain half, and the charter name the
|
|
768
|
+
SAME project (never the outer tooling folder or a namespace).
|
|
769
|
+
- Do NOT add any domain-specific principle, identifier, terminology, regulatory or
|
|
770
|
+
interop rule — those belong to constitution.domain.md.
|
|
771
|
+
- NUMBER the discovered principles with sequential roman numerals from I, NO gaps,
|
|
772
|
+
NO padding. STATE the hand-off in the Sync Impact Report ("Technical principles:
|
|
773
|
+
I–<N>; domain half continues at <N+1>").
|
|
774
|
+
- Fill EVERY placeholder; leave no unexplained [BRACKET] (justify a genuine
|
|
775
|
+
deferral as TODO(<FIELD>): reason). Bump CONSTITUTION_VERSION by semver; ISO
|
|
776
|
+
YYYY-MM-DD dates (RATIFICATION_DATE = today). Preserve heading hierarchy.
|
|
777
|
+
- PREPEND a "Sync Impact Report" HTML comment: version old→new, the DISCOVERED
|
|
778
|
+
principle set, any trait DELIBERATELY OMITTED for lack of evidence (with why),
|
|
779
|
+
the technical count / domain hand-off numeral, and dependent artifacts (✅/⚠).
|
|
780
|
+
Return the complete updated technical constitution content only.
|
|
781
|
+
|
|
782
|
+
- id: technical_validation_loop
|
|
783
|
+
action: loop
|
|
784
|
+
condition: "{{svc_lane}} == true"
|
|
785
|
+
while: "{{technical_ok}} != true"
|
|
786
|
+
max_iterations: 3
|
|
787
|
+
steps:
|
|
788
|
+
- id: tech_lint
|
|
789
|
+
action: execute_script
|
|
790
|
+
script: { ref: actions }
|
|
791
|
+
subcommand: constitution-verify
|
|
792
|
+
args: ["--file", "{{constitution_technical_file}}"]
|
|
793
|
+
outputs:
|
|
794
|
+
- { name: technical_ok, from: "$.ok" }
|
|
795
|
+
- { name: technical_issues, from: "$.issues" }
|
|
796
|
+
- id: tech_lint_break
|
|
797
|
+
action: break
|
|
798
|
+
condition: "{{technical_ok}} == true"
|
|
799
|
+
- id: patch_technical
|
|
800
|
+
action: agent_author
|
|
801
|
+
context: ["{{constitution_technical_file}}"]
|
|
802
|
+
include_standards: false
|
|
803
|
+
output_target: { type: file, path: "{{constitution_technical_file}}" }
|
|
804
|
+
task: |
|
|
805
|
+
Fix these mechanical defects in the technical constitution (target file in
|
|
806
|
+
context), changing NOTHING else — preserve every principle, the heading
|
|
807
|
+
hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder
|
|
808
|
+
with concrete text (or a justified TODO(<FIELD>): reason); make the body's
|
|
809
|
+
version line AGREE with the Sync Impact Report; ISO YYYY-MM-DD dates.
|
|
810
|
+
Defects: {{technical_issues}}
|
|
811
|
+
Return the complete updated technical constitution content only.
|
|
812
|
+
|
|
813
|
+
# ── UI HALF (frontend lane only) ────────────────────────────────────────────
|
|
814
|
+
# Placed HERE for the same reason the greenfield constitution places it here: AFTER
|
|
815
|
+
# the technical half, so the service lane's rules cannot leak into the lane's own
|
|
816
|
+
# base, and BEFORE the domain half, so no domain file can leak into either. Domain
|
|
817
|
+
# reaches the UI lane through the spec, exactly as it reaches the service lane.
|
|
818
|
+
#
|
|
819
|
+
# The direction is INVERTED from greenfield. There, this half ratifies the project's
|
|
820
|
+
# mapped frontend rule files; here those files do not exist yet, so the evidence is
|
|
821
|
+
# the UI SOURCE — read through the scan substrate — and the project is generated
|
|
822
|
+
# afterwards as the detail layer under whatever this half ratifies. That is the same
|
|
823
|
+
# order the technical tier already uses in this workflow.
|
|
824
|
+
|
|
825
|
+
# Create the UI half from its template — on demand, unlike the other two. Its
|
|
826
|
+
# ABSENCE is meaningful: a repo with no UI never gets the file at all.
|
|
827
|
+
- id: setup_ui_constitution
|
|
828
|
+
action: execute_script
|
|
829
|
+
condition: "{{ui_lane}} == true"
|
|
830
|
+
script: { ref: actions }
|
|
831
|
+
subcommand: setup-constitution
|
|
832
|
+
args: ["--ui", "{{setup_tech_flag}}"]
|
|
833
|
+
outputs:
|
|
834
|
+
- { name: constitution_ui_file, from: "$.constitution_ui_file" }
|
|
835
|
+
- { name: ui_created, from: "$.ui_created" }
|
|
836
|
+
|
|
837
|
+
- id: ctx_ui
|
|
838
|
+
action: build_context
|
|
839
|
+
condition: "{{ui_lane}} == true"
|
|
840
|
+
context:
|
|
841
|
+
- { path: "{{constitution_ui_file}}" } # the target half being filled
|
|
842
|
+
- { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — frontend_signals + the UI file lists to read source from
|
|
843
|
+
- { path: .appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md, optional: true } # SHAPE ONLY: heading style, Sync-Impact-Report shape, evidence-line pattern (zero UI content)
|
|
844
|
+
- { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note — corroborate, don't rely on alone
|
|
845
|
+
- id: author_ui
|
|
846
|
+
action: agent_author
|
|
847
|
+
condition: "{{ui_lane}} == true"
|
|
848
|
+
include_standards: false
|
|
849
|
+
output_target: { type: file, path: "{{constitution_ui_file}}" }
|
|
850
|
+
task: |
|
|
851
|
+
Scaffold the USER EXPERIENCE constitution — the FRONTEND LANE's half (the target
|
|
852
|
+
file in context) — for **{{project_name}}**, AS-BUILT and PROVISIONAL. It is a
|
|
853
|
+
TEMPLATE with [ALL_CAPS] tokens. This half is domain-AGNOSTIC, like the technical
|
|
854
|
+
base it runs parallel to.
|
|
855
|
+
Why this lane was detected: {{ui_evidence}}
|
|
856
|
+
Lane declaration: {{ui_declaration_note}}
|
|
857
|
+
User hint (optional, may name nothing about the UI): {{USER_INPUT}}
|
|
858
|
+
|
|
859
|
+
EVIDENCE = THE UI CODE ITSELF (deep read). Authority, in order:
|
|
860
|
+
1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_json}} (in context):
|
|
861
|
+
`frontend_signals` lists the candidate lane roots with their kind
|
|
862
|
+
(spa / server-rendered / desktop), their framework markers, and their
|
|
863
|
+
component / route / store / style file lists. READ ENOUGH OF THOSE FILES to
|
|
864
|
+
state each principle from what the UI ACTUALLY does. Do NOT assert an
|
|
865
|
+
experience trait you have not seen in the code.
|
|
866
|
+
2. The OKF architecture/frontend.md note (in context, if present) — SECONDARY,
|
|
867
|
+
shallow corroboration only.
|
|
868
|
+
The `framework_markers` are MARKERS, not conclusions — name the stack from the code.
|
|
869
|
+
Never carry over a principle, a folder convention, an accessibility target or a
|
|
870
|
+
quality gate from a greenfield UI template, another project, or your own experience
|
|
871
|
+
of how frontends are usually governed. If this code does not show it, it is not a
|
|
872
|
+
principle here.
|
|
873
|
+
|
|
874
|
+
EVIDENCE-FIRST — DISCOVER the principle set; do NOT inherit it. The skeleton
|
|
875
|
+
(ui-constitution.skeleton.md, in context) is a NEUTRAL SHAPE REFERENCE ONLY and
|
|
876
|
+
names no framework, router, component library, design system or conformance
|
|
877
|
+
standard. Copy the SHAPE; discover the CONTENT from the code.
|
|
878
|
+
- `## Declared Lane` — name the lane, what it is built with, and the root it owns,
|
|
879
|
+
ALL READ FROM THE CODE. Where the UI is rendered inside the service tree and owns
|
|
880
|
+
no root of its own, say exactly that: it is a legitimate as-built lane, reversed
|
|
881
|
+
in place. Where a declaration exists and disagrees with the code, REPORT the
|
|
882
|
+
disagreement rather than resolving it silently.
|
|
883
|
+
- Author a UX principle ONLY for an experience trait the UI code evidences, and cite
|
|
884
|
+
the evidence inline on each one (e.g. "(evidence: <real component/route/store
|
|
885
|
+
path>)"). State PARTIAL / INCONSISTENT / ABSENT traits at the level the code
|
|
886
|
+
actually reaches — an app with no accessibility attributes does not get an
|
|
887
|
+
accessibility principle written as though it were met.
|
|
888
|
+
- OMIT a concern the UI shows ZERO of. Do NOT create a debt/backlog sink —
|
|
889
|
+
modernization is a separate later phase, and an unmet ideal is simply not asserted.
|
|
890
|
+
- Where the codebase is INCONSISTENT, state the DOMINANT convention as the rule and
|
|
891
|
+
record the divergence with its coordinates. Do not pick a winner the code has not.
|
|
892
|
+
- NUMBER the principles as a UX-* series (UX-I, UX-II, …). Do NOT continue the
|
|
893
|
+
technical half's numbering or the domain half's — this half is PARALLEL to the
|
|
894
|
+
technical base, so its series is unaffected by how many principles that base has.
|
|
895
|
+
- This half stands ALONE as the frontend lane's base: it neither restates the service
|
|
896
|
+
lane's principles nor cites them by number. Add NO domain-specific principle,
|
|
897
|
+
identifier, terminology or regulatory rule — those belong to constitution.domain.md.
|
|
898
|
+
- Keep every path under the lane's own root. This half never adds to the service
|
|
899
|
+
lane's folder structure.
|
|
900
|
+
- The project name is **{{project_name}}** — use it for the title / any [PROJECT_NAME]
|
|
901
|
+
token, so all the halves name the SAME project.
|
|
902
|
+
- Mark the half PROVISIONAL: it is scaffolded from the whole-repo scan, and a later
|
|
903
|
+
adopt / constitution run reconciles it against per-slice evidence.
|
|
904
|
+
- Fill EVERY placeholder; leave no unexplained [BRACKET] (justify a genuine deferral
|
|
905
|
+
as TODO(<FIELD>): reason). Bump CONSTITUTION_VERSION by semver — this half versions
|
|
906
|
+
independently of the other two. ISO YYYY-MM-DD dates (RATIFICATION_DATE = today).
|
|
907
|
+
Preserve heading hierarchy.
|
|
908
|
+
- PREPEND a "Sync Impact Report" HTML comment: version old→new, the lane, the
|
|
909
|
+
DISCOVERED UX principle set, any experience concern DELIBERATELY OMITTED for lack
|
|
910
|
+
of evidence (with why), and dependent artifacts (✅/⚠).
|
|
911
|
+
Return the complete updated UI constitution content only.
|
|
912
|
+
|
|
913
|
+
- id: ui_validation_loop
|
|
914
|
+
action: loop
|
|
915
|
+
condition: "{{ui_lane}} == true"
|
|
916
|
+
while: "{{ui_ok}} != true"
|
|
917
|
+
max_iterations: 3
|
|
918
|
+
steps:
|
|
919
|
+
- id: ui_lint
|
|
920
|
+
action: execute_script
|
|
921
|
+
script: { ref: actions }
|
|
922
|
+
subcommand: constitution-verify
|
|
923
|
+
args: ["--file", "{{constitution_ui_file}}"]
|
|
924
|
+
outputs:
|
|
925
|
+
- { name: ui_ok, from: "$.ok" }
|
|
926
|
+
- { name: ui_issues, from: "$.issues" }
|
|
927
|
+
- id: ui_lint_break
|
|
928
|
+
action: break
|
|
929
|
+
condition: "{{ui_ok}} == true"
|
|
930
|
+
- id: patch_ui
|
|
931
|
+
action: agent_author
|
|
932
|
+
context: ["{{constitution_ui_file}}"]
|
|
933
|
+
include_standards: false
|
|
934
|
+
output_target: { type: file, path: "{{constitution_ui_file}}" }
|
|
935
|
+
task: |
|
|
936
|
+
Fix these mechanical defects in the UI constitution (target file in context),
|
|
937
|
+
changing NOTHING else — preserve every principle, the UX-* numbering, the heading
|
|
938
|
+
hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder with
|
|
939
|
+
concrete text (or a justified TODO(<FIELD>): reason); make the body's version line
|
|
940
|
+
AGREE with the Sync Impact Report; ISO YYYY-MM-DD dates.
|
|
941
|
+
Defects: {{ui_issues}}
|
|
942
|
+
Return the complete updated UI constitution content only.
|
|
943
|
+
|
|
944
|
+
# The UI half's lint verdict only carries meaning where a lane exists. On a backend-only
|
|
945
|
+
# repo no half was created, so the run reports that rather than a bare false a reader
|
|
946
|
+
# would take for a half that needs a manual touch.
|
|
947
|
+
- id: ui_validation_state_absent
|
|
948
|
+
action: set
|
|
949
|
+
vars: { ui_validation_state: "n/a — no frontend lane, no UI half authored" }
|
|
950
|
+
- id: ui_validation_state_present
|
|
951
|
+
action: set
|
|
952
|
+
condition: "{{ui_lane}} == true"
|
|
953
|
+
vars: { ui_validation_state: "{{ui_ok}}" }
|
|
954
|
+
|
|
955
|
+
# DOMAIN HALF — from the project + charter, principles continue the technical numbering.
|
|
956
|
+
- id: ctx_domain
|
|
957
|
+
action: build_context
|
|
958
|
+
context:
|
|
959
|
+
- { path: "{{constitution_domain_file}}" }
|
|
960
|
+
- { path: "{{constitution_technical_file}}" } # to CONTINUE its numbering (evidenced-only ⇒ not a fixed XV)
|
|
961
|
+
- { path: "{{domain_constitution_source}}" }
|
|
962
|
+
- { path: "{{domain_rule_bindings}}" }
|
|
963
|
+
context_from: project_context
|
|
964
|
+
- id: author_domain
|
|
965
|
+
action: agent_author
|
|
966
|
+
include_standards: false
|
|
967
|
+
output_target: { type: file, path: "{{constitution_domain_file}}" }
|
|
968
|
+
task: |
|
|
969
|
+
Scaffold the DOMAIN ADDENDA constitution for the WHOLE PROJECT **{{project_name}}**
|
|
970
|
+
(domain {{domain_slug}}) — the target file in context — AS-BUILT and PROVISIONAL,
|
|
971
|
+
from the OKF project context (overview, aggregates/index — in context) + the
|
|
972
|
+
domain-constitution source + the generated project (domain-rule-bindings in context; READ
|
|
973
|
+
the project's rule files under guardrails/projects/{{domain_slug}}/). It is a TEMPLATE
|
|
974
|
+
with [ALL_CAPS] tokens; this half carries ONLY domain material.
|
|
975
|
+
- Name the SAME project as the technical half / charter: title / any [PROJECT_NAME]
|
|
976
|
+
token = {{project_name}}. This is a PROJECT constitution, not an aggregate spec —
|
|
977
|
+
govern the domain / bounded context as a whole.
|
|
978
|
+
- Fill EVERY template placeholder — an unfilled one keeps this half out of the
|
|
979
|
+
composed constitution. Brackets of your OWN in the prose are fine: a regulation,
|
|
980
|
+
standard or identifier the domain actually cites is content, not a leftover slot.
|
|
981
|
+
- ADOPTED MODELLING STANDARD: name the methodology the technical half actually
|
|
982
|
+
mandates and cite that principle BY ITS ACTUAL NUMERAL, read from
|
|
983
|
+
constitution.technical.md in context. That half is evidenced-only here, so the
|
|
984
|
+
numeral is whatever the code supported — never a value carried over from another
|
|
985
|
+
constitution. If it mandates no modelling methodology, say so plainly rather than
|
|
986
|
+
supplying one.
|
|
987
|
+
- Author ONLY the domain layer: domain principles, domain folder additions,
|
|
988
|
+
regulatory/security posture, domain governance — from the project + charter. NUMBER
|
|
989
|
+
them by CONTINUING the technical half's roman numerals: READ
|
|
990
|
+
constitution.technical.md (in context), find its LAST numeral N, start the first
|
|
991
|
+
domain principle at N+1 (do NOT assume it ends at XV). TITLE each by DOMAIN
|
|
992
|
+
CONCERN (not a feature name); state which technical principle (by its ACTUAL
|
|
993
|
+
numeral) it EXTENDS. Do NOT restate the technical principles — reference them.
|
|
994
|
+
Mark any principle whose exact rule ids are not yet enumerable `PROVISIONAL —
|
|
995
|
+
reconciled at adopt`.
|
|
996
|
+
- Include a short domain identity / bounded-context map (from the charter).
|
|
997
|
+
- AS-BUILT: the principle is what the code evidences; do NOT introduce a domain
|
|
998
|
+
rule the feature map does not evidence, and do NOT create a debt/backlog.
|
|
999
|
+
- Bump CONSTITUTION_VERSION by semver; ISO YYYY-MM-DD dates. Preserve heading
|
|
1000
|
+
hierarchy. PREPEND a "Sync Impact Report" HTML comment (version old→new, domain
|
|
1001
|
+
principles, dependent artifacts ✅/⚠ + TODOs).
|
|
1002
|
+
Return the complete updated domain addenda content only.
|
|
1003
|
+
|
|
1004
|
+
- id: domain_validation_loop
|
|
1005
|
+
action: loop
|
|
1006
|
+
while: "{{domain_ok}} != true"
|
|
1007
|
+
max_iterations: 3
|
|
1008
|
+
steps:
|
|
1009
|
+
- id: dom_lint
|
|
1010
|
+
action: execute_script
|
|
1011
|
+
script: { ref: actions }
|
|
1012
|
+
subcommand: constitution-verify
|
|
1013
|
+
args: ["--file", "{{constitution_domain_file}}"]
|
|
1014
|
+
outputs:
|
|
1015
|
+
- { name: domain_ok, from: "$.ok" }
|
|
1016
|
+
- { name: domain_issues, from: "$.issues" }
|
|
1017
|
+
- id: dom_lint_break
|
|
1018
|
+
action: break
|
|
1019
|
+
condition: "{{domain_ok}} == true"
|
|
1020
|
+
- id: patch_domain
|
|
1021
|
+
action: agent_author
|
|
1022
|
+
context: ["{{constitution_domain_file}}"]
|
|
1023
|
+
include_standards: false
|
|
1024
|
+
output_target: { type: file, path: "{{constitution_domain_file}}" }
|
|
1025
|
+
task: |
|
|
1026
|
+
Fix these mechanical defects in the domain addenda constitution (target file
|
|
1027
|
+
in context), changing NOTHING else — preserve every principle, the heading
|
|
1028
|
+
hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder
|
|
1029
|
+
(or a justified TODO(<FIELD>): reason); make the body version AGREE with the
|
|
1030
|
+
Sync Impact Report; ISO YYYY-MM-DD dates.
|
|
1031
|
+
Defects: {{domain_issues}}
|
|
1032
|
+
Return the complete updated domain addenda content only.
|
|
1033
|
+
|
|
1034
|
+
# ── COMPOSE + ACTIVATE ───────────────────────────────────────────────────────
|
|
1035
|
+
- id: compose_constitution
|
|
1036
|
+
action: execute_script
|
|
1037
|
+
script: { ref: actions }
|
|
1038
|
+
subcommand: compose-constitution
|
|
1039
|
+
outputs:
|
|
1040
|
+
- { name: composed_file, from: "$.composed_file" }
|
|
1041
|
+
- { name: domain_included, from: "$.domain_included" }
|
|
1042
|
+
# The UI half appends after the two roman-numeral halves and runs its own UX-*
|
|
1043
|
+
# series, so it never enters the numbering check below.
|
|
1044
|
+
- { name: ui_included, from: "$.ui_included" }
|
|
1045
|
+
- { name: numbering_ok, from: "$.numbering_ok" }
|
|
1046
|
+
- { name: numbering_issues, from: "$.issues" }
|
|
1047
|
+
- { name: technical_last, from: "$.technical_last" }
|
|
1048
|
+
- { name: domain_first, from: "$.domain_first" }
|
|
1049
|
+
|
|
1050
|
+
# Numbering gate — the twin of the greenfield constitution workflow's. Brownfield
|
|
1051
|
+
# needs it MORE, not less: the technical half here is evidenced-only, so its length is
|
|
1052
|
+
# discovered from the code rather than fixed by a mapped base, and the domain half is
|
|
1053
|
+
# authored in the same run against a numeral it has just been told to read. Announce
|
|
1054
|
+
# and continue: both halves are written and the composed view shows the clash.
|
|
1055
|
+
# Ordered override — the var holds "ok" unless the check reported a problem, because
|
|
1056
|
+
# require_non_empty reports on EMPTY.
|
|
1057
|
+
- id: numbering_default
|
|
1058
|
+
action: set
|
|
1059
|
+
vars: { numbering_gate: "ok" }
|
|
1060
|
+
- id: numbering_detect
|
|
1061
|
+
action: set
|
|
1062
|
+
condition: "{{numbering_ok}} == false"
|
|
1063
|
+
vars: { numbering_gate: "" }
|
|
1064
|
+
- id: numbering_warning
|
|
1065
|
+
action: verify_context
|
|
1066
|
+
require_non_empty: numbering_gate
|
|
1067
|
+
on_empty: continue
|
|
1068
|
+
on_empty_message: >
|
|
1069
|
+
Principle numbering does not run cleanly across the reverse-engineered halves:
|
|
1070
|
+
{{numbering_issues}} (technical half ends at {{technical_last}}, domain half starts
|
|
1071
|
+
at {{domain_first}}). The technical half is evidenced-only, so its last numeral is
|
|
1072
|
+
whatever the code actually supported — the domain half must resume from the number
|
|
1073
|
+
FOLLOWING it, never from a fixed value. Renumber the domain half in
|
|
1074
|
+
.appweaver/memory/constitution.domain.md and re-run compose; the composed
|
|
1075
|
+
constitution.md was still written so the clash is visible.
|
|
1076
|
+
|
|
1077
|
+
# Auto-activate: point .appweaver/domain.json at the scaffolded project so the forward CR
|
|
1078
|
+
# loop governs development with it from the first change.
|
|
1079
|
+
- id: activate_domain
|
|
1080
|
+
action: execute_script
|
|
1081
|
+
script: { ref: actions }
|
|
1082
|
+
subcommand: set-domain
|
|
1083
|
+
args: ["--domain", "{{domain_slug}}"]
|
|
1084
|
+
outputs:
|
|
1085
|
+
- { name: active_domain, from: "$.domain" }
|
|
1086
|
+
- { name: map_exists, from: "$.map_exists" }
|
|
1087
|
+
|
|
1088
|
+
# ═══════════ TECHNICAL RULE SET (code-derived) — the technical twin of the ═══════
|
|
1089
|
+
# domain set above. This is what stops adopt AND the whole forward
|
|
1090
|
+
# pipeline from falling back to greenfield technical rules.
|
|
1091
|
+
#
|
|
1092
|
+
# Runs AFTER the technical constitution is authored + validated (technical_validation_loop)
|
|
1093
|
+
# so its ratified principles are on hand: each generated tech rule file is the DETAIL layer
|
|
1094
|
+
# under a constitution.technical.md principle (thin ratified line ↑ / enforceable rule ↓).
|
|
1095
|
+
# Evidence = the CODE (deep read via inventory_json's file lists) + the validated technical
|
|
1096
|
+
# constitution + the shallow platform note (corroboration only). Writes:
|
|
1097
|
+
# 1. guardrails/projects/<domain>/service/<concern>.md — evidenced-only code-derived tech rule
|
|
1098
|
+
# files (the ANALOG of a greenfield project's architecture · security · governance set, but reverse-
|
|
1099
|
+
# engineered from THIS code, never a greenfield file), INCLUDING the one file that
|
|
1100
|
+
# feeds /specify: service/domain-modelling.md, the as-built modelling METHODOLOGY (the
|
|
1101
|
+
# analog of the greenfield corpus's technology/<stack>/domain-driven-design.md). Without it brownfield
|
|
1102
|
+
# specify has a model but no HOW-to-model standard, and models a NEW feature in a
|
|
1103
|
+
# different idiom than the code it joins, and
|
|
1104
|
+
# 2. guardrails/projects/<domain>/tech-rule-bindings.md — the TECHNICAL map (resolve-tech +
|
|
1105
|
+
# tech-select read it by that exact name), wiring the generated files per-workflow.
|
|
1106
|
+
# Because onboard already ACTIVATED brf-<domain>, the forward pipeline's + adopt's tech_select
|
|
1107
|
+
# steps now resolve to THESE files — never another project's rules, ever. The project
|
|
1108
|
+
# lives inside pack_dir, so pack_guard (above) already protects it from clobber.
|
|
1109
|
+
- id: ctx_tech_pack
|
|
1110
|
+
action: build_context
|
|
1111
|
+
condition: "{{svc_lane}} == true"
|
|
1112
|
+
context:
|
|
1113
|
+
- { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — read representative SOURCE from its file lists
|
|
1114
|
+
- { path: "{{constitution_technical_file}}" } # PRIMARY: the VALIDATED as-built technology base — the ratified principles these files detail
|
|
1115
|
+
- { path: .appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md, optional: true } # SHAPE ONLY: the technical map's headings + partition + table (zero real files)
|
|
1116
|
+
- { path: .appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md, optional: true } # SHAPE ONLY: one code-derived tech rule file's shape (zero real tech)
|
|
1117
|
+
- { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
|
|
1118
|
+
- { path: "{{bundle_dir}}/architecture/platform.md", optional: true } # SECONDARY (shallow): the OKF as-built platform note — corroborate, don't rely on alone
|
|
1119
|
+
context_from: design_context
|
|
1120
|
+
- id: author_tech_pack
|
|
1121
|
+
action: agent_generate
|
|
1122
|
+
condition: "{{svc_lane}} == true"
|
|
1123
|
+
tools: "Read,Write,Edit"
|
|
1124
|
+
permission_mode: acceptEdits
|
|
1125
|
+
task: |
|
|
1126
|
+
Scaffold the PROJECT-level TECHNICAL RULE SET for **{{project_name}}** (domain
|
|
1127
|
+
{{domain_slug}}) — the CODE-DERIVED replacement for the greenfield technical rule set —
|
|
1128
|
+
into guardrails/projects/{{domain_slug}}/service/ (create it), plus the technical map
|
|
1129
|
+
guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the TECHNICAL twin of the
|
|
1130
|
+
already-generated domain set: it feeds the HOW phases (design/implement/build/…) plus
|
|
1131
|
+
ONE modelling-methodology file for /specify (see domain-modelling below) — and nothing
|
|
1132
|
+
else ever reaches /specify from this tier.
|
|
1133
|
+
|
|
1134
|
+
EVIDENCE = THE CODE ITSELF (deep read) + THE VALIDATED TECHNICAL CONSTITUTION. Authority,
|
|
1135
|
+
in order:
|
|
1136
|
+
1. THE ACTUAL SOURCE CODE (ground truth). Use {{inventory_json}} (in context) to locate
|
|
1137
|
+
representative files across top_level_dirs + a few aggregate_signals, and Read enough
|
|
1138
|
+
to state each technical rule from what the code ACTUALLY does — the folder/tier/module
|
|
1139
|
+
convention, the dependency direction, the persistence approach, concurrency handling,
|
|
1140
|
+
testing convention, the auth/cross-cutting posture. Do NOT assert structure you have
|
|
1141
|
+
not seen in the code.
|
|
1142
|
+
2. constitution.technical.md (in context) — the VALIDATED as-built technology base. Each
|
|
1143
|
+
generated tech rule file is the DETAIL under one of ITS principles; cite the principle
|
|
1144
|
+
numeral on the rules it details. Never contradict it; never restate it wholesale.
|
|
1145
|
+
3. The OKF platform.md (in context, if present) — SECONDARY, shallow corroboration only.
|
|
1146
|
+
NEVER reference, read, copy, or list a rule file belonging to another project
|
|
1147
|
+
(guardrails/projects/<other>/**) — those are the
|
|
1148
|
+
greenfield fixture, NOT this project's rules. Every path you write lives under
|
|
1149
|
+
guardrails/projects/{{domain_slug}}/service/.
|
|
1150
|
+
|
|
1151
|
+
CONCERNS HINT: {{USER_INPUT}} may carry a "concerns: a, b, c" clause. Treat any listed
|
|
1152
|
+
concern as a SEARCH HINT — look for it in the code — but DECIDE presence from evidence:
|
|
1153
|
+
write a tech rule file for a concern ONLY if the code exhibits it, drop a listed concern
|
|
1154
|
+
the code shows none of, and ADD an unlisted concern the code clearly evidences. Ignore any
|
|
1155
|
+
non-concerns text.
|
|
1156
|
+
|
|
1157
|
+
EVIDENCED-ONLY (lean). Write a `service/<concern>.md` ONLY for a technology concern the code
|
|
1158
|
+
actually exhibits — e.g. as-built-architecture, persistence, concurrency, testing,
|
|
1159
|
+
security-posture, api-surface, eventing, observability, hosting. Follow the SHAPE of
|
|
1160
|
+
technical-rule-file.skeleton.md (in context): frontmatter (origin: reverse-engineered,
|
|
1161
|
+
generated_by: aw-spec-onboard/1.6.0, concern), a one-line framing, rules each citing a CODE
|
|
1162
|
+
COORDINATE (real file/folder path or named type) + the constitution principle numeral where
|
|
1163
|
+
it maps. The skeleton carries NO real technology — copy the shape only. State stubs/partials
|
|
1164
|
+
AS-BUILT (do not upgrade a stub into a greenfield ideal); omit a concern the code shows none
|
|
1165
|
+
of (migration is a separate later phase — no debt/backlog sink here).
|
|
1166
|
+
|
|
1167
|
+
PLUS ONE SPECIAL FILE — `service/domain-modelling.md` (concern: domain-modelling). This is the
|
|
1168
|
+
ONE file in this project that feeds /specify, and it is a MODELLING METHODOLOGY: HOW this
|
|
1169
|
+
codebase expresses a domain model, not WHAT the model is (the model itself is the domain
|
|
1170
|
+
project's domain-model file, already written — do NOT restate or duplicate it).
|
|
1171
|
+
Read the code and state the AS-BUILT modelling conventions, each citing a code coordinate:
|
|
1172
|
+
- what marks an aggregate root, and how a root is reached (base class / marker interface
|
|
1173
|
+
/ naming), plus the identity convention (typed id? primitive? value object?);
|
|
1174
|
+
- entity vs value object — how the code distinguishes them, and where each lives;
|
|
1175
|
+
- where invariants actually live (root method / domain service / validator / DB
|
|
1176
|
+
constraint) — state what the code DOES, even if that is "enforced in the handler";
|
|
1177
|
+
- the bounded-context / module boundary and what may cross it (ids only? DTOs? entities?);
|
|
1178
|
+
- domain events, if the code has them: what raises one, and where it is dispatched;
|
|
1179
|
+
- the naming/ubiquitous-language convention the code visibly follows.
|
|
1180
|
+
Write it even when the conventions are partial or inconsistent — say so AS-BUILT and cite
|
|
1181
|
+
the divergent coordinates; that is exactly what /specify needs in order to model a NEW
|
|
1182
|
+
feature the way this codebase already models. Contains NO business vocabulary and NO
|
|
1183
|
+
technology/architecture rules (those are the other files). Omit this file ONLY if the code
|
|
1184
|
+
has no discernible domain model at all (e.g. a pure script/ETL repo).
|
|
1185
|
+
|
|
1186
|
+
tech-rule-bindings.md (MANDATORY — resolve-tech + the tech-select module read this exact
|
|
1187
|
+
filename). Follow the SHAPE of tech-rule-bindings.skeleton.md (in context) and the rule
|
|
1188
|
+
partition (.appweaver/RULE-PARTITION.md, in context). Wire ONLY files you generated, under these headings, and
|
|
1189
|
+
ONLY a heading you have a generated file for (an absent heading soft-continues → loads
|
|
1190
|
+
nothing):
|
|
1191
|
+
- `## /aw-spec-specify` — EXACTLY ONE bullet: `service/domain-modelling.md`, the modelling methodology. NEVER an architecture / persistence / codegen / security file here — specify is the domain phase and any technology rule under this heading breaks its domain purity. Omit the heading only if you did not write domain-modelling.md.
|
|
1192
|
+
- `## /aw-spec-design` — the as-built architecture / cross-cutting rules the design author mediates the spec against.
|
|
1193
|
+
- `## /aw-spec-implement` — the code-generation / convention set the generator builds against (from design.md).
|
|
1194
|
+
- `## /aw-spec-implement-delta` — the same code-generation set, scoped to a change's delta-design.
|
|
1195
|
+
- `## /aw-spec-build` — the layering + convention rules the compile-fixer respects.
|
|
1196
|
+
- `## /aw-spec-analyze-slice` — the conformance rules the design↔code gate validates against.
|
|
1197
|
+
- `## /aw-spec-adopt` — the technical reference set the reversed design mediates against (a subset of design's).
|
|
1198
|
+
- `## /aw-spec-constitution` — the standards a later `/appweaver constitution` re-ratifies the TECHNICAL half from. You authored that half from code evidence before these files existed; this heading is what makes a re-run author from THIS project's rules rather than from an empty set. Ratifiable standards only, no worked `examples/` sample, no domain file.
|
|
1199
|
+
- `## /aw-spec-run` — the runtime / execution conventions the app-run step honors (add ONLY if the code evidences a runtime/hosting concern file; NOT data-migration — migration is the deferred later phase).
|
|
1200
|
+
Each bullet is a
|
|
1201
|
+
workspace-relative path `- guardrails/projects/{{domain_slug}}/service/<file>`. Close with the
|
|
1202
|
+
quick-reference table. Write ONLY inside guardrails/projects/{{domain_slug}}/ (service/ + the map);
|
|
1203
|
+
modify no source. Report the files written + the concerns you found present (with the code
|
|
1204
|
+
paths that evidence them).
|
|
1205
|
+
outputs:
|
|
1206
|
+
- { name: tech_pack_files, from: "$.files" }
|
|
1207
|
+
|
|
1208
|
+
- id: verify_tech_pack
|
|
1209
|
+
action: verify_context
|
|
1210
|
+
condition: "{{svc_lane}} == true"
|
|
1211
|
+
require_non_empty: tech_pack_files
|
|
1212
|
+
on_empty: stop
|
|
1213
|
+
on_empty_message: "No technical rule files were written to guardrails/projects/{{domain_slug}}/service/. Ensure the scan substrate (inventory_json) + the validated technical constitution carry an as-built technology base and re-run."
|
|
1214
|
+
- id: require_tech_rule_bindings
|
|
1215
|
+
action: verify_context
|
|
1216
|
+
required_files: ["{{pack_dir}}/tech-rule-bindings.md"]
|
|
1217
|
+
|
|
1218
|
+
# Did the modelling methodology reach /specify? The map is the only route this tier has
|
|
1219
|
+
# into the domain phase, and `## /aw-spec-specify` carrying service/domain-modelling.md
|
|
1220
|
+
# is what stops brownfield specify from modelling a new feature in a different idiom
|
|
1221
|
+
# than the code it joins. Read it back through the same resolver /specify uses — the
|
|
1222
|
+
# project is already activated, so this asks the question exactly as specify will.
|
|
1223
|
+
# Announce, don't stop: a repo with no discernible domain model legitimately has no such
|
|
1224
|
+
# file, and the run's remaining work is worth keeping either way.
|
|
1225
|
+
- id: probe_specify_wiring
|
|
1226
|
+
action: execute_script
|
|
1227
|
+
condition: "{{svc_lane}} == true"
|
|
1228
|
+
on_error: continue
|
|
1229
|
+
script: { ref: actions }
|
|
1230
|
+
subcommand: resolve-tech
|
|
1231
|
+
args: ["--command", "aw-spec-specify"]
|
|
1232
|
+
outputs:
|
|
1233
|
+
- { name: specify_rules, from: "$.candidates" }
|
|
1234
|
+
- id: warn_specify_wiring
|
|
1235
|
+
action: verify_context
|
|
1236
|
+
condition: "{{svc_lane}} == true"
|
|
1237
|
+
require_non_empty: specify_rules
|
|
1238
|
+
on_empty: continue
|
|
1239
|
+
on_empty_message: >
|
|
1240
|
+
guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
|
|
1241
|
+
`## /aw-spec-specify`, so brownfield specify will model new features with no
|
|
1242
|
+
as-built modelling methodology to follow. That is correct only where the code has no
|
|
1243
|
+
discernible domain model (a pure script/ETL repo). Otherwise add
|
|
1244
|
+
service/domain-modelling.md — HOW this codebase expresses a domain model, not what
|
|
1245
|
+
the model is — and wire it as the single bullet under that heading.
|
|
1246
|
+
|
|
1247
|
+
# ═══════════ FRONTEND RULE SET (code-derived) — the LANE's tier ════════════════
|
|
1248
|
+
# The third generated project, written only where the code has a UI. It is the DETAIL
|
|
1249
|
+
# layer under the UX-* principles the half above ratified (thin ratified line ↑ /
|
|
1250
|
+
# enforceable rule ↓), exactly as service/ is the detail layer under the technical half.
|
|
1251
|
+
#
|
|
1252
|
+
# Runs AFTER the technical set because both write the SAME map file: the technical set
|
|
1253
|
+
# authors tech-rule-bindings.md, and this step APPENDS the lane's heading to it. That
|
|
1254
|
+
# heading is what makes a later /appweaver constitution re-ratify the UI half from
|
|
1255
|
+
# THIS project's lane rules — and it is also the authoritative signal that the project
|
|
1256
|
+
# HAS a frontend lane, so writing it is what lets the greenfield constitution command
|
|
1257
|
+
# find the lane on every future run without stacks.json or a named stack.
|
|
1258
|
+
- id: ctx_ui_pack
|
|
1259
|
+
action: build_context
|
|
1260
|
+
condition: "{{ui_lane}} == true"
|
|
1261
|
+
context:
|
|
1262
|
+
- { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — frontend_signals + the UI file lists to read source from
|
|
1263
|
+
- { path: "{{constitution_ui_file}}" } # PRIMARY: the VALIDATED as-built UX-* base — the ratified principles these files detail
|
|
1264
|
+
- { path: "{{pack_dir}}/tech-rule-bindings.md" } # the map to APPEND to — read it so the edit preserves what the technical set wrote
|
|
1265
|
+
- { path: .appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md, optional: true } # SHAPE ONLY: one code-derived lane rule file's shape (zero real UI tech)
|
|
1266
|
+
- { path: .appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md, optional: true } # SHAPE ONLY: the technical map's headings + partition + table
|
|
1267
|
+
- { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
|
|
1268
|
+
- { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note
|
|
1269
|
+
- id: author_ui_pack
|
|
1270
|
+
action: agent_generate
|
|
1271
|
+
condition: "{{ui_lane}} == true"
|
|
1272
|
+
tools: "Read,Write,Edit"
|
|
1273
|
+
permission_mode: acceptEdits
|
|
1274
|
+
task: |
|
|
1275
|
+
Scaffold the PROJECT-level FRONTEND RULE-FILE PACK for **{{project_name}}** (domain
|
|
1276
|
+
{{domain_slug}}) — the CODE-DERIVED lane rules — into
|
|
1277
|
+
guardrails/projects/{{domain_slug}}/frontend/ (create it), and WIRE it into the existing
|
|
1278
|
+
guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the FRONTEND LANE's
|
|
1279
|
+
twin of the service/ set you have already generated: it is the detail layer under
|
|
1280
|
+
constitution.ui.md's UX-* principles, and it governs only code under the lane's root.
|
|
1281
|
+
|
|
1282
|
+
EVIDENCE = THE UI CODE ITSELF (deep read) + THE VALIDATED UI CONSTITUTION. Authority,
|
|
1283
|
+
in order:
|
|
1284
|
+
1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_json}} (in context):
|
|
1285
|
+
`frontend_signals` gives the lane roots, their kind, their framework markers and
|
|
1286
|
+
their component / route / store / style file lists. Read enough of those files to
|
|
1287
|
+
state each rule from what the UI ACTUALLY does. Do NOT assert a convention you
|
|
1288
|
+
have not seen in the code.
|
|
1289
|
+
2. constitution.ui.md (in context) — the VALIDATED as-built UX-* base. Each file
|
|
1290
|
+
here is the DETAIL under one of ITS principles; cite the UX numeral on the rules
|
|
1291
|
+
it details. Never contradict it; never restate it wholesale.
|
|
1292
|
+
3. The OKF architecture/frontend.md (in context, if present) — SECONDARY, shallow.
|
|
1293
|
+
NEVER reference, read, copy, or list a rule file belonging to another project
|
|
1294
|
+
(guardrails/projects/<other>/**) — those are the greenfield fixture, NOT this project's
|
|
1295
|
+
rules. Never carry over a convention, an accessibility target, a folder taxonomy or a
|
|
1296
|
+
quality gate from a greenfield UI rule file or from how frontends are usually built.
|
|
1297
|
+
Every path you write lives under guardrails/projects/{{domain_slug}}/frontend/.
|
|
1298
|
+
|
|
1299
|
+
EVIDENCED-ONLY (lean). Follow the SHAPE of frontend-rule-file.skeleton.md (in context):
|
|
1300
|
+
frontmatter (origin: reverse-engineered, generated_by: aw-spec-onboard/1.6.0, concern),
|
|
1301
|
+
a one-line framing, then rules each citing a CODE COORDINATE (a real component / route /
|
|
1302
|
+
store / stylesheet / config path) and the UX principle numeral where it maps.
|
|
1303
|
+
- `frontend/ui-constitution.md` — ALWAYS, the lane's base file: the lane declaration
|
|
1304
|
+
(id, what it is built with, the root it owns, whether it is separable or rendered
|
|
1305
|
+
inside the service tree) plus the whole-lane rules. This is the file a later
|
|
1306
|
+
/appweaver constitution re-ratifies the UI half from, so it must stand on its own.
|
|
1307
|
+
- Then a `frontend/<concern>.md` ONLY for an experience concern the UI code actually
|
|
1308
|
+
exhibits — e.g. component-model, routing-and-navigation, state-and-data,
|
|
1309
|
+
styling-and-design-system, accessibility, interaction-states, forms-and-validation,
|
|
1310
|
+
internationalization, performance, ui-testing. Drop any the code shows none of; add
|
|
1311
|
+
any it clearly evidences that is not on that list.
|
|
1312
|
+
State inconsistency AS-BUILT: give the DOMINANT convention as the rule and record the
|
|
1313
|
+
divergence with its coordinates. Do not upgrade a partial into a greenfield ideal, and
|
|
1314
|
+
do not create a debt/backlog sink — modernization is a separate later phase.
|
|
1315
|
+
|
|
1316
|
+
WIRE THE MAP — EDIT guardrails/projects/{{domain_slug}}/tech-rule-bindings.md IN PLACE.
|
|
1317
|
+
It already exists and carries the technical headings you wrote; PRESERVE all of them
|
|
1318
|
+
byte-for-byte. Make exactly two additions:
|
|
1319
|
+
1. A `## /aw-spec-ui-constitution` section, placed after the last technical heading
|
|
1320
|
+
and BEFORE the closing quick-reference table. Bullet ONLY the frontend files you
|
|
1321
|
+
just generated, `frontend/ui-constitution.md` first, each as a workspace-relative
|
|
1322
|
+
path `- guardrails/projects/{{domain_slug}}/frontend/<file>`. Ratifiable lane
|
|
1323
|
+
standards only — no domain file, no technical file, no example. Precede them with
|
|
1324
|
+
a short HTML comment saying what this half ratifies and that the heading is also
|
|
1325
|
+
the authoritative signal that the project has a frontend lane.
|
|
1326
|
+
2. Its row in the quick-reference table, in the same format as the existing rows.
|
|
1327
|
+
Do NOT add `## /aw-spec-ui-design` or `## /aw-spec-ui-implement`: those commands do not
|
|
1328
|
+
exist yet, and a heading mapping files for a command nobody runs is a claim the kit
|
|
1329
|
+
cannot honour. They arrive with the UI lane's own phases.
|
|
1330
|
+
|
|
1331
|
+
Write ONLY inside guardrails/projects/{{domain_slug}}/ (frontend/ + the map edit); modify
|
|
1332
|
+
no source. Report the files written, the concerns you found present with the code paths
|
|
1333
|
+
that evidence them, and the concerns you deliberately omitted.
|
|
1334
|
+
outputs:
|
|
1335
|
+
- { name: ui_pack_files, from: "$.files" }
|
|
1336
|
+
|
|
1337
|
+
- id: verify_ui_pack
|
|
1338
|
+
action: verify_context
|
|
1339
|
+
condition: "{{ui_lane}} == true"
|
|
1340
|
+
require_non_empty: ui_pack_files
|
|
1341
|
+
on_empty: stop
|
|
1342
|
+
on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no lane rule files were written to guardrails/projects/{{domain_slug}}/frontend/. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
|
|
1343
|
+
|
|
1344
|
+
# Did the lane's heading land in the map? The files above are only half the wiring:
|
|
1345
|
+
# `## /aw-spec-ui-constitution` is what a later /appweaver constitution re-ratifies
|
|
1346
|
+
# the UI half from, and it is the authoritative signal that this project HAS a lane.
|
|
1347
|
+
# Written by an in-place edit, so read it back through the resolver that will look for
|
|
1348
|
+
# it. Announce, don't stop — the rule files are on disk and the heading is one edit away.
|
|
1349
|
+
- id: probe_ui_wiring
|
|
1350
|
+
action: execute_script
|
|
1351
|
+
condition: "{{ui_lane}} == true"
|
|
1352
|
+
on_error: continue
|
|
1353
|
+
script: { ref: actions }
|
|
1354
|
+
subcommand: resolve-tech
|
|
1355
|
+
args: ["--command", "aw-spec-ui-constitution"]
|
|
1356
|
+
outputs:
|
|
1357
|
+
- { name: ui_map_rules, from: "$.candidates" }
|
|
1358
|
+
- id: warn_ui_wiring
|
|
1359
|
+
action: verify_context
|
|
1360
|
+
condition: "{{ui_lane}} == true"
|
|
1361
|
+
require_non_empty: ui_map_rules
|
|
1362
|
+
on_empty: continue
|
|
1363
|
+
on_empty_message: >
|
|
1364
|
+
The lane rule files were written to guardrails/projects/{{domain_slug}}/frontend/,
|
|
1365
|
+
but guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
|
|
1366
|
+
`## /aw-spec-ui-constitution`. Without that heading a later /appweaver
|
|
1367
|
+
constitution finds no lane rules to re-ratify the UI half from, and reads this
|
|
1368
|
+
project as backend-only. Add the heading after the last technical one, bulleting
|
|
1369
|
+
frontend/ui-constitution.md first, then the rest of the frontend/ set.
|
|
1370
|
+
|
|
1371
|
+
# ═══════════ LANE DECLARATION — read back, never written ═══════════════════════
|
|
1372
|
+
# onboard does not declare lanes. It used to: before select-stack was the first
|
|
1373
|
+
# command of this sequence, a repo could arrive here with no declaration at all, so
|
|
1374
|
+
# onboard ran its own detection pass and recorded what it found, marked
|
|
1375
|
+
# `origin: reverse-engineered` and gated never to overwrite a lane a person had
|
|
1376
|
+
# confirmed. With the declaration now REQUIRED at the top of this workflow — it is
|
|
1377
|
+
# what told the scan which subtrees to read — that gate can never open, and the
|
|
1378
|
+
# detection pass was re-deriving an answer the run already had.
|
|
1379
|
+
#
|
|
1380
|
+
# So `lane-declare` is the sole writer again, with one caller: select-stack, where a
|
|
1381
|
+
# person picks. That is a stronger property than the two-caller version, and it is
|
|
1382
|
+
# still a grep rather than a convention.
|
|
1383
|
+
#
|
|
1384
|
+
# What remains is a read-back through the same reader every other workflow uses, so
|
|
1385
|
+
# the run reports the lanes it actually scanned under rather than a second opinion
|
|
1386
|
+
# about them.
|
|
1387
|
+
- id: lane_readback
|
|
1388
|
+
action: execute_script
|
|
1389
|
+
on_error: continue
|
|
1390
|
+
script: { ref: actions }
|
|
1391
|
+
subcommand: lane-resolve
|
|
1392
|
+
outputs:
|
|
1393
|
+
- { name: stacks_file, from: "$.path" }
|
|
1394
|
+
- { name: declared_lanes, from: "$.lanes" }
|
|
1395
|
+
- { name: be_lane_root, from: "$.backend_source_path" }
|
|
1396
|
+
- { name: be_lane_profile, from: "$.backend_profile" }
|
|
1397
|
+
- { name: fe_lane_root, from: "$.frontend_source_path" }
|
|
1398
|
+
- { name: fe_lane_profile, from: "$.frontend_profile" }
|
|
1399
|
+
|
|
1400
|
+
# ═══════════ CODE-DERIVED DESIGN TEMPLATES (reverse-engineered) ═══════════════
|
|
1401
|
+
# Runs LAST in onboard — AFTER the governance tier is authored + validated + composed
|
|
1402
|
+
# (compose_constitution above) — so the strongest reverse-engineered evidence is on hand:
|
|
1403
|
+
# the ACTUAL SOURCE CODE + the deterministic scan substrate (inventory_json) + the
|
|
1404
|
+
# VALIDATED technical constitution (the as-built technology base). Establish this repo's
|
|
1405
|
+
# DESIGN CONVENTION by REVERSE-ENGINEERING its own technical structure into a project-
|
|
1406
|
+
# specific design + delta-design template pair, written to the PROJECT-LEVEL override slot
|
|
1407
|
+
# (.appweaver/templates/overrides/{design,delta-design}-template.md — resolve_template
|
|
1408
|
+
# Priority-1). The forward `design` phase's brownfield branch (design-scaffold reports
|
|
1409
|
+
# override_active ⇒ design_mode == bootstrap_bf) then authors EVERY new feature against the
|
|
1410
|
+
# as-built architecture, and a CHANGE authors its delta-design against the SAME code-derived
|
|
1411
|
+
# sections (cr-setup scaffolds the delta from resolve_template("delta-design-template") ⇒
|
|
1412
|
+
# the override) — no adopt required, consistent with the master design.md adopt emits.
|
|
1413
|
+
#
|
|
1414
|
+
# GROUNDED IN CODE + REVERSE-ENGINEERED FILES ONLY. The Part-1 OKF feature map is a SHALLOW
|
|
1415
|
+
# discovery index (by design — NOT a deep reverse), so it is NOT the authority: the section
|
|
1416
|
+
# skeleton is derived from the CODE itself + inventory_json (complete, deterministic) + the
|
|
1417
|
+
# validated technical constitution, with the OKF map as secondary corroboration.
|
|
1418
|
+
#
|
|
1419
|
+
# NO GREENFIELD TEMPLATE IS IN CONTEXT — this tier reads a NEUTRAL SKELETON from
|
|
1420
|
+
# rev-templates/, exactly as the constitution halves and both rule sets already do. The
|
|
1421
|
+
# greenfield design templates carry a Domain/Application/API/Infrastructure layering in
|
|
1422
|
+
# their headings, their example rows and their authoring prose, and a prompt telling an
|
|
1423
|
+
# author not to copy the exemplar in front of it is the weakest control this kit has.
|
|
1424
|
+
# rev-templates/{design,delta-design}-template.skeleton.md carry the SAME neutral bones
|
|
1425
|
+
# (header block, the §1.2 domain/data-model anchor, the traceability spine, the two
|
|
1426
|
+
# deferral ledgers, Change History, the tech-agnostic authoring rules) with the layering
|
|
1427
|
+
# removed and every structural section left as a slot the code fills. The generated
|
|
1428
|
+
# template keeps the §0–§6 shape the forward `design` bootstrap_bf branch expects and the
|
|
1429
|
+
# two anchors aw-xref keys on, so no workflow change is needed to consume it.
|
|
1430
|
+
#
|
|
1431
|
+
# WHERE A FRONTEND LANE EXISTS the lane gets its OWN pair (ui-design-template +
|
|
1432
|
+
# ui-delta-design-template, below), so this pair covers the SERVICE lane only and excludes
|
|
1433
|
+
# the lane's roots from the structure it derives. One lane's template never describes the
|
|
1434
|
+
# other's code. Re-onboard is gated upstream (bundle_guard / pack_guard) — remove the OKF
|
|
1435
|
+
# bundle to regenerate.
|
|
1436
|
+
|
|
1437
|
+
# DESIGN template — the code-derived evidence (code + inventory + technical constitution)
|
|
1438
|
+
# plus a NEUTRAL skeleton for the bones. No greenfield template is in context.
|
|
1439
|
+
- id: ctx_design_template
|
|
1440
|
+
action: build_context
|
|
1441
|
+
condition: "{{svc_lane}} == true"
|
|
1442
|
+
context:
|
|
1443
|
+
- { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate (top_level_dirs, aggregate_signals' per-layer file groupings) — the OKF markdown only SUMMARISES this
|
|
1444
|
+
- { path: "{{constitution_technical_file}}" } # PRIMARY: the VALIDATED as-built technology base (framework/persistence/concurrency/hosting/testing/cross-cutting)
|
|
1445
|
+
- { path: .appweaver/orchestrator/rev-templates/design-template.skeleton.md } # SHAPE ONLY: the neutral bones + the pinned anchors + tech-agnostic authoring rules (zero layering, zero technology)
|
|
1446
|
+
- { path: .appweaver/DESIGN-FORMAT.md } # the HLD contract + its Brownfield variant note (which anchors are pinned, and why)
|
|
1447
|
+
- { path: "{{bundle_dir}}/architecture/platform.md", optional: true } # SECONDARY (shallow): the OKF as-built platform note — corroborate, don't rely on alone
|
|
1448
|
+
- { path: "{{bundle_dir}}/architecture/overview.md", optional: true } # SECONDARY (shallow): the OKF feature map + stack
|
|
1449
|
+
- { path: "{{bundle_dir}}/aggregates/index.md", optional: true } # SECONDARY (shallow): the bounded-context / feature map
|
|
1450
|
+
- id: gen_design_template
|
|
1451
|
+
action: agent_generate
|
|
1452
|
+
condition: "{{svc_lane}} == true"
|
|
1453
|
+
tools: "Read,Write,Edit"
|
|
1454
|
+
permission_mode: acceptEdits
|
|
1455
|
+
task: |
|
|
1456
|
+
REVERSE-ENGINEER this repo's design convention into a PROJECT-SPECIFIC design
|
|
1457
|
+
TEMPLATE and Write it to .appweaver/templates/overrides/design-template.md (create the
|
|
1458
|
+
overrides/ dir if absent). It is a TEMPLATE — concrete project-derived section HEADERS
|
|
1459
|
+
with [PLACEHOLDER] tokens + authoring HTML comments the forward `design` phase fills
|
|
1460
|
+
per feature — NOT a filled design.
|
|
1461
|
+
|
|
1462
|
+
GROUND EVERYTHING IN THE CODE + THE REVERSE-ENGINEERED FILES — not the shallow OKF map
|
|
1463
|
+
and not any architecture you know from elsewhere. Evidence authority, in order:
|
|
1464
|
+
1. THE ACTUAL SOURCE CODE (ground truth). Read REPRESENTATIVE source files across the
|
|
1465
|
+
repo's top_level_dirs and a few aggregate_signals (from {{inventory_json}}) — enough
|
|
1466
|
+
to CONFIRM from the code the recurring folder/tier/module convention + the dependency
|
|
1467
|
+
direction it actually follows. Do NOT assert structure you have not seen in the code.
|
|
1468
|
+
2. {{inventory_json}} — the COMPLETE deterministic scan substrate (top_level_dirs, each
|
|
1469
|
+
aggregate_signal's files grouped by layer, categories, tech stack). The OKF markdown
|
|
1470
|
+
only SUMMARISES this, shallowly — prefer the substrate + the code over it.
|
|
1471
|
+
3. The TECHNICAL CONSTITUTION (constitution.technical.md, in context) — the VALIDATED
|
|
1472
|
+
as-built technology base (framework, persistence, concurrency, hosting, testing,
|
|
1473
|
+
cross-cutting posture). It is the authority for §1.1 As-Built Architecture + §3.
|
|
1474
|
+
4. The OKF platform.md / overview.md / aggregates/index.md (in context, if present) —
|
|
1475
|
+
SECONDARY, shallow corroboration only (Part 1 is a discovery map, NOT a deep
|
|
1476
|
+
reverse). Never rely on them alone.
|
|
1477
|
+
|
|
1478
|
+
THE SKELETON IS SHAPE ONLY. rev-templates/design-template.skeleton.md (in context)
|
|
1479
|
+
carries the neutral bones, the pinned anchors and the authoring rules — and NO layering,
|
|
1480
|
+
NO architecture style and NO technology, because naming one would answer the question
|
|
1481
|
+
this step exists to ask the code. Copy the SHAPE; discover the STRUCTURE. Never carry a
|
|
1482
|
+
Domain/Application/API/Infrastructure layering — or any other reference architecture —
|
|
1483
|
+
into §1.1 or §2 from memory. DESIGN-FORMAT.md (in context, § Brownfield variant) states
|
|
1484
|
+
which anchors are pinned and why.
|
|
1485
|
+
|
|
1486
|
+
SERVICE LANE ONLY. Frontend lane roots this repo has: {{frontend_roots}} (empty = none).
|
|
1487
|
+
Where that is non-empty, EXCLUDE those roots when deriving the structure — the lane has
|
|
1488
|
+
its own design template pair, generated next, and one lane's template must never describe
|
|
1489
|
+
the other's code. A UI tier that is NOT a separable lane (rendered inside the service
|
|
1490
|
+
tree) stays here as one of this project's own structural axes.
|
|
1491
|
+
|
|
1492
|
+
Identify the RECURRING structural convention across features (the real layer/tier/module
|
|
1493
|
+
folders + the dependency rule) from evidence 1–3 — this ONE template governs every
|
|
1494
|
+
future feature.
|
|
1495
|
+
|
|
1496
|
+
Then AUTHOR the template on the skeleton's §0–§6 shape (the shape the forward `design`
|
|
1497
|
+
brownfield branch expects — keep these section numbers + headings):
|
|
1498
|
+
- Keep the skeleton's header block (Aggregate / Design home / Source spec / Version /
|
|
1499
|
+
Status) and its TECHNOLOGY-AGNOSTIC authoring rules (behaviour as signatures +
|
|
1500
|
+
pre/post/invariant/raises, contracts as field shapes, NO code; every element traces to
|
|
1501
|
+
a spec id). Fill [GENERATED_STRUCTURE_NOTE] with this project's convention.
|
|
1502
|
+
- §0 Design Overview + `### Ubiquitous Language (design delta)` — carry over as-is.
|
|
1503
|
+
- §1 Architecture Context & Domain Model:
|
|
1504
|
+
§1.1 As-Built Architecture — describe THIS project's real structural convention you
|
|
1505
|
+
discovered FROM THE CODE + the technical constitution (name the actual layer/tier/
|
|
1506
|
+
module folders with representative code paths, the dependency direction, the tech
|
|
1507
|
+
base). A new feature ALIGNS to this.
|
|
1508
|
+
§1.2 Domain / Data Model — PINNED ANCHOR, carry the skeleton's guidance over
|
|
1509
|
+
unchanged (entities & value objects = spec Key Entities; invariants = spec BR-nnn;
|
|
1510
|
+
aggregate boundary; lifecycle/states; cross-slice references-by-id). aw-xref reads
|
|
1511
|
+
this section for reference edges, so it keeps its position.
|
|
1512
|
+
- §2 Component & Behaviour Design — ONE `### 2.n` subsection PER RECURRING STRUCTURAL
|
|
1513
|
+
AXIS the project actually uses, each TITLED after the project's OWN folder/tier name.
|
|
1514
|
+
The count and the titles are the code's answer; the skeleton's slots are positions, not
|
|
1515
|
+
a set to fill. In each, template the components that live there + their behaviour in
|
|
1516
|
+
signature form + the ports/contracts. Keep exactly one subsection whose heading
|
|
1517
|
+
contains the word "Integration" (the External Integrations table — one port/adapter row
|
|
1518
|
+
per IC-): aw-xref matches it by keyword, so it is pinned regardless of layout.
|
|
1519
|
+
- §3 Cross-Cutting Concerns — one row per concern THIS project's governance carries, read
|
|
1520
|
+
from the technical constitution (Serves = a spec id or a §5 DA-n). Do not import a
|
|
1521
|
+
standard concern list the constitution does not evidence.
|
|
1522
|
+
- §4 Traceability — carry the skeleton's spine over (every FR/BR/CN/DC/IC/US/SC has a
|
|
1523
|
+
design home; the Section column uses the project's OWN section refs).
|
|
1524
|
+
- §5 Assumptions (DA-n) — carry over, "None (as of vX.Y)".
|
|
1525
|
+
- §6 Deviations / Deferred Decisions (WA-n) — carry over, AS-BUILT: it records genuine
|
|
1526
|
+
deviations, NOT "organised unlike a reference architecture" (that is the as-built
|
|
1527
|
+
shape, §1.1).
|
|
1528
|
+
- Change History — carry over.
|
|
1529
|
+
Keep every [PLACEHOLDER] and authoring comment so `design` can fill it — and in those
|
|
1530
|
+
comments DIRECT the downstream author (forward `design` / adopt) to GROUND each filled
|
|
1531
|
+
section in the ACTUAL CODE + the reverse-engineered files (cite real file/folder paths and
|
|
1532
|
+
the relevant technical-constitution principle). Do NOT invent project structure the code
|
|
1533
|
+
does not show; where the convention is unclear, template a generic axis and flag it in a
|
|
1534
|
+
comment. Write ONLY the override file; modify no source.
|
|
1535
|
+
Report the file written + the structural axes you derived (with the code paths that
|
|
1536
|
+
evidence them).
|
|
1537
|
+
outputs:
|
|
1538
|
+
- { name: design_template_files, from: "$.files" }
|
|
1539
|
+
|
|
1540
|
+
- id: verify_design_template
|
|
1541
|
+
action: verify_context
|
|
1542
|
+
condition: "{{svc_lane}} == true"
|
|
1543
|
+
require_non_empty: design_template_files
|
|
1544
|
+
on_empty: stop
|
|
1545
|
+
on_empty_message: "No design template was written to .appweaver/templates/overrides/design-template.md. Ensure the scan substrate (inventory_json) + the technical constitution are present and re-run."
|
|
1546
|
+
|
|
1547
|
+
# DELTA-DESIGN template — MIRROR the just-generated master template's OWN sections so a
|
|
1548
|
+
# change classifies ADDED/MODIFIED/REMOVED against the code-derived structure, not the
|
|
1549
|
+
# greenfield four layers. Aligns with the delta-design module (classifies "per the
|
|
1550
|
+
# master's OWN section structure").
|
|
1551
|
+
- id: ctx_delta_design_template
|
|
1552
|
+
action: build_context
|
|
1553
|
+
condition: "{{svc_lane}} == true"
|
|
1554
|
+
context:
|
|
1555
|
+
- { path: .appweaver/templates/overrides/design-template.md, optional: true } # PRIMARY: the JUST-generated code-derived master — mirror its ACTUAL sections
|
|
1556
|
+
- { path: .appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md } # SHAPE ONLY: the neutral change-record bones (zero layering, zero technology)
|
|
1557
|
+
- { path: "{{constitution_technical_file}}" } # the validated as-built technology base (keep the delta consistent with the master)
|
|
1558
|
+
- id: gen_delta_design_template
|
|
1559
|
+
action: agent_generate
|
|
1560
|
+
condition: "{{svc_lane}} == true"
|
|
1561
|
+
tools: "Read,Write,Edit"
|
|
1562
|
+
permission_mode: acceptEdits
|
|
1563
|
+
task: |
|
|
1564
|
+
Author the matching PROJECT-SPECIFIC DELTA-design TEMPLATE and Write it to
|
|
1565
|
+
.appweaver/templates/overrides/delta-design-template.md. It is a TEMPLATE (placeholders
|
|
1566
|
+
+ authoring comments) for classifying a CHANGE to a feature as ADDED / MODIFIED /
|
|
1567
|
+
REMOVED against the master design.md.
|
|
1568
|
+
|
|
1569
|
+
MIRROR the just-generated master template (.appweaver/templates/overrides/design-template.md,
|
|
1570
|
+
in context — Read it): its ADDED/MODIFIED/REMOVED tables must key off the master's OWN
|
|
1571
|
+
code-derived sections (§1.1/§1.2, the §2.n axes it derived, §3). Use the skeleton's
|
|
1572
|
+
"Section (§ in design.md)" column and fill its example rows with the ACTUAL sections of
|
|
1573
|
+
the generated master template. Never name a layering — neither one you know nor one the
|
|
1574
|
+
master did not derive.
|
|
1575
|
+
- CARRY OVER the neutral parts of rev-templates/delta-design-template.skeleton.md (in
|
|
1576
|
+
context): Change summary, Cross-section impact, Regression targets, New assumptions/
|
|
1577
|
+
deviations (DA-n / WA-n), On close. Keep behaviour technology-agnostic (signatures +
|
|
1578
|
+
contracts, no code); a shared element is MODIFIED in place, never duplicated; every
|
|
1579
|
+
changed element serves a spec id.
|
|
1580
|
+
- This aligns with the delta-design module, which classifies "per the master's OWN
|
|
1581
|
+
section structure" — so the template MUST NOT hardcode a fixed layering.
|
|
1582
|
+
Keep every [PLACEHOLDER] and authoring comment. Write ONLY the override file; modify no
|
|
1583
|
+
source. Report the file written.
|
|
1584
|
+
outputs:
|
|
1585
|
+
- { name: delta_design_template_files, from: "$.files" }
|
|
1586
|
+
|
|
1587
|
+
- id: verify_delta_design_template
|
|
1588
|
+
action: verify_context
|
|
1589
|
+
condition: "{{svc_lane}} == true"
|
|
1590
|
+
require_non_empty: delta_design_template_files
|
|
1591
|
+
on_empty: stop
|
|
1592
|
+
on_empty_message: "No delta-design template was written to .appweaver/templates/overrides/delta-design-template.md. Re-run onboard after confirming the design template override was generated."
|
|
1593
|
+
|
|
1594
|
+
# ═══════ UI DESIGN TEMPLATES (frontend lane only) — the LANE's own pair ═══════
|
|
1595
|
+
# The lane's twin of the two steps above, on the same terms: reverse-engineered from
|
|
1596
|
+
# the UI SOURCE, shaped by a NEUTRAL skeleton, installed in the project override slot
|
|
1597
|
+
# (.appweaver/templates/overrides/{ui-design,ui-delta-design}-template.md). Written ONLY
|
|
1598
|
+
# where the scan found a lane, so a backend-only repo gets neither file — the same
|
|
1599
|
+
# "absence is meaningful" property constitution.ui.md has.
|
|
1600
|
+
#
|
|
1601
|
+
# WHY THE LANE NEEDS ITS OWN PAIR rather than a section inside the service design: the
|
|
1602
|
+
# two lanes are governed by different constitution halves and different map headings,
|
|
1603
|
+
# they are implemented by different commands, and the ONLY thing that crosses between
|
|
1604
|
+
# them is the design contract. A UI section inside design.md would put the lane's
|
|
1605
|
+
# structure under the service lane's rules and hand ⌛ ui-design the whole service
|
|
1606
|
+
# design to read — precisely the context leak the contract projection exists to stop.
|
|
1607
|
+
#
|
|
1608
|
+
# THE SECTION LIST IS RATIFIED, THE CONTENT IS THE CODE'S. aw-spec specifies what
|
|
1609
|
+
# design.ui.md contains (navigation & screen structure · client state · component
|
|
1610
|
+
# structure · interaction & flow · contract binding · cross-cutting · traceability ·
|
|
1611
|
+
# DA-n · WA-n); the skeleton carries exactly that, framework-free. What this step
|
|
1612
|
+
# derives from the lane's source is what goes IN those sections — the real composition
|
|
1613
|
+
# axes, the state and styling conventions, the screen vocabulary.
|
|
1614
|
+
#
|
|
1615
|
+
# THE CONSUMERS ARE ⌛ NOT BUILT (B-14 / B-15: ui-design, ui-implement, the three-master
|
|
1616
|
+
# merge in finalize-delta). The templates are written now anyway, and deliberately: the
|
|
1617
|
+
# evidence for them is the whole-repo vantage that exists exactly once, at onboard, and
|
|
1618
|
+
# resolve_template finds them by name the day those commands land. Nothing reads them
|
|
1619
|
+
# before then, and nothing breaks for their absence in a repo that never onboarded.
|
|
1620
|
+
- id: ctx_ui_design_template
|
|
1621
|
+
action: build_context
|
|
1622
|
+
condition: "{{ui_lane}} == true"
|
|
1623
|
+
context:
|
|
1624
|
+
- { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — frontend_signals + the component/route/store/style file lists to read source from
|
|
1625
|
+
- { path: "{{constitution_ui_file}}" } # PRIMARY: the VALIDATED as-built UX-* base — the ratified principles this structure must serve
|
|
1626
|
+
- { path: .appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md } # SHAPE ONLY: the ratified section list + neutral bones (zero framework, zero component library)
|
|
1627
|
+
- { path: "{{pack_dir}}/frontend/ui-constitution.md", optional: true } # the generated lane rule set's base file — the detail layer under those principles
|
|
1628
|
+
- { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note
|
|
1629
|
+
- id: gen_ui_design_template
|
|
1630
|
+
action: agent_generate
|
|
1631
|
+
condition: "{{ui_lane}} == true"
|
|
1632
|
+
tools: "Read,Write,Edit"
|
|
1633
|
+
permission_mode: acceptEdits
|
|
1634
|
+
task: |
|
|
1635
|
+
REVERSE-ENGINEER this repo's FRONTEND LANE into a PROJECT-SPECIFIC UI DESIGN TEMPLATE
|
|
1636
|
+
and Write it to .appweaver/templates/overrides/ui-design-template.md (create the
|
|
1637
|
+
overrides/ dir if absent). It is a TEMPLATE — concrete lane-derived section content
|
|
1638
|
+
with [PLACEHOLDER] tokens + authoring HTML comments that ⌛ `ui-design` fills per
|
|
1639
|
+
feature into specs/<Feature>/design.ui.md — NOT a filled design.
|
|
1640
|
+
The lane: {{ui_evidence}} · roots: {{frontend_roots}}
|
|
1641
|
+
|
|
1642
|
+
GROUND EVERYTHING IN THE LANE'S OWN CODE. Evidence authority, in order:
|
|
1643
|
+
1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_json}} (in context):
|
|
1644
|
+
`frontend_signals` gives the lane roots, their kind (spa / server-rendered /
|
|
1645
|
+
desktop), their framework markers and their component / route / store / style
|
|
1646
|
+
file lists. READ ENOUGH OF THOSE FILES to state each structural claim from what
|
|
1647
|
+
the UI ACTUALLY does. Do NOT assert a convention you have not seen.
|
|
1648
|
+
2. constitution.ui.md (in context) — the VALIDATED as-built UX-* base. The template's
|
|
1649
|
+
authoring comments point the downstream author at the UX principle each section
|
|
1650
|
+
serves; cite them by their real numerals.
|
|
1651
|
+
3. The generated frontend/ui-constitution.md and the OKF architecture/frontend.md
|
|
1652
|
+
(in context, if present) — the lane's own rule detail and a shallow corroboration.
|
|
1653
|
+
STAY INSIDE THE LANE. Derive structure ONLY from code under the lane's roots. The
|
|
1654
|
+
service lane has its own template, generated just above; this one never describes
|
|
1655
|
+
server-side structure.
|
|
1656
|
+
|
|
1657
|
+
THE SKELETON IS SHAPE ONLY. rev-templates/ui-design-template.skeleton.md (in context)
|
|
1658
|
+
carries the ratified section list, the neutral bones and the authoring rules — and
|
|
1659
|
+
names NO framework, router, state library, component library, design system or styling
|
|
1660
|
+
approach. That omission is deliberate and you MUST preserve it: the generated template
|
|
1661
|
+
stays technology-agnostic even though you derived it from a real stack, because the
|
|
1662
|
+
framework binds later at ⌛ `ui-implement` from constitution.ui.md plus that command's
|
|
1663
|
+
rule set. Describe a component by its RESPONSIBILITY, its INPUTS as field shapes, the
|
|
1664
|
+
EVENTS it raises and the STATES it can be in — never by a framework's own vocabulary.
|
|
1665
|
+
|
|
1666
|
+
Identify the RECURRING composition convention across the lane's screens (how screens
|
|
1667
|
+
are organised and named, what is shared, where client state lives, how server data is
|
|
1668
|
+
fetched and invalidated, how styling is applied) — this ONE template governs every
|
|
1669
|
+
future feature's UI.
|
|
1670
|
+
|
|
1671
|
+
Then AUTHOR the template on the skeleton's shape, keeping its section numbers and
|
|
1672
|
+
headings:
|
|
1673
|
+
- Keep the header block and the TECHNOLOGY-AGNOSTIC authoring rules. Fill
|
|
1674
|
+
[GENERATED_LANE_STRUCTURE_NOTE] and §0's `### As-Built Lane Structure` with this
|
|
1675
|
+
lane's real convention, each claim carrying a representative path. Where the UI is
|
|
1676
|
+
rendered inside the service tree and owns no root of its own, say exactly that.
|
|
1677
|
+
- §1 Navigation & Screen Structure — template the screen inventory and the navigation
|
|
1678
|
+
shape THIS lane uses, described conceptually (a path pattern, a stack, a tab set),
|
|
1679
|
+
read from the routing code and never named after a router.
|
|
1680
|
+
- §2 Client State — template the state kinds this lane actually holds and the
|
|
1681
|
+
invalidation triggers it actually uses. If the lane holds no client state beyond
|
|
1682
|
+
form fields, say so as-built rather than templating a store it does not have.
|
|
1683
|
+
- §3 Component Structure — ONE `### 3.n` subsection PER RECURRING COMPOSITION AXIS the
|
|
1684
|
+
lane uses, each TITLED with the lane's OWN name for it. The count and titles are the
|
|
1685
|
+
code's answer; the skeleton's slots are positions, not a set to fill.
|
|
1686
|
+
- §4 Interaction & Flow and §6 Cross-Cutting — KEEP BOTH, always, even where this lane
|
|
1687
|
+
shows little. They are the two sections a backend-shaped process drops and where
|
|
1688
|
+
most UI defects live. Where the code handles no error or empty state, template the
|
|
1689
|
+
section so the downstream author must record that as-built — never delete it.
|
|
1690
|
+
- §5 Contract Binding — keep the lane boundary intact: the binding table reads the
|
|
1691
|
+
⌛ design-contract projection, never the service design. Note in the authoring
|
|
1692
|
+
comment that where no contract document exists yet the author binds against the
|
|
1693
|
+
spec's own IC-/FR- surface and logs a §8 assumption.
|
|
1694
|
+
- §7 Traceability, §8 Assumptions (DA-n), §9 Deviations (WA-n), Change History — carry
|
|
1695
|
+
over; the §7 Section column uses THIS template's own section refs.
|
|
1696
|
+
Keep every [PLACEHOLDER] and authoring comment so ⌛ `ui-design` can fill it — and in
|
|
1697
|
+
those comments DIRECT the downstream author to GROUND each filled section in the
|
|
1698
|
+
ACTUAL UI CODE and the lane's governance (cite real component/route/store/stylesheet
|
|
1699
|
+
paths and the constitution.ui.md UX numeral). Do NOT invent lane structure the code
|
|
1700
|
+
does not show; where the convention is inconsistent, template the DOMINANT form and
|
|
1701
|
+
flag the divergence in a comment. Write ONLY the override file; modify no source.
|
|
1702
|
+
Report the file written + the composition axes you derived (with the code paths that
|
|
1703
|
+
evidence them).
|
|
1704
|
+
outputs:
|
|
1705
|
+
- { name: ui_design_template_files, from: "$.files" }
|
|
1706
|
+
|
|
1707
|
+
- id: verify_ui_design_template
|
|
1708
|
+
action: verify_context
|
|
1709
|
+
condition: "{{ui_lane}} == true"
|
|
1710
|
+
require_non_empty: ui_design_template_files
|
|
1711
|
+
on_empty: stop
|
|
1712
|
+
on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no UI design template was written to .appweaver/templates/overrides/ui-design-template.md. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
|
|
1713
|
+
|
|
1714
|
+
# UI DELTA-DESIGN template — MIRROR the just-generated UI master's OWN sections, exactly
|
|
1715
|
+
# as the service delta mirrors the service master.
|
|
1716
|
+
- id: ctx_ui_delta_design_template
|
|
1717
|
+
action: build_context
|
|
1718
|
+
condition: "{{ui_lane}} == true"
|
|
1719
|
+
context:
|
|
1720
|
+
- { path: .appweaver/templates/overrides/ui-design-template.md, optional: true } # PRIMARY: the JUST-generated lane master — mirror its ACTUAL sections
|
|
1721
|
+
- { path: .appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md } # SHAPE ONLY: the neutral change-record bones (zero framework)
|
|
1722
|
+
- { path: "{{constitution_ui_file}}" } # the validated UX-* base (keep the delta consistent with the master)
|
|
1723
|
+
- id: gen_ui_delta_design_template
|
|
1724
|
+
action: agent_generate
|
|
1725
|
+
condition: "{{ui_lane}} == true"
|
|
1726
|
+
tools: "Read,Write,Edit"
|
|
1727
|
+
permission_mode: acceptEdits
|
|
1728
|
+
task: |
|
|
1729
|
+
Author the matching PROJECT-SPECIFIC UI DELTA-design TEMPLATE and Write it to
|
|
1730
|
+
.appweaver/templates/overrides/ui-delta-design-template.md. It is a TEMPLATE
|
|
1731
|
+
(placeholders + authoring comments) for classifying a CHANGE to a feature's
|
|
1732
|
+
EXPERIENCE as ADDED / MODIFIED / REMOVED against the master design.ui.md.
|
|
1733
|
+
|
|
1734
|
+
MIRROR the just-generated lane master (.appweaver/templates/overrides/ui-design-template.md,
|
|
1735
|
+
in context — Read it): its ADDED/MODIFIED/REMOVED tables must key off that master's OWN
|
|
1736
|
+
sections, including whatever composition axes its §3 derived. Use the skeleton's
|
|
1737
|
+
"Section (§ in design.ui.md)" column and fill its example rows with the ACTUAL sections
|
|
1738
|
+
of the generated master. Never name a framework or a UI taxonomy the master did not
|
|
1739
|
+
derive.
|
|
1740
|
+
- CARRY OVER the neutral parts of rev-templates/ui-delta-design-template.skeleton.md
|
|
1741
|
+
(in context): Change summary, Interaction states touched, Contract impact,
|
|
1742
|
+
Cross-section impact, Regression targets, New assumptions/deviations (DA-n / WA-n),
|
|
1743
|
+
On close.
|
|
1744
|
+
- KEEP the "Interaction states touched" section whatever this lane's code shows: a new
|
|
1745
|
+
interaction that ships without its loading, empty, error and permission-denied states
|
|
1746
|
+
is an incomplete delta, and the template is where that is enforced.
|
|
1747
|
+
- KEEP the lane boundary: contract impact is raised BACK to the service lane, never
|
|
1748
|
+
worked around in the client.
|
|
1749
|
+
- A shared component or state container is MODIFIED in place, never duplicated into the
|
|
1750
|
+
change; every changed element serves a spec id; behaviour stays technology-agnostic
|
|
1751
|
+
(responsibilities, field shapes, events — no code).
|
|
1752
|
+
Keep every [PLACEHOLDER] and authoring comment. Write ONLY the override file; modify no
|
|
1753
|
+
source. Report the file written.
|
|
1754
|
+
outputs:
|
|
1755
|
+
- { name: ui_delta_design_template_files, from: "$.files" }
|
|
1756
|
+
|
|
1757
|
+
- id: verify_ui_delta_design_template
|
|
1758
|
+
action: verify_context
|
|
1759
|
+
condition: "{{ui_lane}} == true"
|
|
1760
|
+
require_non_empty: ui_delta_design_template_files
|
|
1761
|
+
on_empty: stop
|
|
1762
|
+
on_empty_message: "No UI delta-design template was written to .appweaver/templates/overrides/ui-delta-design-template.md. Re-run onboard after confirming the UI design template override was generated."
|
|
1763
|
+
|
|
1764
|
+
# Post-execution hooks.
|
|
1765
|
+
- id: resolve_post_hooks
|
|
1766
|
+
action: execute_script
|
|
1767
|
+
script: { ref: actions }
|
|
1768
|
+
subcommand: resolve-hooks
|
|
1769
|
+
args: ["--phase", "after_onboard"]
|
|
1770
|
+
outputs:
|
|
1771
|
+
- { name: after_hooks, from: "$.hooks" }
|
|
1772
|
+
- id: dispatch_post_hooks
|
|
1773
|
+
action: dispatch_hooks
|
|
1774
|
+
hooks_from_variable: after_hooks
|
|
1775
|
+
|
|
1776
|
+
outputs:
|
|
1777
|
+
bundle_dir: "{{bundle_dir}}"
|
|
1778
|
+
aggregate_count: "{{aggregate_count}}"
|
|
1779
|
+
concepts: "{{concepts}}"
|
|
1780
|
+
warnings: "{{okf_warnings}}"
|
|
1781
|
+
domain_slug: "{{domain_slug}}"
|
|
1782
|
+
pack_dir: "{{pack_dir}}"
|
|
1783
|
+
domain_rule_bindings: "{{domain_rule_bindings}}"
|
|
1784
|
+
tech_rule_bindings: "{{pack_dir}}/tech-rule-bindings.md"
|
|
1785
|
+
pack_files: "{{pack_files}}"
|
|
1786
|
+
tech_pack_files: "{{tech_pack_files}}"
|
|
1787
|
+
ui_pack_files: "{{ui_pack_files}}"
|
|
1788
|
+
domain_constitution_source: "{{domain_constitution_source}}"
|
|
1789
|
+
constitution_technical_file: "{{constitution_technical_file}}"
|
|
1790
|
+
constitution_domain_file: "{{constitution_domain_file}}"
|
|
1791
|
+
constitution_ui_file: "{{constitution_ui_file}}"
|
|
1792
|
+
composed_file: "{{composed_file}}"
|
|
1793
|
+
active_domain: "{{active_domain}}"
|
|
1794
|
+
# The lanes this run was told to govern, and what their source turned out to hold.
|
|
1795
|
+
service_lane: "{{svc_lane}}"
|
|
1796
|
+
ui_lane: "{{ui_lane}}"
|
|
1797
|
+
ui_lane_evidence: "{{ui_evidence}}"
|
|
1798
|
+
ui_lane_declaration: "{{ui_declaration_note}}"
|
|
1799
|
+
ui_source_evidence_found: "{{ui_evidence_found}}"
|
|
1800
|
+
ui_included: "{{ui_included}}"
|
|
1801
|
+
ui_validation_ok: "{{ui_validation_state}}"
|
|
1802
|
+
frontend_roots: "{{frontend_roots}}"
|
|
1803
|
+
# The lane declaration this run READ. select-stack wrote it; onboard never touches it.
|
|
1804
|
+
stacks_file: "{{stacks_file}}"
|
|
1805
|
+
backend_lane: "{{be_lane_id}} ({{be_profile}}) at {{be_root}}"
|
|
1806
|
+
frontend_lane: "{{fe_lane_id}} ({{fe_profile}}) at {{fe_root}}"
|
|
1807
|
+
# What the scan was scoped to, and how many files each lane's substrate was built
|
|
1808
|
+
# from. Backend signals exclude the UI subtree; frontend signals are that subtree.
|
|
1809
|
+
scanned_service_root: "{{scoped_service_root}}"
|
|
1810
|
+
scanned_ui_root: "{{scoped_ui_root}}"
|
|
1811
|
+
scanned_backend_files: "{{backend_file_count}}"
|
|
1812
|
+
scanned_ui_files: "{{frontend_file_count}}"
|
|
1813
|
+
design_template_override: ".appweaver/templates/overrides/design-template.md"
|
|
1814
|
+
delta_design_template_override: ".appweaver/templates/overrides/delta-design-template.md"
|
|
1815
|
+
design_template_files: "{{design_template_files}}"
|
|
1816
|
+
delta_design_template_files: "{{delta_design_template_files}}"
|
|
1817
|
+
# The lane's own template pair. Empty on a backend-only repo — no lane, no files.
|
|
1818
|
+
ui_design_template_files: "{{ui_design_template_files}}"
|
|
1819
|
+
ui_delta_design_template_files: "{{ui_delta_design_template_files}}"
|
|
1820
|
+
technical_validation_ok: "{{technical_ok}}"
|
|
1821
|
+
domain_validation_ok: "{{domain_ok}}"
|
|
1822
|
+
next: "Onboarded {{project_name}}: a high-level feature map at {{bundle_dir}} + a PROVISIONAL project governance scaffold, domain {{active_domain}} ACTIVATED, and — reverse-engineered from THIS code alone — the rule tiers wired per-workflow: the DOMAIN set (guardrails/projects/{{domain_slug}}/domain/*.domain.md + domain-rule-bindings.md) always, and each LANE's set where that lane is declared. ONE HALF AND ONE RULE SET PER LANE: service_lane / ui_lane report which lanes .appweaver/stacks.json declared, and the declaration is what decided. A declared service lane gets constitution.technical.md, guardrails/projects/{{domain_slug}}/service/*.md + tech-rule-bindings.md, and the service design/delta-design template overrides; a declared UI lane gets constitution.ui.md, guardrails/projects/{{domain_slug}}/frontend/*.md mapped under ## /aw-spec-ui-constitution, and its own template pair. A lane declared (none) in select-stack gets none of it, which is the correct outcome and not an omission. LANE DECLARATION: read, never written — select-stack is its sole writer, and this run scanned the source paths it named (scanned_service_root / scanned_ui_root). The scan was SCOPED by them, so the backend substrate excludes the UI subtree and the frontend substrate is that subtree: scanned_backend_files / scanned_ui_files report each. ui_source_evidence_found false means the UI lane's declared path held nothing a scan recognises as UI, so its governance is thin — move the source path with /appweaver select-stack and re-run. The build/test/run commands on each lane are that PROFILE's defaults and may not match a legacy layout — review them, and re-run /appweaver select-stack to correct any lane. Because the domain is activated, resolve-domain + resolve-tech now route the WHOLE forward pipeline AND adopt to these code-derived rules — never another project's rules as a fallback. Code-derived design + delta-design templates are installed as the project template overrides (.appweaver/templates/overrides/) so a NEW feature is developed against the as-built architecture with NO adopt — every section derived from a NEUTRAL skeleton plus this repo's own structure, with no greenfield template in context. Where the lane exists, the SAME pair is generated for it (ui-design-template.md + ui-delta-design-template.md) from the UI source; ui-design-template.md is consumed by /appweaver adopt, which reverses a slice's design.ui.md from it wherever that slice owns part of the lane's surface; ui-delta-design-template.md still waits, since ui-design / ui-implement are not built yet. Develop an EXISTING feature just-in-time: /appweaver adopt <Feature> reverse-engineers its spec.md + design.md + source-map.md and completes that feature's OKF concept; its governance reconcile is currently HELD, so the scaffold this run wrote stays as it is. Develop a NEW feature straight through the forward pipeline (/appweaver specify → design → implement). Then drive every change through the CR delta loop (/appweaver specify → design → analyze-delta-design → implement-delta → build → finalize-delta → analyze-slice → close-delta). If a validation_ok is false, its constitution half needs a manual touch (see its Sync Impact Report)."
|