pi-aia-asf 0.12.0 → 0.12.2

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,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.12.2] - 2026-10-14
11
+
12
+ ### Added
13
+
14
+ - (describe changes for 0.12.2)
15
+
16
+ ## [0.12.1] - 2026-10-14
17
+
18
+ ### Added
19
+
20
+ - **06j §7 — who enforces the model gate.** The boundary is now written down:
21
+ ASF states the obligation, and the loop guard enforces completion
22
+ **generically**. When a change touches persistence, the model obligations are
23
+ captured as MUST specs (`capture_spec`) and marked `met` with evidence; the
24
+ guard verifies those specs at settle exactly as it verifies any specification
25
+ arriving from any source. What crosses the boundary is the **specification**,
26
+ never the check — the guard does not know what a cascade is and must not have
27
+ to. SKILL.md's Phase 6 model rule now says so directly, and the anti-pattern
28
+ list names the alternative ("asking the loop guard to understand the model").
29
+
10
30
  ## [0.12.0] - 2026-10-14
11
31
 
12
32
  ### Added
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Type surface for the Code Health gate, which stays plain ESM JavaScript
3
+ * (lib/code-health/*.mjs) on purpose: it is a build-time harness that shells
4
+ * out to linters, and rewriting it in TypeScript would buy nothing.
5
+ *
6
+ * This file is the boundary — what index.ts is allowed to rely on. It is
7
+ * hand-maintained, and that is deliberate: a field added to `runHealth`'s
8
+ * return that is not declared here becomes a type error at the call site
9
+ * instead of a silent `any`. Before this file, the whole gate was `any` and
10
+ * `npm run check` could not have noticed.
11
+ */
12
+
13
+ export interface HealthRow {
14
+ key: string;
15
+ value: number | null;
16
+ status: string;
17
+ [extra: string]: unknown;
18
+ }
19
+
20
+ export interface HealthConfig {
21
+ enabled: boolean;
22
+ /** "block" makes violations fail the gate; "warn" reports without blocking. */
23
+ gate: { mode: "block" | "warn" | string; scope: string };
24
+ ignore?: string[];
25
+ [extra: string]: unknown;
26
+ }
27
+
28
+ export interface HealthResult {
29
+ /** Human-readable report — what the `/asf health` command prints. */
30
+ text: string;
31
+ /** Populated only with `--json`. */
32
+ json: unknown;
33
+ /** 1 only when the gate is configured to block and the verdict is unhealthy. */
34
+ exitCode: 0 | 1;
35
+ healthy: boolean;
36
+ rows: HealthRow[];
37
+ config: HealthConfig;
38
+ }
39
+
40
+ export interface HealthDeps {
41
+ readFile?: (path: string) => string | null;
42
+ tools?: unknown;
43
+ [extra: string]: unknown;
44
+ }
45
+
46
+ export declare function runHealth(
47
+ projectRoot: string,
48
+ args?: string[],
49
+ deps?: HealthDeps,
50
+ ): Promise<HealthResult>;
51
+
52
+ export declare function parseArgs(args: string[]): Record<string, boolean | string>;
53
+
54
+ export declare const BASELINE_FILE: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-aia-asf",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
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",
@@ -31,7 +31,7 @@
31
31
  "scripts": {
32
32
  "clean": "echo 'nothing to clean'",
33
33
  "build": "echo 'nothing to build — pi loads .ts via jiti at runtime'",
34
- "check": "tsc --noEmit --target ES2022 --module NodeNext --moduleResolution NodeNext --skipLibCheck --allowImportingTsExtensions --noCheck index.ts",
34
+ "check": "./scripts/typecheck.sh",
35
35
  "test": "./test/run-all.sh",
36
36
  "release": "./scripts/release.sh"
37
37
  },
@@ -64,10 +64,10 @@
64
64
  }
65
65
  },
66
66
  "devDependencies": {
67
- "@earendil-works/pi-agent-core": "0.83.0",
68
- "@earendil-works/pi-ai": "0.83.0",
69
- "@earendil-works/pi-coding-agent": "0.83.0",
70
- "typebox": "1.1.38",
67
+ "@earendil-works/pi-agent-core": "1.2.0",
68
+ "@earendil-works/pi-ai": "1.2.0",
69
+ "@earendil-works/pi-coding-agent": "1.2.0",
70
+ "typebox": "1.3.27",
71
71
  "typescript": "5.9.3"
72
72
  }
