@astram/guide 0.2.14 → 0.2.16
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/CAPABILITIES.md +45 -1
- package/package.json +1 -1
package/CAPABILITIES.md
CHANGED
|
@@ -429,6 +429,38 @@ imports: [
|
|
|
429
429
|
- `actionsOf(reg)` (`@astram/guard`) returns a registration's vocabulary. `actionsFor(typeKey)`
|
|
430
430
|
is deprecated and returns only the CRUD verbs for every type.
|
|
431
431
|
|
|
432
|
+
## Permission labels and first-seen dates (G-027 step 1; engine 0.16, guard 0.23, identity 0.19)
|
|
433
|
+
- **Declare text for every action of your types**, CRUD included:
|
|
434
|
+
`@ObjectType({ ..., label: 'Weld repair rate value', permissions: { read: { label: 'Weld repair
|
|
435
|
+
rate: view', description: 'See the monthly repair rate per site.', caution: '…' }, … } })`.
|
|
436
|
+
`label` is the type's human name. Each `permissions` entry needs a `label`; `description` and
|
|
437
|
+
`caution` are optional (the caution is for a warning an administrator should read before
|
|
438
|
+
granting, e.g. "Give only to roles that see every site").
|
|
439
|
+
- Limits, checked at boot (`RegistrationError` naming the type, action and field): label 1–80
|
|
440
|
+
characters, description ≤ 255, caution ≤ 300 (after trimming), no control characters or line
|
|
441
|
+
breaks, and only actions the type declares (CRUD unless `crudActions: false`, plus `actions`).
|
|
442
|
+
An empty description or caution is refused: leave the field out instead.
|
|
443
|
+
- **No text ⇒ a generated label** `"<type label>: <verb>"` (read → view, create → create, update →
|
|
444
|
+
edit, delete → delete, a custom `manage_keys` → "manage keys"; the type label is `label` or the
|
|
445
|
+
type key with `_` → space), and boot logs ONE warning naming your keys with no declared label
|
|
446
|
+
and those with no description. The framework declares text for all of its own keys.
|
|
447
|
+
- **The catalog shows it**: `GET /identity/permission-catalog` rows carry `label`, `description`,
|
|
448
|
+
`caution`, `firstSeenAt` and `firstSeenVersion` (frontend-core `PermissionCatalogRow`; render
|
|
449
|
+
`label`, keep the raw `key` to a details view). `GET /identity/record-policies/schema` returns
|
|
450
|
+
the type `label`. The catalog reconcile (shortly after boot, then hourly) rewrites stored text
|
|
451
|
+
to match your code.
|
|
452
|
+
- **The text is visible to every tenant.** The catalog is one list for anyone who may read
|
|
453
|
+
roles, in every company. Never put customer, company or person names, or anything specific to
|
|
454
|
+
one tenant, in a label, description or caution.
|
|
455
|
+
- **First seen**: when the catalog first stores a key it records the date and `APP_RELEASE` (an
|
|
456
|
+
optional env value, 1–64 characters of letters, digits, `. _ + -`; a git tag or sha fits; an
|
|
457
|
+
invalid value stops boot; unset ⇒ date only). It is written once and never changed: a key
|
|
458
|
+
removed and added back keeps its first date. Keys already in the catalog when this release is
|
|
459
|
+
installed have no first-seen date. Set `APP_RELEASE` in your deploy (and `.env`).
|
|
460
|
+
- Two releases running side by side (a rolling deploy) each write their own text on reconcile,
|
|
461
|
+
so labels can alternate until the old instances stop. First-seen data is not affected.
|
|
462
|
+
- Text never grants anything: grants, the grant ceiling, wildcards and `decide()` are unchanged.
|
|
463
|
+
|
|
432
464
|
## Separation of duties (ADR-0048; core 1.12, engine 0.14, guard 0.21, identity 0.18)
|
|
433
465
|
- **Declare it on the type** when the people who started or asked about a record must not
|
|
434
466
|
approve it:
|
|
@@ -587,7 +619,19 @@ upload(@Req() req: Record<string, unknown>) {
|
|
|
587
619
|
- **Set `POOL_MAX_ENGINE`** (e.g. 10). Unset, the engine pool uses `APP_DB_MAX_CONNECTIONS`, and
|
|
588
620
|
the single-layout budget `workers × (POOL_MAX_CORE + POOL_MAX_ENGINE + APP_AUTHZ_POOL_MAX) +
|
|
589
621
|
headroom` fails boot. `APP_DB_MAX_USER_CONNECTIONS` (the account's cap, if the host sets one) is
|
|
590
|
-
checked too.
|
|
622
|
+
checked too. The budget also counts 1 connection per worker for the audit sealer's own pool.
|
|
623
|
+
- **Set `POOL_WORKERS` and `APP_DB_MAX_CONNECTIONS` too** (your real worker count and what the
|
|
624
|
+
server gives you). Their defaults (8 workers, 250) describe a dedicated four-database server; on
|
|
625
|
+
them the single-layout budget is 8 × 27 + 40 = 256 > 250 and boot fails.
|
|
626
|
+
- **Idle connections and timeouts (G-026, both layouts):** the `POOL_MAX_*` values are caps. Idle,
|
|
627
|
+
every framework pool shrinks to `POOL_MIN_IDLE` (default 1) after `POOL_IDLE_TIMEOUT_S` (default
|
|
628
|
+
600), so an idle process holds about 4 connections. Optional `APP_DB_QUERY_TIMEOUT_MS`
|
|
629
|
+
(1000–3600000) aborts a longer statement (the framework's lock waits and the sealer are exempt);
|
|
630
|
+
optional `POOL_LEAK_DETECTION_MS` logs a connection held longer. Invalid values fail boot. Never
|
|
631
|
+
build or patch a pool to tune these; if a setting is missing, flag a gap.
|
|
632
|
+
- **Shutdown:** `main.ts` must call `app.enableShutdownHooks()` (the scaffold does; add it to an app
|
|
633
|
+
scaffolded before G-026). Then a SIGTERM stops the framework's jobs, finishes in-flight requests
|
|
634
|
+
and closes every pool. Set PM2 `kill_timeout` (e.g. 5000 ms) above the shutdown time.
|
|
591
635
|
- All framework tables keep their names in `<db>`; your tables live there too. **Reserved
|
|
592
636
|
table names:** your object types and migrations must not use a framework table name (`companies`,
|
|
593
637
|
`users`, `roles`, `departments`, `branches`, `company_membership`, `membership_posting`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guide",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Astram framework — the AI/dev GUIDE layer (ADR-0025). Ships the framework's hard rules + capabilities manifest as installed, upgrade-refreshed docs. A consumer app's CLAUDE.md references FRAMEWORK_RULES.md from this package; `npm update` replaces it wholesale so new rules arrive cleanly, while the app's own .astram/guide/ layer is never touched. This is the framework-owned FLOOR: an app rule may tighten it, never weaken it.",
|
|
6
6
|
"type": "commonjs",
|