@intentius/chant-lexicon-k8s 0.66.0 → 0.67.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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * What this lexicon's entity types are worth to a behaviour engine (#2382).
3
+ *
4
+ * Contributed as rows through the plugin's `behaviourKinds` field; the
5
+ * vocabulary, the resolution and the prediction are
6
+ * `packages/core/src/behaviour-kinds.ts`. These rows were a section of one
7
+ * cross-lexicon table in one lexicon until #2382 moved each substrate's
8
+ * rows to the lexicon that owns the types — this file can say what
9
+ * `K8s::Apps::Deployment` means because it is the file that defines it.
10
+ *
11
+ * A table rather than a heuristic over type names: a heuristic would map
12
+ * `K8s::Rbac::RoleBinding` to storage and price a join table.
13
+ */
14
+ import type { BehaviourKinds } from "@intentius/chant/behaviour-kinds";
15
+ /** This lexicon's answer for its own types. */
16
+ export declare const k8sBehaviourKinds: BehaviourKinds;
17
+ //# sourceMappingURL=behaviour-kinds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behaviour-kinds.d.ts","sourceRoot":"","sources":["../src/behaviour-kinds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAmEvE,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB,EAAE,cAK/B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "8e1c655cc0e915dc9e60dad3cc82afde1fcfadd3440e79fb41b0ce2b51ed0f49",
4
+ "manifest.json": "3e4ee481a4be4a337c58ca4a06ba98b3ed4ee9f12aa81c957180ec72e57cec15",
5
5
  "meta.json": "8b999bc142f448b0b627ecdc9e2388bbe672c8a1f7aae5303135624cf2fe65e3",
6
6
  "types/index.d.ts": "5f67de738adb455805e72600948940af9c664283785fb68c9fd8f5ea90d42cc3",
7
7
  "rules/argo-appset-single-project.ts": "afa9f310753aa2d475f35012b13135b2dfaebed2a35d44edbe185ebc07673674",
@@ -65,5 +65,5 @@
65
65
  "skills/chant-k8s-argo.md": "24c9a85b78a2fc5c6657424baac9cc6d6caff6f47605b8146b2c0082133181cf",
66
66
  "skills/chant-k8s-flux.md": "9670efc2e9854bd14686b5adeb707396b9030a4dcaee6529b30abf56efe2c50c"
67
67
  },
68
- "composite": "30dec82ae0a163081c8468b9fe1d1917ff1d619e04aba3e55fab727106e09d32"
68
+ "composite": "b9cd56cc20464e4184740cb345c6fc86bcdd80cf46a1bba487a8d0cf75e37746"
69
69
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k8s",
3
- "version": "0.66.0",
3
+ "version": "0.67.0",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "K8s",
6
6
  "intrinsics": [],
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AA6BjG,eAAO,MAAM,SAAS,EAAE,aA6tBvB,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AA8BjG,eAAO,MAAM,SAAS,EAAE,aA8tBvB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-k8s",
3
- "version": "0.66.0",
3
+ "version": "0.67.0",
4
4
  "description": "Kubernetes lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -76,7 +76,7 @@
76
76
  "@types/js-yaml": "^4.0.9"
77
77
  },
78
78
  "optionalDependencies": {
79
- "@intentius/chant-k8s-client": "^0.66.0"
79
+ "@intentius/chant-k8s-client": "^0.67.0"
80
80
  },
81
81
  "devDependencies": {
82
82
  "@intentius/chant": "*",
@@ -84,7 +84,7 @@
84
84
  },
85
85
  "peerDependencies": {
86
86
  "zod": "^4.3.6",
87
- "@intentius/chant": "^0.66.0",
87
+ "@intentius/chant": "^0.67.0",
88
88
  "typescript": "^5.9.3"
89
89
  }
90
90
  }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * What this lexicon's entity types are worth to a behaviour engine (#2382).
