@jaimevalasek/aioson 1.16.0 → 1.17.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.
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Neural Chain — shared chain_audit telemetry emit helper.
5
+ *
6
+ * Single emitter used by both the CLI command (`src/commands/chain-audit.js`)
7
+ * and the post-session hook (`src/neural-chain-agent-ingest.js`) so payload
8
+ * shape is identical across code paths (BR-NC-10).
9
+ *
10
+ * Spec payload schema (BR-NC-10), 8 required fields:
11
+ * feature_slug — string | null
12
+ * source_files — string[] (the files edited in this session, plural)
13
+ * impacts_found — number | null (null on query failure)
14
+ * auto_fixable_count — number (per BR-NC-02/03 classification)
15
+ * noise_file — string | null (path written, if any)
16
+ * tokens_used — number (V1 placeholder = 0; M2 hooks LLM-mediated path)
17
+ * duration_ms — number (audit query elapsed; 0 on no-op)
18
+ * error — string | null
19
+ *
20
+ * Emitters may attach extra context fields (e.g. `agent`, `autonomy_mode`,
21
+ * `chain_auto_threshold`, `ingest_stats`, `skipped_reason`) on top of the
22
+ * required schema — those are passed through verbatim.
23
+ *
24
+ * EC-NC-05 no-op event (empty artifact list) also populates `duration_ms = 0`
25
+ * and `error = null` so downstream aggregation never has to special-case the
26
+ * skip path. Hotfix v1.17.1 — bug-found-003 from @tester gap-fill audit.
27
+ */
28
+
29
+ const REQUIRED_FIELDS = Object.freeze([
30
+ 'feature_slug',
31
+ 'source_files',
32
+ 'impacts_found',
33
+ 'auto_fixable_count',
34
+ 'noise_file',
35
+ 'tokens_used',
36
+ 'duration_ms',
37
+ 'error'
38
+ ]);
39
+
40
+ function normalizeSourceFiles(value) {
41
+ if (Array.isArray(value)) return value.slice();
42
+ if (value === null || value === undefined) return [];
43
+ return [String(value)];
44
+ }
45
+
46
+ function buildChainAuditPayload({
47
+ feature_slug = null,
48
+ source_files = [],
49
+ impacts_found = 0,
50
+ auto_fixable_count = 0,
51
+ noise_file = null,
52
+ tokens_used = 0,
53
+ duration_ms = 0,
54
+ error = null,
55
+ ...extras
56
+ } = {}) {
57
+ return {
58
+ feature_slug,
59
+ source_files: normalizeSourceFiles(source_files),
60
+ impacts_found,
61
+ auto_fixable_count,
62
+ noise_file,
63
+ tokens_used,
64
+ duration_ms,
65
+ error,
66
+ ...extras
67
+ };
68
+ }
69
+
70
+ function emitChainAuditEvent(db, { agent = null, message = 'chain:audit', ...payloadOverrides } = {}) {
71
+ if (!db || typeof db.prepare !== 'function') return false;
72
+ const payload = buildChainAuditPayload(payloadOverrides);
73
+ try {
74
+ db.prepare(`
75
+ INSERT INTO execution_events (event_type, agent_name, message, payload_json, created_at)
76
+ VALUES ('chain_audit', ?, ?, ?, ?)
77
+ `).run(agent, message, JSON.stringify(payload), new Date().toISOString());
78
+ return true;
79
+ } catch (_) {
80
+ // BR-NC-10 best-effort: telemetry failure must never propagate to the caller.
81
+ return false;
82
+ }
83
+ }
84
+
85
+ module.exports = {
86
+ buildChainAuditPayload,
87
+ emitChainAuditEvent,
88
+ normalizeSourceFiles,
89
+ REQUIRED_FIELDS
90
+ };
@@ -10,6 +10,7 @@ const {
10
10
  mergeGenomeBindings
11
11
  } = require('./genomes/bindings');
12
12
  const { runMigration: runLearningLoopMigration } = require('./learning-loop-migration');
13
+ const { runMigration: runNeuralChainMigration } = require('./neural-chain-migration');
13
14
 
14
15
  const RUNTIME_DIR = path.join('.aioson', 'runtime');
15
16
  const DB_FILE = 'aios.sqlite';
