@astram/guide 0.2.6 → 0.2.7

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.
Files changed (2) hide show
  1. package/CAPABILITIES.md +36 -3
  2. package/package.json +1 -1
package/CAPABILITIES.md CHANGED
@@ -313,7 +313,7 @@ upload(@Req() req: Record<string, unknown>) {
313
313
  the upload check.
314
314
  - **Lint wall** — the scaffold bans `multer`, `@aws-sdk/*`, `minio`, `fs` / `node:fs` (and
315
315
  `/promises`) in `src/features/**`: use `FileIntake` and `FilesService`, never the bucket.
316
- - Do not grant `stored_file:create` to app roles; uploads go through `FilesService`.
316
+ - Roles that upload need `stored_file:create` (FilesService creates the record as the caller), but app code must create `stored_file` rows only through `FilesService.store()` — never `records.create('stored_file', …)` / `createMany`, which would let a caller set its own `storageKey` (downloads still refuse a key outside the caller's tenant, KI #137).
317
317
  - Not provided: malware scanning, per-tenant encryption of file bytes (SSE-S3 only), streaming
318
318
  downloads, dedup (each upload is its own record; `sha256` is returned so you can detect repeats).
319
319
 
@@ -346,7 +346,41 @@ upload(@Req() req: Record<string, unknown>) {
346
346
  `APP_DB_NAME`, set the same `DDL_DB_NAME` for migrate and the server.
347
347
  - The `<ns>_backup` and `<ns>_monitor` accounts keep server-wide grants and can see every
348
348
  namespace on the server.
349
- - One database per account (some managed hosts) is NOT supported yet (needs the four databases).
349
+ - One database per account (some managed hosts): see the single-database layout below.
350
+
351
+ ## Single-database layout (`SHIELD_DB_LAYOUT=single`, ADR-0041, opt-in, reduced isolation)
352
+ - For hosts that give one database per account. The four-database layout stays the default.
353
+ - **Set:** `SHIELD_DB_LAYOUT=single`, `SHIELD_DB_NAME=<db>` (`^[a-z0-9_]{1,64}$`),
354
+ `SHIELD_DB_LAYOUT_ACK_REDUCED_ISOLATION=1` (exactly `1`, every environment, production
355
+ included), `APP_DB_USER`. Leave `SHIELD_DB_NAMESPACE` unset; `APP_DB_NAME`/`DDL_DB_NAME` unset
356
+ or `<db>`. Same values for the server and `npm run migration:run`. Anything else refuses to boot
357
+ and to migrate.
358
+ - **Set `POOL_MAX_ENGINE`** (e.g. 10). Unset, the engine pool uses `APP_DB_MAX_CONNECTIONS`, and
359
+ the single-layout budget `workers × (POOL_MAX_CORE + POOL_MAX_ENGINE + APP_AUTHZ_POOL_MAX) +
360
+ headroom` fails boot. `APP_DB_MAX_USER_CONNECTIONS` (the account's cap, if the host sets one) is
361
+ checked too.
362
+ - All framework tables keep their names in `<db>`; your tables live there too. **Reserved
363
+ table names:** your object types and migrations must not use a framework table name (`companies`,
364
+ `users`, `roles`, `departments`, `branches`, `company_membership`, `membership_posting`,
365
+ `company_departments`, `company_branches`, `service_account`, `shared_resource`, `stored_file`,
366
+ `identity_credential`, `session`, `refresh_token`, `mfa_device`, `password_reset_token`,
367
+ `mfa_recovery_code`, `email_change_token`, `permission`, `role_permission`,
368
+ `authz_permission_version`, `access_bundle`, `access_bundle_permission`,
369
+ `record_permission_rule`, `record_share`, `scope_closure`, `service_account_key`,
370
+ `cross_tenant_grant`, `audit_log`, the ledger `schema_migrations`) or `prune_audit`. In single
371
+ mode a clash refuses to boot (object type) or to migrate (`CREATE TABLE` in your migrations);
372
+ in the four layout it only warns, so you see it early. The migration check reads whole files,
373
+ `down()` included: an app whose migrations ever created or renamed onto a reserved name cannot
374
+ migrate in single mode.
375
+ - **One account** (`DDL_DB_*` unset ⇒ `APP_DB_*`): migrations and the server share the account
376
+ (`ALL PRIVILEGES ON <db>.*`). You lose append-only audit (#6), no runtime DDL and schema
377
+ separation (#11), the DB-enforced retention floor, and the separate DDL account; `audit:prune`
378
+ refuses to run. Boot logs this list every time (the privilege probe runs with
379
+ `ShieldModule.forRoot({ auth: true })`).
380
+ - **Two accounts** (if the host allows a second user): the framework repo's
381
+ `db-provision --layout single` keeps `audit_log` append-only and the runtime free of DDL, and
382
+ installs `prune_audit`; re-run it after a migration adds a table. Schema separation is still lost.
383
+ - Choose the layout at install: switching an existing install is not supported. MariaDB only.
350
384
 
351
385
  ## Migrations (`@astram/migrate`)
352
386
  - `migrate` / `migrate:revert` / `migrate:status` with the deploy-time DDL account (`DDL_DB_*`);
@@ -389,6 +423,5 @@ upload(@Req() req: Record<string, unknown>) {
389
423
  - External identity providers (OIDC, SAML, LDAP, Entra ID, Cognito, Okta, Google Workspace) and
390
424
  WebAuthn ceremonies.
391
425
  - Tenant- or role-mandated MFA (MFA is enforced for users who enrolled a device).
392
- - Single-database hosting (all framework tables in one database per account).
393
426
 
394
427
  If you need one of these, STOP and flag it in `.astram/guide/gaps.md` (Rule 4).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/guide",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
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",