@meada/meada 0.1.0 → 1.1.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 CHANGED
@@ -6,6 +6,531 @@ All notable changes to Meada are recorded here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.1.0] - 2026-11-02
10
+
11
+ A minor release on the [1.x stability promise](https://github.com/ClaudioMascaro/meada/blob/main/docs/site/en/stability.md):
12
+ local accounts (ADR 0024) in the console, the proposal server and the nodes, carried by the
13
+ `cloud` image, the Compose recipe and the Helm chart; the export's `format` and indexed commit;
14
+ client-side deadlines on every Postgres call; durable pulled-generation writes; resolver fixes
15
+ for C#, Kotlin, Rust and Swift (tier b3); and the fixes of tiers b1 and b2. The index schema
16
+ version changes, so existing indexes are rebuilt once on first use. `meada-core` 1.1.0 adds `format`, `commit` and `dirty` to `Export`, and its
17
+ `export::parse` refuses a document without `format`: re-export with 1.1.0 before parsing an export
18
+ written by 1.0.0. The tree, the `meada-core` pin, the Dockerfile, the compose defaults and the
19
+ Helm chart declare `1.1.0`, and the `v1.1.0` tag follows this entry's merge on main. Publication
20
+ (crates, the staged npm package, the GitHub draft release) belongs to the maintainer.
21
+ Release notes are available in
22
+ [pt-BR](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.1.0.md),
23
+ [English](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.1.0.en.md) and
24
+ [Spanish](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.1.0.es.md).
25
+
26
+ ### Added
27
+
28
+ - The export format and the indexed commit (#512, ADR 0004 "Canonical export"): every export
29
+ starts with `format` (`meada_core::export::FORMAT`, 1), which rises only when a reader of the
30
+ previous shape would misread the new one, never for an added optional field; then
31
+ `repository`, then `commit` and `dirty`, both optional and left out together. Locally `meada export` reads `HEAD` before and
32
+ after its refresh and the checkout's status after it (ignored files, `.meada/` among them, do
33
+ not count), and names the commit only when `HEAD` did not move and the index is fresh; outside
34
+ git or before the first commit both are left out. In server mode they come from the commit
35
+ `meada index --workspace` recorded beside the index, or a generation's `head`, never from the
36
+ mirror's live `HEAD`, with `dirty` false. For `meada-core` crate users: `Export` gains
37
+ `format`, `commit` and `dirty` (a minor change, the struct being `#[non_exhaustive]`, so the
38
+ next `meada-core` release is 1.1.0), and `export::parse` refuses a document without `format`,
39
+ naming the field, so an export written before this release no longer parses. Every `*.export.json` golden gained the three fields.
40
+
41
+ - Named workspaces and the proposal server with local accounts (#562, ADR 0024, from #551):
42
+ `[catalog]` and `[workspaces]` (and so `[proposals]`) accept `[accounts.github]` in place of
43
+ `[oidc.github]` and still need one of the two (`[catalog] needs [oidc.github] or
44
+ [accounts.github]`; `[workspaces]` now names `[ui]` and `[catalog]`, the catalog naming the
45
+ provider). Eligibility reads the account's verified login, an operator account is the platform
46
+ administrator, and workspace operator lists, version authors, history and audit records name
47
+ `local:` subjects. `POST /api/v1/account/tokens` takes `{"surface": "proposals"}` when the
48
+ console's bootstrap has `[proposals]` (audience `meada:proposals`; a 422 `invalid_surface`
49
+ without it), `config` carries `"proposals": true` and the profile page offers the surface. The
50
+ proposal server with `[accounts]` and no `[oidc]` reads the public key at start and admits only
51
+ those tokens (a session token or a node's agent token is a 401 with `WWW-Authenticate: Bearer`,
52
+ no protected resource metadata), deriving the subject, login, groups, grant and role from the
53
+ token alone. No golden changed.
54
+ - The verified GitHub login of local accounts (#561, ADR 0024, from #551): `[accounts.github]`
55
+ (`host`, `roles`, `max_age_seconds` as `[oidc.github]`, plus `api`, `https://api.github.com` by
56
+ default on `github.com` and required on any other host) is the GitHub grant provider of local
57
+ accounts. A person pastes a GitHub personal access token on their profile page or sends it to
58
+ `POST /api/v1/account/github`; the console calls `GET /user` on `api` once, keeps the lowercase
59
+ login and drops the token, and answers a fresh session token carrying the login. A login
60
+ another account holds is a 409 `login_taken`, GitHub's refusal a 422, GitHub out of reach a
61
+ 503. `POST /api/v1/account/github/remove` and the accounts page's `remove_github` action remove
62
+ it. Session and agent tokens carry the verified login, so the GitHub grant joins the groups
63
+ grant in the console (`session` shows `login`, `github_host` and `github_grant`), on nodes, in
64
+ a team operator's additions (`added_by`), in the audit's `login` column and in the exclusions
65
+ marks; `meada github-app roles` reads `[accounts.github]`. Recorded `account.github` and
66
+ `account.remove_github`; the personal access token is never stored, logged or audited. No
67
+ golden changed.
68
+
69
+ - Helm chart support for local accounts (#565, ADR 0024, from #551): `modules.accounts` renders
70
+ `[accounts]` from values, with `values-accounts.yaml` as the proof-of-concept shape (a writable
71
+ console with `operations = true`, Postgres and no identity provider). The Ed25519 private key
72
+ comes from its own Secret and is mounted only in the console's `console` container, the public
73
+ key from another Secret in the console and the nodes (a node also gets `[ui] public_url`, the
74
+ token issuer, and `[postgres]`), the initial admin password from an optional Secret in the
75
+ console. `modules.accounts.groups` and `modules.accounts.github` carry `[accounts.groups]` and
76
+ `[accounts.github]` (the refresh job, with `modules.githubApp`, gets the GitHub grant provider and runs the role check, and
77
+ `modules.workspaces` accepts it in place of `modules.oidc.github`); `modules.accounts.breakGlass`
78
+ keeps `[accounts]` in the console alone beside `modules.oidc`. The chart refuses a missing
79
+ Postgres or console, equal key Secrets, accounts beside OIDC without break glass, and groups or
80
+ GitHub under break glass. `scripts/helm-check` covers the sections, the mounts and the refusals;
81
+ the chart READMEs (pt-BR, English, Spanish) no longer say a writable console needs OIDC. The
82
+ proposal server is not part of the chart. `[accounts.github]` renders as the spec names it and
83
+ is parsed once #561 lands. No golden changed.
84
+
85
+ - One-command proof of concept in the Compose recipe (#564, ADR 0024, from #551):
86
+ `cp .env.accounts.example .env && docker compose up -d` starts the generations fleet, Valkey,
87
+ the store, Postgres with its migration, a writable console with local accounts and nodes that
88
+ admit agent tokens. `compose.accounts.yaml` adds the Ed25519 key pair (made once by the
89
+ `certificates` step, never printed, the private key mounted read-only in the console alone and
90
+ the public one in the nodes), the console's and the nodes' `[accounts]` manifests, a one-shot
91
+ `seed` of the first workspace version (only while the store has none) and a node proxy that
92
+ forwards `Authorization` with no static bearer. The other profiles are unchanged, and
93
+ `scripts/compose-check` covers the new one. The Compose README (pt, en, es) starts with it and
94
+ covers `MEADA_ADMIN_PASSWORD`, `meada ui reset-admin`, key rotation and rate limiting the
95
+ sign-in route at the proxy.
96
+
97
+ - Agent tokens for the nodes (#560, ADR 0024, from #551): a signed-in local account generates,
98
+ on its profile page or through `POST /api/v1/account/tokens` (`{surface: "nodes", hours}`, 1 to
99
+ 168 hours, 8 by default), an agent token shown once (`{token, expires_at, surface}`), signed
100
+ with the account's role and groups as its row stands and a random token id, recorded
101
+ `account.token` (surface, hours, token id, never the token). A change-required account gets the
102
+ 403 `password_change_required`, a suspended one the role refusal; the console answers an agent
103
+ token with 401. A node with `[accounts]` and no `[oidc]` (`meada mcp --listen`) now reads the
104
+ signing public key at start, and the console's `[ui] public_url` from a `[ui]` section its
105
+ manifest must carry, refusing to start without either; it admits only agent tokens for the
106
+ nodes (a 401 `Bearer` before routing for any other, a session token included) and answers
107
+ under the grant `[accounts.groups]` gives their groups (every repository without the table),
108
+ as an identity provider's token is answered. The `accounts` feature now implies `ui`. No golden
109
+ changed.
110
+
111
+ - Accounts page in the console (#559, ADR 0024, from #551): the global operator of a console with
112
+ local accounts gets `/accounts`, listing every account (role, groups, state with a suspended
113
+ account marked and a locked one saying until when, change required, last password change), a
114
+ create form (username pattern and password length checked first, "change on first sign-in"
115
+ checked by default) and, per account, role, groups, suspend, reactivate and reset password,
116
+ each behind the shared confirmation dialog with the server's refusals (`last_operator` and the
117
+ rest) shown unchanged. Any other role, and a console under break glass, gets the not-found
118
+ page at that path. The audit page names every `account.*` action in Portuguese and English.
119
+ The password rule `common_password` now has its own copy. Front end only, no golden changed.
120
+
121
+ - Groups of local accounts (#558, ADR 0024, from #551): the global operator gives accounts groups
122
+ (`groups` on `POST /api/v1/accounts`, and the `groups` action of
123
+ `POST /api/v1/accounts/<username>`, each an owner name, else a 422 `invalid_group`);
124
+ `GET /api/v1/accounts` lists them, and each change is recorded `account.groups`.
125
+ `[accounts.groups]` maps groups to identities as `[oidc.groups]` does: once it exists, a local
126
+ session's grant is what its groups map to, and it bounds every view (the manifest, the
127
+ workspace and its versions, the store, the repositories, the credentials, the playground, the
128
+ exports and the graph views) as an identity provider's grant does; without it every local
129
+ account still reads every repository. A local viewer whose group owns an entry of the current
130
+ workspace version its grant reads is a team operator (ADR 0015). Session tokens carry the
131
+ groups, so a change reaches reads at the next sign-in and writes at once (the account row is
132
+ read before each). `GET /api/v1/admission` with `[accounts]` now answers: `accounts` (the mode,
133
+ `accounts` or `break_glass`, and the signing public key's fingerprint, `blake3:` and the hex
134
+ BLAKE3 hash of the raw Ed25519 key) and, without `[oidc]`, the groups table bounded by the
135
+ caller's grant. No golden changed.
136
+
137
+ - Account administration for local accounts (#557, ADR 0024, from #551): the global operator
138
+ lists every account (`GET /api/v1/accounts`: username, role, state, the end of a lock, change
139
+ required, last password change, created and created by, never a hash), creates one
140
+ (`POST /api/v1/accounts`, `{username, role, password, change_required}`, the policy applied to
141
+ the temporary password, a change required unless the body turns it off; a malformed username a
142
+ 422 `invalid_username`, a taken one a 409 `username_taken`) and changes one
143
+ (`POST /api/v1/accounts/<username>`, one `action`: `role`, `suspend`, `reactivate` or
144
+ `reset_password`, which clears a lock and requires a change unless told not to; an unknown
145
+ account a 404). Suspending or demoting the last active operator is a 409 `last_operator`,
146
+ decided under the schema's advisory lock so two requests at once never leave none. Anyone else
147
+ gets a 403. The routes answer whatever `[ui] operations` says; workspace and generation writes
148
+ keep requiring it. Every console write of a local account now reads the account's row first,
149
+ so a suspended or demoted account loses its writes at once, while its reads last until its
150
+ token expires. Audit actions `account.create`, `account.role`, `account.suspend`,
151
+ `account.reactivate` and `account.reset_password` name the account and the fields changed,
152
+ never a password, written before the change (503 `audit_unavailable` otherwise); `account` is
153
+ the route-level action of a change refused before its body is read. No route deletes or
154
+ renames an account; under `[accounts] break_glass` (#563) none of these routes exists, each a
155
+ 404. No golden changed.
156
+
157
+ - Break-glass account beside the identity provider (#563, ADR 0024, from #551): `[accounts]
158
+ break_glass = true` lets the section sit beside `[oidc]`; without `[oidc]` it is an error, and
159
+ `[accounts.groups]` or `[accounts.github]` under it is an error naming the table. The console
160
+ then signs in only the default account (any other username gets the wrong password's 401,
161
+ audited `not_break_glass`, the table never read) as the global operator, and admits its session
162
+ token beside the identity provider's, each bearer routed by its issuer to one verifier, so the
163
+ identity provider's keys never check a console token and the signing key never checks an
164
+ identity provider's; a console whose `[oidc] issuer` is its own `public_url` refuses to start.
165
+ The password change works; no other route of local accounts exists. Nodes and the proposal
166
+ server keep admitting only the identity provider and read no key. `config` adds `break_glass:
167
+ true`, and the front end offers a discreet break-glass sign-in (`/break-glass`) beside the
168
+ identity provider's, which now waits for a click under break glass. No golden changed.
169
+
170
+ - Hardening of local sign-in (#555, ADR 0024, from #551): the password policy refuses an embedded
171
+ common-password list (SecLists, MIT, the entries of 12 to 128 characters, compared ignoring
172
+ case; rule `common_password`). Ten consecutive failed password checks, at sign-in or as a
173
+ password change's current password, lock an account for fifteen minutes, counted in a
174
+ transaction holding the account row so parallel attempts never pass ten; a success resets the
175
+ count. A locked account gets the wrong password's 401 at a hash's cost, its password unchecked
176
+ and its lock never extended, audited `locked_now` and then `locked`. A stored hash weaker than
177
+ the console's parameters is redone at the next successful sign-in. `meada ui reset-admin
178
+ --workspace <manifest>` (features `ui` and `accounts`) creates or reactivates `admin` as an
179
+ operator, clears its lock and sets the `MEADA_ADMIN_PASSWORD` value or a generated password
180
+ printed once on stdout, with a change required, recorded `account.reset_admin` `via` `cli`
181
+ before the write and refusing with exit 1 when the record cannot be written. No golden changed.
182
+
183
+ - Local sign-in for the console (#554, ADR 0024, from #551): the new `accounts` cargo feature
184
+ (enabled by `cloud`) and its `[accounts]` section, which needs `[postgres]` and never sits
185
+ beside `[oidc]`, name the Ed25519 signing key pair and the default account's initial password,
186
+ each from a variable or a file. Migration 9 adds the `accounts` table, so `meada postgres
187
+ migrate` reaches version 9. On its start the console checks the key pair and creates the
188
+ default account `admin` (password `admin123` with a change required, or the policy-checked
189
+ `MEADA_ADMIN_PASSWORD` without) once, under an advisory lock. `POST /api/v1/login` answers a
190
+ session token the console signs with EdDSA for eight hours; a token carrying the change-required
191
+ mark opens only `POST /api/v1/account/password`. Every route but the static files, `config` and
192
+ `login` then needs a session token; `[ui] operations = true` is accepted with `[accounts]` and
193
+ no `[oidc]`; `config` names the sign-in mode (`sign_in`: `accounts`, or `oidc` with an identity
194
+ provider), `session` adds `account: true`, and
195
+ every account reads every repository while no groups table bounds it. Passwords are argon2id at
196
+ OWASP's parameters under a policy of 12 to 128 characters that refuses the default password and
197
+ the username, at most four hashes run at once, and every sign-in, refusal and password change
198
+ is audited (`account.login`, `account.password`, role `none` for an unknown username) before its
199
+ token. The module table gains `accounts`; no golden changed.
200
+
201
+ - The console's sign-in pages for local accounts (#556, from #551): when `config` says
202
+ `"sign_in": "accounts"` the console shows its own sign-in page (labelled username and password,
203
+ one generic refusal, `busy` and `audit_unavailable` shown as themselves) instead of the identity
204
+ provider's redirect. A change-required sign-in goes straight to a forced password change page
205
+ (the current password and the new one twice, the server's rule shown on a refusal) that offers
206
+ nothing to navigate to until it succeeds, and then opens the workspace. The session token lives
207
+ in `sessionStorage` for the tab's life, is sent as the bearer and is cleared on sign-out and on
208
+ any 401 (which returns to sign-in; a refused current password in the change is not one); it is never in `localStorage`, a URL
209
+ or a log. A profile page offers the voluntary password change and sign-out. pt-BR and English
210
+ copy; the identity provider flow is unchanged. Front end only: no golden changed.
211
+
212
+ - `meada status` names a Kotlin file the grammar misreads (#546, from #434). A declaration read
213
+ as an infix call leaves the file out of the index; the file now sets the new `Facts::misparsed`
214
+ (absent from every other file's stored facts) instead of `unbuilt`, and a new status line,
215
+ `Msg::FileMisparsed`, in English and Portuguese, names it beside the byte-budget and using
216
+ drops. The Java and Kotlin layout skips it as it skips the other drops. The schema version is
217
+ the same: a file dropped before the upgrade gets its line when it next changes, or at once
218
+ after deleting `.meada/index.db`. The `cli.status-budget` goldens gained the new line.
219
+
220
+ ### Changed
221
+
222
+ - The grant providers take neutral inputs (#553, from #551): the new `grant` module computes a
223
+ subject's grant from its groups and its GitHub login (`Providers::grant`), with no reference
224
+ to a token, and holds the GitHub grant provider's permissions cache, which moved out of the
225
+ OIDC module; the OIDC module feeds it from a token's claims. Every reader of `[oidc.github]`
226
+ goes through `Manifest::github`, the console and the proposal server build their sessions
227
+ from a neutral admitted subject (`grant::Admitted`), and a node's pass carries only a grant.
228
+ Nothing a caller sees changes; no golden changed.
229
+
230
+ - The axum provider reader walks each value once per file (#431): the values a file's rebound
231
+ `let`s reach share one `seen` set, and `Code::origins` is not asked for a call whose builder
232
+ chain goes through a method no router hands back, nor for a name written as text, a path, a
233
+ number, a boolean or a character. The reader's share of a one-file refresh on this repository
234
+ drops from about 1.4 s to about 0.1 s. No golden changed.
235
+
236
+ ### Fixed
237
+
238
+ - Swift: a call whose labels differ from a known outside member's resolves as if that base
239
+ were absent (#463): `x.hash(seed: 1)` on a type that conforms to `Hashable` and declares
240
+ `hash(seed:)` is `exact`, while `x.hash(into: &h)` stays opaque. A call with no labels, or in
241
+ another language, is still compared by its bare name.
242
+ - Swift: an alias of an outside type reaches the repository's extensions of that type (#440). A
243
+ receiver typed by `typealias Anim = Animation`, or by an alias of an alias, and `Anim.build()`
244
+ match `extension Animation { }` as `Animation` does; an alias of an outside type with no
245
+ extension stays unresolved.
246
+ - Rust: a call after `?` or `.await` is typed by the value they unwrap (#435, after #401): the
247
+ pack keeps beside a function's written result the first type argument of a `Result` or
248
+ `Option` (`Def::unwrapped`) and the `Output = T` of `impl Future<Output = T>` and
249
+ `Pin<Box<dyn Future<Output = T>>>` (`Def::output`, read only through `.await`), so
250
+ `load()?.port()` and `fut().await.port()` resolve within `T`'s family, `exact` when it
251
+ declares one `port`, where `?` left a name match and a plain `fn` returning a future resolved
252
+ to nothing. A type outside the repository, or a `?` before an `.await`, leaves the call as
253
+ it was. The stored facts gain
254
+ `Def::unwrapped`, `Def::output`, `Call::unwraps` and `Call::awaits`, so the schema version
255
+ changes and Rust indexes are rebuilt once.
256
+ - Kotlin: a class, object or interface nested in an `expect` declaration, at any depth, is
257
+ `expect` too (#437), so a use of it resolves to the `expect` one instead of staying
258
+ `ambiguous` among its `actual` declarations.
259
+ - C# `using static T` imports only the static members and nested types `T` declares (#433): a bare
260
+ `Go()` with `Go` on a base of `T` was an `exact` link to the base's method, which C# rejects
261
+ ("inherited members aren't imported"), and is now a name match at best; `using static` of the
262
+ base itself still gives it. Java's `import static` and Kotlin keep reading inherited members.
263
+ - Kotlin: a bare call resolves in Kotlin's order, an extension of the implicit receiver in scope
264
+ before a top-level function of its name (#436, from #402): inside `fun CoroutineScope.x() {
265
+ launch { } }` the call is `exact` to `CoroutineScope.launch`, not to the top-level `launch`
266
+ (`ambiguous` with it when the extension may apply to any receiver), and an `object`'s name is
267
+ its instance, so `Dispatchers.setMain(..)` reaches an imported `fun Dispatchers.setMain` (it
268
+ was no link) while a class's name keeps companion and statics. "Known ceilings" drops the
269
+ bare-call line. No golden changed.
270
+ - C#: an `internal`, `private` or `private protected` constructor or method of a public type is
271
+ a candidate from its own project's files alone (#441); `InternalsVisibleTo` stays unread.
272
+ - The console writes one `ui: directory: unreadable` stderr line per request when the directory
273
+ cannot be read (#451, after #335): the request's session remembers the failure at admission,
274
+ so the flags, the admission counts and the owner picker take that answer and write no second
275
+ line (`workspace` wrote two), and a write it refuses as 503 `audit_unavailable` prints no
276
+ pre-authentication audit line beside it. Reads still answer with the flags unavailable, the
277
+ counts null and the picker a 503; writes still refuse as before. No golden changed.
278
+ - Postgres calls that had no client-side deadline now have one (#447): a SCIM request (under the
279
+ directory's one write lock), the role check's fence read and write transaction, and the
280
+ console's start check, so a Postgres that accepts the connection and stops answering ends in a
281
+ 503, an exit 1 with no exclusions file a reader admits, and a console that starts, instead of
282
+ holding them forever. `postgres::Config::bound(n)` now adds the version check's two statements
283
+ itself and every call site counts only its own (the audit and directory reads and the overage
284
+ lookup moved accordingly; the accounts' calls, which undercounted, and the permissions poll
285
+ gained the two). No golden changed.
286
+ - A crash after the pointer swap can no longer leave `current` naming a version document that
287
+ never reached the disk (#518): the pointer, the version document `meada workspace pull` writes,
288
+ the pulled contexts file and the exclusions file are replaced through one helper
289
+ (`pull::replace`) that syncs the new file before the rename and removes `<name>.new` when a
290
+ step fails. A failed pointer rename now names `current`, not `current.new`.
291
+ - The docs say what 1.0.0 ships: nine languages (TypeScript, JavaScript, Python, Go, Rust, Java,
292
+ Kotlin, C# and Swift). The three READMEs, the three 1.0.0 release notes and the three user
293
+ guides no longer call Java, Kotlin, C# and Swift later 1.x work, the user guides gain a section
294
+ for each of the four (9.5 to 9.8) with their brokers (JMS, Azure Service Bus) and package
295
+ ecosystems (Maven and Gradle, NuGet, SwiftPM), and ADR 0003 records the change in an
296
+ amendment. No code, default dependency or golden changed.
297
+ - A server-mode mirror's `meada.toml` and `meada.decisions.toml` are read through no symbolic
298
+ link (#547, after #506), as a pulled generation's are: `mirror()`, behind `Manifest::read`
299
+ (`mcp --listen`, snapshot pull, the lock and pointer operations, workspace versions, the
300
+ heartbeat, the UI, the workspaces CLI, the GitHub App), now refuses a link unopened, one that
301
+ stays inside the mirror included, a file that is not regular and a file replaced while read,
302
+ with the generation's messages, and bounds each file at 1 MiB (`GENERATION_CONFIG_MAX`, now
303
+ built without the `snapshot` feature). A local checkout and an operator's own files still
304
+ follow links. The architecture map and the snapshots page, in its three languages, say so.
305
+ - No manifest error quotes a written value (#545), after #449 stopped serde's `invalid type` and
306
+ `invalid value`: `unknown variant` names the key and the values it accepts (`` `workspace.source`:
307
+ is not one of the values it accepts (`file`, `store`) ``) instead of serde's text, an error no
308
+ key spans reads "a value is not valid here" instead of serde's message, and the rule errors
309
+ for `serve.prefix`, `serve.strip`, `serve.documents` and a resource's `kind` name the key and
310
+ the rule (`` `serve.strip`: must start with `/` ``) instead of the value. The console's cut of
311
+ an error to its position stays as a second guard (it still covers an error built outside
312
+ `describe` that names an identity). English and pt-BR texts changed; the workspace validation
313
+ fixture changed only by the new texts.
314
+ - The deploy fetch reads a `[[repository]]` entry by its own keys (#544): any table header ends
315
+ the entry before it, so a `[[repository.peer]]` or `[[repository.resource]]` table no longer
316
+ replaces its `repo` or `path`, and a value is the text between its quotes, so a trailing
317
+ comment is not part of it. Before, such a version stopped the Compose refresh and let the chart
318
+ clone the peer's repository into the entry's path (or into a directory named after the
319
+ comment). `fetch-pulled.sh` and the chart's `workspace.fetch` carry one awk program, and a
320
+ test fails when the two copies drift. No golden changed.
321
+ - A repository identity on the `[oidc.github]` host compares without case wherever it meets the
322
+ catalog (#508): the roles job gives a selected `github.com/Acme/API` and the catalog's
323
+ `github.com/acme/api` one `both` row keyed as written, the `max_repositories` cap does not
324
+ count it as extra, and the console's catalog check and listing match it. A repository selected
325
+ in two spellings (a deployment's `github.com/Acme/API`, a named workspace's
326
+ `github.com/acme/api`) keeps one `source` row under the first and gets its role rows under
327
+ each, so grants, which match exactly, read both. Other hosts compare exactly. No golden
328
+ changed.
329
+ - Compose mirror origins (#445): `fetch.sh` and `fetch-pulled.sh` read an existing mirror's
330
+ `origin` before fetching and refuse one whose HTTP(S) URL carries credentials (a mirror cloned
331
+ from a URL with a token keeps it there), naming the identity and never the URL, and the refresh
332
+ stops before index and publish as a failed fetch does. The READMEs tell the operator to run
333
+ `git remote set-url origin <URL without credentials>` in such a mirror.
334
+ - Java and Kotlin: a file with thousands of fields and locals is read in linear time (#442, from
335
+ #424). The hides check indexes the fields by name instead of scanning every field per local,
336
+ the class around a write is found from the prefixes of its scope, and `declared_before` (and
337
+ Kotlin's `assigned`) read a node's parent from an index built once per file, since
338
+ `Node::parent()` is found from the root and made a deep file quadratic per write. Same answers;
339
+ no golden changed.
340
+ - Indexing: a file a pack drops for passing a limit is named by `meada status` (#434, from
341
+ #419). The Java, Kotlin and Swift qualified-name budget (4 MiB) now sets `Facts::budget`, as the
342
+ C# one does, instead of `unbuilt`, which prints nothing; a C# project that gives its files more
343
+ than 256 usings (`PROJECT_USINGS`) marks each of them with the new `Facts::usings`, which a new
344
+ status line names (`Msg::FileTooManyUsings`, with the count). Kotlin's `misparsed` file stayed
345
+ `unbuilt` (a grammar defect, not a limit; #546 names it too). An index built before this change keeps a Java,
346
+ Kotlin or Swift file dropped by its budget as `unbuilt` until the file changes. No limit
347
+ changed. The `cli.status-budget` goldens gained the new cases; no stored format golden changed
348
+ (the new field is absent from every sample), so the schema version is the same.
349
+ - Resolution: the receiver and call depth (`RECEIVER_DEPTH`) is one count for the whole lookup
350
+ (#432, from #417), carried through a glob, an alias or an on-demand import as the link count is,
351
+ so a chain that alternates receivers and imports costs its length, not `RECEIVER_DEPTH` per link
352
+ up to `LINK_DEPTH`. No limit changed and no answer under the limits; no golden changed.
353
+ - Helm: the default `workspace.fetch` (#444, from #316) reads the repositories from `$1` when
354
+ given (the pulled list under `modules.oidc.github`) else from `workspace.repositories`, now
355
+ mounted as `repositories.toml` so a store-sourced refresh, whose bootstrap lists none, still
356
+ fetches the operator's list, refuses a URL carrying a credential and, as the compose
357
+ scripts do (#445), an existing mirror whose `origin` carries one, keeps each mirror strictly
358
+ under `/data/mirrors`, and on failure prints `refresh: fetch failed for <identity>; the refresh
359
+ stops before publication` and exits nonzero without echoing a URL or token.
360
+ `scripts/helm-check` runs the rendered script under `sh` with a stub `git` to check these; the
361
+ chart READMEs describe it.
362
+ - Workspace import (#450): `meada workspace import` reads its file once, bounded by the version
363
+ size limit, and audits the id of the text it stored; a file past the bound or not a regular
364
+ file is refused before any audit record is written.
365
+ - Manifest type errors (#449): a `meada.toml` or workspace manifest key of the wrong type, or
366
+ with an invalid value, reports the key and the expected kind (`` `oidc.entra`: has the wrong
367
+ type (a table was expected) ``) instead of serde's message, which echoed the written value, so a
368
+ secret pasted under the wrong key no longer reaches stderr.
369
+ - Pulled generations (#506): a mirror's `meada.toml` or `meada.decisions.toml` that is a symbolic
370
+ link is refused unopened, the error naming the file, so a repository can no longer make a node
371
+ read and parse a file of the host. A link into the mirror (`meada.toml -> conf/meada.toml`) is
372
+ refused too, as the index refuses a linked pack config. The file opened is checked to be the one
373
+ checked. Secrets and CAs a manifest names still follow links (Kubernetes mounts them through
374
+ one). The snapshots page says so in its three languages.
375
+ - Named workspaces on a node (#510): a node shows a named workspace's route
376
+ (`/-/workspaces/<id>/<identity>`, pinned or not) and lists it in a 404 only to a token whose
377
+ grant reads every entry of the workspace's version, the entries the sponsor rule excluded
378
+ included, as the console does. Before, once A of a Y+A workspace lost its sponsor, a subject
379
+ reading Y alone found the workspace on a node. A generation's context now records `excluded`,
380
+ the identities the sponsor rule left out, sorted, and its digest covers them; a context without
381
+ one is written as before, with the same generation id, and a generation published earlier reads
382
+ as none excluded. A node on an older binary refuses a generation that records an exclusion, so
383
+ upgrade nodes before or with the publisher. No golden changed.
384
+
385
+ ## [1.0.0] - 2026-10-30
386
+
387
+ The tree declares `1.0.0`: this release raises the workspace, the `meada-core` pin, the Dockerfile,
388
+ the compose defaults and the Helm chart from `0.1.0`, and the `v1.0.0` tag follows its merge on
389
+ main. Publication is still ahead and belongs to the maintainer under
390
+ [#154](https://github.com/ClaudioMascaro/meada/issues/154): `cargo publish` of the crates (core
391
+ first), approval of the staged npm package with 2FA, and publication of the GitHub draft release,
392
+ which triggers the OCI image and Helm chart workflow.
393
+ Release notes and the scope evidence checklist are available in
394
+ [pt-BR](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.0.0.md),
395
+ [English](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.0.0.en.md) and
396
+ [Spanish](https://github.com/ClaudioMascaro/meada/blob/main/docs/releases/1.0.0.es.md).
397
+ The [1.x stability promise](https://github.com/ClaudioMascaro/meada/blob/main/docs/site/en/stability.md)
398
+ starts at publication. The [#32 tracking checklist](https://github.com/ClaudioMascaro/meada/issues/32)
399
+ still needs the post-publication evidence.
400
+
401
+ ### Added
402
+
403
+ - Public fixture benchmark (issue #149): release-profile index/reindex timings, root and
404
+ workspace index sizes, and default-answer/tool-list token estimates in every PR/main CI
405
+ summary and retained JSON/Markdown artifact. Timings are informational.
406
+
407
+ - The English user guide and README (#150, spec #32): `docs/user-guide.en.md` translates both
408
+ halves of the pt-BR guide section by section (sections 1 to 11) with the same neutral examples
409
+ and links the English stability page; `README.en.md` now links it instead of the pt-BR guide.
410
+ No code, default dependency or golden changed.
411
+ - The Spanish user guide (#151, spec #32): `docs/user-guide.es.md`, sections 1 to 11 of the pt-BR
412
+ guide with the same structure and neutral names, linking the Spanish stability page. The Spanish
413
+ README links it instead of the Portuguese guide, and the three READMEs link the stability page
414
+ from the Status section. No code, default dependency or golden changed.
415
+ - The output grammar reference (#145, spec R1): `docs/reference/output-grammar.md`, in English like
416
+ the MCP surface, specifies every line kind of `search`, `context` and `trace`, the link notation
417
+ with its level and reason, the levels in order, the contract identifiers (`http::`, `http::ANY::`
418
+ for a provider of every method, `channel::`, `package::`, `resource::`), the `search` kinds, the
419
+ chain footer, the cut note and the token estimate, and tells readers to skip line kinds and
420
+ fields they do not know. Its tables are the grammar check's input: `tests/it/grammar.rs` matches
421
+ every line of every rendered-answer golden against the line kinds of its tool and fails naming
422
+ the golden and the line, fails on a documented line kind no golden shows, and holds the
423
+ document's levels, entry kinds, open item kinds and `search` kinds to the code's. The stability
424
+ document links it. No output changed; new goldens pin the answers only inline assertions covered (`no symbol
425
+ matches`, `no resource matches`, the server's `index behind the mirror`, and `trace` with no
426
+ start, several symbols, several call sites or a clean working tree).
427
+ - The pt-BR user guide, second half (#147, spec #32), in `docs/user-guide.md` (sections 8 to 11):
428
+ each contract kind (HTTP routes, declared resources and gateway prefixes, OpenAPI and AsyncAPI
429
+ documents, channels with the limit that broker clusters are not modelled, packages), each 1.0
430
+ language pack (TypeScript and JavaScript, Python, Go, Rust) with its frameworks, clients,
431
+ environment reads, manifests, channel clients and known limits (including that Rust calls inside
432
+ macros are not indexed), shape drift, and communities and processes. Java, Kotlin, C# and Swift
433
+ are named only as planned Release 2 work. No code, default dependency or golden changed.
434
+ - The pt-BR user guide, first half (#146, spec #32), in `docs/user-guide.md`: installation through
435
+ every channel (Cargo, prebuilt binary, shell installer, `npx @meada/meada`, container), MCP setup with
436
+ `npx @meada/meada mcp` and the three tools with their parameters, the `meada.toml` reference (every
437
+ table and key), decisions and deciders (protocols, environment variables, what is sent,
438
+ privacy), every CLI command and the export. The READMEs in all three languages gain the
439
+ installation channels, first steps, MCP setup and a 1.0 status section with the stability
440
+ promise. No code, default dependency or golden changed.
441
+ - Surface goldens (#144, spec #32): `tests/golden/mcp.tools.json` holds the MCP tool list (names,
442
+ descriptions and parameter schemas of `search`, `context` and `trace`), checked beside the
443
+ 1,000-token limit of the descriptions, and `tests/golden/cli.help-all.en.txt` the English help of
444
+ every command of the default build. A test pins the default token budget of 2,000. Both
445
+ goldens change only with `MEADA_BLESS=1`.
446
+ - The stability document (#148, spec #32), `docs/site/{pt,en,es}/stability.md`: the surface 1.x
447
+ freezes (the MCP tools, the output grammar, CLI commands and flags, the `meada.toml`,
448
+ `meada.decisions.toml` and `meada.workspace.toml` schemas, the export), what is breaking, what is
449
+ minor, what is not frozen, and the review gate. The READMEs and the site home pages link it.
450
+ - `search`, `context` and `trace` read from each index its contract rows and only the symbols,
451
+ calls and communities of their answer (#396, **Partial export**), instead of every row of every
452
+ repository. Answers are the same bytes; on junit5 a `search` or `context` peaks at about 40 MB
453
+ instead of 170 to 190 MB and answers in about 0.3 s instead of 1 to 1.4 s. The index gains
454
+ seven lookup indexes (about 40% larger on junit5) and its schema version changes, so existing
455
+ indexes are rebuilt. `meada export`, `status` and the decision report still read every row.
456
+ - A Meada skill for agents, `skills/meada/SKILL.md`: when to reach for `search`, `context` and
457
+ `trace`, how to read each level, and that a missing caller is unproven. The READMEs and the
458
+ site's MCP page show how to install it.
459
+ - Per-channel install and MCP setup: the READMEs open with one row per channel (npx, Cargo, shell
460
+ installer, archive, Docker) with its install line and MCP server command, and gain a Docker MCP
461
+ line that mounts the folder holding the repository at the same path and runs without a network.
462
+ `scripts/container-smoke` runs that line as a stdio client.
463
+ - The site's Deploy page (`docs/site/{pt,en,es}/deploy.md`) covers Docker, Compose and Helm, and
464
+ the chart gains `values-minimal.yaml`, which `scripts/helm-check` renders.
465
+
466
+ ### Changed
467
+
468
+ - For `meada-core` crate users: the export's structs (`Export` and each of its pieces, with
469
+ `Shape` and `Drift`) are `#[non_exhaustive]`, so a field added in 1.x is a minor change. Build
470
+ one with `T::default()` and named field assignments, or, for a struct with a field that has no
471
+ default (`Document`, `Import`, `Link`, `Process`, `Step`, `Stale`), with `T::new` taking every
472
+ field in declaration order (`Shape::new` takes the source, the rest set after it). A struct
473
+ literal or an exhaustive pattern of these types outside `meada-core` no longer compiles. No
474
+ output, golden or exported byte changed.
475
+ - The stability promise (spec #32) lets 1.x grow the MCP surface. In
476
+ `docs/site/{pt,en,es}/stability.md` and the three READMEs, these are minor changes: adding an MCP
477
+ tool while the tool list stays within its 1,000-token budget, adding an accepted value to an
478
+ existing parameter (a new value of `changes`) and adding a field at the end of an existing line
479
+ kind. Removing or renaming a tool or parameter and changing what an existing one means stay
480
+ breaking. ADR 0008 is amended: three tools is where the surface started, not a ceiling.
481
+ - `SECURITY` (pt-BR, English and Spanish): the latest published 1.x version receives security
482
+ fixes, which ship as a patch or minor release.
483
+
484
+ ### Fixed
485
+
486
+ - Console GitHub grant (#496): a session's GitHub grant and its state (`unread`, `current`,
487
+ `expired`) are read from the same permissions set at the same instant, so a session never shows
488
+ `expired` with a grant read while the set was fresh.
489
+ - Release preparation keeps the GitHub release in draft state for the maintainer to publish.
490
+ A pinned cargo-dist regeneration helper compares the entire workflow after the explicit
491
+ draft policy; OCI publication follows the human `release: published` event.
492
+
493
+ ### Prepared
494
+
495
+ - The v1 scope: HTTP, declared resources and gateway paths, OpenAPI/AsyncAPI, channels and
496
+ packages; levels and cross-repository chains, recorded decisions with optional deciders,
497
+ shape drift, TypeScript/JavaScript, Python, Go, Rust, communities and processes.
498
+ - The R1 stability promise, normative MCP output grammar, surface goldens, complete user
499
+ references and public-fixture CI benchmark. Fixture timings are informational.
500
+ - Configured Cargo, binary, shell, npm and OCI distribution. Configuration is not evidence
501
+ of actual publication or a successful published-installer smoke check.
502
+
503
+ ### Acceptance
504
+
505
+ The [public #152 receipt](https://github.com/ClaudioMascaro/meada/issues/152#issuecomment-6379316350)
506
+ retains both complete runs on AMD Ryzen 7 5825U, 16 logical CPUs, 7.16 GiB RAM,
507
+ Ubuntu 24.04.5 LTS, x86_64. The measured build was
508
+ `9b99c3a4091b6c1b2c590c43059763f25b6987ef`, `meada 0.1.0`, not every later documentation head.
509
+
510
+ | Metric | Target | First complete run | Complete rerun |
511
+ | --- | --- | --- | --- |
512
+ | Cold configured-workspace index | <= 7 s | 12.680 s, not met | 2.711 s, met |
513
+ | Root index size | <= 37 MB | 21.057536 MB, met | 21.057536 MB, met |
514
+ | Single-file configured-workspace reindex | <= 1 s | 1.346 s, not met | 1.152 s, not met |
515
+ | Compact MCP `tools/list` result | <= 1,000 tokens | 622, met | 622, met |
516
+ | Largest default answer among 11 queries | <= 2,000 tokens | 1,996, met | 1,996, met |
517
+
518
+ MB means 10^6 bytes; tokens are ceil(UTF-8 bytes / 4). Public fixture peers supplement the
519
+ private workload; the receipt does not claim every feature naturally occurs in the private root.
520
+ The [rerun of 2026-10-30](https://github.com/ClaudioMascaro/meada/issues/152#issuecomment-6531862493)
521
+ on main `1d648ad6` uses a reconstructed workspace (not directly comparable) and meets four of the
522
+ five targets: cold index (medians 5.586 to 6.625 s, <= 7 s), root index size (31.883266 MB,
523
+ <= 37 MB), `tools/list` (643 tokens, <= 1,000) and largest default answer (1,999 tokens,
524
+ <= 2,000). The single-file reindex (<= 1 s) met the target in the two quieter runs (0.99 and
525
+ 0.931 s) and missed it in the two runs at a load average near 3 (1.068 and 1.123 s). The
526
+ maintainer [waived the reindex target for 1.0.0](https://github.com/ClaudioMascaro/meada/issues/350#issuecomment-6532716065),
527
+ recorded on [#350](https://github.com/ClaudioMascaro/meada/issues/350).
528
+
529
+ Known limit: the single-file reindex sits near 1 s and exceeds it under load. #350 stays open for
530
+ 1.x, with the goal of 1 s with headroom under ordinary load; a speedup changes no output, so it
531
+ ships as a patch or minor release. Publication is done separately by the maintainer under
532
+ [#154](https://github.com/ClaudioMascaro/meada/issues/154).
533
+
9
534
  ## [0.1.0] - 2026-10-30
10
535
 
11
536
  The first release: the trunk of the roadmap (ADR 0003) and every spec merged since, with
@@ -555,5 +1080,7 @@ and `trace` from the two longest processes. The spec adds about 0.3 MB and 0.03
555
1080
  The rise of the single-file reindex since 2026-10-14 predates it (specs #22 and #23), and at
556
1081
  692 files it is close to its target.
557
1082
 
558
- [Unreleased]: https://github.com/ClaudioMascaro/meada/compare/v0.1.0...HEAD
1083
+ [Unreleased]: https://github.com/ClaudioMascaro/meada/compare/v1.1.0...HEAD
1084
+ [1.1.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v1.1.0
1085
+ [1.0.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v1.0.0
559
1086
  [0.1.0]: https://github.com/ClaudioMascaro/meada/releases/tag/v0.1.0
package/README.md CHANGED
@@ -9,13 +9,127 @@ LLM.
9
9
 
10
10
  ## Instalação
11
11
 
12
+ Escolha a linha que combina com o que você já tem. Todos os canais entregam o mesmo binário
13
+ `meada`, e a última coluna é o comando que a configuração MCP do seu agente executa.
14
+
15
+ | Você tem | Instalação | Comando do servidor MCP |
16
+ | --- | --- | --- |
17
+ | Node.js | nada: `npx -y @meada/meada --version` | `npx -y @meada/meada mcp` |
18
+ | Rust | `cargo install meada` | `meada mcp` |
19
+ | Linux ou macOS | o instalador de shell abaixo | `meada mcp` |
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.1.0` | a linha `docker run` em [Conectar um agente](#conectar-um-agente-mcp) |
22
+
23
+ ```sh
24
+ # Instalador de shell (Linux e macOS)
25
+ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/ClaudioMascaro/meada/releases/latest/download/meada-installer.sh | sh
26
+ ```
27
+
28
+ Os arquivos prontos cobrem Linux, macOS e Windows, em x86_64 e arm64; a imagem cobre Linux amd64
29
+ e arm64. A versão do pacote npm é sempre a da release. Para indexar, o Meada só precisa do
30
+ binário e do git. Os detalhes de cada canal, da console e do contêiner estão em
31
+ [Instalação](https://claudiomascaro.github.io/meada/installation/) e no
32
+ [guia do usuário](docs/user-guide.md) (seção 1, Instalação).
33
+
34
+ ## Primeiros passos
35
+
36
+ Na raiz de um repositório (aqui `web`, que consome a rota de `api`):
37
+
38
+ ```sh
39
+ meada index # monta o índice em .meada/, do repositório e dos pares
40
+ meada status # o estado de cada índice e os pares não encontrados
41
+ ```
42
+
43
+ Para o Meada ligar `web` a `api`, o `meada.toml` de `web` nomeia o par:
44
+
45
+ ```toml
46
+ [[peer]]
47
+ repo = "example.com/acme/api" # remoto git de origin, sem esquema nem .git
48
+ base_url_env = ["API_URL"] # variável de onde o cliente lê a URL base
49
+ ```
50
+
51
+ A referência completa do `meada.toml` está no
52
+ [guia do usuário](docs/user-guide.md) (seção 4, referência do `meada.toml`).
53
+
54
+ ## Conectar um agente (MCP)
55
+
56
+ O cliente executa o comando do servidor MCP e fala com o Meada por stdio. Na configuração do seu
57
+ agente (por exemplo o `.mcp.json` do Claude Code), com npx:
58
+
59
+ ```json
60
+ {
61
+ "mcpServers": {
62
+ "meada": { "command": "npx", "args": ["-y", "@meada/meada", "mcp"] }
63
+ }
64
+ }
65
+ ```
66
+
67
+ No Claude Code, o mesmo em uma linha: `claude mcp add meada -- npx -y @meada/meada mcp`. Com
68
+ `meada` já no `PATH` (Cargo, instalador ou arquivo pronto), use
69
+ `"command": "meada", "args": ["mcp"]`.
70
+
71
+ Com Docker (Linux e macOS):
72
+
73
+ ```json
74
+ {
75
+ "mcpServers": {
76
+ "meada": {
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.1.0 mcp"]
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ O cliente inicia o servidor no seu repositório. O Meada responde sobre o caminho que o cliente
85
+ envia como raiz, então o contêiner monta a pasta que contém o repositório, e os pares vizinhos,
86
+ nesse mesmo caminho; roda com o seu usuário, para o `.meada/` continuar seu, e sem rede, que nem
87
+ a indexação nem o stdio usam.
88
+
89
+ O agente ganha três ferramentas, `search`, `context` e `trace`, que só leem. Veja
90
+ [Agentes e MCP](https://claudiomascaro.github.io/meada/mcp/) e o
91
+ [guia do usuário](docs/user-guide.md) (seção 2, Conectar um agente).
92
+
93
+ ### Skill para agentes
94
+
95
+ [`skills/meada/SKILL.md`](skills/meada/SKILL.md) ensina o agente a escolher cada ferramenta e a
96
+ ler os níveis de uma resposta. No Claude Code:
97
+
12
98
  ```sh
13
- cargo install meada
99
+ mkdir -p ~/.claude/skills/meada
100
+ curl -fsSL https://raw.githubusercontent.com/ClaudioMascaro/meada/v1.1.0/skills/meada/SKILL.md -o ~/.claude/skills/meada/SKILL.md
14
101
  ```
15
102
 
16
- Comece pela instalação completa e escolha entre Cargo, binário, instalador, npm ou contêiner.
103
+ Outros agentes: veja [Agentes e MCP](https://claudiomascaro.github.io/meada/mcp/#skill-para-agentes).
104
+
105
+ ## Status
106
+
107
+ Meada 1.0 entrega todo o escopo da v1 do [ADR 0003](docs/adr/0003-v1-scope-and-roadmap.md):
108
+
109
+ - **Contratos**: rotas HTTP, recursos declarados, documentos OpenAPI e AsyncAPI, filas e
110
+ tópicos, pacotes.
111
+ - **Níveis**: um nível em cada ligação, cadeias que atravessam repositórios e decisões com
112
+ decisor opcional (`meada decide`).
113
+ - **Análises**: drift de forma, comunidades e processos.
114
+ - **Linguagens no 1.0**: nove, TypeScript, JavaScript, Python, Go, Rust, Java, Kotlin, C# e
115
+ Swift (#26 a #29, ADR 0003).
116
+
117
+ **Promessa de estabilidade.** A partir do 1.0 vale o semver: uma mudança incompatível em um
118
+ destes itens pede uma versão major.
119
+
120
+ - os nomes, os parâmetros e a gramática de saída das ferramentas MCP (`search`, `context` e
121
+ `trace` hoje);
122
+ - os comandos e as flags da CLI;
123
+ - os esquemas do `meada.toml` e do `meada.decisions.toml`;
124
+ - o formato do `meada export`.
17
125
 
18
- [Instalação](https://claudiomascaro.github.io/meada/installation/) · [GitHub releases](https://github.com/ClaudioMascaro/meada/releases)
126
+ Acrescentar uma ferramenta MCP, um parâmetro opcional, um valor aceito a um parâmetro, um tipo de
127
+ busca, um campo no fim de uma linha da saída, uma chave de configuração, um campo do export ou
128
+ uma linguagem é mudança menor. Não entram na promessa o texto das mensagens da CLI, o
129
+ texto das descrições das ferramentas, o arquivo de índice e o layout de `.meada/` (reconstruídos
130
+ quando o esquema muda) e quais ligações o Meada encontra num código (melhorar a resolução é
131
+ correção, não quebra). O detalhe do que é congelado e do que não é está em
132
+ [Estabilidade](https://claudiomascaro.github.io/meada/stability/).
19
133
 
20
134
  ## Alimentar uma base de conhecimento
21
135
 
@@ -65,11 +179,14 @@ Meada (invariante 1, [ADR 0002](docs/adr/0002-product-invariants.md)).
65
179
 
66
180
  ## Documentação
67
181
 
182
+ - [Guia do usuário](docs/user-guide.md)
68
183
  - [Configuração](https://claudiomascaro.github.io/meada/configuration/)
69
184
  - [Agentes e MCP](https://claudiomascaro.github.io/meada/mcp/)
70
185
  - [Modo servidor](https://claudiomascaro.github.io/meada/server/)
186
+ - [Implantar com Docker, Compose ou Helm](https://claudiomascaro.github.io/meada/deploy/)
71
187
  - [Console](https://claudiomascaro.github.io/meada/console/)
72
188
  - [Capacidades e limites](https://claudiomascaro.github.io/meada/capabilities/)
189
+ - [Estabilidade](https://claudiomascaro.github.io/meada/stability/)
73
190
  - [Participar](https://claudiomascaro.github.io/meada/contributing/)
74
191
 
75
192
  [Apache-2.0](LICENSE).
@@ -19,7 +19,7 @@
19
19
  "hasInstallScript": true,
20
20
  "license": "Apache-2.0",
21
21
  "name": "@meada/meada",
22
- "version": "0.1.0"
22
+ "version": "1.1.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": "0.1.0"
51
+ "version": "1.1.0"
52
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "artifactDownloadUrls": [
3
- "https://github.com/ClaudioMascaro/meada/releases/download/v0.1.0"
3
+ "https://github.com/ClaudioMascaro/meada/releases/download/v1.1.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": "0.1.0",
92
+ "version": "1.1.0",
93
93
  "volta": {
94
94
  "node": "18.14.1",
95
95
  "npm": "9.5.0"