@clossys/architect 0.1.2

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +171 -0
  4. package/dist/assessment.d.ts +9 -0
  5. package/dist/assessment.d.ts.map +1 -0
  6. package/dist/assessment.js +98 -0
  7. package/dist/assessment.js.map +1 -0
  8. package/dist/cli.d.ts +6 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +96 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/index.d.ts +6 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +5 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/ontology/compatibility.d.ts +7 -0
  17. package/dist/ontology/compatibility.d.ts.map +1 -0
  18. package/dist/ontology/compatibility.js +135 -0
  19. package/dist/ontology/compatibility.js.map +1 -0
  20. package/dist/ontology/define.d.ts +8 -0
  21. package/dist/ontology/define.d.ts.map +1 -0
  22. package/dist/ontology/define.js +30 -0
  23. package/dist/ontology/define.js.map +1 -0
  24. package/dist/ontology/index.d.ts +9 -0
  25. package/dist/ontology/index.d.ts.map +1 -0
  26. package/dist/ontology/index.js +8 -0
  27. package/dist/ontology/index.js.map +1 -0
  28. package/dist/ontology/normalize.d.ts +6 -0
  29. package/dist/ontology/normalize.d.ts.map +1 -0
  30. package/dist/ontology/normalize.js +60 -0
  31. package/dist/ontology/normalize.js.map +1 -0
  32. package/dist/ontology/snapshot.d.ts +14 -0
  33. package/dist/ontology/snapshot.d.ts.map +1 -0
  34. package/dist/ontology/snapshot.js +299 -0
  35. package/dist/ontology/snapshot.js.map +1 -0
  36. package/dist/ontology/types.d.ts +123 -0
  37. package/dist/ontology/types.d.ts.map +1 -0
  38. package/dist/ontology/types.js +16 -0
  39. package/dist/ontology/types.js.map +1 -0
  40. package/dist/ontology/validate.d.ts +8 -0
  41. package/dist/ontology/validate.d.ts.map +1 -0
  42. package/dist/ontology/validate.js +190 -0
  43. package/dist/ontology/validate.js.map +1 -0
  44. package/dist/topology.d.ts +11 -0
  45. package/dist/topology.d.ts.map +1 -0
  46. package/dist/topology.js +237 -0
  47. package/dist/topology.js.map +1 -0
  48. package/dist/types.d.ts +110 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +11 -0
  51. package/dist/types.js.map +1 -0
  52. package/package.json +69 -0
  53. package/src/assessment.ts +98 -0
  54. package/src/cli.ts +74 -0
  55. package/src/index.ts +39 -0
  56. package/src/ontology/compatibility.ts +132 -0
  57. package/src/ontology/define.ts +35 -0
  58. package/src/ontology/index.ts +29 -0
  59. package/src/ontology/normalize.ts +63 -0
  60. package/src/ontology/snapshot.ts +324 -0
  61. package/src/ontology/types.ts +156 -0
  62. package/src/ontology/validate.ts +208 -0
  63. package/src/topology.ts +211 -0
  64. package/src/types.ts +142 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topology.js","sourceRoot":"","sources":["../src/topology.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ /** The business boundary whose operating architecture is being described. */