@@ -775,6 +776,7 @@ function ensureLegacyColumns(db) {
775
776
  `);
776
777
 
777
778
  runLearningLoopMigration(db);
779
+ runNeuralChainMigration(db);
778
780
  }
779
781
 
780
782
  function insertEvent(db, record) {
@@ -84,6 +84,26 @@ Check these in order. Stop at the first failure:
84
84
  | Readiness | `.aioson/context/readiness.md` | If exists, read status |
85
85
  | Implementation plan | `.aioson/context/implementation-plan.md` | Note presence and status |
86
86
  | Skeleton system | `.aioson/context/skeleton-system.md` | Note presence |
87
+ | Neural Chain noises | `.aioson/context/noises/*.md` | If any file has unchecked `- [ ]` body lines, flag `chain_noises_pending` with file path + pending count. Treated as BLOCKER in Step 1.5. |
88
+
89
+ ### Step 1.5 — Neural Chain noise check (BLOCKER, takes precedence over routing)
90
+
91
+ Glob `.aioson/context/noises/*.md`. For each file, count body lines matching `^- \[ \]` (unchecked) versus `^- \[x\]` (checked). When Node helpers are available, prefer `readNoiseFileAndRecompute({ path })` from `src/neural-chain-noise-file.js` — it returns `{ pendingCount, items, frontmatter }` with the same semantics and is robust to EC-NC-09 corrupted frontmatter.
92
+
93
+ **If any noise file has `pendingCount > 0`:**
94
+ - This is a BLOCKER, not info — routing to any other agent (`/dev`, `/deyvin`, `/qa`, etc.) is paused.
95
+ - Surface in the dashboard under the ⛔ section, one block per file:
96
+ - Path (relative to project root)
97
+ - `{pendingCount}/{totalCount}` resolved
98
+ - Each pending item: `target_path — {motivo}` (the `motivo` already includes `edge_type` and `confidence` from BR-NC-06)
99
+ - Recommended next action becomes: "Resolve the noise items above (mark `- [x]` once verified or fixed), OR explicitly say *skip noises* and re-activate `/neo` to confirm intent. Routing stays paused until one of those happens."
100
+ - Set `confidence: low` and `clarification` in the routing block; do NOT recommend a downstream agent until the user resolves or explicitly skips.
101
+
102
+ **If `pendingCount === 0` across every noise file:** noise files are stale — the next `runChainHookOnAgentDone` invocation (or `chain:audit` call) will `maybeDeleteNoiseFile` them automatically (EC-NC-10 idempotent). Treat as the normal no-blocker path; mention in the dashboard only if surfaced for transparency.
103
+
104
+ **If the user explicitly skips:** include `reason: skipped <N> noise file(s)` in the routing block and proceed with normal routing. The noise files persist until resolved.
105
+
106
+ Background: noise files are produced by the Neural Chain audit hook (`runChainHookOnAgentDone` in `src/neural-chain-agent-ingest.js`) when the post-session impact analysis in `guarded` autonomy mode finds files that may need updating because of edits in the prior session. See `.aioson/context/spec-neural-chain.md` § BR-NC-06 for the format and lifecycle.
87
107
 
88
108
  ### Step 2 — Git state snapshot
89
109
 
@@ -99,6 +119,7 @@ Based on Step 1 results, classify the project into one of these stages:
99
119
 
100
120
  | Stage | Condition | Primary agent |
101
121
  |---|---|---|
122
+ | **Chain audit pending** | `chain_noises_pending` flagged in Step 1.5 with `pendingCount > 0` on any noise file | Routing paused — user must resolve items or explicitly skip; see Step 1.5 |
102
123
  | **Not initialized** | config.md missing | Manual: user needs to run `aioson init` |
103
124
  | **Needs setup** | `needs_setup` or `needs_setup_repair` | `/setup` |
104
125
  | **Needs product definition** | Context valid, no PRD | `/product` |
@@ -128,6 +149,7 @@ Memory: bootstrap {N}/4 | brains {count} indexed | last distillation {when or "
128
149
  {if features in progress: "Active feature: {slug} — stage: {feature_stage} | dossier: {yes/no} | harness: {progress.status or "—"}"}
129
150
  {if blockers in readiness.md: "⚠ Blockers: {summary}"}
130
151
  {if harness pending gate or circuit_open: "⛔ Harness: {circuit reason or pending gate id}"}
152
+ {if chain_noises_pending: "⛔ Chain: {N} noise file(s) with pending items — resolve before routing (see list below)"}
131
153
 
132
154
  → Recommended next: /agent — {one-line reason}
133
155
  {if alternative paths exist: "Also possible: /agent2 — {reason}"}