Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 87 additions & 34 deletions docs/active-trajectory.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,36 +105,74 @@ Best blade (Amara): *"Line-count dominance is a smoke detector. Content equivale

The drift trajectory is a metric; the GATE is the ledger. Hand-counts drift; ledgers from `git diff --numstat` don't.

The ledger is computed in two passes (text via `numstat`, binary direction via `name-status`). Per multi-AI review 2026-04-29T10:50Z: binary files emit `-/-` in `numstat` because lines aren't countable, but they CAN be erased on hard-reset, so they need direction classification — `acehack-only` vs `lfg-only` vs `modified-on-both`.

**The shell snippet below is ILLUSTRATIVE, NOT DURABLE.** Per multi-AI review 2026-04-29T11:05Z (Codex + Copilot 7-thread cluster + Amara): the inline awk/grep approach below has real NUL-safety bugs and is not portable across awk implementations:

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refers to a “shell snippet below” / “inline snippet”, but the snippet has been removed in this revision, so the wording is now misleading. Suggest rephrasing to refer to the previously-removed snippet (or delete the “below/inline” references) so readers don’t hunt for code that isn’t there.

Suggested change
**The shell snippet below is ILLUSTRATIVE, NOT DURABLE.** Per multi-AI review 2026-04-29T11:05Z (Codex + Copilot 7-thread cluster + Amara): the inline awk/grep approach below has real NUL-safety bugs and is not portable across awk implementations:
**The earlier illustrative shell approach is NOT DURABLE.** Per multi-AI review 2026-04-29T11:05Z (Codex + Copilot 7-thread cluster + Amara): that awk/grep approach has real NUL-safety bugs and is not portable across awk implementations:

Copilot uses AI. Check for mistakes.

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc section introduces additional direct reviewer/persona names (e.g., “Codex”, “Copilot”, “Amara”). Per docs/AGENT-BEST-PRACTICES.md “No name attribution in code, docs, or skills” (docs/AGENT-BEST-PRACTICES.md:284+), current-state docs should use role references instead of contributor/persona identifiers. Suggest rewriting these references to stable role-refs (e.g., “external reviewer”, “PR reviewer”, “harsh-critic”) and keeping named attribution confined to the allowed history surfaces.

Copilot uses AI. Check for mistakes.

