@windyroad/architect 0.21.3 → 0.21.4-preview.1104
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/package.json
CHANGED
|
@@ -84,14 +84,31 @@ if [ ! -d "$DECISIONS_DIR" ]; then
|
|
|
84
84
|
exit 2
|
|
85
85
|
fi
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
if ! command -v iconv >/dev/null 2>&1; then
|
|
88
|
+
echo "generate-decisions-compendium: iconv is required for UTF-8 validation" >&2
|
|
89
|
+
exit 2
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# Generate into a temporary file so invalid or incomplete output never
|
|
93
|
+
# replaces the last known-good compendium. Write mode uses the target
|
|
94
|
+
# directory so the final rename is atomic.
|
|
89
95
|
if [ "$CHECK_MODE" = "1" ]; then
|
|
90
|
-
COMPENDIUM=$(mktemp -t architect-compendium-check.XXXXXX)
|
|
91
|
-
|
|
96
|
+
if ! COMPENDIUM=$(mktemp -t architect-compendium-check.XXXXXX); then
|
|
97
|
+
echo "generate-decisions-compendium: could not create check-mode temporary file" >&2
|
|
98
|
+
exit 2
|
|
99
|
+
fi
|
|
92
100
|
else
|
|
93
|
-
COMPENDIUM
|
|
101
|
+
if ! COMPENDIUM=$(mktemp "${TARGET_COMPENDIUM}.tmp.XXXXXX"); then
|
|
102
|
+
echo "generate-decisions-compendium: could not create temporary compendium beside $TARGET_COMPENDIUM" >&2
|
|
103
|
+
exit 2
|
|
104
|
+
fi
|
|
94
105
|
fi
|
|
106
|
+
cleanup_compendium() {
|
|
107
|
+
if [ -n "${COMPENDIUM:-}" ] && [ -f "$COMPENDIUM" ]; then
|
|
108
|
+
rm -f "$COMPENDIUM"
|
|
109
|
+
fi
|
|
110
|
+
}
|
|
111
|
+
trap cleanup_compendium EXIT
|
|
95
112
|
|
|
96
113
|
# --- Field extractors ------------------------------------------------------
|
|
97
114
|
|
|
@@ -157,7 +174,8 @@ get_bullets() {
|
|
|
157
174
|
# Joins with "; ". Strips markdown emphasis to keep the line scannable.
|
|
158
175
|
compact_join_bullets() {
|
|
159
176
|
local per_item="${1:-120}"
|
|
160
|
-
|
|
177
|
+
local compacted
|
|
178
|
+
if ! compacted=$(awk -v n="$per_item" '
|
|
161
179
|
{
|
|
162
180
|
# Strip leading checkbox markers `[ ]` / `[x]` (from Confirmation).
|
|
163
181
|
sub(/^\[[ x]\] */, "")
|
|
@@ -172,7 +190,11 @@ compact_join_bullets() {
|
|
|
172
190
|
else out = out "; " line
|
|
173
191
|
}
|
|
174
192
|
END { print out }
|
|
175
|
-
'
|
|
193
|
+
' | iconv -f UTF-8 -t UTF-8 -c); then
|
|
194
|
+
echo "generate-decisions-compendium: failed to truncate confirmation text safely" >&2
|
|
195
|
+
return 1
|
|
196
|
+
fi
|
|
197
|
+
printf '%s\n' "$compacted"
|
|
176
198
|
}
|
|
177
199
|
|
|
178
200
|
# Extract ADR-NNN references from Related bullets. Compact "ADR-NNN" listing
|
|
@@ -242,12 +264,19 @@ emit_entry() {
|
|
|
242
264
|
|
|
243
265
|
# Chosen-option line — truncate to a comfortable summary length.
|
|
244
266
|
chosen=$(get_chosen "$file" | strip_links | oneline)
|
|
245
|
-
chosen=$(printf '%s' "$chosen"
|
|
267
|
+
if ! chosen=$(printf '%s' "$chosen" \
|
|
268
|
+
| awk -v n=240 '{ if (length($0) > n) print substr($0,1,n) "..."; else print }' \
|
|
269
|
+
| iconv -f UTF-8 -t UTF-8 -c); then
|
|
270
|
+
echo "generate-decisions-compendium: failed to truncate chosen text safely for $file" >&2
|
|
271
|
+
return 1
|
|
272
|
+
fi
|
|
246
273
|
|
|
247
274
|
# Confirmation: cap 5 bullets, ≤ 110 chars each, joined with "; " on one line.
|
|
248
275
|
# This is the routine-compliance scannable view; the full Confirmation list
|
|
249
276
|
# remains in the per-ADR body for deep-dive surfaces.
|
|
250
|
-
confirmation=$(get_bullets "$file" "Confirmation" 5 | strip_links | compact_join_bullets 110)
|
|
277
|
+
if ! confirmation=$(get_bullets "$file" "Confirmation" 5 | strip_links | compact_join_bullets 110); then
|
|
278
|
+
return 1
|
|
279
|
+
fi
|
|
251
280
|
|
|
252
281
|
# Related: extract ADR-NNN graph references only. Full relationship prose
|
|
253
282
|
# (amends / extends / relates / composes) stays in the per-ADR body.
|
|
@@ -311,6 +340,13 @@ done < <(find "$DECISIONS_DIR" -maxdepth 1 -type f -name '*.md' \
|
|
|
311
340
|
! -name '*-summary.md' \
|
|
312
341
|
2>/dev/null | sort)
|
|
313
342
|
|
|
343
|
+
for f in "${all_files[@]}"; do
|
|
344
|
+
if ! iconv -f UTF-8 -t UTF-8 "$f" >/dev/null 2>&1; then
|
|
345
|
+
echo "generate-decisions-compendium: invalid UTF-8 in authoritative ADR: $f" >&2
|
|
346
|
+
exit 1
|
|
347
|
+
fi
|
|
348
|
+
done
|
|
349
|
+
|
|
314
350
|
in_force_files=()
|
|
315
351
|
historical_files=()
|
|
316
352
|
for f in "${all_files[@]}"; do
|
|
@@ -364,7 +400,9 @@ total=$((in_force_total + historical_total))
|
|
|
364
400
|
echo ""
|
|
365
401
|
echo "_${in_force_total} ADRs. These are the current rules. The architect agent reads this section first for routine compliance review._"
|
|
366
402
|
for f in "${in_force_files[@]}"; do
|
|
367
|
-
emit_entry "$f"
|
|
403
|
+
if ! emit_entry "$f"; then
|
|
404
|
+
exit 1
|
|
405
|
+
fi
|
|
368
406
|
done
|
|
369
407
|
if [ "$historical_total" -gt 0 ]; then
|
|
370
408
|
echo ""
|
|
@@ -374,11 +412,40 @@ total=$((in_force_total + historical_total))
|
|
|
374
412
|
echo ""
|
|
375
413
|
echo "_${historical_total} ADRs. These were tried and superseded, rejected, or deprecated. Read them as direction for what NOT to do, or to understand the lineage of an in-force decision. Do not enforce them as current rules._"
|
|
376
414
|
for f in "${historical_files[@]}"; do
|
|
377
|
-
emit_entry "$f"
|
|
415
|
+
if ! emit_entry "$f"; then
|
|
416
|
+
exit 1
|
|
417
|
+
fi
|
|
378
418
|
done
|
|
379
419
|
fi
|
|
380
420
|
} > "$COMPENDIUM"
|
|
381
421
|
|
|
422
|
+
validate_compendium() {
|
|
423
|
+
local file="$1" in_force_count historical_count expected_historical=0
|
|
424
|
+
if ! iconv -f UTF-8 -t UTF-8 "$file" >/dev/null 2>&1; then
|
|
425
|
+
echo "generate-decisions-compendium: generated output is not valid UTF-8" >&2
|
|
426
|
+
return 1
|
|
427
|
+
fi
|
|
428
|
+
if ! in_force_count=$(awk '$0 == "## In-force decisions" { n++ } END { print n + 0 }' "$file"); then
|
|
429
|
+
echo "generate-decisions-compendium: could not validate the in-force section" >&2
|
|
430
|
+
return 1
|
|
431
|
+
fi
|
|
432
|
+
if ! historical_count=$(awk '$0 == "## Historical decisions" { n++ } END { print n + 0 }' "$file"); then
|
|
433
|
+
echo "generate-decisions-compendium: could not validate the historical section" >&2
|
|
434
|
+
return 1
|
|
435
|
+
fi
|
|
436
|
+
if [ "$historical_total" -gt 0 ]; then
|
|
437
|
+
expected_historical=1
|
|
438
|
+
fi
|
|
439
|
+
if [ "$in_force_count" -ne 1 ] || [ "$historical_count" -ne "$expected_historical" ]; then
|
|
440
|
+
echo "generate-decisions-compendium: generated output has invalid section structure (in-force=$in_force_count, historical=$historical_count, expected historical=$expected_historical)" >&2
|
|
441
|
+
return 1
|
|
442
|
+
fi
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if ! validate_compendium "$COMPENDIUM"; then
|
|
446
|
+
exit 1
|
|
447
|
+
fi
|
|
448
|
+
|
|
382
449
|
if [ "$CHECK_MODE" = "1" ]; then
|
|
383
450
|
# Check mode: diff temp against target. Idempotency contract holds only
|
|
384
451
|
# when both files exist; treat absence as "stale" (drift detected).
|
|
@@ -403,4 +470,14 @@ if [ "$CHECK_MODE" = "1" ]; then
|
|
|
403
470
|
exit 1
|
|
404
471
|
fi
|
|
405
472
|
|
|
406
|
-
|
|
473
|
+
if ! chmod 0644 "$COMPENDIUM"; then
|
|
474
|
+
echo "generate-decisions-compendium: could not set compendium mode to 0644" >&2
|
|
475
|
+
exit 1
|
|
476
|
+
fi
|
|
477
|
+
if ! mv -f "$COMPENDIUM" "$TARGET_COMPENDIUM"; then
|
|
478
|
+
echo "generate-decisions-compendium: could not replace $TARGET_COMPENDIUM" >&2
|
|
479
|
+
exit 1
|
|
480
|
+
fi
|
|
481
|
+
COMPENDIUM=""
|
|
482
|
+
|
|
483
|
+
echo "generate-decisions-compendium: wrote $TARGET_COMPENDIUM (${total} ADRs total — ${in_force_total} in-force, ${historical_total} historical)" >&2
|