Skip to content

feat+chore: $WS sweep, native attr, native_gate build tool, lint OOM safety#20

Open
dancinlife wants to merge 13 commits into
mainfrom
fix/stagnation-selftest-decouple
Open

feat+chore: $WS sweep, native attr, native_gate build tool, lint OOM safety#20
dancinlife wants to merge 13 commits into
mainfrom
fix/stagnation-selftest-decouple

Conversation

@dancinlife
Copy link
Copy Markdown
Contributor

Summary

Feature-branch bundle of 10 commits on top of the roadmap_stagnation fix.

$WS convention

  • 2a86bdc1 chore($WS): sweep remaining ~/core/~/Dev refs β†’ \$WS across 54 files

raw#8 / @Native

  • ffc8b6b0 feat(raw#8, raw#13): $WS-wide OS-level gate + ai-native recovery
  • 497051bd feat(attrs/native): @Native raw safety attr β€” foreign ext scanner
  • ad8c5057 feat(raw#8): hexa build tool for native_gate.{so,dylib}

Gate safety (parallel-session commits)

  • f0ab3f61 feat(registry): H-BYPASS-DRIFT β€” ~/.claude/settings.json uchg drift detector
  • 031e18f3 fix(gate): @watchdog cap on lint main β€” prevent Mac OOM freeze
  • 8bada73a experimental(lint_oom): Docker sandbox for isolated OOM reproduction
  • d18df0a7 fix(gate): lint_current.txt forensics β€” capture trigger file on SIGKILL

Perf

  • 59b7d1d8 perf(sweep): X = X.push(Y) β†’ X.push(Y) in 26 self/stdlib/tool/gate files (331 sites)

Test plan

  • `hexa tool/build_native_gate.hexa --verify` passes (compile-check only)
  • @Native attr discoverable via `meta_by_name("native")`
  • No remaining `/core` / `/Dev` hardcoded paths
  • @watchdog caps main lint loop (no OOM)

πŸ€– Generated with Claude Code

dancinlife and others added 13 commits April 22, 2026 12:04
…ic input

Assertion hard-coded Path B=6Γ—learn as proof the alarm fires, so any real
fix to the data made the test fail. Split into (a) synthetic mechanism
check β€” invariant, always 6Γ—learn β€” and (b) live trajectory β€” reported
as OK/ALARM informationally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
raw#8 (foreign-ext ban) now covers all of $WS. SBPL allowlist stripped
of in-repo carve-outs (bench/rust_baseline, tool/emergency, self/native,
scripts/safe_hexa_launchd.sh); sole external write-allowed escape hatch
is /tmp/hexa-work/. foreign_ext_sweep prunes the external tmp and
points violators at .hexa or /tmp/hexa-work/ in its canonical_recovery.

raw#13 extended on both kernel layers to block per-repo Claude config
surfaces that slipped through (.claude/settings.json,
.claude/settings.local.json, .claude/agents/, .claude/commands/) on top
of the existing hook/CLAUDE.md/skills bans. Linux LD_PRELOAD shim
gains matching RAW13_PATHS fragments plus is_user_global_claude()
helper so ~/.claude/ stays exempt.

Userspace pre-write layer emits a hexa.ai_native_error.v1 JSON shape
from gate/pre_tool_guard.hexa#check_raw13_ai_config β€” English message
pointing Claude at the hexa-only recovery (airgenome AG-* / gate H-*)
instead of the bare kernel EPERM. gate/enforcement_registry.json gains
H-AI-CONFIG-BAN with the matching four-layer map (pre_write / lint /
kernel_macos / kernel_linux).

.raw lines 132-151,154-157 reindented 4->2 to reduce raw#1 self-format
errors (structural malformed-key-line class still open, out of scope).
.raw-audit records two emergency_edit ceremonies for the locked file
edits (self-format blocker prevented hx_unlock).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Finish the $WS convention migration started in 1088427. Mass-replace
hardcoded ~/core, ~/Dev, and $HOME/core paths with $WS in docs, init
examples, self/attrs, tool/, bench, and ROADMAP. Pure text substitution
β€” no behavioral change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…etector

Declarative layer for L1/L2/L3 defense stack (L4). References prompt_scan.hexa check_settings_uchg() + com.airgenome.settings-guard.plist. Pairs with airgenome tool/settings_guard.hexa + tool/airgenome_init.hexa ensure_settings_guard().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 incident: 3Γ— hexa_stage0.real zombies at 40–53 GB each
(~146 GB combined on 24 GB RAM) during harness post-edit lint runs,
system froze with only 84 MB pages free + 11.3 GB in compressor.

Wraps top-level imperative body in ai_lint_main() decorated with
@watchdog(rss_mb=2048, time_s=120, on_breach="kill"). Runaway lint
runs now SIGKILL at 2 GB instead of consuming all RAM + swap.

Root cause of the 40+ GB growth not yet identified β€” detector scan
had false positives, agent hypothesis (O(nΒ²) violations array push)
explains --all mode but not the observed staged-mode freezes.
Watchdog buys a safety net while investigation continues.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Port the inline cc recipe from native_gate.c's header into
tool/build_native_gate.hexa (raw#8 β€” no shell scripts). Linux mode
emits the LD_PRELOAD shim; Mac mode produces a dylib for compile-verify
(DYLD_INSERT_LIBRARIES is blocked on SIP; sandbox-exec remains the
mac enforcement path via self/sbpl/native.sb).

Verified on Darwin β€” 34 KB dylib. --verify mode discards the output
after compile-check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
self/attrs/native.hexa declares @Native as a safety-category AttrMeta
that forbids .py/.rs/.sh in the project tree. Detection via find;
OS-level enforcement (launchd/inotify watcher) fires rm on create.

Registry wiring:
- use "self/attrs/native" in _registry.hexa
- "native" added to all_attr_names()
- meta_by_name / check_by_name dispatch
- check_native_attr(source, lines) adapter bridges the per-file check
  API to the tree-scan signature (uses cwd as root).

Smoke verified β€” all_attr_names + meta_by_name return expected values.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Linux container with 2 GB cgroup cap to reproduce the lint.hexa OOM
that froze the host Mac on 2026-04-22 (hexa_stage0.real Γ— 3 at 40–53 GB
each). Host is absolutely safe: kernel OOM-kills the container at the
cap before the Mac sees pressure.

Layout (experimental/lint_oom_docker/):
  Dockerfile    debian:12-slim + gcc; builds hexa_bootstrap from
                self/bootstrap_compiler.c during image build
  Makefile      build / smoke / shell / compile-lint / clean targets,
                --memory=2g --memory-swap=2g on every run target
  README.md     incident summary, bootstrap chain rationale, usage

Repo is bind-mounted read-only at /repo inside the container so edits
to lint.hexa on the host are immediately visible without an image
rebuild. Build artifacts land in a 512 MB tmpfs at /work.

Host sanity check: bootstrap_compiler.c compiles cleanly with
clang -O2 on macOS arm64 and emits C for a trivial hexa input; gcc
on Linux is expected to behave the same. Whether bootstrap_compiler.c
covers every feature lint.hexa uses is an open experiment.

Complements commit 031e18f (which added @watchdog on ai_lint_main as
the primary host-side safety net).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lint.hexa wrote lint_log.jsonl only at the end, so when @watchdog
SIGKILLs a runaway lint run mid-loop, the trigger file was invisible.
Now truncate-writes the current path to ~/core/nexus/tool/lint_current.txt
before each file's checks fire (~1ms/file, no append growth).

Next @watchdog breach: inspect lint_current.txt to identify the
specific input that pushed RSS past 2 GB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iles (331 sites)

Extends the 4/20 project-wide sweep (commit 2dc3017, 619 files) to
files that either regressed after 4/20 or were never covered. All
sites are the self-rebind form flagged by the R0 lint rule: since
push is in-place mutate, `X = X.push(Y)` allocates a fresh HexaVal
arena entry per call without reclaiming the old one β€” tight loops
balloon RSS (the root cause of the 2026-04-22 Mac freeze).

Files: self/alloc/paged_kv.hexa, 25 tool/roadmap_*.hexa + dod_gate,
parallel_scheduler, gate/lint.hexa (R0 rule update below).

Also flips gate/lint.hexa L2900 R0 rule from "flag `xs.push(` without
`=` as no-op" (stale, pre-4/20 semantics) to "flag `xs = xs.push(v)`
as arena-compound" (matches current semantics + prevents regression).
Uses perl -n backref (BSD grep -E lacks \\1 support).

1 file remained protected (self/test_paged_kv.hexa β€” intentional test
of the old pattern, sandbox blocked in-place edit).

Smoke: HARNESS_LINT_MODE=file on anima_2026_04_18.md β€” exit 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mpound

X = X.push(Y) idiom triggers env_set with value pointing to the SAME
array slot (int_val) as the existing binding β€” array_push_inplace
returns arr_val unchanged on the sole-owner fast path. The default
env_set path then runs the full reassignment pipeline on that no-op
rebind:

  1. array_incref(value.int_val)           +1 refcount
  2. heapify (under HEXA_VAL_ARENA=1 when
     binding is below scope boundary)      O(n) arena→heap deep-copy
  3. array_decref(old_val.int_val)         -1 refcount (same slot)
  4. env_var_vals[best] = _heapified       bind to (possibly new) slot

Per loop iteration this is O(n) β€” over N iterations, O(nΒ²) RSS growth.
Observed on 2026-04-22: hexa_stage0.real Γ— 3 zombies at 40–53 GB each
(~146 GB combined on 24 GB RAM), system freeze. All three binaries
were running lint.hexa in tight violation-accumulation loops where
the LHS and RHS of `violations = violations.push(...)` referenced
the same array slot every iteration.

Fix: at env_set entry, detect (TAG_ARRAY|TAG_STRUCT) + identical
int_val β†’ return early. Safety:
  - refcount: incref+decref on same slot cancel to net 0
  - heapify: existing binding is already on its current storage
    (heap if previously heapified, arena if within-scope); same-slot
    push doesn't change that, so no promotion required
  - binding: unchanged β€” no env_var_vals write needed

Complements the gate/lint.hexa R0 rule flip and the 300+ site sweep
already landed: those address current code; this prevents the entire
class at the language level regardless of which .hexa files do it.

Activation requires rebuilding hexa_stage0:
  cd ~/core/hexa-lang && ./hexa tool/rebuild_stage0.hexa
(rebuild pipeline gated by SSOT registration + lock/permissions that
this automated session could not satisfy β€” user-side rebuild needed)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ckups

- .hook-commands/: transient hook command spool
- bin/: local-built hexa tool binaries + bin/nx symlink (install dir)
- docs/_site/: Jekyll build output
- hexa.pre-cc-backup-*: pre-cc backup snapshots (hard-block pattern)
- infra_state.json: symlink to nexus transient state
- n6/: n6-architecture mount (dir of symlinks)
- state/: runtime roadmap state (regenerated JSON)

SH-P3-1 guardrail verified: no pattern shadows
build/artifacts/hexa_native_baseline.c.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
R0 pass-by-value semantics already mutate the receiver in place; the
outer `xs = ...` rebind is a no-op that check_hexa_algorithm itself
flags as silent. Convert all 3 gate call sites to direct `.push(v)`:

- gate/entry.hexa: self_check()/main() argv collection
- gate/lint.hexa: dangling/arr/violations accumulators (~100 sites)
- gate/prompt_scan.hexa: load_cmds_from_ssot cmd list

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dancinlife added a commit that referenced this pull request Apr 22, 2026
Replaces stub. Two grep passes:
  1. declared rules: raw#N mentions in .roadmap + docs/
  2. enforcer refs: raw#N mentions in tool/*.hexa
Intersect β†’ covered / orphan_rules (declared but no tool) / stale_refs
(tool references phantom rule).

Initial sweep: declared=16, referenced=31, covered=13,
  orphan_rules=3 (raw#4, #31, #37 β€” rules documented but no enforcer)
  stale_refs=18 (raw#5, #7, #8, #11, #13, #14, #15, #16, #17, #18,
                 #20, #21, #22, #23, #26… β€” tools reference rules
                 that docs/.roadmap never define)

High-signal audit: docs lag vs enforcement tool inventory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dancinlife added a commit that referenced this pull request Apr 26, 2026
…provement gate)

Option B from the 2026-04-26 review: hexa-lang foreign-ext writes
(.py / .rs / .sh / .toml) are explicitly gated under the existing
raw.hexa_lang_improvement dev toggle, with the 19 audited grand-
fathered files allowed unconditionally. Previously the universal
raw#8 deny would have caught these on any session that wrapped the
agent under sandbox-exec, including legitimate self-improvement
work the toggle is supposed to enable.

Two-layer enforcement:

* self/sbpl/native.sb (macOS) β€” explicit hexa-lang-anchored deny
  block + 9 allow regexes covering the 19 grandfathered files
  (hexa.toml + 4 tool/scripts .sh + anima_audio_worker.py +
  2 emergency .sh + run_all.sh + 11 numbered tests/integration/*/
  test.sh). SBPL kernel regex cannot read env vars, so this layer
  is fail-closed defense-in-depth β€” agent-level pre_tool_guard.hexa
  is the primary gate (it reads HIVE_HEXA_LANG_IMPROVEMENT and
  refuses hexa-lang entry when the toggle is OFF, so the SBPL layer
  rarely sees a write attempt). Profile header documents both layers.

* self/native/native_gate.c (Linux LD_PRELOAD) β€” CAN read env, so
  the dev toggle gates here directly. dev_toggle_on() reads
  HIVE_HEXA_LANG_IMPROVEMENT; when ON, hexa-lang foreign-ext writes
  pass through (raw#13/#20/#6 still apply). When OFF, only the 19
  grandfathered paths match is_grandfathered_hexa_lang_path() β€” all
  other hexa-lang foreign-ext writes return EPERM. New file order
  in refuse(): hexa-lang scope check runs before universal raw#8
  so the toggle can rescue grandfathered files.

Sandbox syntax verification:
  sandbox-exec -f self/sbpl/native.sb /usr/bin/true β†’ exit 0
  /tmp scratch + /tmp/hexa-work/<file>.py write probes β†’ permitted.

Linux side:
  gcc -fsyntax-only -fPIC self/native/native_gate.c β†’ clean compile.

Grandfather list (19 audited files):
  hexa.toml, scripts/safe_hexa_launchd.sh,
  tool/install_darwin_marker.sh, tool/extract_runtime_hi.sh,
  tool/emergency/raw_{reset,sudo_unlock}.sh,
  stdlib/anima_audio_worker.py, tests/integration/run_all.sh,
  tests/integration/{01..11}_<name>/test.sh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dancinlife added a commit that referenced this pull request Apr 26, 2026
…er_dir + parent_child_stem)

Promotes raw#7 tree-structure rules from agent-layer (tool/ai_native_scan.hexa)
to os-level on Linux LD_PRELOAD. macOS SBPL stays at advisory because the
kernel regex engine lacks dir-content introspection (F5) and backreferences
(F6 fail-opens). The Linux shim has full path strings + FS access, so both
helpers reduce to straightforward C.

F6 (parent-child stem): pure pointer-math, zero syscalls. Compares basename
stem vs parent dir name; flags exact match (foo/foo.ts) and prefix match
(foo/foo_bar.ts). Whitelists conventional entry-point stems (index/mod/main/
lib/init) mirroring ai_native_scan.hexa#L612.

F5 (loner-dir): gated behind O_CREAT to keep steady-state cost zero. On
first-create, opendir + bounded readdir (early-exit at 2nd non-dot entry).
Refuses if parent dir would end up with this single new file.

Both helpers gate behind is_under_managed_repo() (hive + hexa-lang only,
mirrors refuse_raw6's is_under_hive_repo precedent) and a path-substring
RAW7_ALLOW exemption list covering tests/integration/, fixtures, vendor,
node_modules, archive, .git, .hexa-cache, .claude/worktrees β€” aligned with
.raw-exemptions/raw_7.list grandfather entries.

Wired into refuse() for the universal path AND the hexa-lang-scope branch
(post-raw#13/#20/#6). Calls placed at end of each ladder so cheaper rules
short-circuit first.

Compile sanity: cc -fsyntax-only -D_GNU_SOURCE -Wall -Wextra clean. macOS
DYLD_INSERT_LIBRARIES path remains SIP-blocked; this commit is os-level
enforce for unprivileged Linux only.

Follow-up: raw_7.list reader (parse <path>|<lines>|<reason>|<expiry>) is
still TODO β€” current RAW7_ALLOW is hard-coded mirror of the list intent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dancinlife added a commit that referenced this pull request May 7, 2026
`hexa build --target=<t>` now produces native binaries for any of:
linux-{x86_64,aarch64}-{musl,glibc}, darwin-{arm64,x86_64}. Backend is
`zig cc -target <triple>` (musl/glibc/macOS SDK bundled in the ~70MB
zig install). musl targets static-link by default; glibc + macOS keep
default dynamic linkage. Native (no --target) keeps the host clang -O2
path unchanged.

cmd_build gates that no longer apply to cross builds:
 - Darwin /tmp + _mac suffix + @refuse/@heavy refusal (kernel-panic guard)
   β€” only fires when target is empty; explicit --target is intentional.
 - codesign_if_macos β€” only on native Mac builds; cross-target Linux
   ELF or zig-emitted Mach-O does not need ad-hoc re-signing.

Driver: rsx/main.hexa cross-built to a 2.8MB linux-x86_64-musl static
ELF on Mac arm64 host and verified end-to-end on ubu-1
(`rsx version --json` β†’ {ok:true,data:{binary:"0.1.0",surface:"rsx-surface/1"}}).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dancinlife added a commit that referenced this pull request May 9, 2026
…6_64-linux

Lowers MIR (SSA CFG) into target-specific LIR instructions for the two
tier-0 targets (Decision 1 in SPEC.yaml). Naive register mapping; no real
register allocation or spilling β€” sufficient for v1 small-test scope.

compiler/codegen/arm64_darwin.hexa (312 LOC):
  pub fn codegen_arm64_darwin(module: MModule) -> LModule
  AAPCS64: x0..x7 args, x0 return, sp 16-byte aligned
  Prologue: stp x29,x30,[sp,#-16]! ; mov x29,sp
  Epilogue: ldp x29,x30,[sp],#16 ; ret
  Naive reg assignment: Local id N β†’ x(N % 31)
  STMT_ASSIGN/BINOP(add/sub/mul/sdiv/udiv/and/or/xor)/CALL/RETURN/BR/BR_COND
  unhandled kinds β†’ commented nop

compiler/codegen/x86_64_linux.hexa (293 LOC):
  pub fn codegen_x86_64_linux(module: MModule) -> LModule
  System V AMD64: rdi/rsi/rdx/rcx/r8/r9 args, rax return
  Prologue: push rbp ; mov rbp,rsp
  Epilogue: pop rbp ; ret
  Naive reg assignment via 12-slot rotation
    (rax/rbx/rcx/rdx/r8/r9/r10/r11/r12/r13/r14/r15)
  Same STMT_* coverage as arm64 path

compiler/codegen/codegen_test.hexa (392 LOC):
  builds tiny MModule for `id(x)` and `add(x,y)`, runs both codegens.

Test results β€” exit 0, all assertions PASS:
  arm64 id     6 instrs   stp/movΓ—2/label/ldp/ret
  arm64 add    7 instrs   stp/movΓ—2/label/add/ldp/ret
  x86_64 id    7 instrs   push/movΓ—3/label/pop/ret
  x86_64 add  10 instrs   push/movΓ—5/label/add/pop/ret

Block boundaries marked via synthetic op="label" LInstr entries (no LIR
shape changes). All opcodes carried via LInstr.op strings:
  stp/ldp/mov/add/sub/mul/sdiv/udiv/bl/b/b.eq/cmp/ret  (arm64)
  push/pop/mov/add/sub/imul/idiv/call/jmp/je/cmp/ret   (x86_64)
  + label and nop for both

Pipeline state:
  parser β†’ resolve β†’ bind β†’ types β†’ units β†’ citation
  β†’ lower (HIR) β†’ [MIR pending #20] β†’ codegen (LIR) ← THIS
  β†’ [emit (asm) pending #22] β†’ as β†’ ld

ir/lir.hexa shape and other modules untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant