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,329 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""aw-rev-constitution.py — deterministic substrate for the Brownfield GOVERN-BACKWARD
|
|
3
|
+
phase.
|
|
4
|
+
|
|
5
|
+
A legacy codebase has no GOVERNANCE tier — no split constitution, no rule packs —
|
|
6
|
+
yet specify/design/implement/gates are all driven by one. Govern-backward
|
|
7
|
+
reverse-engineers that tier from what the code itself evidences, so forward
|
|
8
|
+
development of the SAME codebase runs governed exactly like greenfield (Change
|
|
9
|
+
Requests through the CR delta loop).
|
|
10
|
+
|
|
11
|
+
CALLER (2026-07-29 onward): the standalone `/appweaver rev-constitution` workflow
|
|
12
|
+
is RETIRED — do not expect that command to exist. The phase now lives in:
|
|
13
|
+
* `/appweaver onboard` — up front, over the WHOLE repo, before any slice is
|
|
14
|
+
adopted. It is the ONLY caller of this core (workflow `scripts:` ref, both
|
|
15
|
+
shells). At onboard time nothing is adopted yet, so `list-adopted` legitimately
|
|
16
|
+
returns slice_count 0 and draws its context from the OKF bundle instead.
|
|
17
|
+
* `/appweaver adopt` — per slice, reconciling each provisional principle
|
|
18
|
+
against that slice's real spec.md/design.md evidence. Adopt does NOT call this
|
|
19
|
+
core; it reconciles in its own steps.
|
|
20
|
+
|
|
21
|
+
This core survived the retirement unchanged because it is the MODEL-FREE half: it
|
|
22
|
+
enumerates whatever slices ARE adopted and scaffolds the
|
|
23
|
+
`guardrails/projects/brf-<domain>/` project directory; the calling workflow's authoring
|
|
24
|
+
agents fill its rule files + the split constitution. Governance stance is AS-BUILT
|
|
25
|
+
(the constitution reflects what the code does, not an aspiration — a separate
|
|
26
|
+
modernization/migration workflow drains the debt later).
|
|
27
|
+
|
|
28
|
+
Two subcommands, each printing a single JSON object as the LAST stdout line (so
|
|
29
|
+
the orchestrator's execute_script can bind it); human-readable summaries go to
|
|
30
|
+
STDERR so they never corrupt the JSON contract:
|
|
31
|
+
|
|
32
|
+
list-adopted [--root <dir>] [--specs <dir>] [--bundle <dir>]
|
|
33
|
+
-> the union of adopted artifacts to reverse-engineer FROM. Returns
|
|
34
|
+
{slices[], slice_count, reverse_count, spec_context[], design_context[],
|
|
35
|
+
all_context[], project_context[], project_name, overview, platform,
|
|
36
|
+
backlog, root}. *_context arrays are workspace-relative paths ready for a
|
|
37
|
+
build_context `context_from:`. The technology (design) side carries the
|
|
38
|
+
designs + OKF overview + platform note + migration backlog + the per-slice
|
|
39
|
+
source-maps (the code-coordinate bridge) so the TECHNICAL half is derived from
|
|
40
|
+
what the code evidences AND cites real code files/types, not the template —
|
|
41
|
+
including the shared-infra gaps (platform Open Questions) and the as-built debt
|
|
42
|
+
sink to route unmet template ideals to. Stays domain-agnostic by the author's
|
|
43
|
+
prompt (cite code paths, ignore the source-map's domain spec-ids / entity names).
|
|
44
|
+
|
|
45
|
+
project-setup --name <domain> [--fallback <name>] [--root <dir>]
|
|
46
|
+
-> slugify + `brf-` prefix the domain, create guardrails/projects/<slug>/ with its
|
|
47
|
+
service/ frontend/ domain/ subfolders (guard: refuses to clobber a project that
|
|
48
|
+
already holds .md files anywhere). Returns
|
|
49
|
+
{domain_slug, pack_dir, domain_rule_bindings, domain_constitution_source,
|
|
50
|
+
pack_present}. Both maps sit at the project root; every rule file, the
|
|
51
|
+
domain charter included, sits in one of the three subfolders.
|
|
52
|
+
pack_present is the STRING "true"/"false" (so verify_context
|
|
53
|
+
require_value/condition can gate the anti-clobber guard).
|
|
54
|
+
`pack-setup` is the older name for the same subcommand and still works.
|
|
55
|
+
|
|
56
|
+
Usage: aw-rev-constitution.py <list-adopted|project-setup> [options]
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
import argparse
|
|
60
|
+
import json
|
|
61
|
+
import os
|
|
62
|
+
import re
|
|
63
|
+
import sys
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _root(arg_root):
|
|
67
|
+
"""Repo/component root: explicit --root, else CWD (the orchestrator runs each
|
|
68
|
+
execute_script with CWD = the component root, where .appweaver / specs / guardrails live)."""
|
|
69
|
+
return os.path.abspath(arg_root) if arg_root else os.getcwd()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _rel(path, root):
|
|
73
|
+
"""Workspace-relative POSIX path (build_context resolves against CWD = root)."""
|
|
74
|
+
return os.path.relpath(path, root).replace(os.sep, "/")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _emit(obj):
|
|
78
|
+
"""JSON contract: the object as the LAST stdout line."""
|
|
79
|
+
print(json.dumps(obj))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _uniq(seq):
|
|
83
|
+
"""Order-preserving de-dup (context arrays are concatenated from overlapping
|
|
84
|
+
sources — the OKF overview belongs to several of them)."""
|
|
85
|
+
seen, out = set(), []
|
|
86
|
+
for x in seq:
|
|
87
|
+
if x and x not in seen:
|
|
88
|
+
seen.add(x)
|
|
89
|
+
out.append(x)
|
|
90
|
+
return out
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _project_name(overview_abs):
|
|
94
|
+
"""The project's display name — the WHOLE project the governance tier governs,
|
|
95
|
+
NOT the outer tooling folder. Inventory writes the OKF overview's Purpose as
|
|
96
|
+
'## Purpose ... **<ProjectName>** is a ...', so the first bold token in that
|
|
97
|
+
section is the solution/product name (e.g. 'Medicinal.Healthcare'). Empty when no
|
|
98
|
+
overview exists — pack-setup then falls back to the repo basename as before."""
|
|
99
|
+
if not overview_abs or not os.path.isfile(overview_abs):
|
|
100
|
+
return ""
|
|
101
|
+
try:
|
|
102
|
+
with open(overview_abs, "r", encoding="utf-8", errors="replace") as fh:
|
|
103
|
+
text = fh.read(8192)
|
|
104
|
+
except OSError:
|
|
105
|
+
return ""
|
|
106
|
+
m = re.search(r"##\s*Purpose\s*(.+?)(?:\n##\s|\Z)", text, re.IGNORECASE | re.DOTALL)
|
|
107
|
+
scope = m.group(1) if m else text
|
|
108
|
+
b = re.search(r"\*\*([^*\n]+?)\*\*", scope)
|
|
109
|
+
return b.group(1).strip() if b else ""
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# ─────────────────────────────── list-adopted ──────────────────────────────
|
|
113
|
+
def cmd_list_adopted(args):
|
|
114
|
+
root = _root(args.root)
|
|
115
|
+
specs_dir = os.path.join(root, args.specs)
|
|
116
|
+
bundle_dir = os.path.join(root, args.bundle)
|
|
117
|
+
|
|
118
|
+
slices = []
|
|
119
|
+
spec_context = []
|
|
120
|
+
design_context = []
|
|
121
|
+
source_maps = []
|
|
122
|
+
reverse_count = 0
|
|
123
|
+
|
|
124
|
+
if os.path.isdir(specs_dir):
|
|
125
|
+
for name in sorted(os.listdir(specs_dir)):
|
|
126
|
+
sdir = os.path.join(specs_dir, name)
|
|
127
|
+
if not os.path.isdir(sdir):
|
|
128
|
+
continue
|
|
129
|
+
spec = os.path.join(sdir, "spec.md")
|
|
130
|
+
design = os.path.join(sdir, "design.md")
|
|
131
|
+
# A slice is adoptable-governance input only when BOTH docs exist.
|
|
132
|
+
if not (os.path.isfile(spec) and os.path.isfile(design)):
|
|
133
|
+
continue
|
|
134
|
+
smap = os.path.join(sdir, "source-map.md")
|
|
135
|
+
is_reverse = False
|
|
136
|
+
try:
|
|
137
|
+
with open(spec, "r", encoding="utf-8", errors="replace") as fh:
|
|
138
|
+
head = fh.read(4096)
|
|
139
|
+
if re.search(r"reverse-engineered", head, re.IGNORECASE):
|
|
140
|
+
is_reverse = True
|
|
141
|
+
except OSError:
|
|
142
|
+
pass
|
|
143
|
+
if is_reverse:
|
|
144
|
+
reverse_count += 1
|
|
145
|
+
slices.append({
|
|
146
|
+
"name": name,
|
|
147
|
+
"spec": _rel(spec, root),
|
|
148
|
+
"design": _rel(design, root),
|
|
149
|
+
"source_map": _rel(smap, root) if os.path.isfile(smap) else "",
|
|
150
|
+
"origin": "reverse-engineered" if is_reverse else "unknown",
|
|
151
|
+
})
|
|
152
|
+
spec_context.append(_rel(spec, root))
|
|
153
|
+
design_context.append(_rel(design, root))
|
|
154
|
+
if os.path.isfile(smap):
|
|
155
|
+
source_maps.append(_rel(smap, root))
|
|
156
|
+
|
|
157
|
+
# The OKF architecture overview names the actual tech stack (technology half input).
|
|
158
|
+
overview = ""
|
|
159
|
+
overview_abs = ""
|
|
160
|
+
for cand in ("architecture/overview.md", "architecture/architecture.md"):
|
|
161
|
+
p = os.path.join(bundle_dir, cand)
|
|
162
|
+
if os.path.isfile(p):
|
|
163
|
+
overview = _rel(p, root)
|
|
164
|
+
overview_abs = p
|
|
165
|
+
break
|
|
166
|
+
|
|
167
|
+
# TECHNICAL evidence beyond the overview, both domain-free: the shared-platform note
|
|
168
|
+
# (cross-cutting persistence / tenancy / concurrency reality — incl. its Open Questions,
|
|
169
|
+
# e.g. tenancy may be inactive) and the migration backlog (the as-built DEBT SINK the
|
|
170
|
+
# technical author routes any unmet template ideal / stub to, instead of asserting it).
|
|
171
|
+
# These feed the DESIGN side so the technical half is EVIDENCE-FIRST, not template-first.
|
|
172
|
+
platform_ref = ""
|
|
173
|
+
p = os.path.join(bundle_dir, "architecture/platform.md")
|
|
174
|
+
if os.path.isfile(p):
|
|
175
|
+
platform_ref = _rel(p, root)
|
|
176
|
+
backlog_ref = ""
|
|
177
|
+
p = os.path.join(bundle_dir, "migration-backlog.md")
|
|
178
|
+
if os.path.isfile(p):
|
|
179
|
+
backlog_ref = _rel(p, root)
|
|
180
|
+
|
|
181
|
+
# Project-level OKF framing — the PROJECT AS A WHOLE, not just one adopted slice:
|
|
182
|
+
# the overview (mission + aggregate map + external refs + stack), the aggregate
|
|
183
|
+
# index (bounded-context map), and the shared-platform note. These are what let the
|
|
184
|
+
# DOMAIN author write a project charter instead of a single-aggregate spec. The
|
|
185
|
+
# technical half deliberately does NOT get the aggregate index or specs (stays
|
|
186
|
+
# domain-free); it DOES get platform.md + the backlog as technical evidence (below).
|
|
187
|
+
project_context = [overview] if overview else []
|
|
188
|
+
for cand in ("aggregates/index.md", "architecture/platform.md", "index.md"):
|
|
189
|
+
p = os.path.join(bundle_dir, cand)
|
|
190
|
+
if os.path.isfile(p):
|
|
191
|
+
project_context.append(_rel(p, root))
|
|
192
|
+
project_context = _uniq(project_context)
|
|
193
|
+
|
|
194
|
+
# The display name of the whole project the governance tier governs (from the OKF
|
|
195
|
+
# overview), so the project + constitution are named + titled after the PROJECT — not the
|
|
196
|
+
# outer tooling folder the CWD-basename fallback would pick.
|
|
197
|
+
project_name = _project_name(overview_abs)
|
|
198
|
+
|
|
199
|
+
# spec side = domain input (specs + source-maps + PROJECT framing); design side =
|
|
200
|
+
# technology input (designs + OKF stack overview + shared-platform note + as-built
|
|
201
|
+
# backlog + the per-slice source-maps — the code-coordinate bridge, so the TECHNICAL
|
|
202
|
+
# half anchors each principle to a real code file/type, not just a design section;
|
|
203
|
+
# kept domain-agnostic by the author's prompt discipline, not by starving it of the
|
|
204
|
+
# code map — rich enough to DERIVE the principle set from evidence and route unmet
|
|
205
|
+
# ideals to debt); all = the rule-set author's full picture.
|
|
206
|
+
spec_side = _uniq(spec_context + source_maps + project_context)
|
|
207
|
+
design_side = _uniq(
|
|
208
|
+
design_context
|
|
209
|
+
+ source_maps
|
|
210
|
+
+ ([overview] if overview else [])
|
|
211
|
+
+ ([platform_ref] if platform_ref else [])
|
|
212
|
+
+ ([backlog_ref] if backlog_ref else [])
|
|
213
|
+
)
|
|
214
|
+
all_context = _uniq(spec_context + design_context + source_maps + project_context)
|
|
215
|
+
|
|
216
|
+
result = {
|
|
217
|
+
"slices": slices,
|
|
218
|
+
"slice_count": len(slices),
|
|
219
|
+
"reverse_count": reverse_count,
|
|
220
|
+
"spec_context": spec_side,
|
|
221
|
+
"design_context": design_side,
|
|
222
|
+
"all_context": all_context,
|
|
223
|
+
"project_context": project_context,
|
|
224
|
+
"project_name": project_name,
|
|
225
|
+
"overview": overview,
|
|
226
|
+
"platform": platform_ref,
|
|
227
|
+
"backlog": backlog_ref,
|
|
228
|
+
"root": root,
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
names = ", ".join(s["name"] for s in slices) or "(none)"
|
|
232
|
+
print(
|
|
233
|
+
f"[govern-backward] adopted slices: {len(slices)} "
|
|
234
|
+
f"({reverse_count} reverse-engineered) — {names}\n"
|
|
235
|
+
f" project: {project_name or '(unknown — no OKF overview)'} "
|
|
236
|
+
f"overview: {overview or '(none — no OKF bundle)'}\n"
|
|
237
|
+
f" technical evidence: platform={platform_ref or '(none)'} "
|
|
238
|
+
f"backlog={backlog_ref or '(none)'}",
|
|
239
|
+
file=sys.stderr,
|
|
240
|
+
)
|
|
241
|
+
_emit(result)
|
|
242
|
+
return 0
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
# ─────────────────────────────── pack-setup ────────────────────────────────
|
|
246
|
+
def _slugify(name):
|
|
247
|
+
s = (name or "").strip().lower()
|
|
248
|
+
s = re.sub(r"[^a-z0-9]+", "-", s)
|
|
249
|
+
s = re.sub(r"-{2,}", "-", s).strip("-")
|
|
250
|
+
return s
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def cmd_pack_setup(args):
|
|
254
|
+
root = _root(args.root)
|
|
255
|
+
raw = args.name if (args.name and args.name.strip()) else args.fallback
|
|
256
|
+
if not raw or not raw.strip():
|
|
257
|
+
# Last-resort fallback: the component/repo directory name.
|
|
258
|
+
raw = os.path.basename(root.rstrip(os.sep)) or "domain"
|
|
259
|
+
slug = _slugify(raw)
|
|
260
|
+
if not slug:
|
|
261
|
+
slug = "domain"
|
|
262
|
+
# Strip any leading brf- the operator already typed, then re-apply once.
|
|
263
|
+
slug = re.sub(r"^brf-+", "", slug)
|
|
264
|
+
domain_slug = "brf-" + slug
|
|
265
|
+
|
|
266
|
+
pack_dir = os.path.join(root, "guardrails", "projects", domain_slug)
|
|
267
|
+
# Anti-clobber guard: a project that already holds curated .md files is not ours
|
|
268
|
+
# to overwrite (mirrors inventory's bundle_guard). pack_present drives the gate.
|
|
269
|
+
# The walk covers the whole subtree, because a project's rule files live in its
|
|
270
|
+
# service/ frontend/ domain/ subfolders and only the two maps sit at its root.
|
|
271
|
+
present = False
|
|
272
|
+
if os.path.isdir(pack_dir):
|
|
273
|
+
present = any(f.endswith(".md") for _, _, fs in os.walk(pack_dir) for f in fs)
|
|
274
|
+
if not present:
|
|
275
|
+
for sub in ("service", "frontend", "domain"):
|
|
276
|
+
os.makedirs(os.path.join(pack_dir, sub), exist_ok=True)
|
|
277
|
+
|
|
278
|
+
result = {
|
|
279
|
+
"domain_slug": domain_slug,
|
|
280
|
+
"pack_dir": _rel(pack_dir, root),
|
|
281
|
+
"domain_rule_bindings": _rel(os.path.join(pack_dir, "domain-rule-bindings.md"), root),
|
|
282
|
+
# The charter is a domain-tier rule file, so it sits with the rest of them and
|
|
283
|
+
# carries the same name the greenfield industry corpora use. That symmetry is what
|
|
284
|
+
# lets one `## /aw-spec-constitution` bullet serve both ramps: `constitution` finds
|
|
285
|
+
# the project's charter exactly where it finds an industry's.
|
|
286
|
+
"domain_constitution_source": _rel(
|
|
287
|
+
os.path.join(pack_dir, "domain", "domain-constitution.md"), root
|
|
288
|
+
),
|
|
289
|
+
"pack_present": "true" if present else "false",
|
|
290
|
+
"root": root,
|
|
291
|
+
}
|
|
292
|
+
print(
|
|
293
|
+
f"[govern-backward] project: guardrails/projects/{domain_slug}/ "
|
|
294
|
+
f"({'EXISTS — guarded' if present else 'created'})",
|
|
295
|
+
file=sys.stderr,
|
|
296
|
+
)
|
|
297
|
+
_emit(result)
|
|
298
|
+
return 0
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def main(argv):
|
|
302
|
+
ap = argparse.ArgumentParser(prog="aw-rev-constitution.py", add_help=True)
|
|
303
|
+
sub = ap.add_subparsers(dest="cmd")
|
|
304
|
+
|
|
305
|
+
la = sub.add_parser("list-adopted", help="enumerate adopted slices to reverse-engineer from")
|
|
306
|
+
la.add_argument("--root", default="")
|
|
307
|
+
la.add_argument("--specs", default="specs")
|
|
308
|
+
la.add_argument("--bundle", default="knowledge")
|
|
309
|
+
la.set_defaults(func=cmd_list_adopted)
|
|
310
|
+
|
|
311
|
+
# `pack-setup` is the name this subcommand shipped under and is kept as an alias:
|
|
312
|
+
# the folder it creates is a PROJECT, so the primary name says so, and a caller
|
|
313
|
+
# written against either spelling reaches the same code.
|
|
314
|
+
for name in ("project-setup", "pack-setup"):
|
|
315
|
+
ps = sub.add_parser(name, help="create the guardrails/projects/brf-<domain>/ project dir")
|
|
316
|
+
ps.add_argument("--name", default="")
|
|
317
|
+
ps.add_argument("--fallback", default="")
|
|
318
|
+
ps.add_argument("--root", default="")
|
|
319
|
+
ps.set_defaults(func=cmd_pack_setup)
|
|
320
|
+
|
|
321
|
+
args = ap.parse_args(argv)
|
|
322
|
+
if not getattr(args, "func", None):
|
|
323
|
+
ap.print_help(sys.stderr)
|
|
324
|
+
return 2
|
|
325
|
+
return args.func(args)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
if __name__ == "__main__":
|
|
329
|
+
sys.exit(main(sys.argv[1:]))
|