73
73
  }
@@ -236,7 +236,7 @@ Execute the task list milestone by milestone. Discipline rules:
236
236
  9. **Challenge approved designs (M4)**: if a spec's literal reading creates product tension (e.g. feedback clusters under "Plan" when "Plan = plans"), stop and resolve it with the user before implementing — never implement blindly and call it delivered.
237
237
  10. **Trace before claiming delivered (M5)**: the delivery log is a claim; the code is the evidence. Before marking anything ✅, trace the actual code path, confirm the output is consumed by a surface, and confirm the operator-facing outcome test passes.
238
238
  11. **No stubs, no fake data, no invented facts (`references/06i-completeness.md`)**: the deliverable is the real implementation. Finish it, or state the discrepancy plainly to the user — what is missing, why, what remains. Never let the user discover the gap by using the product.
239
- 12. **The model is asserted, not assumed — for any change that WRITES to a store (06b Rule 20 / `references/06j-data-model.md`)**: the trigger is what the change writes, not where the diff lives — "only a backend change" is the case that needs it most. Declare ownership for every relationship touched (composition / instance / ledger, owner, survives-parent), and test the **non-effect**: seed the referencing rows with production-shaped data and assert they survive, and assert the tables the change does not name are unchanged (06g §3). Run `/asf health` and resolve or accept its findings. **Uncertain whether the model is touched? Then it is touched.** A green suite is not evidence here — the table a cascade empties is usually never populated by the suite that stayed green.
239
+ 12. **The model is asserted, not assumed — for any change that WRITES to a store (06b Rule 20 / `references/06j-data-model.md`)**: the trigger is what the change writes, not where the diff lives — "only a backend change" is the case that needs it most. Declare ownership for every relationship touched (composition / instance / ledger, owner, survives-parent), and test the **non-effect**: seed the referencing rows with production-shaped data and assert they survive, and assert the tables the change does not name are unchanged (06g §3). Run `/asf health` and resolve or accept its findings. **Uncertain whether the model is touched? Then it is touched.** A green suite is not evidence here — the table a cascade empties is usually never populated by the suite that stayed green. **Capture the obligations as MUST specs (`capture_spec`)** so the loop guard verifies them at settle as it verifies any specification from any source — the guard checks completion, it does not know what a cascade is and must not have to.
240
240
 
241
241
  ---
242
242
 
@@ -214,6 +214,21 @@ an opinion, and they are the part that works against any store.
214
214
  store exposes no constraints.
215
215
  - [ ] Or: `n/a: no persistence touched, because <reason>`.
216
216
 
217
+ ## 7. Who enforces this
218
+
219
+ ASF states the obligation; the loop guard enforces completion **generically**.
220
+ When a change touches persistence, capture the model obligations as MUST specs
221
+ (`capture_spec`) — the ownership decision per relationship, the invariant and
222
+ non-effect tests, the scan result — and mark each `met` with evidence, not
223
+ assertion. The guard then verifies those specs at settle exactly as it verifies
224
+ any specification that arrives from any source, and refuses "done" while a MUST
225
+ spec is open.
226
+
227
+ Keep model knowledge on this side of the boundary. The guard does not know what
228
+ a cascade is, does not look at schemas, and must not have to — the day it
229
+ inspects your data model is the day it stops being usable outside this factory.
230
+ What crosses the boundary is the **specification**, never the check.
231
+
217
232
  ## Anti-patterns
218
233
 
219
234
  - **The instance that inherited its parent's lifecycle** — a fact about a
@@ -237,3 +252,6 @@ an opinion, and they are the part that works against any store.
237
252
  - **Silent zero** — a missing filter reported as an empty day. (M8)
238
253
  - **Reading a scan exception as a clean deliverable** — an accepted finding is a
239
254
  decision you must show, not a pass you may claim. (§4)
255
+ - **Asking the loop guard to understand the model** — it verifies that specs are
256
+ done; teaching it cascade vocabulary puts a domain check in a general tool.
257
+ Capture the obligation as a spec instead. (§7)