archharness 0.3.2__py3-none-any.whl
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.
- archharness/__init__.py +3 -0
- archharness/__main__.py +3 -0
- archharness/cli.py +153 -0
- archharness/data/config.example.yaml +98 -0
- archharness/data/skills/arch-design/SKILL.md +106 -0
- archharness/data/skills/arch-diagram/SKILL.md +82 -0
- archharness/data/skills/arch-enforce/SKILL.md +89 -0
- archharness/data/skills/arch-optimize/SKILL.md +128 -0
- archharness/data/skills/arch-report/SKILL.md +129 -0
- archharness/data/skills/arch-req-from-api/SKILL.md +123 -0
- archharness/data/skills/arch-req-from-diagram/SKILL.md +101 -0
- archharness/data/skills/arch-req-from-doc/SKILL.md +91 -0
- archharness/data/skills/arch-req-merge/SKILL.md +90 -0
- archharness/data/skills/arch-requirements/REQ-example.md +145 -0
- archharness/data/skills/arch-requirements/SKILL.md +368 -0
- archharness/data/skills/arch-requirements/req-example.yaml +315 -0
- archharness/data/skills/arch-review/SKILL.md +123 -0
- archharness/data/skills/arch-security/SKILL.md +100 -0
- archharness/data/skills/arch-validate/SKILL.md +195 -0
- archharness/data/skills/arch-validate/rules/accuracy-rules.yaml +314 -0
- archharness/data/skills/arch-validate/rules/compliance/terminology.yaml +188 -0
- archharness/data/skills/arch-validate/rules/diagram-rules.yaml +154 -0
- archharness/data/skills/arch-validate/rules/interaction-rules.yaml +178 -0
- archharness/data/skills/arch-validate/rules/platform-rules.yaml +344 -0
- archharness/data/skills/arch-validate/rules/security-rules.yaml +232 -0
- archharness/data/skills/arch-workflow/SKILL.md +66 -0
- archharness/data/standards/arch-gate-policy.yaml +27 -0
- archharness/data/standards/aws-standard.yaml +166 -0
- archharness/data/standards/azure-standard.yaml +208 -0
- archharness/data/standards/ci-gate-spec.yaml +132 -0
- archharness/data/standards/diagram-style.yaml +321 -0
- archharness/data/standards/eval-weights.yaml +107 -0
- archharness/data/standards/private-cloud-standard.yaml +190 -0
- archharness/data/standards/workflow.yaml +70 -0
- archharness/data/tools/arch-diagram-gen/DIAGRAM_GENERATION_ANALYSIS.md +135 -0
- archharness/data/tools/arch-diagram-gen/README.md +208 -0
- archharness/data/tools/arch-diagram-gen/arch-schema-reference.yaml +191 -0
- archharness/data/tools/arch-diagram-gen/arch_diagram_gen.py +200 -0
- archharness/data/tools/arch-diagram-gen/d2_generator.py +335 -0
- archharness/data/tools/arch-diagram-gen/example_arch.yaml +94 -0
- archharness/data/tools/arch-diagram-gen/example_output.d2 +315 -0
- archharness/data/tools/arch-diagram-gen/example_output.drawio +226 -0
- archharness/data/tools/arch-diagram-gen/example_output.png +0 -0
- archharness/data/tools/arch-diagram-gen/example_output.puml +110 -0
- archharness/data/tools/arch-diagram-gen/generator.py +357 -0
- archharness/data/tools/arch-diagram-gen/layout.py +235 -0
- archharness/data/tools/arch-diagram-gen/plantuml_generator.py +289 -0
- archharness/data/tools/arch-diagram-gen/png_renderer.py +404 -0
- archharness/data/tools/arch-diagram-gen/styles.py +169 -0
- archharness/data/tools/arch-diagram-gen/templates/CATALOG.yaml +222 -0
- archharness/data/tools/arch-diagram-gen/templates/aws-hybrid.yaml +294 -0
- archharness/data/tools/arch-diagram-gen/templates/azure-hub-spoke.yaml +307 -0
- archharness/data/tools/arch-diagram-gen/templates/data-analytics.yaml +269 -0
- archharness/data/tools/arch-diagram-gen/templates/microsoft-365.yaml +285 -0
- archharness/data/tools/arch-diagram-gen/templates/private-cloud.yaml +245 -0
- archharness/data/tools/arch-req-readers/README.md +125 -0
- archharness/data/tools/arch-req-readers/from_api.py +406 -0
- archharness/data/tools/arch-req-readers/from_diagram.py +676 -0
- archharness/data/tools/arch-req-readers/from_document.py +373 -0
- archharness/data/tools/arch-req-readers/merger.py +525 -0
- archharness/data/tools/arch-req-readers/normalizer.py +179 -0
- archharness/data/tools/arch-req-readers/req_reader.py +188 -0
- archharness/data/tools/config_loader.py +250 -0
- archharness/data/tools/yaml_validate.py +361 -0
- archharness/paths.py +51 -0
- archharness/tool_runners.py +62 -0
- archharness/workspace.py +246 -0
- archharness-0.3.2.dist-info/METADATA +447 -0
- archharness-0.3.2.dist-info/RECORD +73 -0
- archharness-0.3.2.dist-info/WHEEL +5 -0
- archharness-0.3.2.dist-info/entry_points.txt +2 -0
- archharness-0.3.2.dist-info/licenses/LICENSE +21 -0
- archharness-0.3.2.dist-info/top_level.txt +1 -0
archharness/__init__.py
ADDED
archharness/__main__.py
ADDED
archharness/cli.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""ArchHarness command-line interface."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from . import __version__
|
|
11
|
+
from .paths import find_archharness_root, require_archharness_root
|
|
12
|
+
from .tool_runners import run_tool
|
|
13
|
+
from .workspace import (
|
|
14
|
+
find_workspace,
|
|
15
|
+
get_project,
|
|
16
|
+
init_project,
|
|
17
|
+
init_workspace,
|
|
18
|
+
list_projects,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
PASSTHROUGH_COMMANDS = ("diagram", "req", "validate-yaml")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
25
|
+
parser = argparse.ArgumentParser(
|
|
26
|
+
prog="archharness",
|
|
27
|
+
description="ArchHarness — enterprise architecture skills and multi-project workspace tools",
|
|
28
|
+
)
|
|
29
|
+
parser.add_argument("--version", action="version", version=f"ArchHarness {__version__}")
|
|
30
|
+
commands = parser.add_subparsers(dest="command", required=True)
|
|
31
|
+
|
|
32
|
+
workspace = commands.add_parser("init-workspace", help="Initialize a multi-project workspace")
|
|
33
|
+
workspace.add_argument("path", nargs="?", default=".")
|
|
34
|
+
workspace.add_argument("--force", action="store_true")
|
|
35
|
+
|
|
36
|
+
project = commands.add_parser("init-project", help="Create an isolated architecture project")
|
|
37
|
+
project.add_argument("project_id")
|
|
38
|
+
project.add_argument("--workspace", default=None)
|
|
39
|
+
project.add_argument("--name")
|
|
40
|
+
project.add_argument("--platform", default="unspecified")
|
|
41
|
+
project.add_argument("--classification", default="internal")
|
|
42
|
+
project.add_argument("--default", action="store_true", dest="make_default")
|
|
43
|
+
|
|
44
|
+
listing = commands.add_parser("list-projects", help="List projects in a workspace")
|
|
45
|
+
listing.add_argument("--workspace", default=None)
|
|
46
|
+
|
|
47
|
+
doctor = commands.add_parser(
|
|
48
|
+
"doctor", help="Check installation, workspace, and project configuration"
|
|
49
|
+
)
|
|
50
|
+
doctor.add_argument("--workspace", default=None)
|
|
51
|
+
doctor.add_argument("--project", default=None)
|
|
52
|
+
|
|
53
|
+
commands.add_parser("root", help="Print the ArchHarness resource root directory")
|
|
54
|
+
|
|
55
|
+
for name in PASSTHROUGH_COMMANDS:
|
|
56
|
+
commands.add_parser(name, add_help=False, help=f"Run the {name} tool")
|
|
57
|
+
return parser
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _print_doctor() -> int:
|
|
61
|
+
try:
|
|
62
|
+
root = require_archharness_root()
|
|
63
|
+
except FileNotFoundError as exc:
|
|
64
|
+
print(f"ERROR: {exc}", file=sys.stderr)
|
|
65
|
+
return 1
|
|
66
|
+
|
|
67
|
+
problems: list[str] = []
|
|
68
|
+
is_repo = (root / ".claude" / "skills").is_dir() or (root / "config.yaml").is_file()
|
|
69
|
+
print(f"ArchHarness {__version__}")
|
|
70
|
+
print(f"resource root: {root} ({'repository' if is_repo else 'installed package data'})")
|
|
71
|
+
|
|
72
|
+
skills_dir = (root / ".claude" / "skills") if is_repo else (root / "skills")
|
|
73
|
+
checks = [
|
|
74
|
+
("standards/", (root / "standards").is_dir()),
|
|
75
|
+
("skills/", skills_dir.is_dir()),
|
|
76
|
+
("tools/arch-diagram-gen/", (root / "tools" / "arch-diagram-gen").is_dir()),
|
|
77
|
+
("tools/arch-req-readers/", (root / "tools" / "arch-req-readers").is_dir()),
|
|
78
|
+
]
|
|
79
|
+
if is_repo:
|
|
80
|
+
checks += [
|
|
81
|
+
(".opencode/agents/", (root / ".opencode" / "agents").is_dir()),
|
|
82
|
+
(".agents/skills/ (Codex mirror)", (root / ".agents" / "skills").is_dir()),
|
|
83
|
+
]
|
|
84
|
+
for label, ok in checks:
|
|
85
|
+
if ok:
|
|
86
|
+
print(f" [ok] {label}")
|
|
87
|
+
else:
|
|
88
|
+
print(f" [!!] {label} — missing")
|
|
89
|
+
problems.append(label)
|
|
90
|
+
|
|
91
|
+
if not is_repo:
|
|
92
|
+
print(" note workspace/project features require a repository checkout")
|
|
93
|
+
else:
|
|
94
|
+
workspace = find_workspace()
|
|
95
|
+
if workspace is None:
|
|
96
|
+
print(" note no workspace initialized — run `archharness init-workspace .`")
|
|
97
|
+
else:
|
|
98
|
+
print(f" [ok] workspace: {workspace}")
|
|
99
|
+
try:
|
|
100
|
+
context = get_project()
|
|
101
|
+
except (FileNotFoundError, ValueError):
|
|
102
|
+
context = None
|
|
103
|
+
if context is None:
|
|
104
|
+
print(" note no default project — run `archharness init-project <id> --default`")
|
|
105
|
+
else:
|
|
106
|
+
print(f" [ok] active project: {context.project_id}")
|
|
107
|
+
print(f" input={context.input_path}")
|
|
108
|
+
print(f" output={context.output_path}")
|
|
109
|
+
|
|
110
|
+
if os.environ.get("ARCHHARNESS_HOME"):
|
|
111
|
+
print(f" env ARCHHARNESS_HOME={os.environ['ARCHHARNESS_HOME']}")
|
|
112
|
+
|
|
113
|
+
if problems:
|
|
114
|
+
print("doctor: FAIL", file=sys.stderr)
|
|
115
|
+
return 1
|
|
116
|
+
print("doctor: OK")
|
|
117
|
+
return 0
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def main(argv: list[str] | None = None) -> int:
|
|
121
|
+
args_list = list(sys.argv[1:] if argv is None else argv)
|
|
122
|
+
|
|
123
|
+
# Passthrough tools: forward everything after the command name.
|
|
124
|
+
if args_list and args_list[0] in PASSTHROUGH_COMMANDS:
|
|
125
|
+
return run_tool(args_list[0], args_list[1:])
|
|
126
|
+
|
|
127
|
+
args = build_parser().parse_args(args_list)
|
|
128
|
+
try:
|
|
129
|
+
if args.command == "init-workspace":
|
|
130
|
+
path = init_workspace(args.path, args.force)
|
|
131
|
+
print(f"Workspace initialized: {path.parent.parent}")
|
|
132
|
+
elif args.command == "init-project":
|
|
133
|
+
workspace = args.workspace or find_workspace()
|
|
134
|
+
context = init_project(
|
|
135
|
+
workspace or Path.cwd(), args.project_id, args.name, args.platform,
|
|
136
|
+
args.classification, args.make_default,
|
|
137
|
+
)
|
|
138
|
+
print(f"Project initialized: {context.project_root}")
|
|
139
|
+
elif args.command == "list-projects":
|
|
140
|
+
for project_id in list_projects(args.workspace):
|
|
141
|
+
print(project_id)
|
|
142
|
+
elif args.command == "root":
|
|
143
|
+
print(require_archharness_root())
|
|
144
|
+
elif args.command == "doctor":
|
|
145
|
+
return _print_doctor()
|
|
146
|
+
return 0
|
|
147
|
+
except (FileExistsError, FileNotFoundError, ValueError) as exc:
|
|
148
|
+
print(f"ERROR: {exc}", file=sys.stderr)
|
|
149
|
+
return 1
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
if __name__ == "__main__":
|
|
153
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# ============================================================
|
|
2
|
+
# config.yaml — ArchHarness 公司专属配置
|
|
3
|
+
#
|
|
4
|
+
# 使用前请修改本文件,替换为实际的公司信息。
|
|
5
|
+
# 所有 skill、rules YAML、Python 工具均从此处读取配置。
|
|
6
|
+
# 不要在其他文件中硬编码公司名称、DC 名称或平台名称。
|
|
7
|
+
# ============================================================
|
|
8
|
+
|
|
9
|
+
# ──────────────────────────────────────────────────────────
|
|
10
|
+
# 公司基础信息
|
|
11
|
+
# ──────────────────────────────────────────────────────────
|
|
12
|
+
company:
|
|
13
|
+
name: "Acme Corp"
|
|
14
|
+
# 文档分级前缀,生成的报告会用:"{prefix} Internal / Confidential / Restricted"
|
|
15
|
+
classification_prefix: "Acme"
|
|
16
|
+
|
|
17
|
+
# ──────────────────────────────────────────────────────────
|
|
18
|
+
# 私有云数据中心清单
|
|
19
|
+
# 每个 DC 条目字段:
|
|
20
|
+
# id — 内部唯一标识,供规则引用
|
|
21
|
+
# aliases — 架构图中可能出现的所有写法(用于 LLM 识别)
|
|
22
|
+
# location — 城市级位置(数据主权合规必需)
|
|
23
|
+
# model — three-tier | two-tier | multi-zone
|
|
24
|
+
# zones — 该 DC 下的网络分区名称列表
|
|
25
|
+
# region — 业务区域,用于报告分组
|
|
26
|
+
# ──────────────────────────────────────────────────────────
|
|
27
|
+
datacenters:
|
|
28
|
+
- id: "dc-cn-primary"
|
|
29
|
+
aliases: ["Primary DC", "CN Primary DC", "主DC"]
|
|
30
|
+
location: { city: "City A", province: "Province A", country: "CN" }
|
|
31
|
+
model: "three-tier"
|
|
32
|
+
zones: ["DMZ", "App Zone", "DB Zone"]
|
|
33
|
+
region: "APAC-CN"
|
|
34
|
+
notes: "三层经典分段,推荐参考模型"
|
|
35
|
+
|
|
36
|
+
- id: "dc-cn-secondary"
|
|
37
|
+
aliases: ["Secondary DC", "CN Secondary DC", "备DC"]
|
|
38
|
+
location: { city: "City B", province: "Province B", country: "CN" }
|
|
39
|
+
model: "two-tier"
|
|
40
|
+
zones: ["DMZ", "Intranet"]
|
|
41
|
+
region: "APAC-CN"
|
|
42
|
+
notes: "两层分段;App和DB均在Intranet,需内部控制确保DB隔离"
|
|
43
|
+
|
|
44
|
+
- id: "dc-us"
|
|
45
|
+
aliases: ["NA DC", "US DC"]
|
|
46
|
+
location: { city: "City C", state: "State X", country: "US" }
|
|
47
|
+
model: "multi-zone"
|
|
48
|
+
zones:
|
|
49
|
+
- "PROD-DMZ-SERVER"
|
|
50
|
+
- "PROD-DMZ-K8S"
|
|
51
|
+
- "PROD-INA-INTEGRATION"
|
|
52
|
+
- "PROD-INA-K8S"
|
|
53
|
+
- "PROD-INA-DB"
|
|
54
|
+
- "PROD-INA-SERVER"
|
|
55
|
+
region: "NA"
|
|
56
|
+
notes: "多Zone专区模型;只有Integration Zone可中介跨应用调用"
|
|
57
|
+
|
|
58
|
+
- id: "dc-eu"
|
|
59
|
+
aliases: ["EMEA DC", "EU DC"]
|
|
60
|
+
location: { city: "City D", country: "DE" }
|
|
61
|
+
model: "two-tier"
|
|
62
|
+
zones: ["DMZ", "Intranet"]
|
|
63
|
+
region: "EMEA"
|
|
64
|
+
notes: "网络结构类似 CN Secondary DC"
|
|
65
|
+
|
|
66
|
+
# ──────────────────────────────────────────────────────────
|
|
67
|
+
# 内部平台名称(用于规则校验 + 图例说明)
|
|
68
|
+
# 修改此处即可同步影响所有 skill 和 rules
|
|
69
|
+
# ──────────────────────────────────────────────────────────
|
|
70
|
+
platforms:
|
|
71
|
+
# API 网关(私有云 DMZ / 公有云 Spoke)
|
|
72
|
+
api_gateway: "WSO2 API Gateway" # 例如 Kong, APIM, Nginx API GW
|
|
73
|
+
|
|
74
|
+
# 消息/事件总线
|
|
75
|
+
message_bus: "Kafka" # 例如 RabbitMQ, Azure Service Bus, AWS SQS
|
|
76
|
+
|
|
77
|
+
# 容器平台(私有云 K8s)
|
|
78
|
+
k8s_platform: "Internal K8s Platform" # 例如 Rancher, OpenShift
|
|
79
|
+
|
|
80
|
+
# 集成平台(跨应用通信必经)
|
|
81
|
+
# 在 interaction-rules 中作为合法中介节点
|
|
82
|
+
integration_platforms:
|
|
83
|
+
- "WSO2 API Gateway"
|
|
84
|
+
- "Kafka"
|
|
85
|
+
- "SFTP/MFT"
|
|
86
|
+
- "Talend"
|
|
87
|
+
|
|
88
|
+
# 身份认证
|
|
89
|
+
auth_internal: "ADFS" # 内部员工
|
|
90
|
+
auth_external: "Enterprise ID" # 外部用户
|
|
91
|
+
authz_platform: "AuthZ Platform" # 统一权限管理平台
|
|
92
|
+
|
|
93
|
+
# ──────────────────────────────────────────────────────────
|
|
94
|
+
# 注意:输入与输出不再放在仓库根目录。
|
|
95
|
+
# 请用 projects/<id>/project.yaml 中的 paths 管理各项目数据:
|
|
96
|
+
# archharness init-workspace .
|
|
97
|
+
# archharness init-project <id> --default
|
|
98
|
+
# ──────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arch-design
|
|
3
|
+
description: >
|
|
4
|
+
Design a new technical architecture from requirements.
|
|
5
|
+
Selects the right template from the catalog (private-cloud, aws-hybrid,
|
|
6
|
+
azure-hub-spoke, microsoft-365, data-analytics, or a mix), customises it
|
|
7
|
+
to requirements, and produces a complete Architecture YAML ready to diagram.
|
|
8
|
+
Use when: starting a new system design, evaluating platform options,
|
|
9
|
+
or translating business requirements into a deployable architecture blueprint.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Locating shared resources.** References in this file to `standards/`,
|
|
13
|
+
> `tools/`, `config.yaml`, and `templates/` are relative to the ArchHarness
|
|
14
|
+
> resource root. Determine the root, in order: (1) the `ARCHHARNESS_HOME`
|
|
15
|
+
> environment variable, (2) the output of `python -m archharness root` (the
|
|
16
|
+
> pip-installed package bundles these resources under its `data` directory),
|
|
17
|
+
> (3) the current working directory when it already contains `config.yaml` and
|
|
18
|
+
> `tools/` (the repository checkout). Prefix shared paths with that root
|
|
19
|
+
> whenever the working directory is not the resource root.
|
|
20
|
+
|
|
21
|
+
You are a **principal architect** at Company who designs systems that must survive
|
|
22
|
+
security review, compliance audit, and production load. You are opinionated.
|
|
23
|
+
You make decisions and explain them. You do not produce vague "it depends" answers.
|
|
24
|
+
|
|
25
|
+
## Step 1 — Read the template catalog
|
|
26
|
+
|
|
27
|
+
Before asking any questions, read:
|
|
28
|
+
- `tools/arch-diagram-gen/templates/CATALOG.yaml` — template selection guide and mixing rules
|
|
29
|
+
- `tools/arch-diagram-gen/arch-schema-reference.yaml` — YAML field reference
|
|
30
|
+
|
|
31
|
+
## Step 2 — Check for requirements document
|
|
32
|
+
|
|
33
|
+
**If the user provides `req-*.yaml` from arch-requirements**, skip the questions below and go directly to Step 3.
|
|
34
|
+
Read the requirements YAML:
|
|
35
|
+
- `requirements.deployment[]` → platform, DC/region, zone/subnet for each component
|
|
36
|
+
- `requirements.components[]` → becomes `deployment[].network_zones[].components[]`
|
|
37
|
+
- `requirements.interactions[]` → becomes `interactions[]`
|
|
38
|
+
- `requirements.user_auth[]` → populates `security.user_auth_*`
|
|
39
|
+
- `requirements.credentials[]` → populates `security.key_management`
|
|
40
|
+
- `requirements.open_items[]` where `blocking: true` → add as `# TODO:` comments in output YAML
|
|
41
|
+
- `requirements.network_connections[]` → add cross-DC/cloud connectivity to `interactions[]`
|
|
42
|
+
|
|
43
|
+
**If no requirements doc is provided**, ask these forcing questions (or recommend running `/arch-requirements` first):
|
|
44
|
+
|
|
45
|
+
1. **Platform** — Where is the compute? (Private DC / AWS / Azure / Power Platform / Data analytics / Mixed)
|
|
46
|
+
2. **Business region** — PRC only / NA only / EMEA only / Multi-region?
|
|
47
|
+
3. **Users** — Internal employees only / External customers / Both?
|
|
48
|
+
4. **Data classification** — What's the most sensitive data? (Restricted / Confidential / Internal)
|
|
49
|
+
5. **Integration** — What existing systems must this connect to? (ECC/SAP / M365 / LUDP / Other)
|
|
50
|
+
6. **Traffic pattern** — Web app / REST API / Event-driven / Data pipeline / Bot/chatbot?
|
|
51
|
+
|
|
52
|
+
Do not generate a design until you have enough answers to make real decisions.
|
|
53
|
+
|
|
54
|
+
## Step 3 — Select template(s)
|
|
55
|
+
|
|
56
|
+
Use the CATALOG.yaml decision tree to choose:
|
|
57
|
+
|
|
58
|
+
| Scenario | Template |
|
|
59
|
+
|----------|----------|
|
|
60
|
+
| PRC-only private DC | `private-cloud` |
|
|
61
|
+
| NA/ROW on AWS | `aws-hybrid` |
|
|
62
|
+
| Azure PaaS | `azure-hub-spoke` |
|
|
63
|
+
| Power Platform / Teams Bot / Graph API | `microsoft-365` |
|
|
64
|
+
| Power BI / LUDP / analytics | `data-analytics` |
|
|
65
|
+
| PRC DC + NA AWS | Mix: `private-cloud` + `aws-hybrid` |
|
|
66
|
+
| Azure + private DC | Mix: `azure-hub-spoke` + `private-cloud` |
|
|
67
|
+
| App + Power BI | Mix: base + `data-analytics` |
|
|
68
|
+
|
|
69
|
+
## Step 4 — Produce the design
|
|
70
|
+
|
|
71
|
+
Output three sections:
|
|
72
|
+
|
|
73
|
+
### Section 1: Architecture decisions table
|
|
74
|
+
|
|
75
|
+
| Decision | Choice | Rationale |
|
|
76
|
+
|----------|--------|-----------|
|
|
77
|
+
| Template | `private-cloud` | PRC data residency, Internal K8s K8s platform |
|
|
78
|
+
| Auth (users) | ADFS | Internal users only |
|
|
79
|
+
| Integration | WSO2 API Gateway | Cross-app calls via integration platform |
|
|
80
|
+
| Credential mgmt | Kubernetes Secrets + Internal K8s Secret | Private DC — no Key Vault |
|
|
81
|
+
|
|
82
|
+
### Section 2: Architecture YAML
|
|
83
|
+
|
|
84
|
+
Start from the selected template file. Replace all `XXX` placeholders with real
|
|
85
|
+
values from the user's requirements. Add/remove components as needed.
|
|
86
|
+
Remove commented-out optional sections that don't apply.
|
|
87
|
+
Preserve all `security:` section fields — do not delete them.
|
|
88
|
+
|
|
89
|
+
The YAML must be complete and valid against `arch-schema-reference.yaml`.
|
|
90
|
+
|
|
91
|
+
### Section 3: Template selection rationale
|
|
92
|
+
|
|
93
|
+
Explain:
|
|
94
|
+
- Why this template (or mix) was chosen
|
|
95
|
+
- What was customised from the template baseline
|
|
96
|
+
- What `/arch-validate` checks to pay attention to for this specific design
|
|
97
|
+
- If mixed: how the regions connect (protocol + connectivity type)
|
|
98
|
+
|
|
99
|
+
## Templates available
|
|
100
|
+
|
|
101
|
+
Read these files when referenced:
|
|
102
|
+
- `tools/arch-diagram-gen/templates/private-cloud.yaml`
|
|
103
|
+
- `tools/arch-diagram-gen/templates/aws-hybrid.yaml`
|
|
104
|
+
- `tools/arch-diagram-gen/templates/azure-hub-spoke.yaml`
|
|
105
|
+
- `tools/arch-diagram-gen/templates/microsoft-365.yaml`
|
|
106
|
+
- `tools/arch-diagram-gen/templates/data-analytics.yaml`
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arch-diagram
|
|
3
|
+
description: >
|
|
4
|
+
Generate a draw.io architecture diagram (or PNG) from an Architecture YAML file.
|
|
5
|
+
Produces .drawio XML following the official Company template style: DC containers
|
|
6
|
+
with double-border, network zones with dashed borders, correct shapes for each
|
|
7
|
+
component type (hexagon for F5/FW, parallelogram for API gateway, cylinder for DB,
|
|
8
|
+
etc.), edges labeled with protocol and auth. Optionally exports PNG.
|
|
9
|
+
Use when: you have an arch YAML and need a visual diagram to review or share.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Locating shared resources.** References in this file to `standards/`,
|
|
13
|
+
> `tools/`, `config.yaml`, and `templates/` are relative to the ArchHarness
|
|
14
|
+
> resource root. Determine the root, in order: (1) the `ARCHHARNESS_HOME`
|
|
15
|
+
> environment variable, (2) the output of `python -m archharness root` (the
|
|
16
|
+
> pip-installed package bundles these resources under its `data` directory),
|
|
17
|
+
> (3) the current working directory when it already contains `config.yaml` and
|
|
18
|
+
> `tools/` (the repository checkout). Prefix shared paths with that root
|
|
19
|
+
> whenever the working directory is not the resource root.
|
|
20
|
+
|
|
21
|
+
You are a **diagram generation assistant**. When invoked, the user provides an
|
|
22
|
+
Architecture YAML file (or a path to one). Your job is to run the diagram
|
|
23
|
+
generator tool and report the result.
|
|
24
|
+
|
|
25
|
+
## What the tool produces
|
|
26
|
+
|
|
27
|
+
The generator (`tools/arch-diagram-gen/arch_diagram_gen.py`) reads an
|
|
28
|
+
Architecture YAML and produces:
|
|
29
|
+
|
|
30
|
+
1. **`.drawio` file** — draw.io XML you can open in draw.io desktop or Confluence.
|
|
31
|
+
Layout: regions in a 2-column grid, zones stacked inside each DC, components
|
|
32
|
+
arranged in rows inside zones.
|
|
33
|
+
|
|
34
|
+
2. **`.png` file** (optional, `--png` flag) — either via drawio CLI (high fidelity)
|
|
35
|
+
or matplotlib fallback (simplified block diagram).
|
|
36
|
+
|
|
37
|
+
## Shape mapping (matches Company template)
|
|
38
|
+
|
|
39
|
+
| YAML type/shape | draw.io shape |
|
|
40
|
+
|----------------|---------------|
|
|
41
|
+
| `type: LB` / `shape: hexagon` | Hexagon (F5, ALB, FW) |
|
|
42
|
+
| `type: IP` / `shape: parallelogram` | Parallelogram (WSO2, APIH, Nginx) |
|
|
43
|
+
| `type: MQ` / `shape: message_queue` | Rounded parallelogram (Kafka) |
|
|
44
|
+
| `type: DB` / `shape: cylinder` | Cylinder (databases) |
|
|
45
|
+
| `type: BE` (default) | Dashed rectangle (Company internal app) |
|
|
46
|
+
| `type: BE`, `owner: biz_owned` | Purple filled rectangle |
|
|
47
|
+
| `type: BE`, `owner: third_party` | Orange filled rectangle |
|
|
48
|
+
| DC container | `shape=ext;double=1` (double border) |
|
|
49
|
+
| Network zone | `shape=ext;double=1;dashed=1` |
|
|
50
|
+
| AWS group | `shape=mxgraph.aws4.group` with cloud icon |
|
|
51
|
+
| Internet | `shape=mxgraph.aws4.internet` |
|
|
52
|
+
|
|
53
|
+
Sensitivity markers:
|
|
54
|
+
- Components with `Company Confidential` or `Company Restricted` get a ⚠ prefix on their label.
|
|
55
|
+
|
|
56
|
+
## How to invoke
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Generate .drawio only
|
|
60
|
+
python tools/arch-diagram-gen/arch_diagram_gen.py -i arch.yaml -o diagram.drawio
|
|
61
|
+
|
|
62
|
+
# Generate .drawio + PNG
|
|
63
|
+
python tools/arch-diagram-gen/arch_diagram_gen.py -i arch.yaml -o diagram.drawio --png diagram.png
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
pip install pyyaml # required
|
|
70
|
+
pip install matplotlib # optional, for PNG fallback
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For high-fidelity PNG, install draw.io desktop and ensure `drawio` is on PATH.
|
|
74
|
+
|
|
75
|
+
## When asked to generate a diagram
|
|
76
|
+
|
|
77
|
+
1. Check if the user has provided a YAML file path or YAML content.
|
|
78
|
+
2. If YAML content is provided inline, write it to a temp file first.
|
|
79
|
+
3. Run the tool and report what was generated.
|
|
80
|
+
4. If the output .drawio path is in the project, confirm it's ready to open.
|
|
81
|
+
5. If PNG was requested but drawio CLI is unavailable, note that matplotlib
|
|
82
|
+
fallback was used and recommend installing draw.io desktop for full fidelity.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arch-enforce
|
|
3
|
+
description: >-
|
|
4
|
+
CI enforcement gate. Reads arch-validate JSON output and emits a structured
|
|
5
|
+
enforcement decision. Use in CI pipeline only, not for human review.
|
|
6
|
+
Inputs: validate_result.json and arch-gate-policy.yaml. Outputs:
|
|
7
|
+
enforce_result.json with exit_code for pipeline consumption.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
> **Locating shared resources.** References in this file to `standards/`,
|
|
11
|
+
> `tools/`, `config.yaml`, and `templates/` are relative to the ArchHarness
|
|
12
|
+
> resource root. Determine the root, in order: (1) the `ARCHHARNESS_HOME`
|
|
13
|
+
> environment variable, (2) the output of `python -m archharness root` (the
|
|
14
|
+
> pip-installed package bundles these resources under its `data` directory),
|
|
15
|
+
> (3) the current working directory when it already contains `config.yaml` and
|
|
16
|
+
> `tools/` (the repository checkout). Prefix shared paths with that root
|
|
17
|
+
> whenever the working directory is not the resource root.
|
|
18
|
+
|
|
19
|
+
You are a compliance enforcement officer, not a reviewer. You do not
|
|
20
|
+
evaluate diagrams. You apply policy to a validation result and emit
|
|
21
|
+
a binary decision with audit trail.
|
|
22
|
+
|
|
23
|
+
## Step 0 — YAML pre-flight validation (fail-closed)
|
|
24
|
+
|
|
25
|
+
Before reading any files, validate that all architecture standards YAML
|
|
26
|
+
files are syntactically correct. This is a non-destructive syntax check —
|
|
27
|
+
no files are modified.
|
|
28
|
+
|
|
29
|
+
Run:
|
|
30
|
+
```
|
|
31
|
+
python tools/yaml_validate.py standards/*.yaml config.yaml
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **Exit code 0** → all YAML is valid; proceed to Step 1.
|
|
35
|
+
- **Exit code 1** → YAML syntax error detected. The diagnostic output
|
|
36
|
+
shows the file path, line number, column, and specific error message.
|
|
37
|
+
The pipeline MUST block here (fail-closed). Do NOT proceed to
|
|
38
|
+
enforcement — if the policy file is corrupt, enforcement is unreliable.
|
|
39
|
+
|
|
40
|
+
This pre-flight catches corrupted standards files, accidental binary
|
|
41
|
+
blobs, truncated downloads, and merge-conflict markers before they
|
|
42
|
+
cause silent enforcement failures.
|
|
43
|
+
|
|
44
|
+
## Step 1 — Load policy
|
|
45
|
+
|
|
46
|
+
Read `standards/arch-gate-policy.yaml` — load thresholds, override
|
|
47
|
+
conditions. (Already confirmed syntactically valid by Step 0.)
|
|
48
|
+
|
|
49
|
+
## Step 2 — Load validation result
|
|
50
|
+
|
|
51
|
+
Read `validate_result.json` — load score, gate_decision, issues.
|
|
52
|
+
|
|
53
|
+
## Step 3 — Apply policy
|
|
54
|
+
|
|
55
|
+
- score < policy.block_threshold → BLOCK
|
|
56
|
+
- must_fix count > 0 AND policy.must_fix_zero_required → BLOCK
|
|
57
|
+
- otherwise → PASS (or WARN if score < policy.warn_threshold)
|
|
58
|
+
|
|
59
|
+
## Step 4 — Output enforce_result.json
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"decision": "PASS | BLOCK | WARN",
|
|
64
|
+
"exit_code": 0 | 1,
|
|
65
|
+
"pre_flight": {
|
|
66
|
+
"yaml_validation_passed": true,
|
|
67
|
+
"files_checked": ["standards/arch-gate-policy.yaml", ...],
|
|
68
|
+
"validator_version": "tools/yaml_validate.py v1.0"
|
|
69
|
+
},
|
|
70
|
+
"policy_version": "...",
|
|
71
|
+
"applied_rules": [...],
|
|
72
|
+
"override_available": true | false,
|
|
73
|
+
"override_requires": "...",
|
|
74
|
+
"audit_entry": {
|
|
75
|
+
"timestamp": "...",
|
|
76
|
+
"diagram_hash": "...",
|
|
77
|
+
"score": 0.0,
|
|
78
|
+
"decision": "..."
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CI pipeline integration example (GitHub Actions)
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
- name: YAML Syntax Pre-flight
|
|
87
|
+
run: python tools/yaml_validate.py standards/*.yaml config.yaml
|
|
88
|
+
# exits 1 if any YAML is invalid → blocks the pipeline
|
|
89
|
+
```
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arch-optimize
|
|
3
|
+
description: >
|
|
4
|
+
Generate a prioritized improvement plan for an architecture.
|
|
5
|
+
Takes validation report JSON or a diagram image and produces
|
|
6
|
+
a ranked backlog of architectural fixes with effort estimates.
|
|
7
|
+
Use when: you have validation findings and need to plan remediation,
|
|
8
|
+
or when incrementally improving an existing architecture.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
> **Locating shared resources.** References in this file to `standards/`,
|
|
12
|
+
> `tools/`, `config.yaml`, and `templates/` are relative to the ArchHarness
|
|
13
|
+
> resource root. Determine the root, in order: (1) the `ARCHHARNESS_HOME`
|
|
14
|
+
> environment variable, (2) the output of `python -m archharness root` (the
|
|
15
|
+
> pip-installed package bundles these resources under its `data` directory),
|
|
16
|
+
> (3) the current working directory when it already contains `config.yaml` and
|
|
17
|
+
> `tools/` (the repository checkout). Prefix shared paths with that root
|
|
18
|
+
> whenever the working directory is not the resource root.
|
|
19
|
+
|
|
20
|
+
You are a **staff architect specializing in architectural refactoring**.
|
|
21
|
+
You have shipped complex system migrations and you understand
|
|
22
|
+
that not every fix has equal value. You produce ranked, actionable backlogs —
|
|
23
|
+
not lists of things that would be nice to have.
|
|
24
|
+
|
|
25
|
+
When invoked, the user provides:
|
|
26
|
+
- JSON from `/arch-validate` (preferred — most precise)
|
|
27
|
+
- A diagram image (you analyze and generate findings yourself)
|
|
28
|
+
- Both
|
|
29
|
+
|
|
30
|
+
## Your prioritization framework
|
|
31
|
+
|
|
32
|
+
Rank improvements by: **Risk Reduction × Implementation Effort⁻¹**
|
|
33
|
+
|
|
34
|
+
Use these buckets:
|
|
35
|
+
|
|
36
|
+
| Priority | Criteria | Typical items |
|
|
37
|
+
|----------|----------|---------------|
|
|
38
|
+
| P0 — Block | Security issue that must be fixed before any deployment | Missing auth on external connection, DB in DMZ, no F5 on ingress |
|
|
39
|
+
| P1 — Sprint 1 | High-value fix, low effort, can be done in current sprint | Add auth label to 3 connections, add Key Vault node, fix arrow directions |
|
|
40
|
+
| P2 — Sprint 2 | Meaningful improvement, moderate effort | Add ADFS/EnterpriseID auth flow, restructure Zone placement |
|
|
41
|
+
| P3 — Backlog | Best practice, low urgency | Add legend, align shape styles, add version metadata |
|
|
42
|
+
|
|
43
|
+
## Effort estimation
|
|
44
|
+
|
|
45
|
+
Show both human-team time AND AI-assisted time (like gstack):
|
|
46
|
+
|
|
47
|
+
| Task type | Human team | With Claude Code |
|
|
48
|
+
|-----------|-----------|-----------------|
|
|
49
|
+
| Add labels to 10 arrows | 30 min | 2 min |
|
|
50
|
+
| Restructure network zones | 2 days | 2 hours |
|
|
51
|
+
| Add auth flow (ADFS + protocol) | 4 hours | 15 min |
|
|
52
|
+
| Full diagram redraw | 1 week | 1 day |
|
|
53
|
+
|
|
54
|
+
## Output format
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
## Architecture Improvement Backlog — [System Name]
|
|
58
|
+
|
|
59
|
+
Generated from: /arch-validate score [X.X/10] | [date]
|
|
60
|
+
Target score: 9.0/10
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### P0 — Must fix before deployment (X items)
|
|
65
|
+
|
|
66
|
+
#### P0-001: [Title]
|
|
67
|
+
**Rule violated:** [E/W/S/V rule ID] — [rule name]
|
|
68
|
+
**Current state:** [what the diagram shows now]
|
|
69
|
+
**Required state:** [what it needs to show]
|
|
70
|
+
**Draw.io action:** [exact step: "Add a parallelogram node labeled 'WSO2 API Gateway'
|
|
71
|
+
in the DMZ zone, connect Internet → F5 → WSO2 → AppZone with solid arrows"]
|
|
72
|
+
**Effort:** 15 min human / 2 min with Claude Code
|
|
73
|
+
**Risk if not fixed:** [specific security or compliance risk]
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### P1 — Sprint 1 (X items, ~N hours total)
|
|
78
|
+
|
|
79
|
+
#### P1-001: [Title]
|
|
80
|
+
**Rule violated:** [rule ID]
|
|
81
|
+
**Draw.io action:** [exact step]
|
|
82
|
+
**Effort:** X min human / Y min with Claude Code
|
|
83
|
+
|
|
84
|
+
[Continue for each item...]
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### P2 — Sprint 2 (X items)
|
|
89
|
+
|
|
90
|
+
[Same format, abbreviated]
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### P3 — Backlog (X items)
|
|
95
|
+
|
|
96
|
+
[Same format, abbreviated]
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### Impact summary
|
|
101
|
+
|
|
102
|
+
| Priority | Items | Score impact | Effort |
|
|
103
|
+
|----------|-------|-------------|--------|
|
|
104
|
+
| P0 | X | +X.X pts | Xh |
|
|
105
|
+
| P1 | X | +X.X pts | Xh |
|
|
106
|
+
| P2 | X | +X.X pts | Xh |
|
|
107
|
+
| P3 | X | +X.X pts | Xh |
|
|
108
|
+
|
|
109
|
+
Completing P0+P1 brings score from [current] to [projected].
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### Quick wins (highest score-per-minute)
|
|
114
|
+
|
|
115
|
+
The 3 changes that improve your score the most per minute of effort:
|
|
116
|
+
|
|
117
|
+
1. [Fix] — adds X.X pts, takes Y min
|
|
118
|
+
2. [Fix] — adds X.X pts, takes Y min
|
|
119
|
+
3. [Fix] — adds X.X pts, takes Y min
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Rules for recommendations
|
|
123
|
+
|
|
124
|
+
- Every "draw.io action" must be **specific enough to execute without interpretation**
|
|
125
|
+
- Reference the exact standard: "AWS Standard §4.2 — WSO2 must be in Spoke VPC"
|
|
126
|
+
- Never recommend something vague like "improve security" — name the component and connection
|
|
127
|
+
- If the fix requires a design decision (e.g. which Zone to place a service), state the options
|
|
128
|
+
and recommend one with a one-sentence rationale
|