@meada/meada 1.2.0 → 1.3.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/CHANGELOG.md +706 -1
- package/README.md +3 -3
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,710 @@ All notable changes to Meada are recorded here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.3.0] - 2026-11-11
|
|
10
|
+
|
|
11
|
+
A minor release on the [1.x stability promise](https://github.com/ClaudioMascaro/meada/blob/main/docs/site/en/stability.md):
|
|
12
|
+
infrastructure joins the graph. Config values and IaC nodes (ADR 0025) are read from Terraform and
|
|
13
|
+
OpenTofu (HCL and JSON, with static evaluation of names), Compose, CloudFormation and SAM,
|
|
14
|
+
Serverless Framework, Kubernetes with Kustomize, and Crossplane, and answer to the new `search`
|
|
15
|
+
kinds `value` and `iac` (`image` and `alert` join for their contracts). Infrastructure contracts (ADR 0026) link the code that uses a queue, a
|
|
16
|
+
topic, a bucket, a table, a parameter or a secret to what provisions it on AWS, GCP and Azure,
|
|
17
|
+
through SDK use sides in TypeScript, JavaScript, Python, Java, Go and C#, with orphan reports in
|
|
18
|
+
`meada status`. Image contracts link builders to runners, workloads carry their environments to the
|
|
19
|
+
code they run, alert contracts link rule labels to Alertmanager routes and Datadog
|
|
20
|
+
monitor tags to OpsGenie routing, and HTTP gains route
|
|
21
|
+
providers declared in IaC and base URLs followed through Kubernetes Services, Ingresses and Compose.
|
|
22
|
+
The console graph shows the new roles, a refresh reads unchanged values from a cache beside the
|
|
23
|
+
index (`values.db`, ADR 0027), and `meada mcp` answers calls sent without waiting for each reply
|
|
24
|
+
(#704). The index schema changes, so existing indexes are rebuilt once on first use; export format
|
|
25
|
+
stays 1 and gains optional fields. `meada-core` 1.3.0 gives `ids::VersionEntry` a sixth element and
|
|
26
|
+
`ids::NON_BLOCK_KEYS` a fifth key (`added_by_time`, #454), `authorize::compose_entries` a `now`
|
|
27
|
+
parameter, `manifest::EntryFile` an `added_by_time` field and the export structs new fields.
|
|
28
|
+
Postgres migration 10 needs `meada postgres migrate` before 1.3.0 starts, and 1.2.0 binaries
|
|
29
|
+
refuse the migrated schema. The
|
|
30
|
+
entries below that name a release level were written while this release was in development. The
|
|
31
|
+
tree, the `meada-core` pin, the Dockerfile, the compose defaults and the Helm chart declare `1.3.0`,
|
|
32
|
+
and the `v1.3.0` tag goes on the `release/1.3` branch, cut from this entry's merge on main.
|
|
33
|
+
Publication (crates, the staged npm package, the GitHub draft release) belongs to the maintainer.
|
|
34
|
+
Release notes are available in
|
|
35
|
+
[pt-BR](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.3.0.md),
|
|
36
|
+
[English](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.3.0.en.md) and
|
|
37
|
+
[Spanish](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.3.0.es.md).
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- DynamoDB transactions in Java, Go and C# (#719): `TransactWriteItems` and `TransactGetItems`
|
|
42
|
+
give sides as they do in JavaScript and Python. Each `Put`, `Update` and `Delete` entry
|
|
43
|
+
writes its own table, each `ConditionCheck` and `Get` entry reads its own, with the literal
|
|
44
|
+
and environment rules of the other names. A list or an array of entries held in a name (in
|
|
45
|
+
Go and C#, a request, an item or an entry too) gives its tables only when its function
|
|
46
|
+
mentions the name twice, where it is declared and where the request reads it: any other
|
|
47
|
+
mention may change it, and one that comes in a parameter (in Java, a single entry too) gives
|
|
48
|
+
none. Every Java, Go and .NET AWS operation now has a test. Included in the 1.3.0 minor
|
|
49
|
+
release.
|
|
50
|
+
- Curated operators and private IaC mappings (#671): 43 explicit Strimzi, RabbitMQ Queue,
|
|
51
|
+
ACK, Config Connector and Crossplane AWS/GCP/Azure types provision existing contracts.
|
|
52
|
+
RabbitMQ Exchange/Binding topology routes real publishes to queues without inventing an
|
|
53
|
+
exchange channel. Six terraform-aws-modules sources read declared resource and Lambda/ECS
|
|
54
|
+
workload inputs; `meada.toml` maps exact/private source prefixes and custom group/kind key
|
|
55
|
+
paths to curated entries. Unknown identities and creation controls remain conservative.
|
|
56
|
+
This joins the existing 1.3.0 minor development release.
|
|
57
|
+
- IaC HTTP route providers (#666): Terraform/OpenTofu API Gateway HTTP/REST and explicit quick
|
|
58
|
+
create, SAM Api/HttpApi and Serverless http/httpApi events resolve to local handler symbols
|
|
59
|
+
or the repository, with normalized parameters, cross-repository HTTP links and stored
|
|
60
|
+
path/target evidence. Included in the meada/meada-core 1.3.0 minor release.
|
|
61
|
+
- Azure SDK sides in JavaScript/TypeScript, Python, Java, Go and C# (#670): verified
|
|
62
|
+
constructors connect Service Bus and Event Hubs sends/receives, Blob container reads/writes
|
|
63
|
+
and Key Vault secret reads to physical contracts. New subscription receivers retain their
|
|
64
|
+
topic and subscription through exact factories and scoped workload environments. Existing
|
|
65
|
+
C# Service Bus forms keep their identities; resource readers retain each operation site.
|
|
66
|
+
The bounded inventory joins the shared meada/meada-core 1.3.0 minor release.
|
|
67
|
+
|
|
68
|
+
- GCP SDK use sides in JavaScript/TypeScript, Python, Java, Go and C# (#668): verified client
|
|
69
|
+
constructors connect Pub/Sub publish and subscription receive, Cloud Storage reads/writes
|
|
70
|
+
and Secret Manager access to their physical contracts. Subscription identities remain
|
|
71
|
+
distinct from topics through scoped workload environment resolution. The documented
|
|
72
|
+
operation inventory ships in the shared meada 1.3.0 minor release. Scoped request mutations
|
|
73
|
+
leave stale names unresolved, typed helpers retain their resource kind through factories,
|
|
74
|
+
and asynchronous factories preserve await state.
|
|
75
|
+
- The console graph has image builder-to-runner and alert emitter-to-matcher views, including
|
|
76
|
+
links within a repository, alongside provisioner sides and provisioning links with roots,
|
|
77
|
+
levels and reasons. A bilingual legend explains each role and keyboard navigation. The
|
|
78
|
+
playground exposes `value`, `iac` and `alert` searches. Release level: minor, included in
|
|
79
|
+
meada and meada-core 1.3.0 (#675).
|
|
80
|
+
- Datadog Terraform monitor tags join OpsGenie routing conditions through known tag
|
|
81
|
+
forwarding. Selected Alertmanager receivers explicitly transform grouped rule labels
|
|
82
|
+
into OpsGenie tags or PagerDuty v2 custom details; native PagerDuty PCL conditions keep
|
|
83
|
+
their field paths. Equality is exact; regex, prefix and containment are inferred.
|
|
84
|
+
Missing or unread forwarding yields no link, and matching never predicts final team
|
|
85
|
+
delivery. Included in the existing meada/meada-core 1.3.0 minor release (#673).
|
|
86
|
+
- AWS workload execution and environments (#664): Terraform/OpenTofu Lambda images and local
|
|
87
|
+
code/archive inputs, SAM CodeUri/Handler/ImageUri with Globals overrides, Serverless handlers
|
|
88
|
+
with provider/function environments, and encoded ECS container images/environments. Known
|
|
89
|
+
resource references retain typed identities; secret and dynamic contents remain unread.
|
|
90
|
+
Context, bidirectional traces and scope-aware image orphans include these workloads; new
|
|
91
|
+
local paths refuse absolute paths, every parent component and symbolic links. Included in
|
|
92
|
+
the minor development release of meada and meada-core 1.3.0.
|
|
93
|
+
|
|
94
|
+
- Terraform/OpenTofu JSON (`.tf.json`, `.tofu.json`) now creates IaC nodes with source spans,
|
|
95
|
+
references, evaluated names and local module instances. JSON expression and literal rules
|
|
96
|
+
share the HCL evaluator, provisioners and subscriptions; declared resource `via` addresses
|
|
97
|
+
resolve to JSON nodes and refresh when sources change. Sensitive defaults, tfvars and SSM
|
|
98
|
+
SecureString values also stay redacted in JSON block arrays, a root array of bodies included,
|
|
99
|
+
and a JSON `dynamic` property merges as the types it names (#642, #649).
|
|
100
|
+
- Azure Terraform/OpenTofu contracts (#669): Service Bus queues, topics and topic-qualified
|
|
101
|
+
subscriptions with filter routing, Event Hubs, Storage accounts and blob containers as
|
|
102
|
+
distinct kinds, and Key Vault secrets. ARM identifiers and supported blob/vault URLs give
|
|
103
|
+
exact config uses; provider-specific typed keys remain inferred. Linux Functions run
|
|
104
|
+
evaluated container images; Linux and Windows Functions run safe local deployment archives, with scoped
|
|
105
|
+
app settings and unresolved Key Vault references. Existing C# topic processors retain
|
|
106
|
+
their topic identity. This shares the 1.3.0 development release.
|
|
107
|
+
|
|
108
|
+
- HTTP base URLs follow Kubernetes Service DNS names and Compose service names through their
|
|
109
|
+
workloads to the repositories running the providers. Ingress hosts and literal prefixes
|
|
110
|
+
carry public URLs to their Services; rewrites remain unread mounts. Links are inferred and
|
|
111
|
+
name the Service, with workload environment provenance when applicable. A Service or
|
|
112
|
+
Ingress that reaches no code leaves a host to `[serve] hosts`, which still links it `exact`.
|
|
113
|
+
Included in the minor development release of meada and meada-core 1.3.0 (#665).
|
|
114
|
+
- GCP infrastructure contracts (#667): Terraform/OpenTofu Pub/Sub topics and distinct
|
|
115
|
+
subscription targets, Cloud Storage buckets, Cloud SQL instances and instance-qualified
|
|
116
|
+
databases, and Secret Manager secrets. Structured GCP configuration identifiers are exact;
|
|
117
|
+
provider-specific typed keys remain inferred. Cloud Run v1/v2 services and v2 jobs retain
|
|
118
|
+
container images and scoped environment targets. Provisioning, subscriptions, context,
|
|
119
|
+
trace, scope-aware orphans and export include these kinds and runners. Release level: minor,
|
|
120
|
+
included in meada and meada-core 1.3.0.
|
|
121
|
+
- Declared resource `via` locations now accept IaC addresses in every indexed format and
|
|
122
|
+
`<file>#<key path>` with list selectors (`[key=value]`). Sides retain their precise node or
|
|
123
|
+
key for context and trace; removed locations produce the existing stale status diagnostics.
|
|
124
|
+
Release level: minor, included in meada and meada-core 1.3.0 (#641).
|
|
125
|
+
- Resolve environment reads through the workloads running their code, including Kubernetes ConfigMap references and Compose defaults, with inferred provenance and redacted Secret targets (#663).
|
|
126
|
+
- Alert contracts join Prometheus, Loki, PrometheusRule and Grafana rule labels to Alertmanager
|
|
127
|
+
route matchers, including AlertmanagerConfig. Equality is exact and regular expressions are
|
|
128
|
+
inferred; a negated condition only filters its route, without linking the value it refuses.
|
|
129
|
+
Route context includes the receiver, trace walks both ways, and export and scope-aware
|
|
130
|
+
orphan reports carry the kind. Helm values are not alert emitters. Included in the minor
|
|
131
|
+
development release of meada and meada-core 1.3.0 (#672).
|
|
132
|
+
- Anchored unresolved names across channel, resource and image contracts (#674): only
|
|
133
|
+
literal counterparts with sufficient anchor evidence and whole-segment wildcards link.
|
|
134
|
+
Several names remain ambiguous open items; human or optional decider choices replay through
|
|
135
|
+
`meada.decisions.toml`, including provisioning links and stale-choice reporting. Release
|
|
136
|
+
level: minor, included in meada and meada-core 1.3.0.
|
|
137
|
+
|
|
138
|
+
- Constructor-backed AWS SDK sides in Java 2.x, Go v2 and .NET: SQS, SNS, EventBridge, Kinesis,
|
|
139
|
+
S3, DynamoDB, SSM Parameter Store and Secrets Manager. Literal names and ARNs join
|
|
140
|
+
infrastructure contracts; environment reads retain their variable without a guessed name.
|
|
141
|
+
Every batch name is kept. Exact factories and aliases are followed, hidden bindings and
|
|
142
|
+
incomplete origins are rejected, and injected types alone create no SDK side, except SQS,
|
|
143
|
+
whose declared client types keep its earlier forms. .NET named requests and its S3 metadata
|
|
144
|
+
spelling are supported. SDK resource links are exact while declarations remain declared;
|
|
145
|
+
hierarchy queries stay unresolved. Release level: minor, meada and meada-core 1.3.0 (#660).
|
|
146
|
+
- AWS SDK use sides in TypeScript, JavaScript (SDK v3) and Python (boto3): SNS publishes,
|
|
147
|
+
EventBridge event entries and Kinesis record writes produce channel sides; S3 and DynamoDB
|
|
148
|
+
operations write or read resource sides; SSM and Secrets Manager operations read resources. Batch
|
|
149
|
+
and transaction inputs retain each named resource. Both client and operation origins must be the
|
|
150
|
+
SDK's; name-matched hops and hidden client names produce no side. Complete Python factory evidence
|
|
151
|
+
rejects opaque or missing returns and unawaited coroutine or generator objects, preserves exact
|
|
152
|
+
arguments, class fields and awaited aliases, and shares bounded constructor traversal with
|
|
153
|
+
existing message clients (#659).
|
|
154
|
+
- AWS SDK use sides: literal names and supported ARNs join provisioners at `exact`; environment
|
|
155
|
+
reads stay unresolved and name their variable through `via: env:NAME`, without reading the process
|
|
156
|
+
environment. SDK providers gain an optional `via`, absent on existing providers; format remains 1.
|
|
157
|
+
Existing declared resource sides retain `declared`. Older indexes rebuild. Release level: minor,
|
|
158
|
+
meada and meada-core 1.3.0 (#659).
|
|
159
|
+
- Config values naming AWS resources become directionless use sides (#661): recognized ARNs,
|
|
160
|
+
SQS queue URLs and S3 URIs are exact; plain names under final `queue`, `topic`, `bucket` and
|
|
161
|
+
`table` keys are inferred. Each key links only to provisioners and counts for scoped orphans;
|
|
162
|
+
bare equal values, redacted/cut values and provisioner name definitions create no use.
|
|
163
|
+
Search, context, trace, export's optional `uses` and the console retain key locations
|
|
164
|
+
without adding producer/consumer or writer/reader links. Release level: minor, meada and
|
|
165
|
+
meada-core 1.3.0.
|
|
166
|
+
- Image contracts (#662): normalized `image::<registry>/<repository>` names connect builders
|
|
167
|
+
in GitHub Actions, Compose, Skaffold, ko and Jib to Kubernetes, Compose and Helm runners,
|
|
168
|
+
including Kustomize image overrides. Context shows builders, trace crosses into code and
|
|
169
|
+
back, and status reports image orphans only in scopes with both roles. A Compose build runs
|
|
170
|
+
same-repository code directly at `exact`, without following symlinks: the paths its Dockerfile
|
|
171
|
+
takes from the context (`COPY`, `ADD` and `RUN` bind mounts, in every stage), not the whole of
|
|
172
|
+
it, and `inferred` when it cannot read one; editing the Dockerfile makes the index stale and an
|
|
173
|
+
upward `trace` writes each workload once (#744). Export format 1 adds optional builder `at`
|
|
174
|
+
locations and direct `executions`; the console graph displays both. Release level: minor for
|
|
175
|
+
meada and meada-core, included in synchronized 1.3.0.
|
|
176
|
+
|
|
177
|
+
- AWS infrastructure contracts: Terraform/OpenTofu SNS, EventBridge and Kinesis channels;
|
|
178
|
+
DynamoDB, RDS instances and clusters, ElastiCache clusters and replication groups, SSM and
|
|
179
|
+
Secrets Manager resources, including ARN name extraction. SNS-to-SQS subscriptions and
|
|
180
|
+
EventBridge rules/targets link queue consumers to source producers, exact without a filter
|
|
181
|
+
and inferred with one. Context, trace, export and scoped orphan reporting cover all kinds;
|
|
182
|
+
SSM SecureString values are redacted, including Terraform/OpenTofu JSON. The schema adds subscription summaries and older
|
|
183
|
+
indexes rebuild. Release level: minor, meada and meada-core 1.3.0 (#658).
|
|
184
|
+
- Orphan infrastructure contracts (#657): `meada status` lists provisioners without uses and
|
|
185
|
+
uses without provisioners only for a contract kind and broker or resource kind with both
|
|
186
|
+
sides in the visible scope. Otherwise `search` and `context` mark the side with
|
|
187
|
+
`no provisioner in the workspace` or `no use in the workspace`, without orphan status noise.
|
|
188
|
+
Matching follows provisioning links, including patterns and root labels. Release level:
|
|
189
|
+
minor for both meada and meada-core in the next release.
|
|
190
|
+
|
|
191
|
+
- Terraform provisioners (ADR 0026): `aws_sqs_queue` and `aws_s3_bucket` join the SQS channel
|
|
192
|
+
and S3 resource contracts by physical name, using an embedded, documented type table. Every
|
|
193
|
+
producer, consumer, writer and reader links to each root's provisioner; overridable names
|
|
194
|
+
link at `inferred` with their variables in the reason. `context` lists the sides and
|
|
195
|
+
provisioners, and `trace` crosses provisioning links both ways. Bounded name patterns link
|
|
196
|
+
literal names at `inferred` (several names: `ambiguous`); the console graph lists provisioner
|
|
197
|
+
sides and provisioning links. Export format 1 gains optional
|
|
198
|
+
`iac_nodes`, `provisioners` and `provisions` arrays. The stored-name sample changes the schema,
|
|
199
|
+
rebuilding older indexes. Release level: minor for both meada and meada-core (#656).
|
|
200
|
+
- Config values (ADR 0025): every scalar of every `*.yaml`, `*.yml` and `*.json` file the walk
|
|
201
|
+
visits, and of the YAML and JSON files under the CI configuration at the root (`.github/`,
|
|
202
|
+
`.gitlab-ci.yml`, `.gitlab/`, `.circleci/`, `.buildkite/`, `.drone.yml`), is indexed with its
|
|
203
|
+
file, key path (jq style, the document index first in a file of several documents), value, type
|
|
204
|
+
and line. `search` finds them with the new kind `value` (exact, then prefix, then substring, over
|
|
205
|
+
values and key paths), and the default search answers with them only when no symbol and no
|
|
206
|
+
contract matches (#639).
|
|
207
|
+
- Config values: a value over 1 KiB is stored cut, marked `(cut)`; a Kubernetes `Secret`'s `data`
|
|
208
|
+
and `stringData` are stored as `redacted`. Lockfiles and files that do not parse are skipped, and
|
|
209
|
+
`meada status` counts the config files read and skipped and the values redacted. Values stay out
|
|
210
|
+
of `meada export`. The index schema changes, so existing indexes are rebuilt (#639).
|
|
211
|
+
- `search` with the kind `value` serves substring matches from an FTS5 trigram table beside the
|
|
212
|
+
B-trees that already serve exact and prefix matches, instead of scanning every row; a query
|
|
213
|
+
under three characters still scans, with the same answer. The table holds about four times the
|
|
214
|
+
text of the key paths and values (21 MB for 5 MB on this repository). The index schema
|
|
215
|
+
changes, so existing indexes are rebuilt (#647).
|
|
216
|
+
- Terraform and OpenTofu config values (ADR 0025): `*.tf`, `*.tofu`, `*.tfvars` and `*.auto.tfvars`
|
|
217
|
+
files are read with `hcl-edit` and `hcl-rs`, and `*.tf.json`, `*.tofu.json` and `*.tfvars.json`
|
|
218
|
+
through the JSON reader, so `search` with the kind `value` finds a team name in an OpsGenie
|
|
219
|
+
routing rule or a queue name in Terraform. The key path runs over the block's type and labels and
|
|
220
|
+
the attribute's name (`resource.aws_sqs_queue.orders.name`), a repeated block `[n]`; a literal
|
|
221
|
+
keeps its type, and an expression or a template is stored as written under the type `expression`
|
|
222
|
+
or `template`. A `.tofu` file shadows the `.tf` file of the same name (#640).
|
|
223
|
+
- Terraform and OpenTofu config values: the `default` of a `variable` with `sensitive = true` (or
|
|
224
|
+
`"true"`) and every value a `.tfvars` file gives a variable of that name are stored as `redacted`,
|
|
225
|
+
and so is a default another file of its directory marks sensitive when that directory holds an
|
|
226
|
+
override file (`override.tf`, `*_override.tf`), which Terraform merges into the others; such a
|
|
227
|
+
default never reaches the index, also when only the override file changes. There, a `.tf` file a
|
|
228
|
+
`.tofu` one hides counts as one that does not parse, since Terraform reads it. A file that does
|
|
229
|
+
not parse is skipped and counted by `meada status` (#640).
|
|
230
|
+
- A Go struct field that keeps a base URL (`c.base`) carries the environment read every
|
|
231
|
+
composite literal of the repository that sets it gives it, directly or through a constructor's
|
|
232
|
+
parameter whose callers in the repository all pass that read, so a method that reads the field,
|
|
233
|
+
directly or through a request wrapper, links through `base_url_env` like the same read written
|
|
234
|
+
inline. Two different reads, a literal by position or of an alias, no literal, a write through
|
|
235
|
+
a selector (`c.base = x`), a constructor with no caller or that a call may reach by a name
|
|
236
|
+
match or through an interface (a method another definition shares the name of), and a literal
|
|
237
|
+
string leave the field
|
|
238
|
+
unknown, as before (#687).
|
|
239
|
+
- A TypeScript class field that is `readonly`, `private` or `#x` and written once, by its
|
|
240
|
+
initializer or by one plain `this.f = v` in the constructor body, is a constant of the class:
|
|
241
|
+
`this.f` in a method folds to it, so `` fetch(`${this.baseUrl}/orders`) `` gets the base URL
|
|
242
|
+
the constructor reads, a Backstage `config.getString` through `app-config*.yaml` included, and
|
|
243
|
+
links through `base_url_env`. A public mutable field, a second or conditional write, a write
|
|
244
|
+
outside the constructor, a constructor parameter and a JavaScript file stay unknown (#688).
|
|
245
|
+
- Backstage's `app-config*.yaml` follows `$include` and reads `$env`: a block moved to a partial (`{
|
|
246
|
+
$include: ./partials/acme.yaml }`, or `./partials/acme.yaml#api` for one key path of it) and a
|
|
247
|
+
value written `{ $env: API_URL }` are read as if inline, so a `config.getString` through them
|
|
248
|
+
links through `base_url_env`. The path resolves against the including file's directory, only
|
|
249
|
+
`.json`, `.yaml` and `.yml` files are read, and includes nest from their own directory. A partial
|
|
250
|
+
is a config input of the index, so editing it alone changes the answer on the next refresh. The
|
|
251
|
+
index schema golden changes (it now lists the stored roles), so existing indexes are rebuilt
|
|
252
|
+
(#689).
|
|
253
|
+
- Backstage `$include` limits: an absolute path, one that leaves the repository, a symbolic link, a
|
|
254
|
+
`${` in the path, another extension, a missing file or key path, a sibling key, a cycle, a depth
|
|
255
|
+
past 8, more than 64 includes from one root, more than 1 MiB grafted into one root and more than 4
|
|
256
|
+
MiB parsed for all the roots of a repository (its files named `app-config.yaml` first, then the
|
|
257
|
+
others in path order; an include counting its file's bytes, or its value's size when YAML aliases
|
|
258
|
+
make it larger, an include past its root's limit included) are not followed (#689).
|
|
259
|
+
- Backstage partials that do not parse: such a partial is parsed once per reading, charged its bytes
|
|
260
|
+
or, holding several documents, what reading them built: their keys stay unread and `meada status`
|
|
261
|
+
names each include with its reason. `$file` stays unread, and a config file past 1 MiB is dropped,
|
|
262
|
+
not parsed by half (#689).
|
|
263
|
+
- Backstage proxy endpoints are read wherever Backstage's proxy backend reads them: under
|
|
264
|
+
`proxy.endpoints`, and, when no `app-config*.yaml` has that key, as the keys of `proxy` that
|
|
265
|
+
start with `/` (the legacy shape, accepted from before Backstage 1.17). A string value is
|
|
266
|
+
`{ target }` in either shape, with the default `pathRewrite`, and `ignorePath`, `prependPath`
|
|
267
|
+
and `pathRewrite` another file gives the same endpoint apply to it. An endpoint inside an
|
|
268
|
+
included partial counts as if inline. With both shapes, in one file or across files, only
|
|
269
|
+
`endpoints` is read. A `getBaseUrl('proxy')` call plus `/inventory/clusters` through any of
|
|
270
|
+
them is `http::GET::/clusters`, linked through `base_url_env` like an object `target`. A
|
|
271
|
+
minor bump (#690).
|
|
272
|
+
- IaC nodes (ADR 0025): every Terraform and OpenTofu `resource`, `data` block and `module` call of a
|
|
273
|
+
`*.tf` or `*.tofu` file is a node with an address (`<type>.<name>`, `data.<type>.<name>`,
|
|
274
|
+
`module.<name>`), a type, a file, its lines and the root module that roots its evaluation (a
|
|
275
|
+
directory no other one calls as a local module). A local module's blocks are instantiated once per
|
|
276
|
+
call under the call's address (`module.orders.aws_sqs_queue.this`), and a literal `count` or
|
|
277
|
+
`for_each` gives one node per `[key]`. Override files (`override.tf`, `*_override.tf`) merge into
|
|
278
|
+
the blocks of their directory, as Terraform applies them (#649).
|
|
279
|
+
- IaC nodes: the references between nodes are stored like calls, followed through `var`, `local` and
|
|
280
|
+
module outputs. `search` finds the nodes with the new kind `iac` (by address, type or physical
|
|
281
|
+
name; the default search leaves them out), `context` on an address shows the type, the physical
|
|
282
|
+
name, the references both ways and the config values, and `trace` walks the references down and
|
|
283
|
+
up. Nodes stay out of `meada export`; the index schema changes, so existing indexes are rebuilt
|
|
284
|
+
(#649).
|
|
285
|
+
- Compose services as IaC nodes: a Compose file (`compose.yaml`, `compose.yml`,
|
|
286
|
+
`docker-compose.yaml`, `docker-compose.yml`) with its override file in the same directory is one
|
|
287
|
+
evaluation unit, rooted at the directory, and each service is a node `services.<name>` of type
|
|
288
|
+
`service`. `depends_on`, `links` and shared networks are references (`via depends_on`, `via
|
|
289
|
+
links`, `via networks.<name>`). `${VAR:-default}` resolves to its default and is marked
|
|
290
|
+
overridable; `${VAR}` stays an unresolved part. A service records its image and its build
|
|
291
|
+
context (a path inside the repository, from its root) for the image contract, and `context`
|
|
292
|
+
shows both. `search` kind `iac`, `context` and `trace` answer for them. The index schema
|
|
293
|
+
changes, so existing indexes are rebuilt; release level minor (#652).
|
|
294
|
+
- CloudFormation and SAM templates as IaC nodes (ADR 0025): a YAML file (the short-form tags `!Ref`,
|
|
295
|
+
`!Sub`, `!GetAtt`, `!Join` and the rest are read) or a JSON file with a `Resources` mapping that
|
|
296
|
+
carries `AWSTemplateFormatVersion` or the SAM transform (`AWS::Serverless-2016-10-31`) is one
|
|
297
|
+
evaluation unit, rooted at the template's path, and each resource is a node addressed by its
|
|
298
|
+
logical id, its type (`AWS::SQS::Queue`, `AWS::Serverless::Function`) the node's type. `Ref`,
|
|
299
|
+
`Fn::GetAtt` (with the attribute in the `via`), the variables of `Fn::Sub` and `DependsOn` are
|
|
300
|
+
references. `search` kind `iac`, `context` and `trace` answer for them; a changed template is
|
|
301
|
+
evaluated again alone. The index schema changes, so existing indexes are rebuilt; release level
|
|
302
|
+
minor (#653).
|
|
303
|
+
- CloudFormation and SAM physical names: the physical name of the types the contract kinds will read
|
|
304
|
+
(queues, topics, buckets, tables, functions, streams, secrets and a few more) is evaluated within
|
|
305
|
+
the template: a parameter's default (marked overridable), `Ref`, `Fn::Sub`, `Fn::GetAtt` and
|
|
306
|
+
`Fn::Join`; a pseudo parameter, an import and any other function are unresolved parts and the name
|
|
307
|
+
a pattern. A parameter with `NoEcho` has its default stored as `redacted` among the config values
|
|
308
|
+
and used for no name (#653).
|
|
309
|
+
- Serverless Framework services as IaC nodes (ADR 0025): a `serverless.yml`, `serverless.yaml` or
|
|
310
|
+
`serverless.json` with a `service` is one evaluation unit, rooted at its path. Each function is a
|
|
311
|
+
node `functions.<name>` of type `Serverless::Function`, named by its `name` or
|
|
312
|
+
`<service>-<stage>-<function>`, with its handler and events (`http GET /orders`, `sqs Queue.Arn`,
|
|
313
|
+
`schedule rate(5 minutes)`) recorded and shown by `context`, and a reference to each resource its
|
|
314
|
+
body names with `Ref`, `Fn::GetAtt` or `Fn::Sub`. The `resources` section is read as
|
|
315
|
+
CloudFormation: each resource is a node at its logical id (#654).
|
|
316
|
+
- Serverless Framework variables: `${self:...}` resolves to the value at its path and the default of
|
|
317
|
+
`${opt:...}` resolves and is marked overridable; `${env:...}`, `${ssm:...}` and the other sources
|
|
318
|
+
are unresolved parts, a `*` in a name and `${...}` in a recorded text. `search` kind `iac`,
|
|
319
|
+
`context` and `trace` answer for them; a changed service is evaluated again alone. The index
|
|
320
|
+
schema changes, so existing indexes are rebuilt; release level minor (#654).
|
|
321
|
+
- Kubernetes objects and Kustomize overlays as IaC nodes (ADR 0025): every YAML or JSON document
|
|
322
|
+
with an `apiVersion`, a `kind` and a `metadata.name` is a node addressed
|
|
323
|
+
`<Kind>[.<group>]/<namespace>/<name>` (no namespace for a cluster-scoped kind). Each directory
|
|
324
|
+
with a `kustomization.yaml` that no other names as a base is an overlay and an evaluation unit:
|
|
325
|
+
its `resources`, `bases` and `components` inside the repository are instantiated under it, each
|
|
326
|
+
node labelled by the overlay, with `namePrefix`, `nameSuffix`, `namespace` and `images` applied
|
|
327
|
+
(#651).
|
|
328
|
+
- Kustomize bases and Kubernetes references: a base stays inside the repository (a `..` that stays
|
|
329
|
+
inside is followed; a remote base, one above the root, through a symlink, in a cycle or past 16
|
|
330
|
+
levels is not), and `meada status` counts the entries not followed. A Service references the
|
|
331
|
+
workloads its selector matches, a workload the ConfigMaps and Secrets of its `env`, `envFrom` and
|
|
332
|
+
volumes and its service account, an Ingress its backend Services, in one namespace and one unit.
|
|
333
|
+
`search` with the kind `iac`, `context` (with the images of a workload) and `trace` answer for
|
|
334
|
+
them as for Terraform's nodes. The index schema changes, so existing indexes are rebuilt (#651).
|
|
335
|
+
- Crossplane compositions, claims and managed resources (ADR 0025): among the Kubernetes nodes,
|
|
336
|
+
`context` names what each object is to Crossplane on a new `role:` line (a composite resource
|
|
337
|
+
definition, a composition, a claim or a composite resource of a kind an XRD of the repository
|
|
338
|
+
defines, a managed resource with `spec.forProvider`, a composed resource), and Crossplane's own
|
|
339
|
+
kinds have no namespace. Each resource a composition creates from a literal `base`
|
|
340
|
+
(`spec.resources`, or a function patch-and-transform pipeline step) is a node
|
|
341
|
+
`<composition>/<resource>` of the base's kind, named by its `crossplane.io/external-name`
|
|
342
|
+
annotation or `metadata.name`; a managed resource is named by its external name (#655).
|
|
343
|
+
- Crossplane references, in one unit: a claim to the XRD of its composite kind, a composite resource
|
|
344
|
+
to its XRD, a `compositionRef` to its composition, an XRD to its default and enforced composition,
|
|
345
|
+
a composition to the XRD it composes and to each resource it creates, and a created or managed
|
|
346
|
+
resource to the XRD or `CustomResourceDefinition` of its kind. Patches and functions are not
|
|
347
|
+
evaluated: a name a patch sets, or a base with no name, is the pattern `*`, and a step running any
|
|
348
|
+
other function creates no node. The index schema changes, so existing indexes are rebuilt; release
|
|
349
|
+
level minor (#655).
|
|
350
|
+
- Static evaluation of Terraform names (ADR 0025): an IaC node's physical name (its `name` argument)
|
|
351
|
+
and each `count` and `for_each` are evaluated with `hcl-rs`'s evaluator and Meada's pure functions
|
|
352
|
+
(string, collection and conversion functions and `jsonencode`), from variable defaults, the root's
|
|
353
|
+
`terraform.tfvars`, `*.auto.tfvars` and their JSON forms, locals, local module inputs and outputs
|
|
354
|
+
per call, `each` and `count.index`, without running Terraform or reaching the network, so a
|
|
355
|
+
`for_each` over a variable gives one node per instance. `context` lists under `overridable:` the
|
|
356
|
+
root variables a name went through, by their default or a var file. A changed Terraform file or
|
|
357
|
+
var file evaluates again only the root modules whose unit holds it. The index schema changes, so
|
|
358
|
+
existing indexes are rebuilt (#650).
|
|
359
|
+
- Terraform names never evaluated: data sources, resource attributes, registry modules,
|
|
360
|
+
`terraform.workspace`, `-var`, `-var-file`, `TF_VAR_` and sensitive variables (marked by any of
|
|
361
|
+
their blocks, override files included, and every variable of a directory holding an override file
|
|
362
|
+
and a Terraform file that does not read or a `.tofu` file hides): such a part of a name is a `*`
|
|
363
|
+
and the name a pattern, shown as `pattern "orders-*"` by `search` and `(pattern)` by `context`,
|
|
364
|
+
and linked by nothing yet. A value over 64 KiB, an expression that could make over 1 MiB and a
|
|
365
|
+
root's evaluation past 64 MiB stay unresolved (#650).
|
|
366
|
+
- TypeScript consumers through `new URL(x)`: `new URL(x)` with one argument is `x` (unless the file
|
|
367
|
+
declares a `URL` or imports one from a relative path), and `u.toString()`, `u.href`, `String(u)`
|
|
368
|
+
and `` `${u}` `` pass the URL through, in a constant or built in place, so a `fetch` or a client
|
|
369
|
+
wrapper called with one links to its route and a base URL read from the environment shows its
|
|
370
|
+
`via`. A change through `u.searchParams`, `u.search` or `u.hash` keeps the path; a write to any
|
|
371
|
+
other member of a `new URL` constant, written in parentheses or a type assertion too, leaves it
|
|
372
|
+
unresolved, also through a destructuring or `for (.. of ..)` target, `++`, `Object.assign` or
|
|
373
|
+
another name holding it, or with the target in parentheses or an assertion, as does such a
|
|
374
|
+
write to a sealed field set where it is declared or in its constructor
|
|
375
|
+
(`this.url.pathname = ..`) (#685).
|
|
376
|
+
- TypeScript consumers through `new URL(reference, base)`: the two arguments read as the join the
|
|
377
|
+
WHATWG URL Standard defines (RFC 3986 section 5.2 for these references), so an absolute reference
|
|
378
|
+
is itself, `//host/x` takes its host, `/orders` replaces the base's path and `orders` joins the
|
|
379
|
+
base's directory (`https://h/api/` keeps `api`, `https://h/api` does not). Over a base read from
|
|
380
|
+
the environment (or a hole) an absolute path keeps the base as its lead, so `/orders` is
|
|
381
|
+
`http::GET::/orders` with `via env:API_URL`; a relative reference, one that starts with a read,
|
|
382
|
+
and a query or a fragment alone stay unresolved, and a parameter on either side is resolved at the
|
|
383
|
+
call sites (#686).
|
|
384
|
+
- `new URL(reference, base)` bases: a base is placed only when its scheme leads it, so a proxy's
|
|
385
|
+
`${X}/fetch/https://api.example.com/` is an opaque base, not a link to that host, and every
|
|
386
|
+
reference loses its dot segments. Swift's `URL(string:relativeTo:)` over a literal base goes
|
|
387
|
+
through the same resolver and follows the same rules; over a base read from the environment it
|
|
388
|
+
stays unresolved (#686).
|
|
389
|
+
|
|
390
|
+
### Changed
|
|
391
|
+
|
|
392
|
+
- Development and test builds optimize the main `meada` package at level 1 to reduce the
|
|
393
|
+
resident code footprint of the expanded indexing and contract readers (#711).
|
|
394
|
+
- Kotlin: a name read or called in a lambda looks for a local or local function of the code
|
|
395
|
+
around it in one climb, not one from every enclosing lambda: a file of 300 nested `apply`
|
|
396
|
+
blocks indexes in about 12 s instead of over 100 s (debug build), with the same answers (#711).
|
|
397
|
+
|
|
398
|
+
- A refresh reads the values of the files it did not change from a values cache beside the index
|
|
399
|
+
(`values.db`, ADR 0027) instead of parsing them again: on this repository, a one-line edit of a
|
|
400
|
+
Rust file refreshes in 1.4 s instead of 3.4 s. The refreshed index still equals a cold one, and
|
|
401
|
+
deleting the cache costs only time (#611).
|
|
402
|
+
- A refresh builds no resolver for a group it keeps, resolves each call of a changed group once,
|
|
403
|
+
writes communities again only when the call graph moved, and the actix-web reader skips the
|
|
404
|
+
lookups whose answer it does not use: on this repository a one-line edit of a Rust file
|
|
405
|
+
refreshes in 1.0 s instead of 1.5 s, with the same index (#610).
|
|
406
|
+
- A refresh summarizes a contract configuration again only when its bytes, the IaC nodes it
|
|
407
|
+
read or a path it looked at changed: 60 ConfigMaps of 290 KB refresh with no change in 0.01 s
|
|
408
|
+
instead of 4.5 s (debug build), and a removed or added Lambda handler or Compose build path
|
|
409
|
+
still moves its answer (#711).
|
|
410
|
+
- `search` with the kind `value` reads the value of only the rows its answer shows (each match
|
|
411
|
+
keeps just its sort key), so a broad query such as `e` no longer formats every matching value
|
|
412
|
+
before the budget cuts it (#711).
|
|
413
|
+
|
|
414
|
+
### Fixed
|
|
415
|
+
|
|
416
|
+
- A Java AWS SDK request no longer names a table, topic, bucket or queue its builder had before
|
|
417
|
+
the builder changed (#719). A builder changes in place, so a name is `exact` only when every
|
|
418
|
+
mention of the builder is a form the reader follows: a setter, `.build()`. Any other mention
|
|
419
|
+
leaves the side unresolved: the builder handed to a call or captured, `applyMutation`,
|
|
420
|
+
`copy(consumer)`, an alias at any depth, and a use the reader does not model (a cast, a
|
|
421
|
+
ternary). A value built first keeps its name, as an immutable copy does, except in a loop the
|
|
422
|
+
builder outlives. A request is judged whole: one such entry leaves the others unresolved.
|
|
423
|
+
The check reads a file once, so its cost is linear in the calls.
|
|
424
|
+
- A Java AWS SDK request built by a lambda or a class that runs after its builder changed, one
|
|
425
|
+
its helper assigns again as a parameter, one a caller passes on after its builder changed, a
|
|
426
|
+
builder field hidden by a local, one set from an initializer or another file, one handed to
|
|
427
|
+
caller code by `applyMutation` and a request type another type or an import shadows name no
|
|
428
|
+
table either (#719).
|
|
429
|
+
- A Java AWS SDK request whose builder is set again in a loop around the one its value is built
|
|
430
|
+
in, or inside the request's own expression, names no table either (#719).
|
|
431
|
+
- Terraform static evaluation charges the template text `hcl-rs` parses again at each
|
|
432
|
+
evaluation in a `for`, not only the bytes an expression makes: a template in a `for` over
|
|
433
|
+
thousands of elements is unresolved (`*`) before it runs, where one 24 KB root took seconds
|
|
434
|
+
per resource and minutes in all. A read such as `var.x[0]` in a `for` is charged the copy of
|
|
435
|
+
`var` it makes each time. A refused expression spends the bytes it went through (its text and
|
|
436
|
+
the roots it read), at most the 1 MiB each one spent before, and a literal name that fits one
|
|
437
|
+
value stays exact once the work is spent. A short template (`"${a}-x"`) in a `for` over 2,000
|
|
438
|
+
elements still resolves; one of 40 interpolations resolves over 100 elements, no longer over
|
|
439
|
+
200 (#714).
|
|
440
|
+
- `meada mcp` over stdio answers calls a client sends without waiting for each reply (#704).
|
|
441
|
+
Each call refreshes the index, and a refresh failed at its first write with `database is
|
|
442
|
+
locked` when another call was writing. Now the calls of one server run one refresh at a time
|
|
443
|
+
and wait for it with no timer, sharing the next run; a call that meets its lock elsewhere
|
|
444
|
+
(opening the index, querying it) waits for the refresh too, past the 10 s busy timeout. A
|
|
445
|
+
batch after a change costs about one refresh more than an unchanged one (debug build, Meada's
|
|
446
|
+
own checkout: 50 calls 21 s against 15 s). Across processes, a refresh with nothing to write
|
|
447
|
+
takes no write lock and one that meets another process's writer waits for its commit and
|
|
448
|
+
starts over; a wait past 10 s there still answers `database is locked`, and that server's
|
|
449
|
+
calls wait behind its refresh as long as it takes.
|
|
450
|
+
|
|
451
|
+
- Terraform: a `for` binding a key over a set held in a local or a variable (`local.s` from
|
|
452
|
+
`toset(...)`, a chain of locals, a variable declared `type = set(...)`) is unresolved
|
|
453
|
+
instead of answering the index as an exact key, as it already was over a written `toset(...)`
|
|
454
|
+
(#720). A set reached through an attribute, an index or another call stays a ceiling (#717).
|
|
455
|
+
- Terraform: a value that enters a variable declared `set(T)` (its default, a var file's value, a
|
|
456
|
+
module argument, an override's default) is converted to elements of type `T`, then sorted and
|
|
457
|
+
deduplicated as cty does, so `tolist(var.s)`, `length(var.s)` and `join` over `["b", "a", "a"]`
|
|
458
|
+
see `a`, `b`, and a `set(string)` of `[10, 9]` keeps the strings `"10"` and `"9"` in string
|
|
459
|
+
order. An element Meada cannot convert with certainty leaves the value unresolved (#720).
|
|
460
|
+
- Terraform: an override file that replaces the `type` of a variable whose own block declares a
|
|
461
|
+
set type is now converted as Terraform converts it: the default is converted to the set first,
|
|
462
|
+
then to the new type (`list(string)` gives the set's elements in set order, `any` and `set(string)`
|
|
463
|
+
keep the set; a default an earlier override gave is converted the same way when a later
|
|
464
|
+
one retypes it), and one Terraform rejects (a tuple) gets no exact name. OpenTofu 1.13 and later convert the default
|
|
465
|
+
once, to the final type, and name other instances; Meada follows Terraform (#740), except for a
|
|
466
|
+
variable with a block in a `.tofu` or `.tofu.json` file, which Terraform does not read: it is
|
|
467
|
+
unresolved where the two conversions differ. Known gap: indexed end to end, the four cases tried
|
|
468
|
+
of a `for_each` over a variable retyped to a list got one pattern name where Terraform creates an
|
|
469
|
+
instance per element, and none got a wrong exact name; the cause is open (#783).
|
|
470
|
+
- An Alertmanager configuration with a matcher regex Go's `regexp` refuses (an unclosed
|
|
471
|
+
group, a leading `*`, a backward range, a lookahead) is unreadable, as Alertmanager refuses
|
|
472
|
+
to load it: it gives no alert side or link, where its valid routes kept an `exact` link,
|
|
473
|
+
and `meada status` counts the file under `unreadable`. Only a syntax error established as
|
|
474
|
+
a `regexp/syntax` error code counts; an expression past Meada's own budgets or syntax it
|
|
475
|
+
does not read stays unmatched with the other routes linked (#718).
|
|
476
|
+
- AWS SDK forms in Java, Go and C# follow the ADR 0026 rule TypeScript and Python already
|
|
477
|
+
followed: an EventBridge entry without `EventBusName` produces to `default`, and an SNS
|
|
478
|
+
publish to a phone number or endpoint names no topic. A request Meada cannot see whole (a
|
|
479
|
+
builder from `toBuilder()` or from a factory of the repository's own, a helper's result) keeps
|
|
480
|
+
its unresolved side. TypeScript and
|
|
481
|
+
Python now read the S3, SSM and Secrets Manager operations Java, Go and C# read
|
|
482
|
+
(`DeleteObject`, `HeadObject`, `ListObjects`, `ListObjectsV2`, `PutParameter`,
|
|
483
|
+
`DeleteParameter`, `DeleteParameters`, `PutSecretValue`, `UpdateSecret`, `CreateSecret`,
|
|
484
|
+
`DeleteSecret`); DynamoDB transactions stay TypeScript and Python only (#660).
|
|
485
|
+
- `snapshot publish` no longer publishes the old graph under a new commit when only a contract
|
|
486
|
+
configuration or a path its summary looked at changed (a removed Lambda `worker.zip`, a
|
|
487
|
+
Compose build context): the index is fresh only while all of them are as it read them (#711).
|
|
488
|
+
- An image's Helm values file is any YAML file with a `values` word in its name, as for alerts,
|
|
489
|
+
so `prod-values.yaml` declares image consumers, as `values.prod.yml` already did, and
|
|
490
|
+
`valuesets.yaml` does not (#711).
|
|
491
|
+
|
|
492
|
+
- Python: an import inside a function names its library in that function again, so
|
|
493
|
+
`from requests import get` and `import requests as r` there are HTTP consumers, and
|
|
494
|
+
`import json as requests` there hides the module's `requests` (#668).
|
|
495
|
+
- Python framework and Go router tables retain stable identities in optimized builds, so
|
|
496
|
+
Flask blueprints keep their mounted routes and standard Go mux matching stays consistent (#711).
|
|
497
|
+
|
|
498
|
+
- TypeScript and JavaScript URL consumers respect lexical bindings and writes of `String`
|
|
499
|
+
(#683). A callback named `String` no longer invents a route or host, and a local binding
|
|
500
|
+
leaves the global conversion in other scopes intact. Non-strict block functions follow
|
|
501
|
+
Annex B's enclosing binding; modules, classes and strict prologues retain block scope.
|
|
502
|
+
|
|
503
|
+
- Image runners and links retain each evaluation root when Kustomize overlays reuse the same
|
|
504
|
+
workload and normalized image. Repeated image evidence within one workload and root still
|
|
505
|
+
collapses to one side (#711).
|
|
506
|
+
- A symbol's `context` shows the level, reason and provider of inferred HTTP call links whose
|
|
507
|
+
recorded environment base selects a declared `base_url_env` peer, including through fields
|
|
508
|
+
and Backstage config partials. Editing only a partial refreshes that explanation (#683).
|
|
509
|
+
- Resource SDK reader call sites retain their identities while traces follow writer-to-reader
|
|
510
|
+
data flow and its reverse, show the actual function/location, and continue through the
|
|
511
|
+
reader's body. Shared partial reads and process membership use the same direction; HTTP
|
|
512
|
+
and package calls keep their existing behavior (#659, #660).
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
- Terraform and OpenTofu config values redact an `aws_ssm_parameter` resource's `value` when
|
|
516
|
+
its literal `type` is `SecureString`, in HCL and Terraform JSON, regardless of attribute order.
|
|
517
|
+
Ordinary `String` parameters keep their values (#709).
|
|
518
|
+
- TypeScript and JavaScript URL folding requires the runtime global or the named `URL` export
|
|
519
|
+
of `url` or `node:url`. Unknown imports, repository aliases, other exports and shadowed
|
|
520
|
+
CommonJS loaders no longer invent HTTP consumers or links (#709).
|
|
521
|
+
- CloudFormation nodes and references survive cold indexing and warm refreshes when a qualifying
|
|
522
|
+
template is named `compose.yaml`: its resource types decide ownership before its filename,
|
|
523
|
+
without changing real Compose ownership (#709).
|
|
524
|
+
- A YAML document whose anchors and aliases expand past the nesting limit (128 levels) is
|
|
525
|
+
reported unreadable and skipped, where it could abort meada (#646).
|
|
526
|
+
- Crafted IaC and YAML files no longer exhaust memory or time while indexing: long
|
|
527
|
+
CloudFormation parameter defaults joined or substituted many times, names built through more
|
|
528
|
+
than 32 Terraform variables or CloudFormation parameters (now unresolved), YAML anchors nested
|
|
529
|
+
around a large node, Kustomize files listed many times or reached through a diamond of bases,
|
|
530
|
+
thousands of `images` rules, Ingress hosts past 253 bytes and volume names past 63 (now left
|
|
531
|
+
out), an `Fn::Sub` that names its variable twice at every level, Terraform objects of
|
|
532
|
+
thousands of keys (a file whose objects pass 2^24 key comparisons is now unreadable), costly
|
|
533
|
+
`.tfvars` values (now given but unresolved) and long `trim` and `toset` arguments (#646, #649,
|
|
534
|
+
#651, #653).
|
|
535
|
+
- An Alertmanager route expression of case-insensitive Unicode classes (`(?i)\p{Any}` written
|
|
536
|
+
hundreds of times) no longer takes minutes to compile on every `export` and `status`, nor do
|
|
537
|
+
hundreds of route configurations compile a megabyte automaton each: the expressions of one
|
|
538
|
+
linking pass share 2^22 code points of case folding (counted only in ranges that hold a cased
|
|
539
|
+
letter, a bracket's classes as folding leaves them), 4096 Unicode classes and 16 MiB of
|
|
540
|
+
automata, in equal parts per routing scope and expression, so what links does not depend on
|
|
541
|
+
the repository asking. Past its part an expression stays unmatched (`status` shows its matcher
|
|
542
|
+
as an orphan, not a limit), and the same expression in route configurations of as many
|
|
543
|
+
expressions is compiled once (#672).
|
|
544
|
+
- A long label matched by an Alertmanager route expression of many automaton positions no longer
|
|
545
|
+
runs the expression over it for every route: `.*a.{1000}a.*` against a label of 300,000 bytes
|
|
546
|
+
took 43 s for each route (debug). Before reading a value, each condition is charged a step per
|
|
547
|
+
automaton position (a state that reads nothing, such as an assertion or an empty capture,
|
|
548
|
+
included) and byte offset it may start at, or the bytes it reads for a comparison, against a
|
|
549
|
+
ceiling of 2^26 steps per pass apart from the evaluation ceiling, so that label stops before
|
|
550
|
+
matching and `status` reports the evaluation limit, while route visits and evaluations count as
|
|
551
|
+
before (#711).
|
|
552
|
+
- Alerts: a regular expression Go refuses for a repetition operator stacked on another (`a**`,
|
|
553
|
+
`a{2}*`) no longer links (#711).
|
|
554
|
+
- Alerts: an AlertmanagerConfig route links `inferred`, since prometheus-operator also matches
|
|
555
|
+
the alert's namespace, which Meada does not read (its consumers say `(AlertmanagerConfig
|
|
556
|
+
namespace)`); a Grafana rule group repeated with `count` or `for_each` declares no rule (it may
|
|
557
|
+
be made zero times); a file with a `values` word in its name (`prod-values.yaml`,
|
|
558
|
+
`values.prod.yaml`) is Helm input, not just one starting with `values`; a quoted matcher value
|
|
559
|
+
reads Alertmanager's escapes (`\n`, `\"`, `\\`), so `"a\.b"` keeps its backslash instead of
|
|
560
|
+
invalidating the route and its siblings; and the 4 MiB file ceiling charges the text a rule or
|
|
561
|
+
route stores, so 2,000 small rules (187 KB) are no longer dropped (#672).
|
|
562
|
+
- A Python file of thousands of AWS SDK operations on clients a factory function returns no
|
|
563
|
+
longer takes minutes to index: the operations one reader asks about in a file keep the answers
|
|
564
|
+
no limit cut and share a budget of 2^18 steps, one operation taking up to all that is left
|
|
565
|
+
(each still taking 16 once it is spent, so five factories of 2,000 returns resolve on their
|
|
566
|
+
first operation), and a call passing thousands of clients to one function, or forwarding them
|
|
567
|
+
through a wrapper to the Google Cloud and Azure readers, no longer copies them for every value
|
|
568
|
+
it reads (#660, #668, #669).
|
|
569
|
+
- Terraform: an object written after a `-`, a number or a `/`, or after a quote or heredoc end
|
|
570
|
+
inside a template directive's body, now counts toward the 2^24 key comparisons a file may
|
|
571
|
+
hold, where a file of them could take minutes to parse; a file with a heredoc whose first
|
|
572
|
+
line starts with its identifier is now unreadable, since the parser read it otherwise than
|
|
573
|
+
Terraform and could hide such objects behind it (#640); a JSON
|
|
574
|
+
var file of tens of thousands of keys reads in linear time, where it took over half a minute;
|
|
575
|
+
and a var file Terraform loads that does not read (broken, too wide or past 1 MiB) leaves the
|
|
576
|
+
variables it may give unresolved, where their defaults stood in (#650).
|
|
577
|
+
- Backstage proxy: a `proxy.endpoints`, a whole `proxy` or a root behind an `$include` Meada
|
|
578
|
+
does not follow counts as the endpoints table, as Backstage reads (or refuses) whatever the
|
|
579
|
+
include gives, so the legacy `proxy['/<ep>']` keys beside it or in another file no longer link
|
|
580
|
+
a call; an include whose `#` key path's last key is absent does not, since Backstage leaves that
|
|
581
|
+
key out (#709).
|
|
582
|
+
- Backstage `$include`: an `app-config*.yaml` that is one `$include` is the file it names, a root
|
|
583
|
+
or a partial of more than one YAML document is unreadable, and an include of the file and key
|
|
584
|
+
path being read keeps its `$include` as written rather than being a cycle, all as Backstage's
|
|
585
|
+
config loader reads them (#709).
|
|
586
|
+
- Serverless: a function with no `name` is named after `--stage` first, so `context` lists its
|
|
587
|
+
name as overridable through `opt:stage` (at `provider.stage`'s line, or the function's when the
|
|
588
|
+
file has no stage) and the name links `inferred`; `${self:provider.stage}` still reads the file
|
|
589
|
+
and is no override (#709).
|
|
590
|
+
- Authorization: an `added_by` a team operator wrote while no GitHub grant provider was
|
|
591
|
+
configured no longer decides eligibility once `[oidc.github]` is enabled. Under the provider the
|
|
592
|
+
console stamps each `added_by` it writes with `added_by_time` (its own clock, never the
|
|
593
|
+
submitted text; part of the version id), and without it writes none; Postgres migration 10
|
|
594
|
+
keeps the time the provider's first permissions set started (`<schema>.permission_state`), and `meada github-app roles` reports an addition on the
|
|
595
|
+
host whose `added_by` has no time, or one no later than that set's second, `unattributed` and
|
|
596
|
+
excludes it whatever its roles. Entries saved before this version carry no time, so under the
|
|
597
|
+
provider their additions are excluded until the global operator writes a reviewed
|
|
598
|
+
`added_by_time` or a team operator adds them again; `composeEntries` takes the time as its
|
|
599
|
+
fourth argument (#454).
|
|
600
|
+
- A query no longer reopens each peer's index: the engine refreshes and reads the connection it
|
|
601
|
+
holds, so a peer is never refreshed in one file and read from another (#443).
|
|
602
|
+
- GitHub App: a 403 `Resource not accessible by integration` with quota left (no `retry-after`,
|
|
603
|
+
`x-ratelimit-remaining` above 0) is a permission failure, not a throttle: `github-app roles`
|
|
604
|
+
passes it to the next installation unmarked, records the repository as `forbidden` (no rows, a
|
|
605
|
+
warning) when every installation answers so, and the installations stay eligible for the role
|
|
606
|
+
check and keep minting. A 403 or 429 with `retry-after` or an empty quota still
|
|
607
|
+
throttles, as does any 403 outside the role check's collaborators listing (ADR 0013 amended,
|
|
608
|
+
#452).
|
|
609
|
+
- prove-meada scripts: the console page checks sign in again when a route lands on the sign-in page
|
|
610
|
+
and fail the route that stays there, the Helm overlays `values-identity.yaml` and
|
|
611
|
+
`values-workspaces.yaml` render in their stack (as `scripts/helm-check` does) instead of failing
|
|
612
|
+
alone, and `console.py start --bin` resolves a relative path against the caller's directory (#679).
|
|
613
|
+
- `meada export`, `meada status` and the other commands that print their result once done no
|
|
614
|
+
longer panic when the reader closes its end early (`meada export | head -1`, `| true`): the rest
|
|
615
|
+
of the output is dropped and the command ends as it would, where it panicked with "failed
|
|
616
|
+
printing to stdout: Broken pipe (os error 32)" and exited 101. `meada decide` and `meada mcp`,
|
|
617
|
+
which never panicked, still stop with a "Broken pipe" error and exit 1 (#711).
|
|
618
|
+
- Kustomize: with two bases of their own `namePrefix` that write the same names, a Deployment no
|
|
619
|
+
longer references the other base's ServiceAccount, nor an Ingress the other base's Service. A
|
|
620
|
+
Service reference, and a `serviceAccountName` of the kinds Kustomize renames (Pod, Deployment,
|
|
621
|
+
StatefulSet, DaemonSet, ReplicationController, Job, CronJob), resolve as Kustomize's name
|
|
622
|
+
reference does once the tree is built: among the objects of the referrer's namespace (none and
|
|
623
|
+
`default` alike) a stage renamed or moved from the name as written, the only one, else those
|
|
624
|
+
whose prefix and suffix stages end as the referrer's; with none left, the object called by the
|
|
625
|
+
name as written, a final name included, and with several (a tree Kustomize refuses), none.
|
|
626
|
+
Another kind's account, or the deprecated `serviceAccount`, which Kustomize leaves alone, names
|
|
627
|
+
the account called so. An empty `namespace` in a kustomization no longer sets one (#711).
|
|
628
|
+
- Ingress: a path Meada cannot read as a literal prefix (`/store/(.*)`, `/api/*`) no longer drops
|
|
629
|
+
out of the routing table, where a shorter rule then claimed its URLs; it is an unread mount at
|
|
630
|
+
its literal head cut at its last slash. A `use-regex` annotation or a missing `pathType` also
|
|
631
|
+
leaves the path unread, and so does a path left out (an ImplementationSpecific catch-all); a
|
|
632
|
+
table past its ceilings (64 rules, read or not) leaves every host of the Ingress unread, not
|
|
633
|
+
only the hosts read before the cut (#711).
|
|
634
|
+
- Kustomize `components` change what the kustomization that lists them holds, its bases'
|
|
635
|
+
objects included, as Kustomize applies them; they were instantiated as one more base, so a
|
|
636
|
+
component's `images` rule never retagged the overlay's workloads. Each object a component is
|
|
637
|
+
handed counts against the 50,000 entries one overlay walks, so components reaching one another
|
|
638
|
+
along many paths, or many objects through a long list of them, stop there (#711).
|
|
639
|
+
- HTTP: overlays that repeat one Ingress or Service per environment no longer make a route to a
|
|
640
|
+
single provider `ambiguous`; distinct providers, or a route as long that reaches no code,
|
|
641
|
+
still do. A decision recorded for such a route is now stale; `meada decide --prune` removes it (#711).
|
|
642
|
+
- Images: a module run from a local path (an archive or a directory) in one root no longer drops
|
|
643
|
+
the image another root runs it from, with its environment and provisions; only that root runs
|
|
644
|
+
code without an image (#711).
|
|
645
|
+
- Terraform: `split(",", "")` gives one empty element (a `count` over its length made no node), and
|
|
646
|
+
an IaC name pattern needs three letters or digits besides its wildcards (`*.*.*.*` matched any
|
|
647
|
+
dotted name) (#711).
|
|
648
|
+
- Terraform: an object walks its keys in lexical order, whether a variable or local binds it or the
|
|
649
|
+
expression builds it (a literal, a `merge`): a `for` over it or a `jsonencode` of it gave an
|
|
650
|
+
`exact` name in written order, and a `for` whose collection contains an object whose keys are
|
|
651
|
+
known only once evaluated (a computed key, a comprehension) is now `*` (#711).
|
|
652
|
+
- Terraform: integer arithmetic is exact, as Terraform's: a result past `u64` or below `i64` (`0 -
|
|
653
|
+
18446744073709551615`), a division by zero or with a remainder (`7 / 2`) and arithmetic on a
|
|
654
|
+
fraction leave that part of the name `*`, also on a `for` variable, where the evaluator printed a
|
|
655
|
+
cast, wrapped or floating-point value as an `exact` name. So do a number literal or `tonumber`
|
|
656
|
+
past them, with more digits than a float holds or that a float writes with an exponent
|
|
657
|
+
(`18446744073709551616` printed `1.8446744073709552e19`), a JSON number written with a fraction or
|
|
658
|
+
an exponent and a negative zero (`-0`, `0 * -1` printed `0`). Such a value in a var file is given
|
|
659
|
+
but unresolved, so the variable's default no longer stands in for it (#711).
|
|
660
|
+
- Terraform: `toset` orders its elements as Terraform does (numbers by value, `false` before
|
|
661
|
+
`true`, a null last, strings with numbers or bools as strings), where it kept a number's or a
|
|
662
|
+
bool's first order: `tolist(toset([10, 9]))[0]` was an `exact` `10` for Terraform's `9`. A set of
|
|
663
|
+
collections, in Terraform's hash order, and a set of numbers and bools, which Terraform refuses,
|
|
664
|
+
are `*` (#711).
|
|
665
|
+
- Terraform: a null or a collection interpolated into a name (`"q-${null}"`, `"q-${[1]}"`), which
|
|
666
|
+
Terraform refuses, is `*`, where it gave the `exact` names `q-null` and `q-[\n 1\n]` (#711).
|
|
667
|
+
- Terraform: arithmetic on a `for` variable in a `.tfvars` file (`[for x in [1, 2] : x * 2][1]`)
|
|
668
|
+
resolves, as Terraform evaluates it, where the value was given but unresolved (#711).
|
|
669
|
+
- Terraform: a `%{ for }` directive's collection is read as any other expression, where its keys
|
|
670
|
+
kept their written order and a number its float text (`%{for k, v in {b = 1, a = 2}}` gave
|
|
671
|
+
`b1a2`, Terraform `a2b1`); a negative zero there is `*`. An object of several keys inside a var
|
|
672
|
+
file's template, with or without line comments, no longer drops the value for the default (#711).
|
|
673
|
+
- Terraform: `tolist` and `tomap` convert their elements to one type, as Terraform does, where
|
|
674
|
+
they kept each element's type: `jsonencode(tolist(["a", 1]))` gave an `exact` `["a",1]` for
|
|
675
|
+
Terraform's `["a","1"]`; collections unify as cty does (`[[1], ["a"]]` to `[["1"],["a"]]`). A
|
|
676
|
+
number with a bool and a list's null beside a collection, which Terraform refuses, are `*` (#711).
|
|
677
|
+
- Terraform: a `for` over `tolist`, `toset` or `tomap` (`{for o in tolist(var.items) : o.name =>
|
|
678
|
+
o}`) costs as a `for` over its argument, so forty objects from a var file expand where the
|
|
679
|
+
estimate, the argument's size squared, left the resource `*` past about a kilobyte (#711).
|
|
680
|
+
- Terraform: a `for` or `%{ for }` binding a key over `toset(...)` (`for k, v in toset(x)`) is
|
|
681
|
+
`*`, where the key was the index (`q-0`) and Terraform's is the element (#711).
|
|
682
|
+
- Images: a direct path that went through a value a deployer can override (`${CTX:-./app}`)
|
|
683
|
+
runs code `inferred`, not `exact`; a repository's literal image and its own pattern matching
|
|
684
|
+
the same runner are one link, not two `ambiguous` ones; a Helm `image.registry` prefixes
|
|
685
|
+
`image.repository` (a templated one as an unresolved segment), where the runner named a Docker
|
|
686
|
+
Hub image; and an unresolved image name (`image::*`, from `docker/metadata-action`) is no
|
|
687
|
+
`status` orphan (#711).
|
|
688
|
+
- Compose: an override file's `build` with no `context` keeps the base service's context, where
|
|
689
|
+
it built from the override's directory, and the `!reset` and `!override` tags clear or replace a
|
|
690
|
+
base value. A `build` context Docker reads as a git repository (`git@github.com:a/b.git`,
|
|
691
|
+
`github.com/a/b`) is no local directory, so it runs no code of the repository. SAM: a
|
|
692
|
+
function with no `CodeUri` of its own takes `Globals.Function.CodeUri`. Kustomize: a
|
|
693
|
+
`bitbucket.org/` base is remote, as `github.com/` and `gitlab.com/` ones are, where one without
|
|
694
|
+
`?ref` counted as missing (#711).
|
|
695
|
+
- SDK names (GCP and Azure, and AWS in TypeScript): a request field written through a computed
|
|
696
|
+
key (`{['name']: ..}`) or a spread of another object (a spread of a spread too), or written
|
|
697
|
+
after the call inside a loop statement that also holds the call, leaves the name unresolved;
|
|
698
|
+
each gave an `exact` link to the name first written (#711).
|
|
699
|
+
- AWS SDK: a request changed after it is made names no resource: a TypeScript command input
|
|
700
|
+
(SQS's too) whose field is assigned again before the `send`; a Java builder held in a local or
|
|
701
|
+
a `final` field that is set again or handed to another call, itself, through a chain off it or
|
|
702
|
+
through a local holding it (`b.topicArn(..)` before `client.publish(b.build())`), also for SQS and Azure Service Bus and Event Hubs builders; and
|
|
703
|
+
a named entry an inline request holds (an EventBridge entry in C# or Go, an entry builder in
|
|
704
|
+
Java); and a Go request replaced whole through its pointer (`*input = sqs.SendMessageInput{..}`).
|
|
705
|
+
Each gave an `exact` link and provision to the name first written. A TypeScript field
|
|
706
|
+
read off a local object (`{Bucket: cfg.bucket}`) now names its bucket (#711).
|
|
707
|
+
- TypeScript and JavaScript: a generator (`function*` and `async function*`, declared or as an
|
|
708
|
+
expression, a `*method()` of a class or an object) returns its iterator, so a `return new
|
|
709
|
+
Storage()` in one no longer makes it a client factory; it gave an SDK resource (Pub/Sub, Cloud
|
|
710
|
+
Storage, Azure Service Bus and Blob) and an `exact` provision to code that never holds the
|
|
711
|
+
client (#711).
|
|
712
|
+
|
|
9
713
|
## [1.2.0] - 2026-11-04
|
|
10
714
|
|
|
11
715
|
A minor release on the [1.x stability promise](https://github.com/ClaudioMascaro/meada/blob/main/docs/site/en/stability.md):
|
|
@@ -1297,7 +2001,8 @@ and `trace` from the two longest processes. The spec adds about 0.3 MB and 0.03
|
|
|
1297
2001
|
The rise of the single-file reindex since 2026-10-14 predates it (specs #22 and #23), and at
|
|
1298
2002
|
692 files it is close to its target.
|
|
1299
2003
|
|
|
1300
|
-
[Unreleased]: https://github.com/ClaudioMascaro/meada/compare/v1.
|
|
2004
|
+
[Unreleased]: https://github.com/ClaudioMascaro/meada/compare/v1.3.0...HEAD
|
|
2005
|
+
[1.3.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v1.3.0
|
|
1301
2006
|
[1.2.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v1.2.0
|
|
1302
2007
|
[1.1.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v1.1.0
|
|
1303
2008
|
[1.0.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v1.0.0
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Escolha a linha que combina com o que você já tem. Todos os canais entregam o
|
|
|
18
18
|
| Rust | `cargo install meada` | `meada mcp` |
|
|
19
19
|
| Linux ou macOS | o instalador de shell abaixo | `meada mcp` |
|
|
20
20
|
| Qualquer sistema | o arquivo do seu sistema nas [releases do GitHub](https://github.com/ClaudioMascaro/meada/releases), com `meada` no `PATH` | `meada mcp` |
|
|
21
|
-
| Docker | `docker pull ghcr.io/claudiomascaro/meada:1.
|
|
21
|
+
| Docker | `docker pull ghcr.io/claudiomascaro/meada:1.3.0` | a linha `docker run` em [Conectar um agente](#conectar-um-agente-mcp) |
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
24
|
# Instalador de shell (Linux e macOS)
|
|
@@ -75,7 +75,7 @@ Com Docker (Linux e macOS):
|
|
|
75
75
|
"mcpServers": {
|
|
76
76
|
"meada": {
|
|
77
77
|
"command": "sh",
|
|
78
|
-
"args": ["-c", "exec docker run -i --rm --network none --user \"$(id -u):$(id -g)\" -v \"${PWD%/*}:${PWD%/*}\" -w \"$PWD\" ghcr.io/claudiomascaro/meada:1.
|
|
78
|
+
"args": ["-c", "exec docker run -i --rm --network none --user \"$(id -u):$(id -g)\" -v \"${PWD%/*}:${PWD%/*}\" -w \"$PWD\" ghcr.io/claudiomascaro/meada:1.3.0 mcp"]
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -97,7 +97,7 @@ ler os níveis de uma resposta. No Claude Code:
|
|
|
97
97
|
|
|
98
98
|
```sh
|
|
99
99
|
mkdir -p ~/.claude/skills/meada
|
|
100
|
-
curl -fsSL https://raw.githubusercontent.com/ClaudioMascaro/meada/v1.
|
|
100
|
+
curl -fsSL https://raw.githubusercontent.com/ClaudioMascaro/meada/v1.3.0/skills/meada/SKILL.md -o ~/.claude/skills/meada/SKILL.md
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
Outros agentes: veja [Agentes e MCP](https://claudiomascaro.github.io/meada/mcp/#skill-para-agentes).
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hasInstallScript": true,
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"name": "@meada/meada",
|
|
22
|
-
"version": "1.
|
|
22
|
+
"version": "1.3.0"
|
|
23
23
|
},
|
|
24
24
|
"node_modules/detect-libc": {
|
|
25
25
|
"engines": {
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"requires": true,
|
|
51
|
-
"version": "1.
|
|
51
|
+
"version": "1.3.0"
|
|
52
52
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"artifactDownloadUrls": [
|
|
3
|
-
"https://github.com/ClaudioMascaro/meada/releases/download/v1.
|
|
3
|
+
"https://github.com/ClaudioMascaro/meada/releases/download/v1.3.0"
|
|
4
4
|
],
|
|
5
5
|
"bin": {
|
|
6
6
|
"meada": "run-meada.js"
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"zipExt": ".tar.xz"
|
|
90
90
|
}
|
|
91
91
|
},
|
|
92
|
-
"version": "1.
|
|
92
|
+
"version": "1.3.0",
|
|
93
93
|
"volta": {
|
|
94
94
|
"node": "18.14.1",
|
|
95
95
|
"npm": "9.5.0"
|