3
+ *
4
+ * Contributed as rows through the plugin's `behaviourKinds` field; the
5
+ * vocabulary, the resolution and the prediction are
6
+ * `packages/core/src/behaviour-kinds.ts`. These rows were a section of one
7
+ * cross-lexicon table in one lexicon until #2382 moved each substrate's
8
+ * rows to the lexicon that owns the types — this file can say what
9
+ * `K8s::Apps::Deployment` means because it is the file that defines it.
10
+ *
11
+ * A table rather than a heuristic over type names: a heuristic would map
12
+ * `K8s::Rbac::RoleBinding` to storage and price a join table.
13
+ */
14
+
15
+ import type { BehaviourKinds } from "@intentius/chant/behaviour-kinds";
16
+
17
+ /** Types an engine prices, with the declared property its size is read from. */
18
+ const MAPPED: BehaviourKinds["mapped"] = {
19
+
20
+ // No `sizeProp` on the five workload kinds. A workload's size is its pod
21
+ // template's container resource requests — an object, per container, over an
22
+ // array — and this contract's `size` is one string in the provider's own
23
+ // vocabulary. Kubernetes has no such string for a workload. Naming
24
+ // `spec.template.spec.containers` here, as the first version did, advertised
25
+ // a column that resolved to an array and therefore to nothing, on every
26
+ // Kubernetes workload in the repository.
27
+ "K8s::Apps::Deployment": { kind: "compute" },
28
+ "K8s::Apps::StatefulSet": { kind: "compute" },
29
+ "K8s::Apps::DaemonSet": { kind: "compute" },
30
+ "K8s::Core::Pod": { kind: "compute" },
31
+ "K8s::Batch::Job": { kind: "serverless" },
32
+ "K8s::Batch::CronJob": { kind: "serverless" },
33
+ // These two do state a size, as a single string in Kubernetes' own
34
+ // vocabulary: a quantity (`20Gi`) and a service type (`LoadBalancer`).
35
+ "K8s::Core::PersistentVolumeClaim": { kind: "block-store", sizeProp: "spec.resources.requests.storage", sizeType: "string" },
36
+ "K8s::Core::Service": { kind: "load-balancer", sizeProp: "spec.type", sizeType: "string" },
37
+ "K8s::Networking::Ingress": { kind: "load-balancer" },
38
+ };
39
+
40
+ /**
41
+ * Types considered and declared unsendable, each with the reason it carries no
42
+ * rate. The fifth family core's contributor guidance names is this lexicon's
43
+ * own: a controller's request is not the thing it creates. A `Certificate`
44
+ * costs nothing; the issuer's work and the Secret it writes are elsewhere in
45
+ * the graph or outside the cluster entirely.
46
+ */
47
+ const UNMAPPED: BehaviourKinds["unmapped"] = {
48
+ "K8s::Rbac::Role": "an RBAC role is a grant; the workloads it admits are what cost and saturate",
49
+ "K8s::Rbac::RoleBinding": "an RBAC binding is a grant; the workloads it admits are what cost and saturate",
50
+ "K8s::Rbac::ClusterRole": "the cluster-scoped twin of an RBAC role, and a grant for the same reason",
51
+ "K8s::Rbac::ClusterRoleBinding": "the cluster-scoped twin of an RBAC binding, and a grant for the same reason",
52
+ "K8s::Core::ServiceAccount": "an identity, not a workload",
53
+ "K8s::Core::Namespace": "a boundary the workloads sit inside, and the workloads carry the figures",
54
+ "K8s::Networking::IngressClass": "names which controller handles an Ingress; the controller and the load balancer it creates carry the figures",
55
+ "K8s::Networking::NetworkPolicy": "a filter on edges that already exist, not a thing at either end of one",
56
+ "K8s::Storage::StorageClass": "the kind of disk a claim may ask for; the PersistentVolumeClaim carries the figures",
57
+ "K8s::Autoscaling::HorizontalPodAutoscaler": "an instruction about how many replicas to run; the workload it scales carries the figures, and a prediction is at one stated traffic level rather than across a scaling range",
58
+ "K8s::HorizontalPodAutoscaler": "an instruction about how many replicas to run; the workload it scales carries the figures, and a prediction is at one stated traffic level rather than across a scaling range",
59
+ "K8s::Policy::PodDisruptionBudget": "a constraint on voluntary eviction. It shapes what a lost zone does to a workload and has no rate of its own; expressing that constraint to an engine is a resilience input this contract has no field for",
60
+ "K8s::Core::LimitRange": "a default and a ceiling for workloads in a namespace; the workloads carry the figures",
61
+ "K8s::Core::ResourceQuota": "a ceiling on a namespace's total requests; the workloads under it carry the figures",
62
+ // ── A controller's request is not the thing it creates ───────────
63
+ "K8s::Argo::Application": "a request to Argo CD to reconcile a source; whatever it creates is priced where that lands",
64
+ "K8s::Flux::GitRepository": "a source Flux polls; the workloads it reconciles carry the figures",
65
+ "K8s::Flux::Kustomization": "a request to Flux to apply a source; whatever it creates is priced where that lands",
66
+ "K8s::CertManager::Certificate": "a request to an issuer. The certificate costs nothing; the issuer's work and the Secret it writes are elsewhere",
67
+ "K8s::CertManager::ClusterIssuer": "the issuer a certificate request names; it holds no capacity and serves no traffic",
68
+ "K8s::ExternalSecrets::ExternalSecret": "a request to copy a value from an external store into a Secret; neither end is a rate",
69
+ "K8s::ExternalSecrets::ClusterSecretStore": "names where secrets are fetched from; it holds no capacity and serves no traffic",
70
+ "K8s::Monitoring::ServiceMonitor": "tells Prometheus what to scrape; Prometheus is a workload elsewhere in the graph and carries the figures",
71
+ "K8s::Monitoring::PrometheusRule": "alerting and recording rules evaluated by Prometheus, which carries the figures",
72
+ "K8s::Traefik::IngressRoute": "routing handled by the Traefik workload, which carries the figures",
73
+ "K8s::Calico::FelixConfiguration": "tuning for the CNI agent on every node; the nodes carry the figures",
74
+ "K8s::GKE::BackendConfig": "tuning for a Google load balancer an Ingress creates; the gcp substrate is not modelled here, so neither end is priced here",
75
+ "K8s::NetworkingGKE::ManagedCertificate": "a certificate Google issues for an Ingress; the gcp substrate is not modelled here",
76
+ "K8s::NetworkingGKEBeta::FrontendConfig": "tuning for a Google load balancer an Ingress creates; the gcp substrate is not modelled here",
77
+ // ── Configuration and secrets: real, declared, carrying no rate ──
78
+ "K8s::Core::ConfigMap": "configuration the workloads read; it has no rate and no saturation axis of its own",
79
+ "K8s::Core::Secret": "configuration the workloads read; it has no rate and no saturation axis of its own",
80
+ };
81
+
82
+ /** This lexicon's answer for its own types. */
83
+ export const k8sBehaviourKinds: BehaviourKinds = {
84
+ provider: "kubernetes",
85
+ prefixes: ["K8s::"],
86
+ mapped: MAPPED,
87
+ unmapped: UNMAPPED,
88
+ };
package/src/plugin.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import type { LexiconPlugin, InitTemplateSet, ResourceMetadata } from "@intentius/chant/lexicon";
9
+ import { k8sBehaviourKinds } from "./behaviour-kinds";
9
10
  import type { CommandGroup } from "@intentius/chant/cli/command-group";
10
11
  import { kubeCommandGroup } from "./kube/group";
11
12
  import { detectTemplate } from "./detect";
@@ -35,6 +36,7 @@ import { encryptedSecretBuildRoot } from "./sops/encrypted-secret-file";
35
36
  import type { Declarable } from "@intentius/chant/declarable";
36
37
 
37
38
  export const k8sPlugin: LexiconPlugin = {
39
+ behaviourKinds: k8sBehaviourKinds,
38
40
  name: "k8s",
39
41
  ownershipChannel: { keys: LABEL_OWNERSHIP_KEYS, reads: ["describeResources", "observeResourcesDeep", "exportResources"] },
40
42
  configSchema: k8sConfigSchema,