pi-aia-asf 0.13.2 → 0.13.3

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
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.13.3] - 2026-10-16
11
+
12
+ ### Fixed
13
+
14
+ - **06j §5 had drifted back into enumerating products.** The section now carries
15
+ the store-agnostic *rule* — the defect is not SQL-shaped, and the distinction
16
+ that makes a hand-written cascade decidable is the **reference** (a row removing
17
+ itself vs one entity deciding the fate of another) — instead of a table of
18
+ store families and a list of ORM dialects. Which dialects the scanner
19
+ recognises is an implementation detail in `lib/code-health/model.mjs`, reported
20
+ per finding so you can see what it looked at; the standard states categories and
21
+ leaves the rest to `model.extraCascadePatterns` /
22
+ `model.extraHandWrittenPatterns`. A recognised dialect is not a coverage
23
+ promise: an unknown persistence shape is a `scanned: 0` you say out loud, not a
24
+ clean bill of health. The fixtures keep naming the concrete dialects — that is
25
+ where a pattern set belongs.
26
+
10
27
  ## [0.13.2] - 2026-10-16
11
28
 
12
29
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-aia-asf",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "Ai Applied Agentic Software Factory — codifies the full software development flow: intake, research, spec capture, adversarial analysis, planning with approval gates, test-first implementation, and release. Requires pi-vigilant, pi-smart-web-search, pi-smart-fetch, and pi-aia-browser.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -179,36 +179,33 @@ requirement: "is this ownership correct?" is judgment and stays in review, while
179
179
  "does this file declare a cascade with no `asf-model:` tag?" is measurable.
180
180
 
181
181
  **It is a tripwire, not an authority — and it is store-agnostic by design.** The
182
- defect is not SQL-shaped: an instance inheriting its parent's lifecycle happens
182
+ defect is not SQL-shaped. An instance inheriting its parent's lifecycle happens
183
183
  in a relational FK action, in an ORM mapping attribute, in a document store's
184
184
  delete dependency, in a key-value prefix wipe, or in a loop someone wrote to
185
185
  delete children by hand. Three rules run:
186
186
  `undeclared-cascade` (a cascade declaration with no ownership declaration),
187
187
  `delete-then-reinsert` (rebuild-by-delete over one table or collection), and
188
- `handwritten-cascade` — the store-agnostic half, for stores that have **no
189
- constraint to declare the cascade in the first place**:
190
-
191
- | Store family | What the cascade looks like when nobody wrote it down |
192
- |---|---|
193
- | **MongoDB / Mongoose** | `deleteMany({ userId })` over a child collection — no FK action exists, so this code *is* the cascade |
194
- | **Firestore** | a recursive `collectionGroup` / subcollection delete; missing a nested subcollection is the standard failure |
195
- | **DynamoDB** | `DeleteItem` / `BatchWriteItem` driven by a parent key across tables; GSI/LSI are wiped with the table, items are not |
196
- | **CouchDB** | documents selected and marked `_deleted: true` in one `bulkDocs` |
197
- | **Redis** | a key-pattern wipe — `keys('session:<id>:*')` then `del`/`unlink`; the prefix *is* the parent |
198
- | **Elasticsearch** | `deleteByQuery` on a parent field; no referential integrity exists to fall back on |
199
-
200
- ORM-level declarations are matched too — `CascadeType.REMOVE`/`ALL`,
201
- `orphanRemoval = true`, `DeleteBehavior.Cascade`, `onDelete: Cascade`
202
- (Prisma/Sequelize), `on_delete=models.CASCADE` (Django),
203
- `dependent: :destroy` / `:delete_all` (Rails), `cascade = "…delete…"`
204
- (SQLAlchemy) — so the gate is not SQL DDL only.
205
-
206
- A fire here asks for a **declaration**; it does not claim the ownership is
207
- wrong, which stays a judgement in review. A delete of a row by its own identity
208
- (`deleteOne({ _id: id })`) is not a cascade and does not fire — a rule that
209
- fires on ordinary deletes gets switched off, and the coverage goes with it.
210
- Projects add dialects with `model.extraCascadePatterns` and
211
- `model.extraHandWrittenPatterns` rather than waiting for a release.
188
+ `handwritten-cascade` — the shape a cascade takes in a store that has **no
189
+ constraint to declare it in**, where the decision exists only as code someone
190
+ wrote: a multi-delete driven by a reference to *another* entity.
191
+
192
+ The distinction that makes `handwritten-cascade` decidable rather than
193
+ judgemental is the **reference**. `deleteOne({ _id: id })` is a row removing
194
+ itself; `deleteMany({ userId })` is one entity deciding the fate of another. The
195
+ first does not fire — a rule that fires on ordinary deletes gets switched off and
196
+ the coverage goes with it, which is why the near-miss fixtures matter more than
197
+ the fire fixtures. A fire asks for a **declaration**; it does not claim the
198
+ ownership is wrong, and that judgement stays in review.
199
+
200
+ **The pattern set is illustrative and the standard does not enumerate products.**
201
+ The categories above are the standard; the dialects the scanner happens to
202
+ recognise are an implementation detail in `lib/code-health/model.mjs`, reported
203
+ per finding so you can see what it looked at. A project whose store is not in
204
+ that set adds its own spelling with `model.extraCascadePatterns` /
205
+ `model.extraHandWrittenPatterns` rather than waiting for a release — and a
206
+ recognised dialect is not a coverage promise. If your persistence layer speaks a
207
+ shape the scanner does not know, that is a `scanned: 0` you must say out loud,
208
+ not a clean bill of health.
212
209
 
213
210
  **Where the store has no constraint to inspect, the scan has nothing to attach
214
211
  to and the invariant tests below are the only hard gate** — say which of the two