- `awk $3` with default whitespace FS breaks on paths with spaces (need `FS='\t'`).
- `grep -Ff` reads newline-delimited patterns, not NUL-delimited (the `ORS="\0"` write doesn't compose with `grep -f`).
- `numstat -z` rename/copy records are `adds<TAB>dels<TAB>NUL old<NUL>new<NUL>`, not just one NUL-delimited row.
- `name-status -z` rename/copy rows are `status<NUL>old<NUL>new<NUL>` (3 fields), not `status<NUL>path<NUL>` (2 fields). The toggle parser desynchronizes.
- `RS='\0'` / `ORS='\0'` is a gawk extension; macOS BSD awk doesn't support it.
- `/tmp/binary-paths.nul` is a fixed path with no `mktemp` + `trap` cleanup; clobber-prone under concurrency.

The durable home for the gate-runner is `tools/zero-zero-zero/check-gate.sh` (deferred follow-up, see "Deferred follow-ups" below). That script must be tested against fixtures including: paths with spaces, binary add, binary delete, binary modify, binary rename, binary copy, gawk-vs-BSD-awk.
Comment thread
AceHack marked this conversation as resolved.

**Stopgap rule for this round**: if `binary_modified_files` is non-zero in this ledger, do NOT rely on the inline snippet to classify direction. Use `git diff --name-status -z origin/main..acehack/main -- <path>` per binary file + direct `git show` evidence, manually, until the gate-runner script exists.
Comment thread
AceHack marked this conversation as resolved.
Outdated

```bash
git diff --numstat origin/main..acehack/main | awk '
# Binary files: numstat emits "-\t-\t<path>". They have no countable lines,
# but content can still be lost on hard-reset. Count them separately so
# they require explicit classification rather than being silently dropped.
$1 == "-" && $2 == "-" {
binary_files += 1
next
}
{
add += $1; del += $2; files += 1
if ($1 == 0) zero_files += 1
}
END {
print "text_modified_files=" files
print "zero_acehack_only_files=" zero_files
print "potential_loss_lines=" add
print "lfg_newer_lines=" del
print "binary_modified_files=" (binary_files+0)
if ((binary_files+0) > 0) {
print "WARNING: binary files in diff need separate classification (lines uncountable)."
print "Run: git diff --name-status origin/main..acehack/main | awk '\''$1!~/^[D]$/'\'' | grep -F -f <(git diff --numstat origin/main..acehack/main | awk '\''$1==\"-\"{print $3}'\'')"
}
}
'
# Pass 1: text files (numstat reports lines)
git diff --numstat -z origin/main..acehack/main \
| awk -v RS='\0' '
Comment thread
AceHack marked this conversation as resolved.
Outdated
$1 != "-" && $2 != "-" {
add += $1; del += $2; files += 1
if ($1 == 0) zero_files += 1
}
Comment thread
AceHack marked this conversation as resolved.
Outdated
END {
print "text_modified_files=" files
print "zero_acehack_only_text_files=" zero_files
print "potential_loss_lines=" add
print "lfg_newer_lines=" del
}
'

# Pass 2: binary files split by direction (name-status reports A/M/D/R/T)
# - "A" from AceHack-side perspective = AceHack-only (hard-reset ERASES) → loss-relevant
# - "D" from AceHack-side perspective = LFG-only (hard-reset ADDS) → not a loss
# - "M"/"R"/"T" = modified on both sides → needs semantic classification
git diff --numstat -z origin/main..acehack/main \
| awk -v RS='\0' 'BEGIN{ORS="\0"} $1 == "-" && $2 == "-" { print $3 }' \
> /tmp/binary-paths.nul
if [ -s /tmp/binary-paths.nul ]; then
git diff --name-status -z origin/main..acehack/main \
| awk -v RS='\0' '
# name-status with -z: status<NUL>path or for renames status<NUL>old<NUL>new
BEGIN{i=0}
{if (i==0) {st=$0; i=1} else {p=$0; print st "\t" p; i=0}}
Comment thread
AceHack marked this conversation as resolved.
Outdated
' \
Comment thread
AceHack marked this conversation as resolved.
Outdated
| grep -Ff /tmp/binary-paths.nul \
Comment thread
AceHack marked this conversation as resolved.
Outdated
Comment thread
AceHack marked this conversation as resolved.
Outdated
Comment thread
AceHack marked this conversation as resolved.
Outdated
| awk -F'\t' '
$1=="A" { ace_only += 1 }
$1=="D" { lfg_only += 1 }
$1 ~ /^[MRTC]/ { modified_both += 1 }
Comment thread
AceHack marked this conversation as resolved.
Outdated
END {
print "binary_acehack_only_files=" (ace_only+0)
print "binary_lfg_only_files=" (lfg_only+0)
print "binary_modified_or_renamed_files=" (modified_both+0)
}
'
Comment thread
AceHack marked this conversation as resolved.
Outdated
Comment thread
AceHack marked this conversation as resolved.
Outdated
fi
```

Per Codex 2026-04-29T10:42Z catch (PR #835): the prior version of this script silently excluded binary files via `$1 != "-" && $2 != "-"`. `git diff --numstat` emits `-/-` for binary content because it can't count lines, but binary files CAN still be erased on hard-reset. New version counts them separately and surfaces a warning when present.
Per Codex 2026-04-29T10:42Z catch + Amara 2026-04-29T10:50Z direction-split: the prior one-pass version silently excluded binary files via `$1 != "-" && $2 != "-"`. The conceptual fix (split direction into three buckets) is correct. The inline implementation above is illustrative only — see the warning block above this code; the durable NUL-safe + portable implementation lives in the deferred gate-runner script.

Verified 2026-04-29T10:43Z: the 5 binary-classified files in the current diff are all LFG-only (status `D` from AceHack perspective; hard-reset ADDS them, doesn't erase AceHack content), so this specific instance has zero binary-loss surface. The script fix is for general correctness.
**Reset-loss surface for binary files:**

- `binary_acehack_only_files` → would be ERASED on hard-reset; this is the gate-relevant count.
- `binary_lfg_only_files` → would be ADDED on hard-reset; not a loss.
- `binary_modified_or_renamed_files` → exists on both with content/mode/path differences; needs semantic classification (e.g., is the AceHack version more correct, or is LFG's the canonical?).

Verified 2026-04-29T10:43Z: the 5 binary-classified files in the current diff have status `D` (LFG-only), so `binary_acehack_only_files = 0` and `binary_modified_or_renamed_files = 0` in this specific round.

Current ledger (computed 2026-04-29T10:25Z):

Expand All @@ -150,14 +188,15 @@ unclassified_lines = 176 HEURISTIC_LFG_DOMINATES — pending per-file sema
Hard-reset is signoff-eligible ONLY when:

```text
unclassified_lines = 0
unsafe_lines = 0
binary_acehack_only_files = 0 (binary files exist only on LFG, OR each binary file has been classified)
fresh-clone fsck = clean
hard-reset preflight = clean
ls-remote-vs-fetch SHA match = verified
dry-run push shape = clean
maintainer signoff = yes
unclassified_lines = 0
unsafe_lines = 0
binary_acehack_only_files = 0 (would be ERASED on hard-reset)
binary_modified_or_renamed_classified = all (each must be SAFE_TO_RESET_LFG_SUPERSEDES or NEEDS_FORWARD_SYNC)
Comment thread
AceHack marked this conversation as resolved.
Outdated
fresh-clone fsck = clean
hard-reset preflight = clean
ls-remote-vs-fetch SHA match = verified
dry-run push shape = clean
maintainer signoff = yes
```

Per multi-AI review 2026-04-29T10:35Z: dry-run push shape verification is added to the gate. Validates refspec + credentials + push shape before the real destructive operation. The real lease still matters at the real push (server-side check); dry-run is an additive safety check, not a replacement.
Expand Down Expand Up @@ -358,6 +397,15 @@ A peer-call to Grok this session reported the inverse claim ("AceHack has the se

**Hard-reset is NOT YET signoff-eligible.** The strict gate above requires `unclassified_lines = 0`, and the current ledger says `unclassified_lines = 176` (18 files in HEURISTIC_LFG_DOMINATES). The next agent-owned work is per-file semantic inspection of those 18 files to either promote each to SAFE_TO_RESET_LFG_SUPERSEDES (with named evidence) or downgrade to NEEDS_FORWARD_SYNC.

### Deferred follow-ups (NOT blocking 0/0/0 progress, captured for visibility)

Per multi-AI review 2026-04-29T10:50Z packet:

- **Gate-runner script** (now bumped to highest priority among deferred follow-ups): build `tools/zero-zero-zero/check-gate.sh` that emits a machine-readable summary of all 9 gate conditions and fails closed. Replaces the prose ledger AND the illustrative inline snippet above with a verifiable-by-execution gate. Per multi-AI review 2026-04-29T11:05Z (Codex P1 + Copilot 5 threads + Amara): the durable script must be tested against fixtures: paths with spaces, binary add, binary delete, binary modify, binary rename, binary copy, gawk-vs-BSD-awk portability, `mktemp` + `trap` cleanup. Until the script lands, binary direction MUST be classified manually via `git diff --name-status -z` per file + direct `git show` evidence. Best blade (Amara): *"The binary hole is found. The gate condition is right. The parser still needs teeth."*

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bullet says the future gate-runner should emit “all 9 gate conditions”, but the gate list above currently contains 11 lines. Please reconcile the count (either adjust the bullet to match the current gate, or update the gate list/counting so it really is 9) to avoid cross-reference drift.

Suggested change
- **Gate-runner script** (now bumped to highest priority among deferred follow-ups): build `tools/zero-zero-zero/check-gate.sh` that emits a machine-readable summary of all 9 gate conditions and fails closed. Replaces the prose ledger AND the illustrative inline snippet above with a verifiable-by-execution gate. Per multi-AI review 2026-04-29T11:05Z (Codex P1 + Copilot 5 threads + Amara): the durable script must be tested against fixtures: paths with spaces, binary add, binary delete, binary modify, binary rename, binary copy, gawk-vs-BSD-awk portability, `mktemp` + `trap` cleanup. Until the script lands, binary direction MUST be classified manually via `git diff --name-status -z` per file + direct `git show` evidence. Best blade (Amara): *"The binary hole is found. The gate condition is right. The parser still needs teeth."*
- **Gate-runner script** (now bumped to highest priority among deferred follow-ups): build `tools/zero-zero-zero/check-gate.sh` that emits a machine-readable summary of all 11 gate conditions and fails closed. Replaces the prose ledger AND the illustrative inline snippet above with a verifiable-by-execution gate. Per multi-AI review 2026-04-29T11:05Z (Codex P1 + Copilot 5 threads + Amara): the durable script must be tested against fixtures: paths with spaces, binary add, binary delete, binary modify, binary rename, binary copy, gawk-vs-BSD-awk portability, `mktemp` + `trap` cleanup. Until the script lands, binary direction MUST be classified manually via `git diff --name-status -z` per file + direct `git show` evidence. Best blade (Amara): *"The binary hole is found. The gate condition is right. The parser still needs teeth."*

Copilot uses AI. Check for mistakes.
- **Self-reference rule for personas in operational specs**: "Otto" is a named identity in the substrate. Should references to "Otto" in reusable operational specs follow the same role-vs-name rule as references to "Aaron" / "Amara"? Probably yes. Capture in `docs/AGENT-BEST-PRACTICES.md` extension.
- **LOST recovery soft-trigger predicate format**: "deferred with stated condition" needs a verifiable predicate that auto-resurfaces the work for resume/retire decision when the condition becomes true. Example shape: `"deferred until: (B-0105 lands) AND (no consolidation work is active)"`.
Comment thread
AceHack marked this conversation as resolved.
- **Time-gap between dry-run and real push**: structure the destructive sequence so dry-run + real push run as one operator-approved unit, not two separate decisions. Capture timestamps for both for any post-incident analysis.

State summary:

- 9 infra files: SAFE_TO_RESET_LFG_SUPERSEDES (6 files, 97 lines, named evidence) or ALREADY_RESOLVED (3 files, 0 lines, identical content).
Expand Down Expand Up @@ -424,6 +472,11 @@ Remaining steps to clear the gate:
refs/remotes/origin/main:refs/heads/main
then
echo "LEASE REJECTED: acehack/main moved or expectation stale."
echo ""
echo "If dry-run succeeded above and real push rejected: the remote moved"
echo "between dry-run and push. This is EXPECTED behavior — the lease did"
echo "its job. The fix is NOT to debug syntax."
echo ""
echo "DO NOT RETRY BLINDLY. Re-fetch, recompute content-drift ledger,"
echo "and re-enter the signoff gate from the top."
exit 1
Expand Down
Loading