2
+ export type OperatingScopeKind = "portfolio" | "business";
3
+ /** A provider-neutral kind of system in an operating topology. */
4
+ export type OperatingSystemKind = "workspace" | "repository" | "service" | "data-store" | "external-system";
5
+ /** Stable responsibilities that systems can perform without prescribing repository names. */
6
+ export type OperatingResponsibility = "control-plane" | "product" | "commercial" | "delivery" | "knowledge" | "platform";
7
+ export interface OperatingScopeDefinition {
8
+ id: string;
9
+ kind: OperatingScopeKind;
10
+ }
11
+ /** One addressable system. Provider locators are descriptive, never credentials. */
12
+ export interface OperatingSystemDefinition {
13
+ id: string;
14
+ kind: OperatingSystemKind;
15
+ responsibilities: readonly OperatingResponsibility[];
16
+ provider?: string;
17
+ locator?: string;
18
+ visibility?: "public" | "private" | "restricted";
19
+ }
20
+ /** One consumer-owned declaration of authority and its authoritative record. */
21
+ export interface AuthorityDefinition {
22
+ responsibility: OperatingResponsibility;
23
+ owner: string;
24
+ systemOfRecord: string;
25
+ }
26
+ /** An allowed directional crossing between two declared systems. */
27
+ export interface OperatingInterfaceDefinition {
28
+ id: string;
29
+ from: string;
30
+ to: string;
31
+ responsibilities: readonly OperatingResponsibility[];
32
+ description?: string;
33
+ }
34
+ /** Provider-neutral desired operating architecture. */
35
+ export interface OperatingTopologyDefinition {
36
+ id: string;
37
+ schemaVersion: string;
38
+ scope: OperatingScopeDefinition;
39
+ systems?: readonly OperatingSystemDefinition[];
40
+ authorities?: readonly AuthorityDefinition[];
41
+ interfaces?: readonly OperatingInterfaceDefinition[];
42
+ }
43
+ export interface OperatingTopology extends OperatingTopologyDefinition {
44
+ systems: readonly OperatingSystemDefinition[];
45
+ authorities: readonly AuthorityDefinition[];
46
+ interfaces: readonly OperatingInterfaceDefinition[];
47
+ }
48
+ export type ArchitectureFindingSeverity = "error" | "warning";
49
+ export interface ArchitectureFinding {
50
+ rule: string;
51
+ severity: ArchitectureFindingSeverity;
52
+ message: string;
53
+ path?: string;
54
+ }
55
+ export interface OperatingTopologyChange {
56
+ kind: "additive" | "breaking";
57
+ subject: "topology" | "scope" | "system" | "authority" | "interface";
58
+ id: string;
59
+ message: string;
60
+ }
61
+ export interface OperatingTopologyCompatibilityReport {
62
+ compatible: boolean;
63
+ changes: readonly OperatingTopologyChange[];
64
+ previousFindings: readonly ArchitectureFinding[];
65
+ nextFindings: readonly ArchitectureFinding[];
66
+ }
67
+ /** One actual system-to-system crossing observed during a change. */
68
+ export interface BoundaryCrossingObservation {
69
+ from: string;
70
+ to: string;
71
+ responsibility: OperatingResponsibility;
72
+ interface?: string;
73
+ }
74
+ /** Evidence about one actual change. Non-material changes do not enter the metric. */
75
+ export interface ArchitectureChangeObservation {
76
+ id: string;
77
+ observedAt: string;
78
+ material: boolean;
79
+ crossings: readonly BoundaryCrossingObservation[];
80
+ }
81
+ export interface ArchitectureAssessmentOptions {
82
+ /** Inclusive setpoint in [0, 1]. */
83
+ maximumExceptionRate: number;
84
+ }
85
+ export type ArchitectureAssessmentState = "satisfied" | "violated" | "indeterminate";
86
+ export interface AssessedBoundaryCrossing extends BoundaryCrossingObservation {
87
+ declared: boolean;
88
+ }
89
+ export interface AssessedArchitectureChange {
90
+ id: string;
91
+ observedAt: string;
92
+ material: boolean;
93
+ crossings: readonly AssessedBoundaryCrossing[];
94
+ hasException: boolean;
95
+ }
96
+ /** Pure assessment result. `exceptionRate` is null whenever evidence is indeterminate. */
97
+ export interface ArchitectureExceptionAssessment {
98
+ state: ArchitectureAssessmentState;
99
+ exceptionRate: number | null;
100
+ maximumExceptionRate: number;
101
+ observedChanges: number;
102
+ observedMaterialChanges: number;
103
+ materialChangesWithExceptions: number;
104
+ changes: readonly AssessedArchitectureChange[];
105
+ findings: readonly ArchitectureFinding[];
106
+ }
107
+ export declare const OPERATING_SCOPE_KINDS: readonly OperatingScopeKind[];
108
+ export declare const OPERATING_SYSTEM_KINDS: readonly OperatingSystemKind[];
109
+ export declare const OPERATING_RESPONSIBILITIES: readonly OperatingResponsibility[];
110
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ export const OPERATING_SCOPE_KINDS = ["portfolio", "business"];
2
+ export const OPERATING_SYSTEM_KINDS = ["workspace", "repository", "service", "data-store", "external-system"];
3
+ export const OPERATING_RESPONSIBILITIES = [
4
+ "control-plane",
5
+ "product",
6
+ "commercial",
7
+ "delivery",
8
+ "knowledge",
9
+ "platform",
10
+ ];
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoIA,MAAM,CAAC,MAAM,qBAAqB,GAAkC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC9F,MAAM,CAAC,MAAM,sBAAsB,GAAmC,CAAC,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;AAC9I,MAAM,CAAC,MAAM,0BAA0B,GAAuC;IAC5E,eAAe;IACf,SAAS;IACT,YAAY;IACZ,UAAU;IACV,WAAW;IACX,UAAU;CACX,CAAC"}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@clossys/architect",
3
+ "version": "0.1.2",
4
+ "private": false,
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ },
15
+ "./ontology": {
16
+ "types": "./dist/ontology/index.d.ts",
17
+ "import": "./dist/ontology/index.js"
18
+ }
19
+ },
20
+ "bin": {
21
+ "architect-check": "./dist/cli.js"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "src",
26
+ "!src/**/*.test.ts",
27
+ "README.md",
28
+ "CHANGELOG.md",
29
+ "LICENSE"
30
+ ],
31
+ "sideEffects": false,
32
+ "description": "The architect role: provider-neutral operating topology, ontology, authority and interface contracts, plus evidence-based architecture exception assessment.",
33
+ "keywords": [
34
+ "architecture",
35
+ "ontology",
36
+ "operating-model",
37
+ "topology",
38
+ "validation",
39
+ "typescript"
40
+ ],
41
+ "author": "Calvin Hung",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/clossys/foundry.git",
45
+ "directory": "packages/architect"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/clossys/foundry/issues"
49
+ },
50
+ "homepage": "https://github.com/clossys/foundry/tree/main/packages/architect#readme",
51
+ "engines": {
52
+ "node": ">=20"
53
+ },
54
+ "scripts": {
55
+ "build": "tsc -p tsconfig.json",
56
+ "prepublishOnly": "node ../../scripts/check-name-collision.mjs . && npm run build",
57
+ "typecheck": "tsc -p tsconfig.json --noEmit",
58
+ "test": "vitest run"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^22.10.0",
62
+ "typescript": "~6.0.0",
63
+ "vitest": "^4.1.9"
64
+ },
65
+ "publishConfig": {
66
+ "registry": "https://registry.npmjs.org",
67
+ "access": "public"
68
+ }
69
+ }
@@ -0,0 +1,98 @@
1
+ import { validateOperatingTopology } from "./topology.js";
2
+ import { OPERATING_RESPONSIBILITIES } from "./types.js";
3
+ import type {
4
+ ArchitectureAssessmentOptions,
5
+ ArchitectureChangeObservation,
6
+ ArchitectureExceptionAssessment,
7
+ ArchitectureFinding,
8
+ AssessedArchitectureChange,
9
+ AssessedBoundaryCrossing,
10
+ OperatingInterfaceDefinition,
11
+ OperatingTopologyDefinition,
12
+ } from "./types.js";
13
+
14
+ type UnknownRecord = Record<string, unknown>;
15
+
16
+ function isRecord(value: unknown): value is UnknownRecord {
17
+ return typeof value === "object" && value !== null && !Array.isArray(value);
18
+ }
19
+
20
+ function finding(rule: string, message: string, path: string): ArchitectureFinding {
21
+ return { rule, severity: "error", message, path };
22
+ }
23
+
24
+ /** Validates observations as evidence without using them to certify themselves. */
25
+ export function validateArchitectureChangeObservations(value: unknown): ArchitectureFinding[] {
26
+ if (!Array.isArray(value)) return [finding("observations-shape", "Architecture observations must be an array.", "$")];
27
+ const findings: ArchitectureFinding[] = [];
28
+ const ids = new Set<string>();
29
+ for (const [index, candidate] of value.entries()) {
30
+ const path = `[${index}]`;
31
+ if (!isRecord(candidate)) { findings.push(finding("observation-shape", "An observation must be an object.", path)); continue; }
32
+ if (typeof candidate.id !== "string" || candidate.id.length === 0) findings.push(finding("observation-id", "id must be a non-empty string.", `${path}.id`));
33
+ else if (ids.has(candidate.id)) findings.push(finding("duplicate-observation-id", `Duplicate observation id "${candidate.id}".`, `${path}.id`));
34
+ else ids.add(candidate.id);
35
+ if (typeof candidate.observedAt !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(candidate.observedAt)) findings.push(finding("observed-at", "observedAt must be an RFC 3339 timestamp with an offset.", `${path}.observedAt`));
36
+ if (typeof candidate.material !== "boolean") findings.push(finding("material-shape", "material must be a boolean.", `${path}.material`));
37
+ if (!Array.isArray(candidate.crossings)) { findings.push(finding("crossings-shape", "crossings must be an array.", `${path}.crossings`)); continue; }
38
+ for (const [crossingIndex, crossing] of candidate.crossings.entries()) {
39
+ const crossingPath = `${path}.crossings[${crossingIndex}]`;
40
+ if (!isRecord(crossing)) { findings.push(finding("crossing-shape", "A boundary crossing must be an object.", crossingPath)); continue; }
41
+ for (const endpoint of ["from", "to"] as const) if (typeof crossing[endpoint] !== "string" || crossing[endpoint].length === 0) findings.push(finding("crossing-endpoint", `${endpoint} must be a non-empty system id.`, `${crossingPath}.${endpoint}`));
42
+ if (typeof crossing.responsibility !== "string" || !(OPERATING_RESPONSIBILITIES as readonly string[]).includes(crossing.responsibility)) findings.push(finding("crossing-responsibility", "responsibility must be a supported value.", `${crossingPath}.responsibility`));
43
+ if (crossing.from !== undefined && crossing.from === crossing.to) findings.push(finding("crossing-boundary", "A boundary crossing must name two different systems.", crossingPath));
44
+ if (crossing.interface !== undefined && (typeof crossing.interface !== "string" || crossing.interface.length === 0)) findings.push(finding("crossing-interface", "interface must be a non-empty string when provided.", `${crossingPath}.interface`));
45
+ }
46
+ }
47
+ return findings;
48
+ }
49
+
50
+ function isDeclared(crossing: { from: string; to: string; responsibility: string; interface?: string }, interfaces: readonly OperatingInterfaceDefinition[]): boolean {
51
+ return interfaces.some((entry) => entry.from === crossing.from && entry.to === crossing.to && (entry.responsibilities as readonly string[]).includes(crossing.responsibility) && (crossing.interface === undefined || entry.id === crossing.interface));
52
+ }
53
+
54
+ function indeterminate(maximumExceptionRate: number, observedChanges: number, findings: ArchitectureFinding[]): ArchitectureExceptionAssessment {
55
+ return { state: "indeterminate", exceptionRate: null, maximumExceptionRate, observedChanges, observedMaterialChanges: 0, materialChangesWithExceptions: 0, changes: [], findings };
56
+ }
57
+
58
+ /**
59
+ * Measures the package's primary metric from independent observations.
60
+ * No material observations is explicitly indeterminate, never a zero rate.
61
+ */
62
+ export function assessArchitectureExceptions(
63
+ topology: unknown,
64
+ observations: unknown,
65
+ options: ArchitectureAssessmentOptions,
66
+ ): ArchitectureExceptionAssessment {
67
+ const topologyFindings = validateOperatingTopology(topology);
68
+ const observationFindings = validateArchitectureChangeObservations(observations);
69
+ const optionFindings: ArchitectureFinding[] = [];
70
+ if (!Number.isFinite(options.maximumExceptionRate) || options.maximumExceptionRate < 0 || options.maximumExceptionRate > 1) optionFindings.push(finding("maximum-exception-rate", "maximumExceptionRate must be a finite number in [0, 1].", "options.maximumExceptionRate"));
71
+ const observedChanges = Array.isArray(observations) ? observations.length : 0;
72
+ const findings = [...topologyFindings, ...observationFindings, ...optionFindings];
73
+ if (findings.some((entry) => entry.severity === "error")) return indeterminate(options.maximumExceptionRate, observedChanges, findings);
74
+
75
+ const definition = topology as OperatingTopologyDefinition;
76
+ const evidence = observations as readonly ArchitectureChangeObservation[];
77
+ const interfaces = definition.interfaces ?? [];
78
+ const changes: AssessedArchitectureChange[] = evidence.map((observation) => {
79
+ const crossings: AssessedBoundaryCrossing[] = observation.crossings.map((crossing) => ({ ...crossing, declared: isDeclared(crossing, interfaces) }));
80
+ return { id: observation.id, observedAt: observation.observedAt, material: observation.material, crossings, hasException: observation.material && crossings.some((crossing) => !crossing.declared) };
81
+ });
82
+ const material = changes.filter((change) => change.material);
83
+ if (material.length === 0) {
84
+ return { state: "indeterminate", exceptionRate: null, maximumExceptionRate: options.maximumExceptionRate, observedChanges: changes.length, observedMaterialChanges: 0, materialChangesWithExceptions: 0, changes, findings: [{ rule: "material-evidence-required", severity: "warning", message: "No observed material changes are available; architecture exception rate is unobserved." }] };
85
+ }
86
+ const exceptions = material.filter((change) => change.hasException).length;
87
+ const exceptionRate = exceptions / material.length;
88
+ return {
89
+ state: exceptionRate <= options.maximumExceptionRate ? "satisfied" : "violated",
90
+ exceptionRate,
91
+ maximumExceptionRate: options.maximumExceptionRate,
92
+ observedChanges: changes.length,
93
+ observedMaterialChanges: material.length,
94
+ materialChangesWithExceptions: exceptions,
95
+ changes,
96
+ findings: [],
97
+ };
98
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { assessArchitectureExceptions } from "./assessment.js";
6
+ import { validateOperatingTopology } from "./topology.js";
7
+
8
+ const USAGE = `Usage: architect-check topology <topology-file>
9
+ architect-check exceptions <topology-file> <observations-file> --maximum-exception-rate <rate>
10
+
11
+ Commands:
12
+ topology Validate a provider-neutral operating topology.
13
+ exceptions Assess architecture exception rate from observed changes.
14
+
15
+ Exit codes: 0 = satisfied, 1 = violated, 2 = indeterminate or could not run.`;
16
+
17
+ export class ArchitectCliInputError extends Error {}
18
+
19
+ function readJson(path: string, label: string): unknown {
20
+ const resolved = resolve(path);
21
+ if (!existsSync(resolved)) throw new ArchitectCliInputError(`${label} "${path}" does not exist`);
22
+ try { if (!statSync(resolved).isFile()) throw new ArchitectCliInputError(`${label} "${path}" is not a file`); }
23
+ catch (error) { if (error instanceof ArchitectCliInputError) throw error; throw new ArchitectCliInputError(`cannot inspect ${label} "${path}": ${error instanceof Error ? error.message : String(error)}`); }
24
+ try { return JSON.parse(readFileSync(resolved, "utf8")); }
25
+ catch (error) { throw new ArchitectCliInputError(`${label} "${path}" is not valid JSON: ${error instanceof Error ? error.message : String(error)}`); }
26
+ }
27
+
28
+ function topologyCommand(argv: readonly string[]): number {
29
+ if (argv.length !== 1) throw new ArchitectCliInputError("topology requires exactly one topology-file");
30
+ const findings = validateOperatingTopology(readJson(argv[0] as string, "topology-file"));
31
+ const report = { state: findings.some((entry) => entry.severity === "error") ? "violated" : "satisfied", findings };
32
+ console.log(JSON.stringify(report, null, 2));
33
+ return report.state === "satisfied" ? 0 : 1;
34
+ }
35
+
36
+ function exceptionsCommand(argv: readonly string[]): number {
37
+ let topologyFile: string | undefined;
38
+ let observationsFile: string | undefined;
39
+ let rate: number | undefined;
40
+ for (let index = 0; index < argv.length; index++) {
41
+ const argument = argv[index] as string;
42
+ if (argument === "--maximum-exception-rate") {
43
+ const value = argv[++index];
44
+ if (value === undefined) throw new ArchitectCliInputError("--maximum-exception-rate requires a value");
45
+ rate = Number(value);
46
+ } else if (argument.startsWith("-")) throw new ArchitectCliInputError(`unknown option "${argument}"`);
47
+ else if (topologyFile === undefined) topologyFile = argument;
48
+ else if (observationsFile === undefined) observationsFile = argument;
49
+ else throw new ArchitectCliInputError(`unexpected extra argument "${argument}"`);
50
+ }
51
+ if (topologyFile === undefined || observationsFile === undefined || rate === undefined) throw new ArchitectCliInputError("exceptions requires topology-file, observations-file, and --maximum-exception-rate");
52
+ const report = assessArchitectureExceptions(readJson(topologyFile, "topology-file"), readJson(observationsFile, "observations-file"), { maximumExceptionRate: rate });
53
+ console.log(JSON.stringify(report, null, 2));
54
+ return report.state === "satisfied" ? 0 : report.state === "violated" ? 1 : 2;
55
+ }
56
+
57
+ /** Testable command dispatcher. Invalid arguments throw and the executable maps them to 2. */
58
+ export function main(argv: readonly string[]): number {
59
+ if (argv.length === 1 && (argv[0] === "--help" || argv[0] === "-h")) { console.log(USAGE); return 0; }
60
+ const [command, ...rest] = argv;
61
+ if (command === "topology") return topologyCommand(rest);
62
+ if (command === "exceptions") return exceptionsCommand(rest);
63
+ throw new ArchitectCliInputError(command === undefined ? "a command is required" : `unknown command "${command}"`);
64
+ }
65
+
66
+ function run(): void {
67
+ try { process.exitCode = main(process.argv.slice(2)); }
68
+ catch (error) {
69
+ console.error(`architect-check: ${error instanceof Error ? error.message : String(error)}`);
70
+ process.exitCode = 2;
71
+ }
72
+ }
73
+
74
+ if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === resolve(process.argv[1])) run();
package/src/index.ts ADDED
@@ -0,0 +1,39 @@
1
+ /** Provider-neutral operating-architecture contracts and evidence-based assessment. */
2
+ export {
3
+ OPERATING_RESPONSIBILITIES,
4
+ OPERATING_SCOPE_KINDS,
5
+ OPERATING_SYSTEM_KINDS,
6
+ } from "./types.js";
7
+ export {
8
+ compareOperatingTopologies,
9
+ defineOperatingTopology,
10
+ normalizeOperatingTopology,
11
+ serializeOperatingTopology,
12
+ validateOperatingTopology,
13
+ } from "./topology.js";
14
+ export {
15
+ assessArchitectureExceptions,
16
+ validateArchitectureChangeObservations,
17
+ } from "./assessment.js";
18
+ export type {
19
+ ArchitectureAssessmentOptions,
20
+ ArchitectureAssessmentState,
21
+ ArchitectureChangeObservation,
22
+ ArchitectureExceptionAssessment,
23
+ ArchitectureFinding,
24
+ ArchitectureFindingSeverity,
25
+ AssessedArchitectureChange,
26
+ AssessedBoundaryCrossing,
27
+ AuthorityDefinition,
28
+ BoundaryCrossingObservation,
29
+ OperatingInterfaceDefinition,
30
+ OperatingResponsibility,
31
+ OperatingScopeDefinition,
32
+ OperatingScopeKind,
33
+ OperatingSystemDefinition,
34
+ OperatingSystemKind,
35
+ OperatingTopology,
36
+ OperatingTopologyChange,
37
+ OperatingTopologyCompatibilityReport,
38
+ OperatingTopologyDefinition,
39
+ } from "./types.js";
@@ -0,0 +1,132 @@
1
+ import { normalizeDomainModel } from "./normalize.js";
2
+ import { validateDomainModel } from "./validate.js";
3
+ import type { DomainModel, DomainModelChange, DomainModelCompatibilityReport, DomainModelDefinition, DomainTypeDefinition, FieldDefinition, RelationDefinition, ValueTypeDefinition, VocabularyDefinition } from "./types.js";
4
+
5
+ function mapById<T extends { id: string }>(items: readonly T[]): Map<string, T> {
6
+ return new Map(items.map((item) => [item.id, item]));
7
+ }
8
+
9
+ function stable(value: unknown): string {
10
+ return JSON.stringify(value);
11
+ }
12
+
13
+ function compareFields(
14
+ previous: readonly FieldDefinition[],
15
+ next: readonly FieldDefinition[],
16
+ subject: "field" | "relation-property",
17
+ ownerId: string,
18
+ changes: DomainModelChange[],
19
+ ): void {
20
+ const before = mapById(previous);
21
+ const after = mapById(next);
22
+ for (const [id, field] of before) {
23
+ const replacement = after.get(id);
24
+ if (replacement === undefined) {
25
+ changes.push({ kind: "breaking", subject, id, message: `${subject} "${id}" was removed from "${ownerId}".` });
26
+ continue;
27
+ }
28
+ if (field.valueType !== replacement.valueType) {
29
+ changes.push({ kind: "breaking", subject, id, message: `${subject} "${id}" changed valueType.` });
30
+ }
31
+ if (field.required !== true && replacement.required === true) {
32
+ changes.push({ kind: "breaking", subject, id, message: `${subject} "${id}" became required.` });
33
+ }
34
+ if (field.required === true && replacement.required !== true) {
35
+ changes.push({ kind: "additive", subject, id, message: `${subject} "${id}" became optional.` });
36
+ }
37
+ }
38
+ for (const [id, field] of after) {
39
+ if (!before.has(id)) {
40
+ changes.push({
41
+ kind: field.required === true ? "breaking" : "additive",
42
+ subject,
43
+ id,
44
+ message: `${subject} "${id}" was added to "${ownerId}"${field.required === true ? " as required" : ""}.`,
45
+ });
46
+ }
47
+ }
48
+ }
49
+
50
+ function compareValueTypes(previous: readonly ValueTypeDefinition[], next: readonly ValueTypeDefinition[], changes: DomainModelChange[]): void {
51
+ const before = mapById(previous);
52
+ const after = mapById(next);
53
+ for (const [id, valueType] of before) {
54
+ const replacement = after.get(id);
55
+ if (replacement === undefined) changes.push({ kind: "breaking", subject: "value-type", id, message: `Value type "${id}" was removed.` });
56
+ else if (valueType.primitive !== replacement.primitive) changes.push({ kind: "breaking", subject: "value-type", id, message: `Value type "${id}" changed primitive.` });
57
+ }
58
+ for (const [id] of after) if (!before.has(id)) changes.push({ kind: "additive", subject: "value-type", id, message: `Value type "${id}" was added.` });
59
+ }
60
+
61
+ function compareVocabularies(previous: readonly VocabularyDefinition[], next: readonly VocabularyDefinition[], changes: DomainModelChange[]): void {
62
+ const before = mapById(previous);
63
+ const after = mapById(next);
64
+ for (const [id, vocabulary] of before) {
65
+ const replacement = after.get(id);
66
+ if (replacement === undefined) {
67
+ changes.push({ kind: "breaking", subject: "vocabulary", id, message: `Vocabulary "${id}" was removed.` });
68
+ continue;
69
+ }
70
+ const previousValues = new Set(vocabulary.values);
71
+ const nextValues = new Set(replacement.values);
72
+ for (const value of previousValues) if (!nextValues.has(value)) changes.push({ kind: "breaking", subject: "vocabulary-value", id: `${id}.${value}`, message: `Vocabulary value "${value}" was removed from "${id}".` });
73
+ for (const value of nextValues) if (!previousValues.has(value)) changes.push({ kind: "additive", subject: "vocabulary-value", id: `${id}.${value}`, message: `Vocabulary value "${value}" was added to "${id}".` });
74
+ }
75
+ for (const [id] of after) if (!before.has(id)) changes.push({ kind: "additive", subject: "vocabulary", id, message: `Vocabulary "${id}" was added.` });
76
+ }
77
+
78
+ function compareTypes(previous: readonly DomainTypeDefinition[], next: readonly DomainTypeDefinition[], changes: DomainModelChange[]): void {
79
+ const before = mapById(previous);
80
+ const after = mapById(next);
81
+ for (const [id, type] of before) {
82
+ const replacement = after.get(id);
83
+ if (replacement === undefined) changes.push({ kind: "breaking", subject: "type", id, message: `Type "${id}" was removed.` });
84
+ else compareFields(type.fields ?? [], replacement.fields ?? [], "field", id, changes);
85
+ }
86
+ for (const [id] of after) if (!before.has(id)) changes.push({ kind: "additive", subject: "type", id, message: `Type "${id}" was added.` });
87
+ }
88
+
89
+ function compareRelations(previous: readonly RelationDefinition[], next: readonly RelationDefinition[], changes: DomainModelChange[]): void {
90
+ const before = mapById(previous);
91
+ const after = mapById(next);
92
+ for (const [id, relation] of before) {
93
+ const replacement = after.get(id);
94
+ if (replacement === undefined) {
95
+ changes.push({ kind: "breaking", subject: "relation", id, message: `Relation "${id}" was removed.` });
96
+ continue;
97
+ }
98
+ if (relation.from !== replacement.from || relation.to !== replacement.to) changes.push({ kind: "breaking", subject: "relation", id, message: `Relation "${id}" changed an endpoint.` });
99
+ if (relation.cardinality !== replacement.cardinality) changes.push({ kind: "breaking", subject: "relation", id, message: `Relation "${id}" changed cardinality.` });
100
+ compareFields(relation.properties ?? [], replacement.properties ?? [], "relation-property", id, changes);
101
+ }
102
+ for (const [id] of after) if (!before.has(id)) changes.push({ kind: "additive", subject: "relation", id, message: `Relation "${id}" was added.` });
103
+ }
104
+
105
+ /**
106
+ * Compares actual model content. Labels and `schemaVersion` are intentionally
107
+ * not compatibility surface; stable identifiers and structural contracts are.
108
+ */
109
+ export function compareDomainModels(previous: DomainModelDefinition, next: DomainModelDefinition): DomainModelCompatibilityReport {
110
+ const previousFindings = validateDomainModel(previous);
111
+ const nextFindings = validateDomainModel(next);
112
+ if (previousFindings.some((entry) => entry.severity === "error") || nextFindings.some((entry) => entry.severity === "error")) {
113
+ return { compatible: false, changes: [], previousFindings, nextFindings };
114
+ }
115
+ const before: DomainModel = normalizeDomainModel(previous);
116
+ const after: DomainModel = normalizeDomainModel(next);
117
+ const changes: DomainModelChange[] = [];
118
+
119
+ if (before.id !== after.id) changes.push({ kind: "breaking", subject: "model", id: after.id, message: `Model id changed from "${before.id}" to "${after.id}".` });
120
+ compareValueTypes(before.valueTypes, after.valueTypes, changes);
121
+ compareVocabularies(before.vocabularies, after.vocabularies, changes);
122
+ compareTypes(before.types, after.types, changes);
123
+ compareRelations(before.relations, after.relations, changes);
124
+
125
+ changes.sort((left, right) => stable(left).localeCompare(stable(right)));
126
+ return {
127
+ compatible: changes.every((entry) => entry.kind !== "breaking"),
128
+ changes,
129
+ previousFindings,
130
+ nextFindings,
131
+ };
132
+ }
@@ -0,0 +1,35 @@
1
+ import type { DomainModel, DomainModelDefinition, DomainTypeDefinition, FieldDefinition, RelationDefinition, ValueTypeDefinition, VocabularyDefinition } from "./types.js";
2
+
3
+ function copyField(field: FieldDefinition): FieldDefinition {
4
+ return { ...field, required: field.required === true };
5
+ }
6
+
7
+ function copyType(type: DomainTypeDefinition): DomainTypeDefinition {
8
+ return { ...type, fields: (type.fields ?? []).map(copyField) };
9
+ }
10
+
11
+ function copyRelation(relation: RelationDefinition): RelationDefinition {
12
+ return { ...relation, properties: (relation.properties ?? []).map(copyField) };
13
+ }
14
+
15
+ /**
16
+ * Creates a detached model value for authoring and later validation. This
17
+ * function deliberately does not claim the definition is valid; call
18
+ * `validateDomainModel` against the returned value before consuming it.
19
+ */
20
+ export function defineDomainModel(definition: DomainModelDefinition): DomainModel {
21
+ const valueTypes: ValueTypeDefinition[] = (definition.valueTypes ?? []).map((valueType) => ({ ...valueType }));
22
+ const vocabularies: VocabularyDefinition[] = (definition.vocabularies ?? []).map((vocabulary) => ({
23
+ ...vocabulary,
24
+ values: [...vocabulary.values],
25
+ }));
26
+
27
+ return {
28
+ id: definition.id,
29
+ schemaVersion: definition.schemaVersion,
30
+ valueTypes,
31
+ vocabularies,
32
+ types: (definition.types ?? []).map(copyType),
33
+ relations: (definition.relations ?? []).map(copyRelation),
34
+ };
35
+ }
@@ -0,0 +1,29 @@
1
+ /** Dependency-free machinery for product-owned domain models, never product values. */
2
+ export { defineDomainModel } from "./define.js";
3
+ export { normalizeDomainModel, serializeDomainModel } from "./normalize.js";
4
+ export { validateDomainModel } from "./validate.js";
5
+ export { compareDomainModels } from "./compatibility.js";
6
+ export { defineDomainSnapshot, normalizeDomainSnapshot, serializeDomainSnapshot, validateDomainSnapshot } from "./snapshot.js";
7
+ export { PRIMITIVE_VALUE_TYPES, RELATION_CARDINALITIES } from "./types.js";
8
+ export type {
9
+ DomainModel,
10
+ DomainModelChange,
11
+ DomainModelCompatibilityReport,
12
+ DomainModelDefinition,
13
+ DomainModelFinding,
14
+ DomainRecord,
15
+ DomainRecordDefinition,
16
+ DomainRelation,
17
+ DomainRelationDefinition,
18
+ DomainSnapshot,
19
+ DomainSnapshotDefinition,
20
+ DomainSnapshotFinding,
21
+ DomainTypeDefinition,
22
+ FieldDefinition,
23
+ FieldValueType,
24
+ PrimitiveValueType,
25
+ RelationCardinality,
26
+ RelationDefinition,
27
+ ValueTypeDefinition,
28
+ VocabularyDefinition,
29
+ } from "./types.js";