arkgate 2.12.0 → 2.13.0

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 (70) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +55 -31
  3. package/bin/ark-check.mjs +95 -36
  4. package/bin/ark-mcp.mjs +11 -5
  5. package/bin/ark-shared.mjs +88 -56
  6. package/bin/ark.mjs +45 -10
  7. package/bin/lib/agent-gates.mjs +12 -0
  8. package/bin/lib/architecture-scan.mjs +8 -0
  9. package/bin/lib/ci-and-commands.mjs +9 -3
  10. package/bin/lib/codex-home.mjs +7 -0
  11. package/bin/lib/config-contract.mjs +331 -0
  12. package/bin/lib/doctor-plan.mjs +43 -16
  13. package/bin/lib/enforcement-profiles.mjs +97 -0
  14. package/bin/lib/host-support-matrix.mjs +77 -0
  15. package/bin/lib/install-migrate.mjs +45 -14
  16. package/bin/lib/mcp-adoption.mjs +35 -3
  17. package/bin/lib/open-html.mjs +75 -0
  18. package/bin/lib/presets.mjs +3 -2
  19. package/bin/lib/safety-diagnostics.mjs +31 -11
  20. package/bin/lib/skill-install.mjs +64 -0
  21. package/bin/lib/ts-resolve.mjs +2 -1
  22. package/bin/lib/weakest-link.mjs +417 -0
  23. package/bin/lib/write-path-capabilities.mjs +182 -0
  24. package/bin/lib/write-path-detect.mjs +62 -99
  25. package/dist/configContract-iBLxx5Tz.d.cts +53 -0
  26. package/dist/configContract-iBLxx5Tz.d.ts +53 -0
  27. package/dist/eslint/index.cjs +375 -13
  28. package/dist/eslint/index.cjs.map +1 -1
  29. package/dist/eslint/index.d.cts +30 -20
  30. package/dist/eslint/index.d.ts +30 -20
  31. package/dist/eslint/index.js +375 -13
  32. package/dist/eslint/index.js.map +1 -1
  33. package/dist/index.cjs +723 -61
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +95 -5
  36. package/dist/index.d.ts +95 -5
  37. package/dist/index.js +716 -61
  38. package/dist/index.js.map +1 -1
  39. package/dist/nestjs/index.cjs +150 -42
  40. package/dist/nestjs/index.cjs.map +1 -1
  41. package/dist/nestjs/index.d.cts +2 -1
  42. package/dist/nestjs/index.d.ts +2 -1
  43. package/dist/nestjs/index.js +150 -42
  44. package/dist/nestjs/index.js.map +1 -1
  45. package/dist/runtime/index.cjs +723 -61
  46. package/dist/runtime/index.cjs.map +1 -1
  47. package/dist/runtime/index.d.cts +3 -2
  48. package/dist/runtime/index.d.ts +3 -2
  49. package/dist/runtime/index.js +716 -61
  50. package/dist/runtime/index.js.map +1 -1
  51. package/dist/{types-BZ17b9i5.d.cts → types-BxBwnBpC.d.cts} +9 -36
  52. package/dist/{types-BZ17b9i5.d.ts → types-Wcs_l1_J.d.ts} +9 -36
  53. package/docs/agent-guide.md +32 -20
  54. package/docs/ai-gates.md +53 -18
  55. package/docs/configuration.md +97 -0
  56. package/docs/enthusiast/README.md +3 -3
  57. package/docs/enthusiast/how-to-agent-gates.md +7 -3
  58. package/docs/migrate-from-ark-runtime-kernel.md +3 -0
  59. package/docs/package-surface.md +14 -9
  60. package/docs/production-hardening.md +15 -2
  61. package/docs/threat-model.md +65 -0
  62. package/docs/typescript-support.md +3 -3
  63. package/package.json +15 -2
  64. package/schemas/ark.config.schema.json +750 -0
  65. package/server.json +2 -2
  66. package/templates/hooks/pre-commit-ark +37 -0
  67. package/templates/skills/ark-coverage.md +2 -2
  68. package/templates/skills/ark-runtime.md +8 -5
  69. package/templates/skills/ark-upgrade.md +36 -16
  70. package/tests/fixtures/ts-consumer/ark.config.json +2 -0
