@elevasis/core 0.38.0 → 0.39.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/core",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "license": "MIT",
5
5
  "description": "Minimal shared constants across Elevasis monorepo",
6
6
  "sideEffects": false,
@@ -23,6 +23,7 @@ import {
23
23
  computeInterfaceReadiness,
24
24
  type SystemInterfaceReadinessIssueFamily
25
25
  } from '../../business/acquisition/ontology-validation'
26
+ import { SYSTEM_INTERFACE_PROFILES } from '../../organization-model/domains/systems'
26
27
  import type { OmTopologyNodeRef } from '../../organization-model/domains/topology'
27
28
  import type {
28
29
  TriggerDefinition,
@@ -615,20 +616,28 @@ function addSystemInterfaceIssue(
615
616
 
616
617
  /**
617
618
  * Detects systems that are API-backed (have resources with non-empty ontology
618
- * bindings) but have not declared `apiInterface` in the Organization Model.
619
+ * bindings), CAN adopt a platform-cataloged `apiInterface` readinessProfile
620
+ * (system path appears in `SYSTEM_INTERFACE_PROFILES`), but have not declared
621
+ * `apiInterface` in the Organization Model.
619
622
  *
620
- * Broad-by-design tighten via test-driven counterexample.
621
- * See _execution-plan.mdx Decision 1.
623
+ * Originally broad-by-design (flagged any system with ontology actions/writes
624
+ * lacking apiInterface). Tightened in @elevasis/sdk@1.30.1 after the template
625
+ * surfaced the unactionable-paradox case: custom systems (e.g. `sys.operations`,
626
+ * `sys.notifications`) have valid `ontology.actions` bindings but cannot adopt
627
+ * one of the closed-catalog readiness profiles, AND the documented guidance
628
+ * ("Custom Systems should not declare apiInterface") is incompatible with the
629
+ * broad heuristic. The gate now only flags systems where adoption is even
630
+ * possible — i.e. the system path matches a cataloged profile's `systemPath`.
622
631
  *
623
- * A system is flagged when:
632
+ * A system is flagged when ALL of:
624
633
  * (a) `system.apiInterface === undefined`, AND
625
634
  * (b) at least one resource in `organizationModel.resources` has
626
635
  * `resource.systemPath` matching the system path AND
627
- * `resource.ontology` non-empty (has `actions` and/or `writes` defined).
636
+ * `resource.ontology` non-empty (has `actions` and/or `writes` defined), AND
637
+ * (c) the system path appears as a cataloged `systemPath` in
638
+ * `SYSTEM_INTERFACE_PROFILES` (so adopting a profile is actually possible).
628
639
  *
629
640
  * Returns `[]` when `organizationModel` is undefined or no gaps are found.
630
- * The structured return value drives both CLI warnings and scaffold fill-mode
631
- * input payloads without any transformation on the caller side.
632
641
  */
633
642
  export function detectMissingApiInterfaceDeclarations(
634
643
  orgName: string,
@@ -655,10 +664,15 @@ export function detectMissingApiInterfaceDeclarations(
655
664
 
656
665
  if (apiBoundResourcesBySystemPath.size === 0) return []
657
666
 
667
+ // Closed-catalog filter: a system is only a candidate for missing apiInterface
668
+ // if it could actually adopt one of the cataloged platform profiles.
669
+ const catalogedSystemPaths = new Set<string>(SYSTEM_INTERFACE_PROFILES.map((profile) => profile.systemPath))
670
+
658
671
  const gaps: ApiInterfaceConformanceGap[] = []
659
672
 
660
673
  for (const { path, system } of listAllSystems(organizationModel)) {
661
674
  if (system.apiInterface !== undefined) continue
675
+ if (!catalogedSystemPaths.has(path)) continue
662
676
  const resourceIds = apiBoundResourcesBySystemPath.get(path)
663
677
  if (!resourceIds || resourceIds.length === 0) continue
664
678
  gaps.push({