@agentsfleet/orly 0.9.2 → 0.9.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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # cross-tier-rates.sh — pin numeric parity of the rate constants
3
- # across Zig + three TypeScript surfaces.
3
+ # across the daemon + three TypeScript surfaces.
4
4
  #
5
5
  # RULE UFS extension. The shipped billing surface depends on these constants
6
6
  # having identical numeric values everywhere they appear:
@@ -16,13 +16,13 @@
16
16
  #
17
17
  # Files (one definition site per constant per file):
18
18
  #
19
- # src/agentsfleetd/state/tenant_billing.zig — server enforces the charge
19
+ # rustd/crates/afd_billing/src/nanos.rs — server enforces the charge
20
20
  # ui/packages/website/src/lib/rates.ts — pricing page display
21
21
  # ui/packages/app/lib/types.ts — dashboard display
22
22
  # cli/src/constants/billing.ts — `agentsfleet doctor --json` billing block
23
23
  #
24
24
  # A drift between any two = a billing-display lie or a server-vs-CLI disagreement.
25
- # Zig is the source of truth (server enforces); the three TS surfaces echo it.
25
+ # The daemon is the source of truth (server enforces); the three TS surfaces echo it.
26
26
  #
27
27
  # Fires in: make harness-verify, make harness-verify-all.
28
28
  # Exits 0 clean, 1 on any drift.
@@ -37,7 +37,7 @@ readonly NAMES=(
37
37
  )
38
38
 
39
39
  readonly FILES=(
40
- src/agentsfleetd/state/tenant_billing.zig
40
+ rustd/crates/afd_billing/src/nanos.rs
41
41
  ui/packages/website/src/lib/rates.ts
42
42
  ui/packages/app/lib/types.ts
43
43
  cli/src/constants/billing.ts
@@ -96,7 +96,7 @@ if [[ $FAIL -ne 0 ]]; then
96
96
  printf " %s\n" "$v" >&2
97
97
  done
98
98
  printf "\nFix: align all four files on the canonical Zig value\n" >&2
99
- printf " (src/agentsfleetd/state/tenant_billing.zig is the server-side enforcer).\n" >&2
99
+ printf " (rustd/crates/afd_billing/src/nanos.rs is the server-side enforcer).\n" >&2
100
100
  exit 1
101
101
  fi
102
102
 
@@ -60,11 +60,14 @@ note() { printf "NOTE: %s\n" "$*"; }
60
60
  # ---------------------------------------------------------------------------
61
61
  case "$MODE" in
62
62
  --staged|staged)
63
- mapfile -t FILES < <(git diff --cached --name-only --diff-filter=ACMRT \
63
+ # while read, not mapfile — bash-3.2 portability (see scripts/run-playbook-tests.sh).
64
+ FILES=()
65
+ while IFS= read -r f; do FILES+=("$f"); done < <(git diff --cached --name-only --diff-filter=ACMRT \
64
66
  | grep -E '^src/.*\.zig$' || true)
65
67
  ;;
66
68
  --all|all)
67
- mapfile -t FILES < <(find src -type f -name '*.zig' 2>/dev/null || true)
69
+ FILES=()
70
+ while IFS= read -r f; do FILES+=("$f"); done < <(find src -type f -name '*.zig' 2>/dev/null || true)
68
71
  ;;
69
72
  *)
70
73
  printf "usage: %s [--staged|--all]\n" "$0" >&2
@@ -106,10 +109,13 @@ done
106
109
  # M70 perf: pre-compute file sets in batched greps instead of one grep
107
110
  # per file (~760 forks → 2 forks). Reads as "membership sets" for the
108
111
  # per-init loop below.
