Software Design Evidence
任职要求真正考什么
公司给出的能力描述看起来像一组名词,实际可归并为四个连续问题:
- 能否建立完整模型。面对一个子系统或关键模块,能否识别边界、场景、结构、运行、部署和质量属性,而不是只描述当前代码。
- 能否做出可解释决策。能否从竞争力目标和约束出发比较候选方案,记录为什么选择、放弃什么、承担什么代价。
- 能否把设计落到实现和验证。能否让安全、可靠、性能、可测试等设计在代码、配置、测试和指标中找到对应。
- 能否持续看护。能否识别依赖、接口、数据和部署边界的腐化,把关键架构规则变成可执行门禁,并组织改进。
因此,最小证据链不是“需求 → commit”,而是:
1 | 需求/Top 问题 -> 质量属性场景 -> 候选方案与 ADR -> 架构视图 |
这里必须分清三种产物:
| 产物 | 回答的问题 | 能否由 commit 单独证明 |
|---|---|---|
| 软件设计文档 | 系统为何这样设计,如何满足功能和质量约束 | 不能;commit 只能校验设计是否落地 |
| 实现/验证报告 | 实际改了什么,在什么环境下得到什么结果 | 部分可以;仍需测试、环境和统计口径 |
| 任职举证报告 | 候选人承担什么责任,做出什么关键判断,产生什么可验证影响 | 不能;还需角色、评审、决策和组织行为证据 |
4+1 视图
Philippe Kruchten 的原始论文提出用多个并行视图分别处理不同干系人的关注点:逻辑视图、进程视图、开发视图、物理视图,再用少数关键场景驱动和校验它们。+1 不是第五张装饰图,而是把其他视图放进同一个端到端情境中检查。
ISO/IEC/IEEE 42010:2022进一步把架构描述组织为关注者、关注点、视点、视图和模型。两者共同强调:先问读者要解决什么不确定性,再选择模型;视图不是图形模板。
| 视图 | 核心问题 | 主要关注者 | 可选表达 | 可核验证据 |
|---|---|---|---|---|
| 逻辑视图 | 系统提供哪些能力,关键抽象、职责、接口和数据是什么 | 用户、产品、领域专家、开发 | 系统上下文、领域模型、组件图、类图、ER、接口/数据契约 | 需求 ID、API/Schema、模块、单元/契约测试 |
| 进程视图 | 运行时如何并发、同步、通信、排队、限流和失败 | 性能、可靠性、集成、运维人员 | 时序图、活动图、状态机、运行拓扑、队列/线程表 | 进程/任务/队列、超时重试、Trace、集成与故障测试 |
| 开发视图 | 源码如何分层、构建、依赖、发布并由谁维护 | 开发、构建、配置管理、项目管理 | 模块/包/层次图、构建图、依赖规则、所有权表 | 文件/target、依赖声明、CODEOWNERS、CI 架构测试 |
| 物理视图 | 软件如何映射到节点、网络、设备、区域和故障域 | 系统、部署、运维、容量人员 | 部署图、网络拓扑、资源表、环境矩阵 | IaC/配置、容量、HA/DR、部署与恢复验证 |
| 场景视图 | 哪些关键正常、异常和质量场景贯穿并校验前四个视图 | 所有评审者 | 用例、端到端时序、Given-When-Then、场景矩阵 | 需求、设计元素、测试、指标和结果的双向追踪 |
这张图需要从三个方向阅读:
- 纵向:场景不是只对应逻辑功能,还要触发运行时行为、代码模块和部署映射。
- 横向:同一个元素在不同视图中身份不同。例如“推理调度器”在逻辑视图是能力组件,在进程视图是队列和 worker,在开发视图是 package/target,在物理视图映射到特定节点或设备。
- 横切:安全、可靠性和性能不是另写三段形容词,而是改变组件边界、通信协议、部署、观测和测试。
4+1 不是固定五图
OMG UML 2.5.1提供用例、类、组件、部署、活动、状态和时序等语言;C4 Model用 Context、Container、Component、Code 做静态结构缩放,并补充动态和部署图。它们是表达工具,不是 4+1 的同义词。
例如:
- 数据密集系统的逻辑视图可能主要使用 ER、数据契约和数据流,而不是类图;
- 运行在单进程中的关键模块仍需要进程视图,用来说明线程、异步任务、锁和资源生命周期;
- 一个 C4 Container 可能映射到进程视图中的多个 worker,也可能在物理视图中部署多个副本;
- 小型模块可以用表格和一张时序图表达,不必为了“完整”生成五张空图。
组件化与微服务化
组件化首先是职责、接口和依赖的边界:组件内部高内聚,外部通过稳定契约协作,并能被独立理解、测试和替换。它可以发生在同一进程、同一仓库甚至同一二进制中。
微服务化进一步把边界变成独立部署、运行和运维单元。它带来团队自治、隔离和独立扩缩的可能,也引入网络失败、数据一致性、版本兼容、可观测性、发布编排和基础设施成本。
| 判断 | 组件化 | 微服务化 |
|---|---|---|
| 主要边界 | 代码职责与接口 | 独立部署与运行责任 |
| 必然跨网络 | 否 | 通常是 |
| 数据所有权 | 可以共享,但应明确 | 倾向服务自治,跨服务通过契约 |
| 主要收益 | 降低耦合、提高可测试与复用 | 独立交付、隔离、扩缩和团队自治 |
| 主要代价 | 抽象、接口和版本维护 | 分布式故障、运维、数据与发布复杂度 |
| 举证重点 | 依赖规则、接口、测试接缝 | API/事件契约、故障隔离、独立部署和 SLO |
微服务不是比组件化更高级的任职证据。如果一个进程内模块已经满足变化、性能和团队边界,继续拆服务可能只是扩大故障面。技术决策能力体现在选择了足够小、又能承受真实变化的边界。
原则、模式与架构风格
这三个词常被混在一句话中,实际处于不同层级:
- 设计原则是判断约束,例如“隐藏容易变化的决定”“高层策略不依赖底层细节”。
- 设计模式是反复出现的局部协作结构,描述问题、参与者、关系和后果。
- 架构风格是系统级组织方式,例如分层、端口适配器、事件驱动和微服务。
一个系统可以遵守依赖倒置原则,用 Strategy 模式替换算法,在更大尺度采用组件化单体;三者不冲突,也不能互相代替。
常用设计原则
Parnas 的模块分解工作强调按可能变化的设计决定隐藏信息,而不是按处理步骤机械切模块。Robert C. Martin 后来整理的 SOLID 则为面向对象依赖提供一组启发式约束。
| 原则 | 直观含义 | 评审时看什么 |
|---|---|---|
| 关注点分离 | 不同变化原因尽量由不同边界承载 | 业务、存储、通信、观测是否相互缠绕 |
| 信息隐藏 | 模块隐藏容易变化的决定,只暴露稳定契约 | 调用方是否依赖内部数据布局或算法细节 |
| 高内聚、低耦合 | 相关职责放在一起,跨边界依赖最少且明确 | 变更是否扩散,接口是否承载隐式共享状态 |
| KISS | 用能满足约束的最简单机制 | 是否为假设中的未来扩展提前引入复杂框架 |
| DRY | 一个知识事实应有单一权威来源 | 重复逻辑是否真是同一规则,还是恰好相似 |
| YAGNI | 未被需求和风险证明的能力暂不实现 | 预留扩展是否有具体变化场景和触发器 |
| 组合优于继承 | 用可替换协作组合行为,避免脆弱层级 | 继承是否违反替换语义或暴露父类细节 |
SOLID 的五项需要分别理解:
- SRP,单一职责原则:一个模块应围绕同一类变化原因,而不是“只能有一个函数”。
- OCP,开闭原则:常见变化通过扩展点进入,稳定核心不被反复修改;扩展点本身也有维护成本。
- LSP,里氏替换原则:子类型不能破坏调用者依赖的前置条件、后置条件和不变量。
- ISP,接口隔离原则:调用者只依赖所需能力,避免“大而全”接口迫使无关实现承担变化。
- DIP,依赖倒置原则:高层策略和低层细节共同依赖稳定抽象;不是给每个类机械增加一个接口。
安全设计原则
Saltzer 与 Schroeder 在 The Protection of Information in Computer Systems中总结了八项经典原则,它们仍可作为系统设计检查表:
| 原则 | 设计问题 | 典型证据 |
|---|---|---|
| 简化机制 | 安全关键机制是否足够小、可审查 | 集中策略、较小 TCB、负向测试 |
| 默认拒绝 | 未明确授权时是否拒绝访问 | deny-by-default 策略、权限测试 |
| 完全仲裁 | 每次访问是否经过权限检查,缓存是否安全失效 | 中间件/策略点、token 失效测试 |
| 开放设计 | 安全是否依赖密钥而非算法保密 | 公开协议、密钥管理、代码评审 |
| 权限分离 | 高风险动作是否需要多个独立条件 | 双人审批、双 token、多因素 |
| 最小权限 | 主体是否只获得完成任务所需权限 | IAM、容器权限、临时凭证 |
| 最小共享机制 | 不同用户/租户是否减少共享状态与通道 | 租户隔离、独立队列/密钥/配额 |
| 心理可接受性 | 安全机制是否与正常工作流一致、易正确使用 | 可用性测试、清晰反馈、安全默认值 |
NIST SP 800-218 SSDF 1.1把安全实践集成到不同软件生命周期,但高层框架不能代替具体系统的资产、信任边界、攻击路径和验证。
GoF 23 个设计模式
GoF 原书出版社的介绍明确写的是 23 个模式,不是 24 个。常被加成“第 24 个”的 MVC 是更大尺度的界面/架构模式;Repository、依赖注入、Actor 等也不属于 GoF 原目录。
| 类别 | 模式 | 核心意图 | 适用信号 |
|---|---|---|---|
| 创建型 | Abstract Factory | 创建一族相互兼容的对象而不暴露具体类 | 多平台/多后端产品族必须成套切换 |
| 创建型 | Builder | 分步骤构造复杂对象,同一过程产生不同表示 | 参数多、有顺序/校验/默认值,构造与表示应分离 |
| 创建型 | Factory Method | 把具体产品的创建推迟给子类或实现 | 稳定流程依赖可扩展的产品类型 |
| 创建型 | Prototype | 通过复制原型创建对象 | 初始化昂贵,实例主要由已有配置变化而来 |
| 创建型 | Singleton | 保证一个实例并提供全局访问点 | 真正存在进程级唯一资源;需警惕全局状态和测试污染 |
| 结构型 | Adapter | 把既有接口转换为调用方期望的接口 | 复用旧组件或第三方后端,但接口不兼容 |
| 结构型 | Bridge | 分离抽象层次和实现层次,使二者独立变化 | 两个变化维度会形成继承组合爆炸 |
| 结构型 | Composite | 用统一接口处理树中的叶子和组合节点 | 目录、表达式、计算图等部分—整体结构 |
| 结构型 | Decorator | 运行时逐层叠加职责而不修改原对象 | 缓存、重试、鉴权、观测等可组合横切行为 |
| 结构型 | Facade | 为复杂子系统提供简化入口 | 调用方不应理解内部编排与依赖 |
| 结构型 | Flyweight | 共享不可变内在状态,降低大量细粒度对象成本 | 对象数量巨大且大部分状态可共享 |
| 结构型 | Proxy | 用替身控制对真实对象的访问 | 远程、延迟加载、缓存、权限或生命周期控制 |
| 行为型 | Chain of Responsibility | 让请求沿处理链传递,直到被处理 | 过滤、审批、中间件、错误处理链 |
| 行为型 | Command | 把请求封装为对象 | 排队、撤销、重放、审计或事务化操作 |
| 行为型 | Interpreter | 为小型语言定义语法和解释执行 | 规则/表达式语法稳定且规模有限 |
| 行为型 | Iterator | 在不暴露内部表示的情况下遍历聚合 | 多种集合需要统一遍历协议 |
| 行为型 | Mediator | 用中介集中多对象之间的复杂协作 | 同级对象形成网状依赖和协议耦合 |
| 行为型 | Memento | 在不破坏封装的情况下保存和恢复状态 | 撤销、检查点、回滚和历史快照 |
| 行为型 | Observer | 一对多发布状态变化通知 | 事件订阅、UI 更新、领域事件;需处理顺序和背压 |
| 行为型 | State | 把状态相关行为放入可替换状态对象 | 条件分支随状态增加,转换规则需要显式化 |
| 行为型 | Strategy | 封装并替换一族算法 | 路由、调度、压缩、重试等算法需按场景切换 |
| 行为型 | Template Method | 在基类固定流程骨架,由步骤扩展细节 | 流程稳定、少数步骤变化,且继承约束可接受 |
| 行为型 | Visitor | 在稳定对象结构上增加新操作 | 节点类型稳定、操作频繁新增;新增节点类型代价较高 |
这张表只回答“分别是什么”,不证明项目应该使用它们。模式举证至少要写清:原问题、参与者、代码位置、替代方案、正负后果和验证。例如 Observer 可能解耦发布者,也可能引入事件顺序、重复消费和难以追踪的隐式控制流。
横切质量设计
ISO/IEC 25010:2023 的产品质量模型可帮助检查需求、设计、测试和验收是否完整,但分类名称仍需转成具体场景。一个可评审的质量属性场景至少包含:
1 | 刺激来源 -> 刺激 -> 环境 -> 受影响对象 -> 系统响应 -> 可测阈值 |
“高性能、高可靠、安全、易用、可测试”都只是方向;没有场景、边界和阈值就无法做技术决策。
安全威胁分析
OWASP Threat Modeling用四个问题组织过程:正在做什么、可能出什么问题、准备怎样处理、是否做得足够好。可落地为:
- 定义范围与资产:模型权重、训练数据、凭证、算力、控制面、供应链和审计记录中,什么必须保护。
- 画暴露面:外部入口、信任边界、数据流、依赖、插件、管理接口和运维通道。
- 枚举威胁:STRIDE 提示伪装、篡改、抵赖、信息泄露、拒绝服务和权限提升;它是搜索提示,不是风险结论。
- 连成攻击路径:攻击者能力 → 入口 → 前置条件/漏洞 → 横向移动 → 关键资产影响。
- 设计控制:预防、检测、响应和恢复控制分别落到需求、接口、权限、隔离、审计和供应链。
- 验证并接受残余风险:负向测试、扫描、渗透、配置审计和责任人签字。
例如,一个训练平台允许加载用户提交的插件:关键资产是集群凭证和模型权重;暴露面是插件包、构建流水线和运行容器;攻击路径可能是恶意 commit 进入构建产物,运行时读取宿主凭证并经外网回传。有效设计需要签名/来源校验、构建隔离、运行时最小权限、凭证分离、网络出口控制、审计和负向测试,而不是只写“使用鉴权和加密”。
可靠与可用性
可靠性关注任务期间能否持续正确完成,可用性关注需要服务时是否可用。一个长时间训练任务可能接口一直“在线”却频繁失败,表现为高可用、低任务可靠;一个离线批处理系统不追求 24×7 在线,却可能要求作业成功率和数据恢复严格达标。
可靠/可用性设计至少包含:
- 用户可观察的 SLI/SLO、任务窗口、RTO、RPO、耐久和一致性;
- 依赖、故障域、单点、容量和故障传播;
- FMEA 从组件故障模式向上分析影响、探测和处置;
- FTA 从不可接受的 Top failure 向下分析可能的组合路径;
- 隔离、冗余、幂等、超时、有限重试、退避/抖动、背压、降级、回滚、备份与恢复;
- 故障注入、恢复演练、监控和 SLO 结果。
NASA 软件可靠性指南把 FMEA 和 FTA 作为互补方法:前者自底向上,后者自顶向下。Google SRE 的 SLO 方法则把用户可见可靠性目标连接到工程优先级和错误预算。
可测试性
可测试性不是“写了多少测试”,而是设计是否允许低成本构造条件并判断结果:
| 维度 | 设计问题 | 典型机制与证据 |
|---|---|---|
| 可控 | 能否设置输入、依赖、时间、随机性和故障 | 端口/依赖注入、虚拟时钟、seed、故障注入点 |
| 可观 | 能否看见状态、输出和关键中间结果 | 结构化日志、指标、Trace、状态查询、明确错误码 |
| 可隔离 | 能否把被测对象与昂贵或不稳定依赖分开 | fake/stub、契约测试、容器化依赖、测试后端 |
| 可重复 | 同一条件是否得到可比较结果 | 固定数据/版本/配置、幂等清理、确定性执行边界 |
| 可自动 | 能否稳定进入 CI 并快速定位回归 | 分层测试、机器可读 oracle、并行和失败归因 |
如果一个模块必须连接真实集群、依赖全局单例、没有可查询状态且错误只写自由文本日志,那么“补几个测试用例”解决不了问题;需要先改代码边界和观测接口。
功能安全与体验
功能安全关注安全相关系统因 E/E/可编程系统失效而产生的不可接受物理风险。ISO 26262 明确面向量产道路车辆的安全相关 E/E 系统;IEC 61508 提供更通用的安全生命周期框架。普通 Web 页面、推荐准确率或“功能不能出错”不能直接称为功能安全。
适用时,需要 hazard/HARA、运行场景、安全目标、ASIL/SIL 或行业等级、安全需求、独立性、监控/降级/安全状态、验证与确认。若项目不适用,应写“不适用的理由 + 仍需处理的一般安全/可靠性风险”,而不是静默删除章节。
体验设计也不是 UI 美化。ISO 9241-210:2019 把人本设计放在交互系统全生命周期中。软件设计文档至少应记录用户、任务、使用环境、关键旅程、错误预防与恢复、反馈、可访问性,以及开发者/运维者体验;最终由原型、可用性测试、工单或用户任务指标验证。
高性能设计
“参与过性能设计,模块无明显性能问题”有一个隐藏前提:先定义什么叫问题。没有工作负载、阈值和测量窗口,“无明显问题”只表示暂时没有收到投诉。
一个可举证的性能设计闭环包括:
- 负载合同:输入规模和分布、并发、突发、读写比、硬件、软件、精度、版本、预热、重复和统计口径。
- 预算分解:端到端延迟/尾延迟、吞吐、容量、CPU/NPU/GPU、内存/显存、I/O、网络和成本预算落到关键路径。
- 瓶颈假设:算法复杂度、对象生命周期、拷贝/序列化、锁、队列、通信、缓存命中和扩展上限。
- 设计消减:批处理、并行/异步、缓存、数据布局、融合、背压、限流、分片、降级或容量预留。
- 受控验证:同条件 baseline/candidate Profiling 或 Benchmark,同时记录收益、代价、退化区间和回退条件。
- 持续防回归:性能测试、容量阈值、线上 SLI 和发布门禁。
性能举证的强度依次增加:代码中存在优化分支;Profiling 证明热点被改变;同条件实验证明端到端指标改善;持续门禁证明后续提交没有把问题带回来。前一层不能自动推导后一层。
架构治理与技术决策
识别架构腐化
架构腐化通常不是某次大改造成,而是例外持续积累:跨层调用、循环依赖、共享数据库、重复领域模型、接口泄漏、隐式全局状态、版本漂移、部署边界与代码边界错位、关键路径不可观测、文档和实现长期不一致。
举证“识别并组织改进”至少需要:
- 腐化点的实例、趋势和影响,而不是个人感觉;
- 候选人如何召集所有者、制定边界和分期计划;
- 迁移期间如何兼容、回退并保护业务;
- 改进前后的依赖、缺陷、交付或运行证据;
- 怎样把规则持续化,避免下一次重新腐化。
持续化的关键是把重要约束写成架构适应度函数。例如 ArchUnit可以在 Java 测试中检查层间依赖、循环和包规则;其他语言可以使用依赖图、lint、自定义 CI 或 Schema/API 兼容检查。工具只执行明确规则,不能替架构师决定哪些边界值得保护。
记录技术决策
Michael Nygard 的 ADR用短文本保存 Context、Decision、Status 和 Consequences,并保留被替代的旧决定。它特别适合敏捷开发:每次只记录一个架构重要决定,与代码一起版本化。
当性能、可靠性、安全、可修改性等目标互相拉扯时,可以借鉴 SEI ATAM:建立质量效用树和高优先级场景,比较候选架构,识别风险、非风险、敏感点和权衡点。
| 弱举证 | 强举证 |
|---|---|
| “参与了方案讨论” | 提出两个可比较候选,定义准则,推动评审并记录决定 |
| “建议使用微服务” | 证明独立交付/故障域/团队边界需要拆分,并承担分布式代价 |
| “使用了设计模式” | 说明原问题、结构、代码位置、替代方案、后果和测试 |
| “优化了性能” | 固定环境,定位瓶颈,选择机制,给出 baseline/candidate 与回归门禁 |
| “治理了架构” | 识别腐化趋势,组织迁移,把约束转成持续自动检查 |
从 commits 生成举证材料
输入合同
最小输入包括:
- 需求、问题陈述或目标;
- 目标系统/子系统/模块边界;
- 仓库路径;
- 至少一个 commit、commit range、PR 或明确代码路径。
更强的输入包括 Top 问题来源、需求/验收、现有设计与 ADR、评审纪要、测试、Profiling、SLO、故障演练、安全验证、用户研究,以及候选人的负责范围和决策权。
Skill 会先判断交付模式:跨多个模块/进程/部署单元时生成子系统设计;聚焦一个关键机制和 Top 问题时生成关键模块方案;已有设计只缺任职材料时做举证审计。
证据等级
| 等级 | 材料 | 允许结论 |
|---|---|---|
| E0 陈述 | 个人描述,无可核验路径 | “候选人陈述……” |
| E1 设计 | 设计文档、ADR、评审记录 | “提出/设计了……” |
| E2 实现 | commit、PR、代码、配置 | “实现/组织落地了……” |
| E3 验证 | 测试、Profiling、演练、SLO、用户验证、治理对比 | “在给定边界下验证了……” |
任职结论不得高于材料能支持的等级。证据冲突时,报告会列出时间顺序和最小确认问题,而不是挑选对候选人更有利的一份。
输出与缺口
本地 software-design-evidence Skill 输出:
- 软件子系统设计文档或关键模块设计方案;
- 任职能力举证报告;
- 需求—设计—风险—commit—测试—结果双向追踪矩阵;
充分 / 部分 / 缺失 / 不适用 / 证据冲突的逐项审计;- 按 P0/P1/P2 排序的设计、代码、测试、度量、归属和时间证据缺口。
每个缺口不是一句“补文档”,而要写清影响、最小动作、责任人、产物、验收方式和补齐后能达到的证据等级。例如:
| 缺口 | 类型 | 最小补齐工作 | 验收 |
|---|---|---|---|
| 无法证明为何选择异步队列 | 设计/时间 | 责任人确认回溯 ADR,补候选方案与负面后果 | ADR 被评审,明确为回溯记录 |
| 安全章节只有 STRIDE 列表 | 设计/测试 | 补资产、信任边界、Top 攻击路径、控制与负向测试 | 威胁—控制—测试可追踪,残余风险有责任人 |
| 声称吞吐提升但无同条件基线 | 度量 | 固定环境、数据、并发、预热和统计口径重跑 baseline/candidate | 原始结果可复现,包含尾延迟与资源代价 |
| 识别循环依赖但会继续新增 | 治理/代码 | 增加依赖规则和 CI 门禁,制定存量迁移计划 | 新违规阻断,存量趋势可见 |
| “主导”只有团队 commit | 归属 | 补评审纪要、ADR owner、任务/PR 责任和相关证明 | 个人动作与团队成果边界清楚 |
使用方式
1 | 使用 $software-design-evidence 完成软件设计与任职举证。 |
总结
软件设计能力不是背出 4+1、SOLID 或 23 个 GoF 模式,而是选择合适模型消除不确定性,并让关键判断能穿过设计、实现、验证和治理。敏捷与文档并不冲突:大而全、无人维护的说明书没有价值;与需求、ADR、代码和测试一起演进的小型证据单元非常有价值。
面对已经完成的 AI 穿刺代码,最诚实也最有说服力的做法是:能证明的写成事实,合理但未记录的写成推断,仍需决定的写成问题,缺少的设计和代码工作写成可验收任务。这样的报告既能服务任职,也能真正提高下一次开发的质量。
参考资料
- Philippe Kruchten, Architectural Blueprints—The “4+1” View Model of Software Architecture, IEEE Software, 1995.
- ISO/IEC/IEEE 42010:2022 — Architecture description.
- OMG Unified Modeling Language 2.5.1.
- C4 Model.
- Gamma, Helm, Johnson, Vlissides, Design Patterns, Addison-Wesley, 1994.
- D. L. Parnas, On the Criteria To Be Used in Decomposing Systems into Modules, 1972.
- J. H. Saltzer and M. D. Schroeder, The Protection of Information in Computer Systems, 1975.
- OWASP Threat Modeling.
- NIST SP 800-218 SSDF 1.1.
- ISO/IEC 25010:2023 — Product quality model.
- NASA, Software Reliability and FMECA Guideline.
- Google SRE, Implementing SLOs.
- ISO 26262-1:2018 — Functional safety and IEC 61508.
- ISO 9241-210:2019 — Human-centred design.
- Michael Nygard, Documenting Architecture Decisions, 2011.
- CMU SEI, Architecture Tradeoff Analysis Method.
- ArchUnit User Guide.
Software Design Evidence
http://icarus.shaojiemike.top/2026/08/03/Work/0-Digital Worker/Software-Design-Evidence/