qualia-framework 5.4.0 → 5.8.0
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/README.md +21 -17
- package/agents/builder.md +25 -8
- package/agents/plan-checker.md +50 -2
- package/agents/planner.md +25 -1
- package/agents/research-synthesizer.md +4 -1
- package/agents/researcher.md +6 -1
- package/agents/visual-evaluator.md +1 -1
- package/bin/install.js +8 -8
- package/bin/plan-contract.js +32 -1
- package/bin/slop-detect.mjs +1 -1
- package/docs/erp-contract.md +11 -0
- package/docs/onboarding.html +623 -0
- package/guide.md +8 -9
- package/hooks/session-start.js +1 -1
- package/package.json +1 -1
- package/skills/qualia-discuss/SKILL.md +123 -9
- package/skills/qualia-feature/SKILL.md +216 -0
- package/skills/qualia-milestone/SKILL.md +73 -1
- package/skills/qualia-new/SKILL.md +52 -25
- package/skills/qualia-optimize/SKILL.md +1 -1
- package/skills/{qualia-polish-loop → qualia-polish}/REFERENCE.md +5 -5
- package/skills/qualia-polish/SKILL.md +13 -4
- package/skills/{qualia-polish-loop → qualia-polish}/scripts/loop.mjs +2 -2
- package/skills/{qualia-polish-loop → qualia-polish}/scripts/playwright-capture.mjs +1 -1
- package/skills/qualia-report/SKILL.md +8 -6
- package/skills/qualia-road/SKILL.md +10 -11
- package/templates/CONTEXT.md +3 -2
- package/templates/help.html +1 -1
- package/templates/phase-context.md +5 -4
- package/templates/project-discovery.md +83 -0
- package/templates/project.md +7 -0
- package/tests/bin.test.sh +104 -62
- package/tests/lib.test.sh +21 -0
- package/tests/slop-detect.test.sh +2 -2
- package/docs/archive/session-report-2026-04-18.md +0 -199
- package/docs/install-redesign-builder-prompt.md +0 -290
- package/docs/install-redesign-pilot.md +0 -234
- package/docs/instruction-budget-audit.md +0 -113
- package/docs/journey-demo.html +0 -1008
- package/docs/playwright-loop-builder-prompt.md +0 -185
- package/docs/playwright-loop-design-notes.md +0 -108
- package/docs/playwright-loop-tester-prompt.md +0 -213
- package/docs/polish-loop-supervised-run.md +0 -111
- package/skills/qualia-polish-loop/SKILL.md +0 -201
- package/skills/qualia-prd/SKILL.md +0 -199
- package/skills/qualia-quick/SKILL.md +0 -44
- package/skills/qualia-task/SKILL.md +0 -98
- /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/broken.html +0 -0
- /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/clean.html +0 -0
- /package/skills/{qualia-polish-loop → qualia-polish}/scripts/score.mjs +0 -0
package/tests/bin.test.sh
CHANGED
|
@@ -1131,52 +1131,59 @@ fi
|
|
|
1131
1131
|
echo ""
|
|
1132
1132
|
echo "--- v5.0.0 (visual-polish loop addendum) ---"
|
|
1133
1133
|
|
|
1134
|
-
# 99. qualia-polish
|
|
1134
|
+
# 99. qualia-polish SKILL.md installs (v5.8: polish-loop consolidated into --loop flag)
|
|
1135
1135
|
TMP=$(mktmp)
|
|
1136
1136
|
echo "QS-FAWZI-01" | HOME="$TMP" $NODE "$INSTALL_JS" >/dev/null 2>&1
|
|
1137
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1138
|
-
pass "qualia-polish
|
|
1137
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/SKILL.md" ]; then
|
|
1138
|
+
pass "qualia-polish SKILL.md installs"
|
|
1139
1139
|
else
|
|
1140
|
-
fail_case "qualia-polish
|
|
1140
|
+
fail_case "qualia-polish SKILL.md missing after install"
|
|
1141
1141
|
fi
|
|
1142
1142
|
|
|
1143
|
-
# 100. qualia-polish
|
|
1144
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1145
|
-
pass "qualia-polish
|
|
1143
|
+
# 100. qualia-polish REFERENCE.md installs (carries the loop spec)
|
|
1144
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/REFERENCE.md" ]; then
|
|
1145
|
+
pass "qualia-polish REFERENCE.md installs"
|
|
1146
1146
|
else
|
|
1147
|
-
fail_case "qualia-polish
|
|
1147
|
+
fail_case "qualia-polish REFERENCE.md missing after install"
|
|
1148
1148
|
fi
|
|
1149
1149
|
|
|
1150
|
-
# 101. qualia-polish
|
|
1151
|
-
if grep -q "design-rubric.md" "$TMP/.claude/skills/qualia-polish
|
|
1152
|
-
pass "qualia-polish
|
|
1150
|
+
# 101. qualia-polish SKILL.md references the design rubric
|
|
1151
|
+
if grep -q "design-rubric.md" "$TMP/.claude/skills/qualia-polish/SKILL.md"; then
|
|
1152
|
+
pass "qualia-polish references design-rubric.md"
|
|
1153
1153
|
else
|
|
1154
|
-
fail_case "qualia-polish
|
|
1154
|
+
fail_case "qualia-polish missing rubric reference"
|
|
1155
1155
|
fi
|
|
1156
1156
|
|
|
1157
|
-
# 102. qualia-polish
|
|
1158
|
-
if grep -q "DEFAULT TO 3" "$TMP/.claude/skills/qualia-polish
|
|
1159
|
-
pass "qualia-polish
|
|
1157
|
+
# 102. qualia-polish REFERENCE.md has the anchored vision eval prompt
|
|
1158
|
+
if grep -q "DEFAULT TO 3" "$TMP/.claude/skills/qualia-polish/REFERENCE.md"; then
|
|
1159
|
+
pass "qualia-polish REFERENCE.md has anchored rubric prompt"
|
|
1160
1160
|
else
|
|
1161
|
-
fail_case "qualia-polish
|
|
1161
|
+
fail_case "qualia-polish REFERENCE.md missing anchored rubric"
|
|
1162
1162
|
fi
|
|
1163
1163
|
|
|
1164
|
-
# 103. qualia-polish
|
|
1165
|
-
if grep -q "LOOP_REGRESSION_DETECTED" "$TMP/.claude/skills/qualia-polish
|
|
1166
|
-
pass "qualia-polish
|
|
1164
|
+
# 103. qualia-polish REFERENCE.md has regression detection (LOOP_REGRESSION_DETECTED)
|
|
1165
|
+
if grep -q "LOOP_REGRESSION_DETECTED" "$TMP/.claude/skills/qualia-polish/REFERENCE.md"; then
|
|
1166
|
+
pass "qualia-polish has regression kill-switch"
|
|
1167
1167
|
else
|
|
1168
|
-
fail_case "qualia-polish
|
|
1168
|
+
fail_case "qualia-polish missing regression kill-switch"
|
|
1169
|
+
fi
|
|
1170
|
+
|
|
1171
|
+
# 103b. qualia-polish SKILL.md documents the --loop flag
|
|
1172
|
+
if grep -q -- "--loop" "$TMP/.claude/skills/qualia-polish/SKILL.md"; then
|
|
1173
|
+
pass "qualia-polish SKILL.md documents --loop flag"
|
|
1174
|
+
else
|
|
1175
|
+
fail_case "qualia-polish SKILL.md missing --loop documentation"
|
|
1169
1176
|
fi
|
|
1170
1177
|
|
|
1171
1178
|
# 104. score.mjs exists in the framework skill scripts
|
|
1172
|
-
if [ -f "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1179
|
+
if [ -f "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" ]; then
|
|
1173
1180
|
pass "score.mjs exists in skill scripts"
|
|
1174
1181
|
else
|
|
1175
1182
|
fail_case "score.mjs missing from skill scripts"
|
|
1176
1183
|
fi
|
|
1177
1184
|
|
|
1178
1185
|
# 105. score.mjs computes pass correctly (all dims >= 3)
|
|
1179
|
-
SCORE_OUT=$(echo '{"typography":3,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1186
|
+
SCORE_OUT=$(echo '{"typography":3,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" 2>&1)
|
|
1180
1187
|
EXIT=$?
|
|
1181
1188
|
if [ "$EXIT" -eq 0 ] && echo "$SCORE_OUT" | grep -q '"pass": true'; then
|
|
1182
1189
|
pass "score.mjs pass on all-3 scores"
|
|
@@ -1185,7 +1192,7 @@ else
|
|
|
1185
1192
|
fi
|
|
1186
1193
|
|
|
1187
1194
|
# 106. score.mjs computes fail correctly (one dim < 3)
|
|
1188
|
-
SCORE_OUT=$(echo '{"typography":2,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1195
|
+
SCORE_OUT=$(echo '{"typography":2,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" 2>&1)
|
|
1189
1196
|
EXIT=$?
|
|
1190
1197
|
if [ "$EXIT" -eq 1 ] && echo "$SCORE_OUT" | grep -q '"pass": false'; then
|
|
1191
1198
|
pass "score.mjs fail on dim < 3"
|
|
@@ -1193,38 +1200,38 @@ else
|
|
|
1193
1200
|
fail_case "score.mjs fail computation" "exit=$EXIT"
|
|
1194
1201
|
fi
|
|
1195
1202
|
|
|
1196
|
-
# 107. qualia-road references
|
|
1197
|
-
if grep -
|
|
1198
|
-
pass "qualia-road references qualia-polish
|
|
1203
|
+
# 107. qualia-road references the polish loop (now via --loop flag)
|
|
1204
|
+
if grep -qE "qualia-polish --loop|/qualia-polish --loop" "$TMP/.claude/skills/qualia-road/SKILL.md"; then
|
|
1205
|
+
pass "qualia-road references /qualia-polish --loop"
|
|
1199
1206
|
else
|
|
1200
|
-
fail_case "qualia-road missing qualia-polish
|
|
1207
|
+
fail_case "qualia-road missing /qualia-polish --loop reference"
|
|
1201
1208
|
fi
|
|
1202
1209
|
|
|
1203
1210
|
# 108. package.json version is 5.x (5.1+ accepted; v5.1 / v5.2 share the v5 line)
|
|
1204
|
-
if grep -qE '"5\.[
|
|
1211
|
+
if grep -qE '"5\.([1-9]|[1-9][0-9])\.' "$FRAMEWORK_DIR/package.json"; then
|
|
1205
1212
|
pass "package.json version is 5.x"
|
|
1206
1213
|
else
|
|
1207
1214
|
fail_case "package.json version not 5.x"
|
|
1208
1215
|
fi
|
|
1209
1216
|
|
|
1210
1217
|
# 109. loop.mjs installs (orchestrator)
|
|
1211
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1212
|
-
pass "qualia-polish
|
|
1218
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/scripts/loop.mjs" ]; then
|
|
1219
|
+
pass "qualia-polish scripts/loop.mjs installs"
|
|
1213
1220
|
else
|
|
1214
1221
|
fail_case "scripts/loop.mjs missing — install.js scripts/ subfolder copy broken"
|
|
1215
1222
|
fi
|
|
1216
1223
|
|
|
1217
1224
|
# 110. playwright-capture.mjs installs (capture helper)
|
|
1218
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1219
|
-
pass "qualia-polish
|
|
1225
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/scripts/playwright-capture.mjs" ]; then
|
|
1226
|
+
pass "qualia-polish scripts/playwright-capture.mjs installs"
|
|
1220
1227
|
else
|
|
1221
1228
|
fail_case "scripts/playwright-capture.mjs missing"
|
|
1222
1229
|
fi
|
|
1223
1230
|
|
|
1224
1231
|
# 111. fixtures/ subfolder installs (self-test pages)
|
|
1225
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1226
|
-
[ -f "$TMP/.claude/skills/qualia-polish
|
|
1227
|
-
pass "qualia-polish
|
|
1232
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/fixtures/clean.html" ] && \
|
|
1233
|
+
[ -f "$TMP/.claude/skills/qualia-polish/fixtures/broken.html" ]; then
|
|
1234
|
+
pass "qualia-polish fixtures/ installs (clean.html + broken.html)"
|
|
1228
1235
|
else
|
|
1229
1236
|
fail_case "fixtures/ subfolder not copied by install.js"
|
|
1230
1237
|
fi
|
|
@@ -1237,7 +1244,7 @@ else
|
|
|
1237
1244
|
fi
|
|
1238
1245
|
|
|
1239
1246
|
# 113. loop.mjs parses as valid Node ESM
|
|
1240
|
-
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1247
|
+
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" 2>/dev/null || EXIT=$?
|
|
1241
1248
|
if [ "$EXIT" -eq 0 ]; then
|
|
1242
1249
|
pass "loop.mjs parses as valid Node ESM"
|
|
1243
1250
|
else
|
|
@@ -1245,7 +1252,7 @@ else
|
|
|
1245
1252
|
fi
|
|
1246
1253
|
|
|
1247
1254
|
# 114. playwright-capture.mjs parses as valid Node ESM
|
|
1248
|
-
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1255
|
+
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish/scripts/playwright-capture.mjs" 2>/dev/null || EXIT=$?
|
|
1249
1256
|
if [ "$EXIT" -eq 0 ]; then
|
|
1250
1257
|
pass "playwright-capture.mjs parses as valid Node ESM"
|
|
1251
1258
|
else
|
|
@@ -1255,7 +1262,7 @@ fi
|
|
|
1255
1262
|
# 115. loop.mjs init creates a valid state file
|
|
1256
1263
|
TMP_STATE=$(mktmp)/qpl-state.json
|
|
1257
1264
|
mkdir -p "$(dirname "$TMP_STATE")"
|
|
1258
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1265
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1259
1266
|
--state "$TMP_STATE" --url "http://localhost:3000" --max 4 --budget 50000 >/dev/null 2>&1 || EXIT=$?
|
|
1260
1267
|
if [ "$EXIT" -eq 0 ] && [ -f "$TMP_STATE" ] && grep -q '"verdict": "pending"' "$TMP_STATE"; then
|
|
1261
1268
|
pass "loop.mjs init creates valid state.json"
|
|
@@ -1267,7 +1274,7 @@ fi
|
|
|
1267
1274
|
TMP_STATE2=$(mktmp)/qpl-kill.json
|
|
1268
1275
|
TMP_EVAL=$(mktmp)/qpl-eval.json
|
|
1269
1276
|
mkdir -p "$(dirname "$TMP_STATE2")" "$(dirname "$TMP_EVAL")"
|
|
1270
|
-
$NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1277
|
+
$NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1271
1278
|
--state "$TMP_STATE2" --url "http://localhost:3000" --max 8 >/dev/null 2>&1
|
|
1272
1279
|
# write 3 identical evals
|
|
1273
1280
|
KILL_OK=true
|
|
@@ -1282,7 +1289,7 @@ for ITER in 1 2 3; do
|
|
|
1282
1289
|
"pass": false
|
|
1283
1290
|
}
|
|
1284
1291
|
EOF
|
|
1285
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1292
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" record \
|
|
1286
1293
|
--state "$TMP_STATE2" --eval "$TMP_EVAL" >/dev/null 2>&1 || EXIT=$?
|
|
1287
1294
|
if [ "$ITER" -lt 3 ] && [ "$EXIT" -ne 1 ]; then KILL_OK=false; fi
|
|
1288
1295
|
if [ "$ITER" -eq 3 ] && [ "$EXIT" -ne 3 ]; then KILL_OK=false; fi
|
|
@@ -1430,7 +1437,7 @@ fi
|
|
|
1430
1437
|
|
|
1431
1438
|
# 128. package.json bumped to 5.x (5.1+ accepted; 5.2 is the v5.2 release)
|
|
1432
1439
|
PKG_V=$($NODE -e 'console.log(require("'"$FRAMEWORK_DIR"'/package.json").version)')
|
|
1433
|
-
if echo "$PKG_V" | grep -qE "^5\.[
|
|
1440
|
+
if echo "$PKG_V" | grep -qE "^5\.([1-9]|[1-9][0-9])\."; then
|
|
1434
1441
|
pass "package.json version bumped to 5.x ($PKG_V)"
|
|
1435
1442
|
else
|
|
1436
1443
|
fail_case "package.json version not 5.x" "got=$PKG_V"
|
|
@@ -1442,7 +1449,7 @@ echo "--- v5.2.0 (polish-loop reliability) ---"
|
|
|
1442
1449
|
# 129. loop.mjs init accepts --routes and stores the URL list
|
|
1443
1450
|
TMP_S=$(mktmp)/qpl-routes.json
|
|
1444
1451
|
mkdir -p "$(dirname "$TMP_S")"
|
|
1445
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1452
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1446
1453
|
--state "$TMP_S" \
|
|
1447
1454
|
--routes "http://x.test/a,http://x.test/b,http://x.test/c" \
|
|
1448
1455
|
--max 4 >/dev/null 2>&1 || EXIT=$?
|
|
@@ -1466,7 +1473,7 @@ fi
|
|
|
1466
1473
|
# 131. loop.mjs init accepts --reduced-motion and records it in state
|
|
1467
1474
|
TMP_S2=$(mktmp)/qpl-rm.json
|
|
1468
1475
|
mkdir -p "$(dirname "$TMP_S2")"
|
|
1469
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1476
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1470
1477
|
--state "$TMP_S2" --url "http://x.test/" --reduced-motion >/dev/null 2>&1 || EXIT=$?
|
|
1471
1478
|
if [ "$EXIT" -eq 0 ] && grep -q '"reduced_motion": true' "$TMP_S2"; then
|
|
1472
1479
|
pass "loop.mjs init --reduced-motion records state.reduced_motion=true"
|
|
@@ -1475,7 +1482,7 @@ else
|
|
|
1475
1482
|
fi
|
|
1476
1483
|
|
|
1477
1484
|
# 132. playwright-capture.mjs accepts --reduced-motion (parses without error)
|
|
1478
|
-
EXIT=0; OUT=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1485
|
+
EXIT=0; OUT=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/playwright-capture.mjs" --help 2>&1) || EXIT=$?
|
|
1479
1486
|
if [ "$EXIT" -eq 0 ] && echo "$OUT" | grep -q -- "--reduced-motion"; then
|
|
1480
1487
|
pass "playwright-capture.mjs --help documents --reduced-motion"
|
|
1481
1488
|
else
|
|
@@ -1485,7 +1492,7 @@ fi
|
|
|
1485
1492
|
# 133. loop.mjs init rejects when neither --url nor --routes given
|
|
1486
1493
|
TMP_S3=$(mktmp)/qpl-nourl.json
|
|
1487
1494
|
mkdir -p "$(dirname "$TMP_S3")"
|
|
1488
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1495
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1489
1496
|
--state "$TMP_S3" --max 4 >/dev/null 2>&1 || EXIT=$?
|
|
1490
1497
|
if [ "$EXIT" -eq 2 ]; then
|
|
1491
1498
|
pass "loop.mjs init rejects missing --url/--routes (exit 2)"
|
|
@@ -1496,9 +1503,9 @@ fi
|
|
|
1496
1503
|
# 134. loop.mjs report mentions multi-route when state.urls > 1
|
|
1497
1504
|
TMP_S4=$(mktmp)/qpl-rep.json
|
|
1498
1505
|
mkdir -p "$(dirname "$TMP_S4")"
|
|
1499
|
-
$NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1506
|
+
$NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1500
1507
|
--state "$TMP_S4" --routes "http://a/,http://b/" >/dev/null 2>&1
|
|
1501
|
-
REP=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1508
|
+
REP=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" report --state "$TMP_S4" 2>&1)
|
|
1502
1509
|
if echo "$REP" | grep -q "URLs (2)"; then
|
|
1503
1510
|
pass "loop.mjs report renders multi-route header"
|
|
1504
1511
|
else
|
|
@@ -1512,27 +1519,32 @@ echo "--- v5.3.0 (Matt Pocock gaps: prd, hook-gen, parallel-interface) ---"
|
|
|
1512
1519
|
TMP=$(mktmp)
|
|
1513
1520
|
echo "QS-FAWZI-01" | HOME="$TMP" $NODE "$INSTALL_JS" >/dev/null 2>&1
|
|
1514
1521
|
|
|
1515
|
-
# 135. qualia-prd
|
|
1516
|
-
|
|
1517
|
-
|
|
1522
|
+
# 135-137. /qualia-prd removed in v5.8.0 (was deprecated, overlapped /qualia-discuss).
|
|
1523
|
+
# Assert non-existence so the framework cannot accidentally re-ship it.
|
|
1524
|
+
if [ ! -f "$TMP/.claude/skills/qualia-prd/SKILL.md" ]; then
|
|
1525
|
+
pass "qualia-prd removed (v5.8.0 cleanup)"
|
|
1518
1526
|
else
|
|
1519
|
-
fail_case "qualia-prd
|
|
1527
|
+
fail_case "qualia-prd unexpectedly present after v5.8.0 removal"
|
|
1520
1528
|
fi
|
|
1521
1529
|
|
|
1522
|
-
#
|
|
1523
|
-
if
|
|
1524
|
-
|
|
1525
|
-
pass "qualia-prd describes synthesis flow + pairs with /qualia-issues"
|
|
1530
|
+
# v5.8.0: assert /qualia-quick + /qualia-task also removed (were deprecated in v5.7).
|
|
1531
|
+
if [ ! -f "$TMP/.claude/skills/qualia-quick/SKILL.md" ]; then
|
|
1532
|
+
pass "qualia-quick removed (v5.8.0 cleanup)"
|
|
1526
1533
|
else
|
|
1527
|
-
fail_case "qualia-
|
|
1534
|
+
fail_case "qualia-quick unexpectedly present after v5.8.0 removal"
|
|
1528
1535
|
fi
|
|
1529
1536
|
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
&& grep -q "Token discipline" "$TMP/.claude/skills/qualia-prd/SKILL.md"; then
|
|
1533
|
-
pass "qualia-prd documents fork-based synthesis (token discipline)"
|
|
1537
|
+
if [ ! -f "$TMP/.claude/skills/qualia-task/SKILL.md" ]; then
|
|
1538
|
+
pass "qualia-task removed (v5.8.0 cleanup)"
|
|
1534
1539
|
else
|
|
1535
|
-
fail_case "qualia-
|
|
1540
|
+
fail_case "qualia-task unexpectedly present after v5.8.0 removal"
|
|
1541
|
+
fi
|
|
1542
|
+
|
|
1543
|
+
# v5.8.0: assert /qualia-feature is the canonical single-feature surface.
|
|
1544
|
+
if [ -f "$TMP/.claude/skills/qualia-feature/SKILL.md" ]; then
|
|
1545
|
+
pass "qualia-feature installed (canonical single-feature surface)"
|
|
1546
|
+
else
|
|
1547
|
+
fail_case "qualia-feature missing after install"
|
|
1536
1548
|
fi
|
|
1537
1549
|
|
|
1538
1550
|
# 138. qualia-hook-gen skill installs
|
|
@@ -1577,12 +1589,42 @@ fi
|
|
|
1577
1589
|
|
|
1578
1590
|
# 143. package.json version is 5.x (5.1+ accepted; v5.3 is the v5.3 release)
|
|
1579
1591
|
PKG_V=$($NODE -e 'console.log(require("'"$FRAMEWORK_DIR"'/package.json").version)')
|
|
1580
|
-
if echo "$PKG_V" | grep -qE "^5\.[
|
|
1592
|
+
if echo "$PKG_V" | grep -qE "^5\.([1-9]|[1-9][0-9])\."; then
|
|
1581
1593
|
pass "package.json version is 5.x ($PKG_V) — v5.3 accepted"
|
|
1582
1594
|
else
|
|
1583
1595
|
fail_case "package.json version not 5.x" "got=$PKG_V"
|
|
1584
1596
|
fi
|
|
1585
1597
|
|
|
1598
|
+
echo ""
|
|
1599
|
+
echo "--- ERP shift-report contract ---"
|
|
1600
|
+
|
|
1601
|
+
# 144. qualia-report describes clock-out as truthful shift submission, not task completion
|
|
1602
|
+
if grep -qi "daily shift report" "$TMP/.claude/skills/qualia-report/SKILL.md" \
|
|
1603
|
+
&& grep -qi "not a task-completion ceremony" "$TMP/.claude/skills/qualia-report/SKILL.md" \
|
|
1604
|
+
&& grep -qi "What happened during your shift" "$TMP/.claude/skills/qualia-report/SKILL.md"; then
|
|
1605
|
+
pass "qualia-report frames clock-out as shift submission, not task completion"
|
|
1606
|
+
else
|
|
1607
|
+
fail_case "qualia-report missing shift-submission contract"
|
|
1608
|
+
fi
|
|
1609
|
+
|
|
1610
|
+
# 145. ERP contract documents the date model: project, milestone, employee submission
|
|
1611
|
+
if grep -q "Project deadline" "$FRAMEWORK_DIR/docs/erp-contract.md" \
|
|
1612
|
+
&& grep -q "Milestone deadline" "$FRAMEWORK_DIR/docs/erp-contract.md" \
|
|
1613
|
+
&& grep -q "Employee submission date" "$FRAMEWORK_DIR/docs/erp-contract.md" \
|
|
1614
|
+
&& grep -q "Phase and task counters remain framework telemetry" "$FRAMEWORK_DIR/docs/erp-contract.md"; then
|
|
1615
|
+
pass "ERP contract documents project/milestone/submission date model"
|
|
1616
|
+
else
|
|
1617
|
+
fail_case "ERP contract missing date-model clarification"
|
|
1618
|
+
fi
|
|
1619
|
+
|
|
1620
|
+
# 146. Project glossary keeps framework tasks internal to agent execution
|
|
1621
|
+
if grep -q "framework-internal execution unit" "$FRAMEWORK_DIR/templates/CONTEXT.md" \
|
|
1622
|
+
&& grep -q "ERP tracks project deadlines, milestone deadlines, and employee shift submissions" "$FRAMEWORK_DIR/templates/CONTEXT.md"; then
|
|
1623
|
+
pass "CONTEXT template distinguishes internal tasks from ERP workflow"
|
|
1624
|
+
else
|
|
1625
|
+
fail_case "CONTEXT template missing framework-task vs ERP-workflow distinction"
|
|
1626
|
+
fi
|
|
1627
|
+
|
|
1586
1628
|
echo ""
|
|
1587
1629
|
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
1588
1630
|
[ "$FAIL" -eq 0 ] && exit 0 || exit 1
|
package/tests/lib.test.sh
CHANGED
|
@@ -57,6 +57,27 @@ console.log(errs.length > 0 ? "REJECTED" : "ACCEPTED");
|
|
|
57
57
|
')
|
|
58
58
|
[ "$OUT" = "REJECTED" ] && ok "rejects malformed contract" || fail "malformed accepted"
|
|
59
59
|
|
|
60
|
+
OUT=$($NODE -e '
|
|
61
|
+
const pc = require("'"$PC"'");
|
|
62
|
+
const slop = {
|
|
63
|
+
version: 1, phase: 1, goal: "x", why: "y",
|
|
64
|
+
generated_at: "t", generated_by: "planner", source_plan_hash: "h",
|
|
65
|
+
success_criteria: ["sc"],
|
|
66
|
+
tasks: [{
|
|
67
|
+
id: "T1", title: "t", wave: 1, depends_on: [],
|
|
68
|
+
files_modify: [], files_create: [], files_delete: [],
|
|
69
|
+
acceptance_criteria: ["minimal implementation of login"],
|
|
70
|
+
action: "Add hardcoded for now placeholder, will be wired later",
|
|
71
|
+
context_files: [],
|
|
72
|
+
verification: [{ type: "file-exists", path: "a.ts" }]
|
|
73
|
+
}]
|
|
74
|
+
};
|
|
75
|
+
const errs = pc.validate(slop);
|
|
76
|
+
const hits = errs.filter(e => /scope-reduction/.test(e));
|
|
77
|
+
console.log(hits.length >= 2 ? "DETECTED" : "MISSED:" + errs.join(";"));
|
|
78
|
+
')
|
|
79
|
+
[ "$OUT" = "DETECTED" ] && ok "detects scope-reduction phrases in action + acceptance_criteria" || fail "scope-reduction missed: $OUT"
|
|
80
|
+
|
|
60
81
|
OUT=$($NODE -e '
|
|
61
82
|
const pc = require("'"$PC"'");
|
|
62
83
|
const c = {
|
|
@@ -121,8 +121,8 @@ else
|
|
|
121
121
|
fail_case "gradient detection" "expected exit 1, got $EXIT_CODE"
|
|
122
122
|
fi
|
|
123
123
|
|
|
124
|
-
# ── Existing fixture: skills/qualia-polish
|
|
125
|
-
FIXTURE="$(cd "$(dirname "$0")/.." && pwd)/skills/qualia-polish
|
|
124
|
+
# ── Existing fixture: skills/qualia-polish/fixtures/broken.html ──
|
|
125
|
+
FIXTURE="$(cd "$(dirname "$0")/.." && pwd)/skills/qualia-polish/fixtures/broken.html"
|
|
126
126
|
if [ -f "$FIXTURE" ]; then
|
|
127
127
|
EXIT_CODE=0
|
|
128
128
|
$NODE "$SLOP_DETECT" "$FIXTURE" >/dev/null 2>&1 || EXIT_CODE=$?
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
# Session Report — 2026-04-18
|
|
2
|
-
|
|
3
|
-
**Project:** qualia-framework
|
|
4
|
-
**Branch:** feature/full-journey (local, not pushed)
|
|
5
|
-
**Released:** v3.7.0 (staged on feature/story-file-plans) and **v4.0.0** (staged on feature/full-journey)
|
|
6
|
-
**Owner:** Fawzi Goussous
|
|
7
|
-
**Duration:** ~4 hours
|
|
8
|
-
|
|
9
|
-
## What this session shipped
|
|
10
|
-
|
|
11
|
-
Two releases staged on separate feature branches, ready for push + merge + `npm publish`.
|
|
12
|
-
|
|
13
|
-
| Tag | Branch | Commits | Theme |
|
|
14
|
-
|---|---|---|---|
|
|
15
|
-
| **v3.7.0** | feature/story-file-plans | 1 commit (8ae5b0e) | Story-file plan format — every phase plan task carries inline Why, Acceptance Criteria, Validation, explicit Depends on |
|
|
16
|
-
| **v4.0.0** | feature/full-journey | 8 commits total (includes v3.7.0) | Full Journey release — /qualia-new maps the entire arc to handoff, --auto chains the Road end-to-end, milestone hierarchy locked, /qualia-idk rebuilt as diagnostician |
|
|
17
|
-
|
|
18
|
-
**Test suite:** 150 → 156 green (+6 v4 coverage, 0 regressions).
|
|
19
|
-
**Package:** version bumped 3.6.0 → 4.0.0.
|
|
20
|
-
**Release candidate:** v4.0.0 commit is `f790554` on feature/full-journey.
|
|
21
|
-
|
|
22
|
-
## Background & trigger
|
|
23
|
-
|
|
24
|
-
Fawzi came in with three pain points from Sakani's ERP view:
|
|
25
|
-
1. "Unphased Tasks" and "Phase 0: Central Bank Demo" rendering at the same tree level as "Milestone 1", "Milestone 2", etc. — milestones collapsed into single phases, numbering skipped (missing M5).
|
|
26
|
-
2. `/qualia-new` stops at v1 — team improvises subsequent milestones, no clear path to handoff.
|
|
27
|
-
3. Team members don't understand the framework's dev cycle. Need something a non-technical person can follow without getting lost.
|
|
28
|
-
|
|
29
|
-
Plus: "make it sexier," personalize the Qualia experience, enhance every command for best practices, ship a stable v4.0.
|
|
30
|
-
|
|
31
|
-
## The approach
|
|
32
|
-
|
|
33
|
-
Split the work into labeled phases on a feature branch so commits tell the story:
|
|
34
|
-
|
|
35
|
-
### v3.7.0 prerequisite — story-file plans
|
|
36
|
-
- `templates/plan.md` rewritten to 7-field story-file format (Wave, Files, Depends on, Why, Acceptance Criteria, Action, Validation, Context + optional Persona)
|
|
37
|
-
- `agents/planner.md` generates the new format
|
|
38
|
-
- `agents/plan-checker.md` validates the 7 fields and cross-checks wave↔deps consistency
|
|
39
|
-
- `agents/builder.md` reads rationale, respects Depends on, runs Validation before commit
|
|
40
|
-
- `agents/verifier.md` adds 3-layer check (phase Success Criteria + per-task AC + Verification Contract)
|
|
41
|
-
- `bin/qualia-ui.js` adds `plan-summary` command — terminal dashboard with colored persona chips, dependency arrows, AC/check counts per task
|
|
42
|
-
- `bin/state.js` accepts both legacy `Done when:` and new `Acceptance Criteria:` anchors (backward-compatible)
|
|
43
|
-
|
|
44
|
-
Committed on `feature/story-file-plans` as v3.7.0 (`8ae5b0e`). Standalone useful release; branched v4 off of it.
|
|
45
|
-
|
|
46
|
-
### v4.0.0 — Full Journey, phased
|
|
47
|
-
|
|
48
|
-
**Phase A — Model foundation** (`2e371c2`)
|
|
49
|
-
- `templates/journey.md` — new JOURNEY.md schema (hard ceiling 5 milestones, hard floor 2, final milestone always Handoff with 4 fixed phases)
|
|
50
|
-
- `tracking.json` gains `milestone_name`, `milestones[]` (array of closed milestone summaries)
|
|
51
|
-
- `state.js close-milestone` readiness guards: MILESTONE_NOT_READY, MILESTONE_TOO_SMALL (both bypassable with --force)
|
|
52
|
-
- `state.js init` accepts `--milestone_name` and preserves milestones[] across re-init
|
|
53
|
-
- Tests: +4
|
|
54
|
-
|
|
55
|
-
**Phase B — Roadmapper + /qualia-new full-journey output** (`87af253`)
|
|
56
|
-
- `agents/roadmapper.md` rewritten: now produces JOURNEY.md (all milestones) + REQUIREMENTS.md (grouped by milestone) + ROADMAP.md (Milestone 1's phase detail only)
|
|
57
|
-
- **Dropped** the old "no review/deploy/handoff phases" rule. **Replaced** with: final milestone is always literally named "Handoff" with fixed 4 phases.
|
|
58
|
-
- `skills/qualia-new/SKILL.md` rewritten: always runs research (no more `workflow.research` gate), single approval on the whole journey, new `--auto` flag
|
|
59
|
-
- `agents/research-synthesizer.md` thinks across all milestones
|
|
60
|
-
- `skills/qualia-milestone/SKILL.md` reads next milestone from JOURNEY.md (no longer asks user)
|
|
61
|
-
- `templates/requirements.md` multi-milestone format with standard Handoff section (HAND-01..HAND-15)
|
|
62
|
-
- `templates/roadmap.md` scoped to current milestone only
|
|
63
|
-
|
|
64
|
-
**Phase C — Auto-chain wiring** (`400cd17`)
|
|
65
|
-
- `--auto` flag added to `/qualia-plan`, `/qualia-build`, `/qualia-verify`, `/qualia-milestone`
|
|
66
|
-
- Auto-chain decision table in `/qualia-verify`: PASS → next phase OR milestone close OR ship+handoff; FAIL → gap closure OR halt at limit
|
|
67
|
-
- Two human gates total per project: journey approval + each milestone boundary
|
|
68
|
-
|
|
69
|
-
**Phase D+E — Builder pre-inline + journey visualization** (`74dd26e`)
|
|
70
|
-
- Builder pre-inlines PROJECT.md + DESIGN.md + Context files into agent prompt BEFORE spawning (GSD-pattern borrowing, saves 3-5 Read calls per task)
|
|
71
|
-
- `qualia-ui.js journey-tree` renders JOURNEY.md as ASCII ladder (green shipped, teal current, dim future, [FINAL] tag for Handoff)
|
|
72
|
-
- `qualia-ui.js milestone-complete` celebration banner
|
|
73
|
-
- 5 new banner actions: milestone ◆, journey ◯, auto ⚡, research ◱, roadmap ◐
|
|
74
|
-
- `/qualia` router renders journey-tree for "you are here" orientation
|
|
75
|
-
- `/qualia-milestone` renders journey-tree + milestone-complete
|
|
76
|
-
|
|
77
|
-
**Phase F — Ship-side fields + handoff deliverables** (`b41a52d`)
|
|
78
|
-
- `state.js` bumps `build_count` on each 'built' transition, `deploy_count` on each 'shipped' (previously never incremented)
|
|
79
|
-
- `qualia-report` ERP payload now includes all v4 fields (project_id, team_id, git_remote, milestone_name, milestones[], build_count, deploy_count, session_started_at, last_pushed_at)
|
|
80
|
-
- `/qualia-handoff` rewritten: explicit 4 mandatory deliverables — production URL verified (HTTP + latency + auth), docs updated, `.planning/archive/` check, final ERP report
|
|
81
|
-
|
|
82
|
-
**Phase G — Smoke test fix + coverage** (`f62e753`)
|
|
83
|
-
- Bug fix: close-milestone summary was recording current phase's tasks, not cumulative milestone total. Fixed via `lifetime.tasks_completed − sum(prior milestones[].tasks_completed)`
|
|
84
|
-
- Tests: +2 (cumulative task count, build_count bump)
|
|
85
|
-
|
|
86
|
-
**Release (`f790554`)**
|
|
87
|
-
- Single unified v4.0.0 release commit
|
|
88
|
-
- Package bumped 3.7.0 → 4.0.0
|
|
89
|
-
- CHANGELOG.md v4.0.0 entry with full feature list + migration notes
|
|
90
|
-
- `/qualia-idk` rebuilt as real diagnostician (was briefly v4.0.1 in the branch history, folded into v4.0.0 per owner request)
|
|
91
|
-
|
|
92
|
-
### The `/qualia-idk` rebuild (folded into v4.0.0)
|
|
93
|
-
|
|
94
|
-
Before: thin one-line alias to `/qualia`.
|
|
95
|
-
|
|
96
|
-
Now: interpretive diagnostic. When user says "I don't know what's going on" / "something feels off":
|
|
97
|
-
1. Spawns **Plan view** Explore subagent — reads only `.planning/*`, reports what plan says
|
|
98
|
-
2. Spawns **Code view** Explore subagent in parallel — reads only source code, reports what's actually built, cites file:line
|
|
99
|
-
3. Synthesizes: structured "What I see / The mismatch / What I think is happening / What to do next" in plain language
|
|
100
|
-
4. Maps recommendations to existing commands where applicable
|
|
101
|
-
|
|
102
|
-
`/qualia` description scoped back to mechanical state routing — no longer claims "idk/stuck/lost/confused" triggers (those route to `/qualia-idk` now).
|
|
103
|
-
|
|
104
|
-
## Competitive research completed
|
|
105
|
-
|
|
106
|
-
During the session, ran deep research on competing Claude Code frameworks:
|
|
107
|
-
- **Superpowers** (Jesse Vincent) — 93K stars — rigid 5-phase gates, Visual Companion, cross-agent portability
|
|
108
|
-
- **BMAD-METHOD** — 43K stars — 12-19 named role agents, story files, expansion packs
|
|
109
|
-
- **gstack** (Garry Tan) — 74K stars — 23-role team, persistent browser daemon, /codex cross-model review
|
|
110
|
-
- **GSD** (Get Shit Done, v1+v2) — 54K + 6K stars — state-machine auto-advance, pre-inlined dispatch, adaptive replanning
|
|
111
|
-
- **SuperClaude, Agent OS, Context Engineering/PRP, Claude-Flow, Cursor 2.0, Windsurf** — broader landscape
|
|
112
|
-
|
|
113
|
-
Patterns borrowed in v4.0.0:
|
|
114
|
-
- **Story-file plan format** (BMAD) — inline rationale + acceptance criteria
|
|
115
|
-
- **State-machine auto-advance** (GSD v2) — the --auto chain
|
|
116
|
-
- **Pre-inline context at dispatch** (GSD v2) — builder's <pre-loaded-context> block
|
|
117
|
-
- **Journey-as-first-class-artifact** (NotebookLM synthesis of Qualia's own docs)
|
|
118
|
-
|
|
119
|
-
Patterns deferred to v4.1+:
|
|
120
|
-
- Visual/mockup generation (gstack design-shotgun, Superpowers Visual Companion)
|
|
121
|
-
- Cross-model review (gstack /codex)
|
|
122
|
-
- Cross-project vector memory (claude-mem, Claude-Flow)
|
|
123
|
-
- IDE integration
|
|
124
|
-
- Token-budget compression
|
|
125
|
-
|
|
126
|
-
## Verification at checkpoint
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
✅ Git 8 commits clean on feature/full-journey
|
|
130
|
-
✅ Tests 156/156 pass
|
|
131
|
-
✅ Smoke state transitions + close-milestone + milestones[] summary verified on scratch project
|
|
132
|
-
✅ UI journey-tree + milestone-complete render correctly with real fixtures
|
|
133
|
-
✅ Backward compat older tracking.json without milestones[]/milestone_name still passes state.js check
|
|
134
|
-
✅ No regressions Vs v3.6 baseline — all 150 existing tests still pass
|
|
135
|
-
✅ Package version 4.0.0, ready for `npm publish`
|
|
136
|
-
✅ Handoff V4_REVIEW.md written for next agent
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## Pending (not done by this session)
|
|
140
|
-
|
|
141
|
-
- **Git push** — both branches are local only
|
|
142
|
-
- **Merge to main** — owner decides merge strategy (recommend v3.7.0 tag then v4.0.0 tag)
|
|
143
|
-
- **`npm publish`** — requires owner auth
|
|
144
|
-
- **Tag creation** — after merge
|
|
145
|
-
- **Live auto-chain verification** — smoke tests covered state machine; the --auto chain (which spawns planner→builder→verifier subagents in sequence) wasn't exercised end-to-end. Recommended first real test is on a throwaway project post-publish.
|
|
146
|
-
- **ERP-side updates** — v4 tracking.json fields are additive; ERP should accept them via its existing Zod strip-unknowns pattern, but worth verifying on deploy.
|
|
147
|
-
|
|
148
|
-
## Files the next reviewer should eyeball
|
|
149
|
-
|
|
150
|
-
Priority order (highest leverage first):
|
|
151
|
-
|
|
152
|
-
1. `V4_REVIEW.md` — this file lives in repo root, written as the handoff doc
|
|
153
|
-
2. `CHANGELOG.md` [4.0.0] section — full feature list
|
|
154
|
-
3. `templates/journey.md` — new artifact schema
|
|
155
|
-
4. `agents/roadmapper.md` — biggest agent rewrite
|
|
156
|
-
5. `skills/qualia-new/SKILL.md` — core flow, 14 steps
|
|
157
|
-
6. `skills/qualia-idk/SKILL.md` — new diagnostic
|
|
158
|
-
7. `skills/qualia-verify/SKILL.md` — auto-chain decision table
|
|
159
|
-
8. `skills/qualia-handoff/SKILL.md` — 4 deliverables enforcement
|
|
160
|
-
9. `bin/state.js` close-milestone (~975-1050) — readiness guards + summary append
|
|
161
|
-
10. `bin/qualia-ui.js` journey-tree + milestone-complete functions
|
|
162
|
-
|
|
163
|
-
## Recommended publish sequence
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
# Push both branches
|
|
167
|
-
git push -u origin feature/story-file-plans
|
|
168
|
-
git push -u origin feature/full-journey
|
|
169
|
-
|
|
170
|
-
# Merge v3.7.0 to main, tag, push
|
|
171
|
-
git checkout main
|
|
172
|
-
git merge --ff-only feature/story-file-plans
|
|
173
|
-
git tag v3.7.0
|
|
174
|
-
git push origin main --tags
|
|
175
|
-
|
|
176
|
-
# Merge v4.0.0 to main, tag, push
|
|
177
|
-
git merge --ff-only feature/full-journey
|
|
178
|
-
git tag v4.0.0
|
|
179
|
-
git push origin main --tags
|
|
180
|
-
|
|
181
|
-
# Publish
|
|
182
|
-
npm publish
|
|
183
|
-
npm view qualia-framework version # should return 4.0.0
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## Known limitations / open questions
|
|
187
|
-
|
|
188
|
-
1. **Auto-chain not live-tested.** Unit tests cover state transitions; subagent chaining is covered by the skill prompt text but not exercised. First real project run will reveal edge cases.
|
|
189
|
-
2. **Milestone-summary `tasks_completed` accuracy** depends on lifetime counter deltas. Works if close-milestone is the only consumer — verified in test suite.
|
|
190
|
-
3. **/qualia-idk two-pass isolation** depends on Explore subagent respecting the "do not read .planning/" and "do not read source code" instructions. Prompt-level enforcement, not hard boundary.
|
|
191
|
-
4. **Builder pre-inline** inflates prompt size for monorepos with large DESIGN.md + multiple context files. Acceptable for most projects; could be optimized in v4.1.
|
|
192
|
-
|
|
193
|
-
## For questions
|
|
194
|
-
|
|
195
|
-
Contact: Fawzi Goussous — fawzi@qualiasolutions.net
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
*Written 2026-04-18 at release-candidate time. Supersedes the 2026-04-17 session report covering v3.4.2 / v3.5.0 / v3.6.0.*
|