109
- declare -A files_with_cleanup=()
112
+ # A membership set as a newline-delimited string, not declare -A: associative
113
+ # arrays are bash 4+ and macOS ships 3.2. Lookup is a substring test on
114
+ # \n<file>\n, which filenames cannot fake.
115
+ files_with_cleanup=$'\n'
110
116
  if [[ ${#present_files[@]} -gt 0 ]]; then
111
117
  while IFS= read -r f; do
112
- [[ -n "$f" ]] && files_with_cleanup["$f"]=1
118
+ [[ -n "$f" ]] && files_with_cleanup="${files_with_cleanup}${f}"$'\n'
113
119
  done < <(grep -lE "$CLEANUP_RE" "${present_files[@]}" 2>/dev/null || true)
114
120
  fi
115
121
 
@@ -151,7 +157,7 @@ if [[ -n "$inits_list" ]]; then
151
157
  fi
152
158
 
153
159
  inits_requires_cleanup=$((inits_requires_cleanup + 1))
154
- if [[ -z "${files_with_cleanup[$f]+x}" ]]; then
160
+ if [[ "$files_with_cleanup" != *$'\n'"$f"$'\n'* ]]; then
155
161
  inits_unpaired=$((inits_unpaired + 1))
156
162
  reason=""
157
163
  [[ $heap -eq 1 ]] && reason="heap-return"
@@ -108,7 +108,10 @@ gather_used_paths() {
108
108
  esac
109
109
  }
110
110
 
111
- mapfile -t USED_PATHS < <(gather_used_paths)
111
+ # `while read` rather than mapfile: mapfile is bash 4+ and macOS ships 3.2 —
112
+ # the portability rule scripts/run-playbook-tests.sh already records.
113
+ USED_PATHS=()
114
+ while IFS= read -r p; do USED_PATHS+=("$p"); done < <(gather_used_paths)
112
115
  if [[ ${#USED_PATHS[@]} -eq 0 ]]; then
113
116
  ok "no source files in scope ($MODE)"
114
117
  exit 0
package/audits/logging.sh CHANGED
@@ -110,7 +110,10 @@ gather_paths() {
110
110
  esac
111
111
  }
112
112
 
113
- mapfile -t FILES < <(gather_paths)
113
+ # `while read` rather than mapfile: mapfile is bash 4+ and macOS ships 3.2 —
114
+ # the portability rule scripts/run-playbook-tests.sh already records.
115
+ FILES=()
116
+ while IFS= read -r p; do FILES+=("$p"); done < <(gather_paths)
114
117
  if [[ ${#FILES[@]} -eq 0 ]]; then
115
118
  ok "no source files in scope ($MODE)"
116
119
  exit 0
@@ -139,7 +142,9 @@ for f in "${FILES[@]}"; do
139
142
  done
140
143
 
141
144
  if [[ ${#rust_nontest[@]} -gt 0 ]]; then
142
- mapfile -t rust_candidates < <(grep -lE '(^|[^[:alnum:]_])(println|eprintln|dbg)!|tracing::(error|warn|info|debug|trace)!' "${rust_nontest[@]}" 2>/dev/null || true)
145
+ rust_candidates=()
146
+ while IFS= read -r p; do rust_candidates+=("$p"); done \
147
+ < <(grep -lE '(^|[^[:alnum:]_])(println|eprintln|dbg)!|tracing::(error|warn|info|debug|trace)!' "${rust_nontest[@]}" 2>/dev/null || true)
143
148
  fi
144
149
 
145
150
  # ---------------------------------------------------------------------------
@@ -388,12 +393,17 @@ fi
388
393
  # ---------------------------------------------------------------------------
389
394
  scoped_hits=0
390
395
  scoped_eligible=()
391
- for f in "${zig_nontest[@]}"; do
392
- case "$f" in
393
- src/logging/*) continue ;;
394
- esac
395
- scoped_eligible+=("$f")
396
- done
396
+ # Guarded like every sibling loop: bash 3.2 under `set -u` treats "${empty[@]}"
397
+ # as unbound (fixed only in 4.4), so an unguarded expansion aborts the audit in
398
+ # any repository with no Zig sources. macOS ships 3.2.
399
+ if [[ ${#zig_nontest[@]} -gt 0 ]]; then
400
+ for f in "${zig_nontest[@]}"; do
401
+ case "$f" in
402
+ src/logging/*) continue ;;
403
+ esac
404
+ scoped_eligible+=("$f")
405
+ done
406
+ fi
397
407
  if [[ ${#scoped_eligible[@]} -gt 0 ]]; then
398
408
  while IFS= read -r line; do
399
409
  [[ -z "$line" ]] && continue
@@ -48,13 +48,17 @@ note() { printf "NOTE: %s\n" "$*"; }
48
48
  # Discover spec files in scope.
49
49
  case "$MODE" in
50
50
  --staged|staged)
51
- mapfile -t SPECS < <(git diff --cached --name-only --diff-filter=ACMRT | grep -E '^docs/v[0-9]+/(pending|active|done)/.*\.md$' || true)
51
+ # while read, not mapfile — bash-3.2 portability (see scripts/run-playbook-tests.sh).
52
+ SPECS=()
53
+ while IFS= read -r s; do SPECS+=("$s"); done < <(git diff --cached --name-only --diff-filter=ACMRT | grep -E '^docs/v[0-9]+/(pending|active|done)/.*\.md$' || true)
52
54
  ;;
53
55
  --all|all)
54
- mapfile -t SPECS < <(find docs/v[0-9]* -type f -name '*.md' 2>/dev/null | grep -E '/(pending|active)/' || true)
56
+ SPECS=()
57
+ while IFS= read -r s; do SPECS+=("$s"); done < <(find docs/v[0-9]* -type f -name '*.md' 2>/dev/null | grep -E '/(pending|active)/' || true)
55
58
  ;;
56
59
  --include-done|include-done)
57
- mapfile -t SPECS < <(find docs/v[0-9]* -type f -name '*.md' 2>/dev/null | grep -E '/(pending|active|done)/' || true)
60
+ SPECS=()
61
+ while IFS= read -r s; do SPECS+=("$s"); done < <(find docs/v[0-9]* -type f -name '*.md' 2>/dev/null | grep -E '/(pending|active|done)/' || true)
58
62
  ;;
59
63
  --file|file)
60
64
  # Single named spec, both families — the lifecycle engine's spec.gate
package/audits/sql-mod.sh CHANGED
@@ -46,10 +46,13 @@ added_hit() {
46
46
 
47
47
  case "$MODE" in
48
48
  --staged|staged)
49
- mapfile -t FILES < <(git diff --cached --name-only --diff-filter=ACMRT -- '*.zig' || true)
49
+ # while read, not mapfile — bash-3.2 portability (see scripts/run-playbook-tests.sh).
50
+ FILES=()
51
+ while IFS= read -r f; do FILES+=("$f"); done < <(git diff --cached --name-only --diff-filter=ACMRT -- '*.zig' || true)
50
52
  STAGED=1 ;;
51
53
  --all|all)
52
- mapfile -t FILES < <(find src -type f -name '*.zig' 2>/dev/null || true)
54
+ FILES=()
55
+ while IFS= read -r f; do FILES+=("$f"); done < <(find src -type f -name '*.zig' 2>/dev/null || true)
53
56
  STAGED=0 ;;
54
57
  *)
55
58
  printf "usage: %s [--staged|--all]\n" "$0" >&2
package/audits/ufs.sh CHANGED
@@ -116,7 +116,12 @@ if [ "$MODE" = "--staged" ]; then
116
116
  else
117
117
  scope_files() { git ls-files; }
118
118
  fi
119
- mapfile -t FILES < <(scope_files | while read -r f; do
119
+ # `while read` rather than mapfile: mapfile is bash 4+ and macOS ships 3.2 —
120
+ # the portability rule scripts/run-playbook-tests.sh already records.
121
+ FILES=()
122
+ while IFS= read -r f; do
123
+ FILES+=("$f")
124
+ done < <(scope_files | while read -r f; do
120
125
  is_source "$f" && echo "$f"
121
126
  done)
122
127
 
@@ -344,9 +349,13 @@ done < <(awk -v re="$NUMERIC_RE" '
344
349
 
345
350
  # ── 3. cross-runtime-orphan ─────────────────────────────────────────────────
346
351
  # Full-tree ERR_* parity. Scoped to the ERR_* prefix because that is the
347
- # cross-runtime contract surface — server error codes a client consumes. Zig is
348
- # the source of truth: every client-side ERR_* must have a matching Zig
349
- # `pub const ERR_*`. Zig-only codes are fine; a server-internal code needs no
352
+ # cross-runtime contract surface — server error codes a client consumes. The
353
+ # daemon is the source of truth. A Rust daemon declares its codes through a
354
+ # registry — `ErrorCode::declare("…")` — and the contract a client holds is
355
+ # that STRING, so parity is checked on the string: every client
356
+ # `export const ERR_X = "…"` must name a code the registry declares. Where no
357
+ # registry exists and Zig does, the Zig `pub const ERR_*` NAMES are the
358
+ # oracle instead. Daemon-only codes are fine; a server-internal code needs no
350
359
  # client mirror.
351
360
  #
352
361
  # Scoped BY RUNTIME, not by one repository's directory names. The previous form
@@ -381,11 +390,29 @@ parity_codes() {
381
390
  | grep -oE 'ERR_[A-Z][A-Z0-9_]+' | sort -u || true
382
391
  }
383
392
 
393
+ # The Rust registry outranks a Zig mirror: a runner that keeps a Zig subset of
394
+ # the daemon's codes for its own use is a client, not the oracle. `record`
395
+ # mutates globals, so the loop runs in this shell over a here-string — never on
396
+ # the right of a pipe, which would run it in a subshell and drop every finding.
397
+ rust_codes=$(git ls-files -z -- '*.rs' 2>/dev/null \
398
+ | { grep -zvE "$PARITY_EXCLUDE" || true; } \
399
+ | { xargs -0 grep -hoE 'ErrorCode::declare\("[^"]+"\)' 2>/dev/null || true; } \
400
+ | { grep -oE '"[^"]+"' || true; } | tr -d '"' | sort -u)
384
401
  zig_err=$(parity_codes '^pub const ERR_[A-Z][A-Z0-9_]+[[:space:]]*=' '*.zig')
385
402
  client_err=$(parity_codes '^export const ERR_[A-Z][A-Z0-9_]+[[:space:]]*=' '*.js' '*.jsx' '*.ts' '*.tsx')
386
403
 
387
- if [ -z "$zig_err" ]; then
388
- ok "audit-ufs: cross-runtime parity skipped — no Zig ERR_* declared, so this repository has no source of truth to compare against"
404
+ if [ -n "$rust_codes" ]; then
405
+ client_decls=$(git ls-files -z -- '*.js' '*.jsx' '*.ts' '*.tsx' 2>/dev/null \
406
+ | { grep -zvE "$PARITY_EXCLUDE" || true; } \
407
+ | { xargs -0 grep -hE '^export const ERR_[A-Z][A-Z0-9_]+[[:space:]]*=[[:space:]]*"[^"]+"' 2>/dev/null || true; })
408
+ while IFS= read -r line; do
409
+ [ -n "$line" ] || continue
410
+ name=$(printf '%s' "$line" | grep -oE 'ERR_[A-Z][A-Z0-9_]+' | head -1)
411
+ code=$(printf '%s' "$line" | sed -E 's/^[^=]*=[[:space:]]*"([^"]+)".*/\1/')
412
+ echo "$rust_codes" | grep -qxF -- "$code" || record "cross-runtime-orphan $name ($code) absent-in-daemon"
413
+ done <<<"$client_decls"
414
+ elif [ -z "$zig_err" ]; then
415
+ ok "audit-ufs: cross-runtime parity skipped — no Rust registry and no Zig ERR_* declared, so this repository has no source of truth to compare against"
389
416
  else
390
417
  # Every client-side ERR_* must exist in Zig.
391
418
  for c in $client_err; do
package/dispatch/lib.sh CHANGED
@@ -53,7 +53,10 @@ DISPATCH_RC=0
53
53
  # Rule-code gloss map — canonical short expansions (full text in RULES.md legend).
54
54
  # Keep in sync with RULES.md; dispatch-coverage.sh fails on a code with no
55
55
  # gloss entry. snake-of-record: CODE → "Short Gloss".
56
- declare -A DISPATCH_GLOSS=(
56
+ # A heredoc of `[CODE]="Gloss"` lines, not declare -A: associative arrays are
57
+ # bash 4+ and macOS ships 3.2. The line shape is load-bearing —
58
+ # evals/dispatch/coverage.sh greps lib.sh for it (checks f and g).
59
+ DISPATCH_GLOSS="$(cat <<'GLOSS'
57
60
  [NDC]="No Dead Code"
58
61
  [NLR]="No Legacy Retained (touch-it-fix-it)"
59
62
  [NLG]="No Legacy compat shims (pre-v2.0.0)"
@@ -83,10 +86,17 @@ declare -A DISPATCH_GLOSS=(
83
86
  [ERR-RS]="Rust ERror discipline (one type per crate, Result alias, no stringified cause)"
84
87
  [GRP]="GREptile rule audit (diff vs greptile-learnings/RULES.md codes)"
85
88
  [LDC]="Legacy-Design Consult (A remove / B patch / C keep)"
86
- )
89
+ GLOSS
90
+ )"
87
91
 
88
92
  # Look up a gloss; empty string if the code is unknown (audit will catch it).
89
- dispatch_gloss() { printf '%s' "${DISPATCH_GLOSS[$1]:-}"; }
93
+ # Pure parameter expansion — no fork per finding. `[` is escaped so the code
94
+ # is matched literally, not as a glob class.
95
+ dispatch_gloss() {
96
+ local rest; rest="${DISPATCH_GLOSS#*\[$1\]=\"}"
97
+ [[ "$rest" == "$DISPATCH_GLOSS" ]] && return 0
98
+ printf '%s' "${rest%%\"*}"
99
+ }
90
100
 
91
101
  dispatch_init() {
92
102
  DISPATCH_LANG="$1"; shift
@@ -33,12 +33,12 @@ dispatch_run_helper "LOG" "logging.sh" "--staged"
33
33
  dispatch_run_helper "MSID" "msid-ui.sh" "--staged"
34
34
 
35
35
  # ── delegations (run only in the product repo — need state absent from dotfiles) ──
36
- # ERR's leaf hard-exits if src/agentsfleetd/errors/error_registry.zig is absent (it
36
+ # ERR's leaf hard-exits if the product repo's error registry is absent (it
37
37
  # cross-references emitted codes against the registry), unlike UFS/LOG/MSID which
38
38
  # pass gracefully on empty input. So it can't run in dotfiles — delegate it; the
39
39
  # product repo's `make harness-verify` runs error-codes.sh against the real
40
40
  # registry. The .md keeps [DETERMINISTIC → ERR]: deterministic, just not run here.
41
- dispatch_delegate "ERR" "make harness-verify (error-codes.sh — needs src/agentsfleetd/errors/error_registry.zig)"
41
+ dispatch_delegate "ERR" "make harness-verify (error-codes.sh — needs the product repo's error registry)"
42
42
 
43
43
  # ── judgment gates (no script can decide; agent states verdict in chat) ──
44
44
  dispatch_judgment "GRP" "per-iteration (diff langs change) + end-of-turn: audit the diff against docs/greptile-learnings/RULES.md — one row per applicable code (UFS/ORP/TST-NAM/PRI/EMS/…); \"it's just a label\" is not an exception"
@@ -480,7 +480,7 @@ Rules:
480
480
 
481
481
  New production Zig modules must not define SQL statement text inline. Put query
482
482
  text in a domain-local `sql.zig` and import it from the state/handler/service
483
- module. This mirrors `src/agentsfleetd/fleet_bundle/sql.zig`: table names and
483
+ module. The shape is a domain-local `sql.zig` beside the module it serves: table names and
484
484
  query statements stay grepable in one place, while the public module owns row
485
485
  mapping, allocator ownership, and error translation.
486
486
 
@@ -14,5 +14,5 @@ Editing `~/Projects/docs/changelog.mdx` or any other Mintlify `<Update>` block.
14
14
  - **Internal cleanup / refactor entries get the most aggressive trimming.** One lead paragraph + one bullet list. Skip "Test coverage" sections unless the test count is the headline. Indy's exact direction: *"Keep internal code cleanup, refactor to a minimal."*
15
15
  - **Never drop load-bearing facts.** Error codes (`UZ-AUTH-003`), endpoint paths + method + body shape + status code, env var names + defaults, schema column / table names, CLI subcommand + flag names, migration steps, money amounts. Tighten prose, not meaning.
16
16
  - **Historical entries are archives.** Brevity-pass them; never rewrite the past. A typo correction (e.g. `$0.001` → `$0.01` when it was never true) is allowed and must be called out in the commit message.
17
- - **Rate constants flow through three pinned files only:** `src/agentsfleetd/state/tenant_billing.zig`, `ui/packages/website/src/lib/rates.ts`, `~/Projects/docs/snippets/rates.mdx`. Bumping a rate requires a paired Pull Request (PR) across the docs repo — there is no automated guard. In `*.mdx`, use `import { STARTER_CREDIT, EVENT_RATE, STAGE_RATE } from "/snippets/rates.mdx"` instead of hand-typing `$5`.
17
+ - **Rate constants flow through three pinned files only:** `rustd/crates/afd_billing/src/nanos.rs`, `ui/packages/website/src/lib/rates.ts`, `~/Projects/docs/snippets/rates.mdx`. Bumping a rate requires a paired Pull Request (PR) across the docs repo — there is no automated guard. In `*.mdx`, use `import { STARTER_CREDIT, EVENT_RATE, STAGE_RATE } from "/snippets/rates.mdx"` instead of hand-typing `$5`.
18
18
  - **The Mintlify reference Indy pasted (May 1 / May 8 entries) is canonical voice.** Mirror its rhythm, not its product nouns.
@@ -22,7 +22,7 @@ Every triggered document requires one `📖 DOC READ: <path>` proof-line **per t
22
22
  | `*.mdx` | `dispatch/write_mdx.md` — structure, front matter, links, code fences, accessibility, and Mintlify isolation. | <!-- oracle-packs:language.mdx -->
23
23
  | Log emit (any language; see LOGGING GATE triggers) | `docs/LOGGING_STANDARD.md` — wire format (logfmt), severity ladder, error-code embedding, scope/event discipline, PII redaction, §10A tightenings. LOGGING GATE per edit. |
24
24
  | Lifecycle method in `*.zig` (`init|deinit|close|release|destroy|shutdown|dispose|free`) | `docs/LIFECYCLE_PATTERNS.md` — init/deinit pairing, errdefer placement, allocator ownership, defer/errdefer mutual exclusion, §10A tightenings. LIFECYCLE GATE per edit. |
25
- | `src/agentsfleetd/http/handlers/**` or `public/openapi/**` | `docs/REST_API_DESIGN_GUIDELINES.md` — Quick Checklist; §1–§5 (URL/method/body/response/error), §6 (OpenAPI), §7 (6-place route registration), §8 (`Hx` handler interface), §10 (pre-PR gates). |
25
+ | `rustd/crates/afd_api*/src/handler/**` or `public/openapi/**` | `docs/REST_API_DESIGN_GUIDELINES.md` — Quick Checklist; §1–§5 (URL/method/body/response/error), §6 (OpenAPI), §7 (6-place route registration), §8 (`Hx` handler interface), §10 (pre-PR gates). |
26
26
  | `ui/packages/**/*.{tsx,jsx,css}`, `app/**/*.{tsx,jsx,css}`, `components/**/*.{tsx,jsx,css}`, repo-root `globals.css`, or any file changing visual tokens / motion / typography | `DESIGN.md` (repo root) or `docs/DESIGN_SYSTEM.md` — whichever the repo carries. Design system source of truth: typography stack, color tokens, the single accent and its currency rule, motion signature, spacing/density, component principles, CLI palette mapping. DOC READ proof-line per turn. |
27
27
  | `*.tsx` / `*.jsx` under `ui/packages/{app,website}/` | `dispatch/write_ts_adhere_bun.md` (Design Tokens) — token-utility table (text/tracking/leading/max-w/min-w/spacing/motion/radius/color). DESIGN TOKEN GATE fires per edit; audit via project-side `audits/design-tokens.sh`. |
28
28
  | Auth-flow | `docs/AUTH.md`. |
@@ -35,7 +35,7 @@ Documented honestly, not aspirationally. Pre-M62 baseline (the fix-pass converge
35
35
 
36
36
  - The named module `log` (source: `src/lib/logging/mod.zig`) exposes `scoped(.tag)` returning a logger struct with `.err` / `.warn` / `.info` / `.debug` methods. M62 removed the older free-function helpers (`logErr` / `logErrWithHint` / `logWarnErr`) — there is no compat shim.
37
37
  - TypeScript (`cli/src/**`) calls `console.log`/`console.error` directly. No structure. No scope. No severity beyond err vs out.
38
- - Error-code embedding (`UZ-XXX-NNN`) appears on some `err` lines but not others. The registry (`src/agentsfleetd/errors/error_registry.zig`) is the source of truth, but enforcement is voluntary.
38
+ - Error-code embedding (`UZ-XXX-NNN`) appears on some `err` lines but not others. The registry (`rustd/crates/afd_core/src/error_code.rs`) is the source of truth, but enforcement is voluntary.
39
39
  - No collector-friendly format. Logs are a mix of free-form English and ad-hoc `key={value}` fragments.
40
40
 
41
41
  The proposed standard below is what every new emit must conform to and what the fix-pass converges existing emits toward.
@@ -168,7 +168,7 @@ Log the source (`source=env:OPENAI_API_KEY`), never the value, at every level.
168
168
 
169
169
  > [DETERMINISTIC → LOG]
170
170
 
171
- Every `err` and `warn` record that maps to a domain error MUST carry `error_code=UZ-XXX-NNN` where `UZ-XXX-NNN` is declared in `src/agentsfleetd/errors/error_registry.zig`.
171
+ Every `err` and `warn` record that maps to a domain error MUST carry `error_code=UZ-XXX-NNN` where `UZ-XXX-NNN` is declared in `rustd/crates/afd_core/src/error_code.rs`.
172
172
 
173
173
  - **Used-but-undeclared** (`UZ-FAKE-999` appearing in code, no entry in registry): **blocking** in `make lint`.
174
174
  - **Declared-but-unreferenced** (registry has `UZ-LEGACY-007`, no code references it): **informational**. Deletion may be deferred to a sweep milestone.
@@ -115,7 +115,7 @@ surfaces:
115
115
  {
116
116
  "commands": { "conform": [["make", "harness-verify"]],
117
117
  "verify.unit": [["make", "test-unit-all"]] },
118
- "surfaces": { "user": ["src/agentsfleetd/http/", "cli/src/"],
118
+ "surfaces": { "user": ["src/http/", "cli/src/"],
119
119
  "docs": ["docs/"] }
120
120
  }
121
121
  ```
@@ -16,7 +16,7 @@ Destructive changes (`DROP TABLE`, `DROP COLUMN`, type rewrites) require an expl
16
16
 
17
17
  - Each SQL file must be **≤100 lines** and **single-concern** (one table, one logical group, or one additive change).
18
18
  - Files are numbered sequentially: `001_core_foundation.sql`, `002_core_workflow.sql`, etc. New migrations append the next number; shipped numbers are never reused or slid.
19
- - Every SQL file must be registered in `schema/embed.zig` (compile-time embed) and `src/agentsfleetd/cmd/common.zig` (migration version array).
19
+ - Every SQL file must be registered in `schema/embed.zig` (compile-time embed) and `rustd/crates/afd_db/src/migration.rs` (migration version array).
20
20
  - No-op stub files (e.g., columns folded into earlier files) are kept for version history but excluded from the migrations array.
21
21
 
22
22
  ## SQL Qualification
@@ -37,14 +37,14 @@ Destructive changes (`DROP TABLE`, `DROP COLUMN`, type rewrites) require an expl
37
37
 
38
38
  - **Column:** `id`
39
39
  - **Type:** Universally Unique Identifier (UUID) `PRIMARY KEY`
40
- - **Generation:** Application-side UUID version 7 (UUIDv7) via `src/agentsfleetd/types/id_format.zig`, never `gen_random_uuid()`.
40
+ - **Generation:** Application-side UUID version 7 (UUIDv7) via `rustd/crates/afd_core/src/id.rs`, never `gen_random_uuid()`.
41
41
  - **No second unique key on the same value.** This is a correctness rule, not only a storage one: `ON CONFLICT` can arbitrate exactly one constraint, so a table carrying two unique keys over the same value makes two sessions inserting a brand-new row race to a duplicate-key error on the *other* index instead of taking the update arm. `schema/043_runner_lifetime_counters.sql` recorded this before the rule was generalised.
42
42
  - **Foreign keys reference the primary key**, never a secondary unique constraint.
43
43
  - **Constraint:** every table carries a UUIDv7 CHECK:
44
44
  ```sql
45
45
  CONSTRAINT ck_{table}_id_uuidv7 CHECK (substring(id::text from 15 for 1) = '7')
46
46
  ```
47
- - **Adding a new table:** add a `generate{TableName}Id()` function to `src/agentsfleetd/types/id_format.zig`.
47
+ - **Adding a new table:** add a `generate{TableName}Id()` function to `rustd/crates/afd_core/src/id.rs`.
48
48
  - **API shape:** unchanged — public fields keep exposing `id`, `tenant_id`, `workspace_id` and the other documented names. The column now *is* the public name in most tables, so the aliasing the old rule required mostly disappears; where a public field differs from `id`, alias at the boundary rather than renaming client-facing payloads.
49
49
  - **Exceptions,** each stated in the slot that creates the table: a curated catalogue keyed by a stable slug (`core.fleet_library`) and a singleton keyed by a pinned integer (`core.model_catalogue_revision`) carry no UUID.
50
50
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsfleet/orly",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Repository-scoped engineering harness: renders agent rules, materialises the gates that enforce them, and proves the PR boundary \u2014 for any coding agent.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -80,7 +80,7 @@ Spec asserts "503 on Redis down", code returns 200 → test the spec, flag the c
80
80
  | **Standard** | New service method, new Redis stream/key, schema change with logic | + T4 + T5 + T6 |
81
81
  | **Hardening** | Auth / payment / lease / migration / streaming / anything in the data-loss radius | + T7 (if applicable) + T8 + chaos pass |
82
82
 
83
- Auto-detect from diff: `src/auth/**`, `src/agent/leases/**`, `src/runner/**` + `src/agentsfleetd/fleet/**` (the lease/reclaim/fence + client-daemon surface → T9), schema migrations, streaming handlers → Hardening. CRUD-only against existing schema → Smoke. Default → Standard.
83
+ Auto-detect from diff: `src/auth/**`, `src/agent/leases/**`, `src/runner/**` + `rustd/crates/afd_fleet/**` (the lease/reclaim/fence + client-daemon surface → T9), schema migrations, streaming handlers → Hardening. CRUD-only against existing schema → Smoke. Default → Standard.
84
84
 
85
85
  Any operation that touches multiple systems or acquires the same resource more than once is **Standard at minimum** and must run T4, even when the endpoint is otherwise CRUD-only.
86
86