@astram/guide 0.2.11 → 0.2.13
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 +16 -1
- package/package.json +1 -1
package/CAPABILITIES.md
CHANGED
|
@@ -324,7 +324,11 @@ imports: [
|
|
|
324
324
|
joins the outer transaction.
|
|
325
325
|
- `transaction(fn)` runs several pipe calls in one unit of work (rolls back on any failed write);
|
|
326
326
|
`lockForUpdate(typeKey, id)` serialises a check-then-write.
|
|
327
|
-
- `@Field({ immutable: true })` create-only fields; `
|
|
327
|
+
- `@Field({ immutable: true })` create-only fields; `@Field({ nullable: true })` fields that
|
|
328
|
+
create, update and `createMany` may set to NULL (`json` included: SQL NULL, not `"null"`;
|
|
329
|
+
the audit row lists the cleared keys, never values; the column must be NULL-able in your
|
|
330
|
+
migration; refused on trusted, primary-key, `readScope` and `required` fields). Without
|
|
331
|
+
`nullable`, `null` is a validation error. `trusted` fields are stamped server-side.
|
|
328
332
|
`readScope` declares the subtree wall; `create: 'unscoped'` opts a type out of the create wall.
|
|
329
333
|
- **Physical wall** — the raw DB pool is sealed in the engine. The scaffold's
|
|
330
334
|
`server/eslint.config.mjs` fails lint on driver imports, raw pools, `.query()` and the
|
|
@@ -380,6 +384,17 @@ imports: [
|
|
|
380
384
|
action or `*`). Allow resolves `void`; deny, a missing row and another tenant's row all throw
|
|
381
385
|
the same `AuthorizationDeniedError` (403); an undeclared action throws `RegistrationError`
|
|
382
386
|
(500) before any query. It returns no row data, writes no audit row and is not a list filter.
|
|
387
|
+
- **Type-level check before the first write**: `records.authorizeType(typeKey, action)` (also on
|
|
388
|
+
`BoundRecords` and the `transaction(fn)` handle) needs no record id and writes nothing. Use it
|
|
389
|
+
when a request may or may not write a type, so the grant decides, not the data: e.g. call
|
|
390
|
+
`authorizeType('my_issue', 'create')` before writing a batch that has 0–500 issue rows. It runs
|
|
391
|
+
the same type-level decision a `create` runs (and the same refusals): allow resolves `void`,
|
|
392
|
+
deny throws `AuthorizationDeniedError` (403), an undeclared action throws `RegistrationError`.
|
|
393
|
+
No query, no audit row; a deny you catch inside `transaction(fn)` does not make it
|
|
394
|
+
rollback-only (an uncaught one rolls it back, as any throw does). It proves the
|
|
395
|
+
type grant only: a `readScope` create can still be refused after insert (outside your
|
|
396
|
+
subtree), and for `read`/`update`/`delete`/custom actions use `authorize(typeKey, id, action)`
|
|
397
|
+
for the record-level answer.
|
|
383
398
|
- **A handler that writes needs two grants**: `authorize()` for the custom action, then the
|
|
384
399
|
write through the normal pipe (`records.update(...)`), which needs `update` and is audited.
|
|
385
400
|
There is no write under the custom action's key. With `activate` alone the update is 403. To
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guide",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
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",
|