@@ -1,5 +1,6 @@
1
1
  import { DynamicModule, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
2
- import { A as ArkKernel, C as CreateArkKernelOptions } from '../types-BZ17b9i5.cjs';
2
+ import { A as ArkKernel, C as CreateArkKernelOptions } from '../types-BxBwnBpC.cjs';
3
+ import '../configContract-iBLxx5Tz.cjs';
3
4
 
4
5
  /** Injection token for the Ark kernel instance. */
5
6
  declare const ARK_KERNEL: unique symbol;
@@ -1,5 +1,6 @@
1
1
  import { DynamicModule, InjectionToken, OptionalFactoryDependency } from '@nestjs/common';
2
- import { A as ArkKernel, C as CreateArkKernelOptions } from '../types-BZ17b9i5.js';
2
+ import { A as ArkKernel, C as CreateArkKernelOptions } from '../types-Wcs_l1_J.js';
3
+ import '../configContract-iBLxx5Tz.js';
3
4
 
4
5
  /** Injection token for the Ark kernel instance. */
5
6
  declare const ARK_KERNEL: unique symbol;
@@ -1648,6 +1648,138 @@ function createIntentRegistry() {
1648
1648
  return new IntentRegistry();
1649
1649
  }
1650
1650
 
1651
+ // src/domain/configContract.ts
1652
+ var ARK_CONFIG_SCHEMA_VERSION = "1.0";
1653
+ var ARK_CONFIG_SCHEMA_URL = "https://unpkg.com/arkgate@2/schemas/ark.config.schema.json";
1654
+ var DEFAULT_LAYER_NAMES = [
1655
+ "DomainModel",
1656
+ "ApplicationOrchestration",
1657
+ "PersistenceAdapters",
1658
+ "IntegrationAdapters",
1659
+ "WorkflowSagaEngine",
1660
+ "BackgroundJobsScheduling",
1661
+ "PresentationAdapters",
1662
+ "ReportingReadModels",
1663
+ "ExtensibilityMetadata",
1664
+ "SecurityAuditObservability",
1665
+ "Kernel"
1666
+ ];
1667
+ var DEFAULT_ALLOWED_FLOWS = /* @__PURE__ */ new Set([
1668
+ "PresentationAdapters->ApplicationOrchestration",
1669
+ "ApplicationOrchestration->DomainModel",
1670
+ "WorkflowSagaEngine->ApplicationOrchestration",
1671
+ "WorkflowSagaEngine->DomainModel",
1672
+ "BackgroundJobsScheduling->ApplicationOrchestration"
1673
+ ]);
1674
+ function createDefaultRules() {
1675
+ const rules = [];
1676
+ for (const from of DEFAULT_LAYER_NAMES) {
1677
+ for (const to of DEFAULT_LAYER_NAMES) {
1678
+ if (from === to || DEFAULT_ALLOWED_FLOWS.has(`${from}->${to}`)) continue;
1679
+ rules.push({ from, to, allowed: false });
1680
+ }
1681
+ }
1682
+ return rules;
1683
+ }
1684
+ var DEFAULT_ARK_CONFIG_RULES = createDefaultRules();
1685
+ var stringArraySchema = {
1686
+ type: "array",
1687
+ items: { type: "string", minLength: 1 },
1688
+ uniqueItems: true
1689
+ };
1690
+ var ARK_CONFIG_SCHEMA = {
1691
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1692
+ $id: ARK_CONFIG_SCHEMA_URL,
1693
+ title: "ArkGate architecture contract",
1694
+ description: "Versioned contract consumed identically by ArkGate CLI, MCP, and ESLint surfaces.",
1695
+ type: "object",
1696
+ additionalProperties: false,
1697
+ required: ["$schema", "schemaVersion", "include", "layers", "rules"],
1698
+ properties: {
1699
+ $schema: {
1700
+ type: "string",
1701
+ minLength: 1,
1702
+ default: ARK_CONFIG_SCHEMA_URL,
1703
+ description: "Editor-facing URL or local path for this JSON Schema."
1704
+ },
1705
+ schemaVersion: {
1706
+ type: "string",
1707
+ const: ARK_CONFIG_SCHEMA_VERSION,
1708
+ default: ARK_CONFIG_SCHEMA_VERSION
1709
+ },
1710
+ name: { type: "string", minLength: 1 },
1711
+ include: { ...stringArraySchema, minItems: 1, default: ["src"] },
1712
+ exclude: { ...stringArraySchema, default: [] },
1713
+ excludeGenerated: { type: "boolean", default: true },
1714
+ frameworkOverlay: { type: "string", minLength: 1 },
1715
+ layers: {
1716
+ type: "array",
1717
+ default: [],
1718
+ items: { $ref: "#/$defs/layer" }
1719
+ },
1720
+ rules: {
1721
+ type: "array",
1722
+ default: DEFAULT_ARK_CONFIG_RULES,
1723
+ items: { $ref: "#/$defs/rule" }
1724
+ },
1725
+ cyclePolicy: {
1726
+ type: "string",
1727
+ enum: ["strict", "soft", "framework-soft", "off"],
1728
+ default: "strict"
1729
+ },
1730
+ dynamicImportAllowlist: { ...stringArraySchema, default: [] },
1731
+ safety: {
1732
+ $ref: "#/$defs/safety",
1733
+ default: {
1734
+ maxTsSuppressions: 0,
1735
+ maxAnyCasts: 0,
1736
+ allowInMemory: false,
1737
+ allowDisabledPeerIsolation: false
1738
+ }
1739
+ }
1740
+ },
1741
+ $defs: {
1742
+ layer: {
1743
+ type: "object",
1744
+ additionalProperties: false,
1745
+ required: ["name", "patterns"],
1746
+ properties: {
1747
+ name: { type: "string", minLength: 1 },
1748
+ patterns: { ...stringArraySchema, minItems: 1 },
1749
+ exclude: stringArraySchema,
1750
+ intentPrefixes: stringArraySchema,
1751
+ description: { type: "string", minLength: 1 },
1752
+ forbiddenGlobals: stringArraySchema,
1753
+ mayImportInfrastructure: { type: "boolean" },
1754
+ optional: { type: "boolean" }
1755
+ }
1756
+ },
1757
+ rule: {
1758
+ type: "object",
1759
+ additionalProperties: false,
1760
+ required: ["from", "to", "allowed"],
1761
+ properties: {
1762
+ from: { type: "string", minLength: 1 },
1763
+ to: { type: "string", minLength: 1 },
1764
+ allowed: { type: "boolean" },
1765
+ message: { type: "string", minLength: 1 },
1766
+ peerIsolation: { type: "boolean" },
1767
+ sliceFolders: { ...stringArraySchema, minItems: 1 }
1768
+ }
1769
+ },
1770
+ safety: {
1771
+ type: "object",
1772
+ additionalProperties: false,
1773
+ properties: {
1774
+ maxTsSuppressions: { type: "integer", minimum: 0, default: 0 },
1775
+ maxAnyCasts: { type: "integer", minimum: 0, default: 0 },
1776
+ allowInMemory: { type: "boolean", default: false },
1777
+ allowDisabledPeerIsolation: { type: "boolean", default: false }
1778
+ }
1779
+ }
1780
+ }
1781
+ };
1782
+
1651
1783
  // src/kernel/layers/ArchitectureProfile.ts
1652
1784
  function normalizePrefix(prefix) {
1653
1785
  return prefix.endsWith(".") ? prefix : `${prefix}.`;
@@ -1657,21 +1789,6 @@ function byLongestPrefix(a, b) {
1657
1789
  const maxB = b.prefixes.length ? Math.max(...b.prefixes.map((p) => p.length)) : 0;
1658
1790
  return maxB - maxA;
1659
1791
  }
1660
- function flowKey(from, to) {
1661
- return `${from}->${to}`;
1662
- }
1663
- function createStrictDenyRules(layers, allowedFlows) {
1664
- const allowed = new Set(allowedFlows.map((flow) => flowKey(flow.from, flow.to)));
1665
- const rules = [];
1666
- for (const from of layers) {
1667
- for (const to of layers) {
1668
- if (from.name === to.name) continue;
1669
- if (allowed.has(flowKey(from.name, to.name))) continue;
1670
- rules.push({ from: from.name, to: to.name, allowed: false });
1671
- }
1672
- }
1673
- return rules;
1674
- }
1675
1792
  function createArchitectureProfile(options) {
1676
1793
  const layers = options.layers.map((layer) => ({
1677
1794
  ...layer,
@@ -1758,27 +1875,17 @@ var elevenLayerProfileLayers = [
1758
1875
  order: 11
1759
1876
  }
1760
1877
  ];
1761
- var elevenLayerAllowedFlows = [
1762
- { from: "PresentationAdapters", to: "ApplicationOrchestration" },
1763
- { from: "ApplicationOrchestration", to: "DomainModel" },
1764
- { from: "WorkflowSagaEngine", to: "ApplicationOrchestration" },
1765
- { from: "WorkflowSagaEngine", to: "DomainModel" },
1766
- { from: "BackgroundJobsScheduling", to: "ApplicationOrchestration" }
1767
- ];
1768
1878
  var elevenLayerProfile = createArchitectureProfile({
1769
1879
  name: "Ark 11-layer Hexagonal Event-Driven Profile",
1770
1880
  layers: elevenLayerProfileLayers,
1771
- rules: createStrictDenyRules(
1772
- elevenLayerProfileLayers,
1773
- elevenLayerAllowedFlows
1774
- )
1881
+ rules: DEFAULT_ARK_CONFIG_RULES.map((rule) => ({ ...rule }))
1775
1882
  });
1776
1883
 
1777
1884
  // src/kernel/manifest/constants.ts
1778
1885
  var MANIFEST_SCHEMA_VERSION = "1.0";
1779
1886
 
1780
1887
  // src/version.ts
1781
- var version = "2.12.0";
1888
+ var version = "2.13.0";
1782
1889
 
1783
1890
  // src/kernel/manifest/createArkManifest.ts
1784
1891
  function policyId(name) {
@@ -1914,14 +2021,14 @@ function createMetadataRegistry() {
1914
2021
  }
1915
2022
 
1916
2023
  // src/kernel/observability/ObservabilityReporter.ts
1917
- function flowKey2(flow) {
2024
+ function flowKey(flow) {
1918
2025
  return `${flow.from}->${flow.to}`;
1919
2026
  }
1920
2027
  function uniqueFlows(flows) {
1921
2028
  const seen = /* @__PURE__ */ new Set();
1922
2029
  const result = [];
1923
2030
  for (const flow of flows) {
1924
- const key = flowKey2(flow);
2031
+ const key = flowKey(flow);
1925
2032
  if (seen.has(key)) continue;
1926
2033
  seen.add(key);
1927
2034
  result.push(flow);
@@ -1929,8 +2036,8 @@ function uniqueFlows(flows) {
1929
2036
  return result;
1930
2037
  }
1931
2038
  function difference(left, right) {
1932
- const rightKeys = new Set(right.map(flowKey2));
1933
- return left.filter((flow) => !rightKeys.has(flowKey2(flow)));
2039
+ const rightKeys = new Set(right.map(flowKey));
2040
+ return left.filter((flow) => !rightKeys.has(flowKey(flow)));
1934
2041
  }
1935
2042
  function createObservabilityReporter(options) {
1936
2043
  const registry = options.registry;
@@ -2275,22 +2382,13 @@ var WorkflowEngineImpl = class {
2275
2382
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
2276
2383
  snapshot.attempts[step.name] = attempt;
2277
2384
  await this.store.save(snapshot);
2385
+ let result;
2278
2386
  try {
2279
- const result = await withTimeout(
2387
+ result = await withTimeout(
2280
2388
  (signal) => Promise.resolve(step.execute(snapshot.context, this.bus, signal)),
2281
2389
  step.timeoutMs,
2282
2390
  step.name
2283
2391
  );
2284
- if (result) Object.assign(snapshot.context, result);
2285
- snapshot.completedSteps.push(step.name);
2286
- snapshot.currentStep = void 0;
2287
- snapshot.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2288
- await this.store.save(snapshot);
2289
- await this.audit("workflow.step.completed", snapshot, {
2290
- step: step.name,
2291
- attempt
2292
- });
2293
- return;
2294
2392
  } catch (err) {
2295
2393
  if (attempt < maxAttempts) {
2296
2394
  if (retry.delayMs) await sleep(retry.delayMs);
@@ -2306,6 +2404,16 @@ var WorkflowEngineImpl = class {
2306
2404
  });
2307
2405
  throw err;
2308
2406
  }
2407
+ if (result) Object.assign(snapshot.context, result);
2408
+ snapshot.completedSteps.push(step.name);
2409
+ snapshot.currentStep = void 0;
2410
+ snapshot.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2411
+ await this.store.save(snapshot);
2412
+ await this.audit("workflow.step.completed", snapshot, {
2413
+ step: step.name,
2414
+ attempt
2415
+ });
2416
+ return;
2309
2417
  }
2310
2418
  throw new Error(`Workflow step "${step.name}" did not complete.`);
2311
2419
  }