Commit Graph

280 Commits

Author SHA1 Message Date
leetcrypt a254267e1a docs(sor): PROPOSED stage-05 RQ2 per-circuit posterior clarification (blind)
Overseer ruled DIRECTION=A: fill the specification gap the frozen prereg
left on RQ2's per-circuit adversary sender-posterior, rather than
silently redefine the DV (B) or relabel a confirmatory test (C).

Proposes: adversary observes a circuit's exit-bridge/house and forms a
uniform posterior over the observation-consistent anonymity set A_i;
per-circuit H_i = Miller-Madow(log2 m_i), with S=2^H [Serjantov2002] and
d=H/log2 N [Diaz2002] as the cited normalizations. Makes RQ2-P1 (two-
sided ΔH) and RQ2-P3 (Spearman) computable OFFLINE from the immutable raw
records (per_circuit_seeds + deterministic assemble()).

Status PROPOSED — operator ratification pending. Pre-specified BLIND
(2026-07-20, battery running, zero RQ2 statistics computed) so this is
honest pre-registration completion, not HARKing. Frozen prereg untouched;
sign not presumed (honest-shrink reported with equal prominence).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-20 00:14:32 -07:00
leetcrypt 6efa9df1ec docs(sor): note SS2 wrapper exit-1 is benign; battery verified healthy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 23:15:39 -07:00
leetcrypt 8224a38072 feat(sor): SS3 RQ1 confirmatory loader (pcap -> frozen pair set)
confirm_load.py reconstructs the RQ1 (entry,exit) circuit-pair set from
the REAL per-hop pcaps (bin_pcap_bytes -> score_matrix; diagonal=linked,
off-diagonal=unlinked) so confirm.rq1_p1_leak scores measured data — the
frozen §4 unit. classify_run reads persisted metrics.json;
collect_rq1_p1_pairs selects only bridge=on no-pad runs.

Plumbing unit-tested on SYNTHETIC pcaps only (prereg §2 blinding — no
inspecting intermediate confirmatory results before the battery
completes). RQ1-P2 nopad/pad pairing + all RQ2 held for the operator
ruling (NEEDS-OPERATOR: RQ2 per-circuit posterior underspecified).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 23:13:02 -07:00
leetcrypt 6d376018ec docs(sor): NEEDS-OPERATOR — RQ2 per-circuit posterior underspecified vs instrument
Frozen §3/§4/§6 pin RQ2 DV as a per-circuit adversary sender-posterior
entropy (Miller-Madow, bootstrap over circuits; RQ2-P3 needs per-circuit
H). The committed executor measures a per-run realized-frequency entropy
instead — no per-circuit posterior, no per-circuit H. No formula for the
posterior construction exists in the frozen prereg or the instrument.
Flagged rather than invent a posterior model post-freeze (HARKing/
fabrication on a confirmatory DV). Battery left running (raw records
recoverable → RQ2 recomputable offline under any ruling). RQ1 proceeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 23:08:16 -07:00
leetcrypt 68b82e563d docs(sor): OVERSEER SS2 — confirmatory battery firing (frozen R=30xC=50)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 23:04:28 -07:00
leetcrypt 557ebaa0f0 docs(sor): OVERSEER SS1 — executor committed, driving to SS2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 23:00:54 -07:00
leetcrypt ce68d41348 feat(sor): confirmatory data-collection executor (anti-fabrication)
Measures RQ1 bridge-correlation AUC + RQ2 Shannon entropy from REAL
per-hop pcaps of live isolated-docker circuits. run_battery(live=False)
hard-raises and the executor refuses (ExecutorError) any DV it did not
measure — the executor-side twin of the launcher's "never fabricate
cells" guard. Wired into confirmatory_run's triple-locked tokened GO
(executor.run_battery(live=True) behind operator token + verified frozen
prereg SHA + engine!=local + green preflight + full grid).

Containment intact: self-fixture bytes only, isolated engine only, no
external target. Frozen prereg untouched (SHA f22331a72e…).

Verify: test_sor_executor.py 7 + confirmatory_run + full SOR suite = 163
passed; preflight green (grid 3/3, READY); no confirmatory data collected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 23:00:39 -07:00
leetcrypt c3ef888648 docs(overseer): record commit SHA 6d61c53 in start-line status entry
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 20:49:28 -07:00
leetcrypt 6d61c53152 RQ1+RQ2 start-line: live per-cell condition assembler + guarded launcher + Holm ratification
Wire the live per-cell condition assembler (cmd_chat/sor/assembler.py): compose
the existing R1/R4/R5/R6 pieces into a condition-encoding CircuitSpec per frozen
§2 cell, so a cell_id maps to a genuinely distinct, ForwarderPlan-gated
(engine != local) isolated circuit rather than the plain 3-hop control:
  - RQ1 bridge-on / on+padding insert a live bridge hop (+ R1 PADDING stream);
  - RQ2 bridge-/directory-federated genuinely span >= 2 houses
    (federation.select_federated_path, split-knowledge).
Plans only: opens no socket, moves no traffic, stands up no engine.

battery.assembler_dry_check validates on FIXTURES (6/6 cells distinct
fingerprints, all isolation-gated, same (cell,seed) reproduces, RQ1 bridge +
padding arms live, RQ2 federation >= 2 houses); write-once, kept out of any
confirmatory data dir. confirmatory_run preflight now runs it; the --operator-go
path no longer refuses cells as "not wired" — triple-lock + green preflight HOLD
on grid completion, then surface the operator's immutable data-run gate. No
confirmatory cell is ever fabricated.

Start-line instrument-validation gate (cmd_chat/sor/gate.py), grid + containment
pin (grid.py), and the guarded launcher (confirmatory_run.py) land alongside.

Holm: hold family_size = 7, report the 4 RQ1/RQ2 tests -> multipliers 7,6,5,4.
This is the pre-registration, not a deviation (prereg §6 [APPROVAL] size-7 family
+ D6 disclosure in the lead paper); docs/stage-05-holm-clarification.md marked
RATIFIED. RQ3-fold and alpha-split declined.

Containment intact; prereg untouched (SHA f22331a72e...); worktree-only. output/
gitignored (runtime artifacts, never source). Full SOR suite 156 passed. No
confirmatory data collected — the live data run remains the human gate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 20:49:12 -07:00
leetcrypt 72a6c7b519 R7/battery: RQ1+RQ2 confirmatory-battery orchestration (start-line, no data)
Enumerates the frozen §2 confirmatory cells (3 RQ1 bridge levels + 3 RQ2 topology
levels at their controls; bridge-off+padding recorded as a declared N/A, not run),
derives each run's seed by the frozen §4 rule (SHA256('<S0>|<cell_id>|<run_index>')
big-endian first 8 bytes -> u64, S0=20260719), and lays out the §2 schedule with
run order randomized within each cell and each RQ's control interleaved before and
after its treatments.

write_cell_plan emits the auditable cell x run plan artifact (R=30, C=50 -> 180
runs / 9000 circuits, seed rule, matched-N rule, full schedule). dry_pass exercises
the R2/R3 provenance pipeline on FIXTURES only (deterministic replay_and_seal, no
engine, no traffic) to prove schema-valid + checksummed provenance and that a seed
reproduces its circuit-build sequence. Collects no confirmatory data — that remains
the human gate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 19:39:14 -07:00
leetcrypt cb4b6869fc R7/analysis: RQ1/RQ2 confirmatory decision layer (frozen §6 gates in code)
Encodes the four lead-paper confirmatory tests exactly per the frozen prereg §6,
calibrated on synthetic ground truth only (never re-fit to cell data):

- RQ1-P1 leak: correlation AUC + BCa CI; gate = CI excludes 0.5 (D2); 0.60 CI
  lower bound = separate materiality label (material / weak-but-real), not the gate.
- RQ1-P2 padding: paired ΔAUC = AUC(no-pad) − AUC(pad) over circuits; effective
  iff CI > 0.
- RQ2-P1 anonymity set: ΔH = H(federated) − H(single, matched N) with Miller-Madow
  per-circuit entropy; two-sided grow / honest-shrink / inconclusive by CI sign.
- RQ2-P3 mechanism: Spearman ρ(top-3 bridge concentration, per-circuit H) + CI.

apply_holm corrects the reported RQ1/RQ2 subset against the full frozen family of
7 (family_size default 7) — never re-optimised to the 4 reported. Bootstrap
p-values order the Holm step-down only; every decision is a CI gate, never a bare p.

stats.py: bootstrap CIs can now return their resample distribution so the Holm
ordering p-value comes from the same resamples as the CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 19:36:17 -07:00
leetcrypt 06352ecf47 R7/analysis: pre-registered §6 inference toolkit (BCa bootstrap, Miller-Madow, Spearman, Holm)
Turnkey implementation of the frozen prereg §6 analysis plan, written before any
confirmatory data exists (analysis-precedes-data, rigor-standards §Statistics).
Pure stdlib, no I/O, no engine, no traffic — calibrated on synthetic ground truth only:

- bootstrap_ci / two_sample_diff_ci: BCa 95% CIs (10k resamples default) with a
  percentile fallback when bias/acceleration terms are degenerate; seeded and
  reproducible (CIResult carries method+seed for the §6 three-seed spot-check).
- miller_madow_entropy_bits: plug-in Shannon entropy + Miller-Madow bias
  correction (§3 estimator).
- spearman: rank correlation for RQ2-P3.
- holm_bonferroni: step-down multiplicity correction with explicit family_size so
  a lead paper reporting a subset of the frozen 7-test family still corrects
  against the full family (never re-optimised to the reported subset).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 19:32:12 -07:00
leetcrypt 0734d18989 R7: pluggable SelectorPolicy seam + local-OSS (Ollama) confirmatory agent arm
Adds the RQ3 agent-selector backend as a reproducible, offline measurement
decision — not relay/data-plane traffic. Containment is untouched: the model
query is a local call to localhost:11434.

- selector.py: SelectorPolicy ABC seam; static/random/agent(heuristic) built-ins;
  make_policy() resolves (strategy, agent_backend); run_selection writes a
  write-once selector.json provenance sidecar.
- agent_selector.py: OllamaAgentPolicy — reproducible confirmatory arm
  (temp=0 + per-run seed, decisions cached keyed by (seed, state-hash),
  deterministic heuristic fallback on any model/parse failure, model weights
  digest pinned for the manifest). ClaudeExploratoryPolicy — EXPLORATORY-only
  stub: makes no paid call, refuses to serve as a confirmatory backend.
- provenance.py: additive selector_backend field so an agent-selected run pins
  the exact model id + weights digest.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 18:15:28 -07:00
leetcrypt 12fd2537e3 R7 (live halves): seeded churn + rebuild selector + metrics.json
churn.py emits a seed-deterministic kill/spawn schedule (pure data — no real VM
spin/kill; the live fabric half stays gated by the containment law). selector.py
consumes the schedule and rebuilds a circuit whenever a kill drops one of its
hops, across static | random | agent strategies; the paid frontier-model agent
arm (GOAL envelope (c)) is human-gated and NOT wired — the agent strategy here is
a local stability heuristic that spends nothing. analysis/metrics.py aggregates
the four DV families (RQ1 correlation AUC, RQ2 entropy bits, RQ3 throughput
retention + rebuild-classifier AUC) into a schema-valid, write-once metrics.json.
Acceptance check green: under a fixed churn seed the selector rebuilds every
dropped circuit (every_drop_rebuilt, all strategies) and metrics.json is
produced. Python R7 selector suite 11 passed; full SOR suite 92 passed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 17:18:44 -07:00
leetcrypt 21263da8ca R6: multi-house federation — signed roster directory + blind bridge
federation.py adds both federation modes as offline-verifiable logic (no socket,
no engine, no external target — this measures a trust model, it provides
anonymity to no one). directory-federation: a signature-gated HOUSE-PEER roster
(PeerRoster/build_peer_frame/parse_peer_frame, Ed25519-signed, forged/unsigned
rejected) merged into a pubkey->house Directory, with select_federated_path
drawing a seed-deterministic circuit that spans >=2 houses and refuses to
collapse to one — so no single house's logs hold every hop identity (RQ2 split
knowledge). bridge-member: BlindBridge holds no room key and relays only opaque
SOR tunnel bytes verbatim (chat/consent/unknown frames refused, plaintext never
read), emitting metadata-only bridge_forward R3 events. Acceptance check green:
roster signature-gated, path spans two houses, bridge is plaintext-blind. Python
federation suite 10 passed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 17:14:01 -07:00
leetcrypt a78441b938 R4 (e2e half): 3-hop nested-SSH circuit delivery + per-hop pcaps (gate item 1)
run_circuit_fixture stands up an isolated docker N-hop nested-SSH chain, pipes a
seed-deterministic self-generated payload through it, verifies end-to-end
delivery, captures + checksums a per-hop pcap, emits R3 events, and always tears
the circuit down. Containment is load-bearing: assert_isolated refuses
local/unknown engines up front, every hop is built through the ForwarderPlan
guard, only our own fixture bytes move between our own containers, and the runner
is wired for docker only (multipass e2e refused, not faked). Adds the sor-hop
fixture image (alpine + sshd + tcpdump, lab-relay only) and a docker-gated
acceptance test that skips where no daemon/image is present. Instrument-validation
gate item 1 GREEN: live 3-hop delivery verified, 3 distinct hops, pcaps checksum.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 17:08:26 -07:00
leetcrypt 92da24dfe2 R7 (partial): offline detector calibration — entropy + bridge-correlation AUC
Land only the offline-validatable half of R7 (instrument-validation gate items
3 and 4): the detectors the gate calibrates on synthetic fixtures, never on
confirmatory-cell data. Pure stdlib functions over in-memory series — no pcaps,
no engine, no traffic, no VM fabric.

- analysis/detectors.py: shannon_entropy_bits (RQ2 anonymity-set entropy),
  pearson/score_matrix/auc/linkage_auc, bridge_correlation_auc (RQ1
  linkability scorer), and synthetic_bridge_fixture (seed-deterministic
  known-linked / known-unlinked ground truth via the R1 SorRng).

Calibration green: entropy returns exactly log2(N) for N equiprobable senders
(gate item 4); a known-linked control pair scores AUC=1.0 and the unlinked
estimator is unbiased at chance (ensemble mean over 40 seeds = 0.498 ~ 0.5,
gate item 3). Detectors are calibrated on synthetic fixtures only — no fitting.

The traffic-moving R7 pieces (churn.py VM spin/kill, live selector rebuild loop,
metrics.json emission) are HELD for R4/R6 + a live grid and are absent here.
Python SOR suite 66 passed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 16:47:56 -07:00
leetcrypt dfc2e60e1b R4 (partial): isolated-engine-only forwarder guard (gate item 5)
Land only the containment-refusal half of R4: the guard every SOR forwarder
must pass before it does anything — assert engine != local, or refuse. It moves
no traffic, opens no socket, spawns no engine, and builds no SSH chain.

- forwarder.py: assert_isolated (raises on local and on any engine off the
  manifest allow-list), isolation_prefix (docker/multipass exec argv, no host
  path), ForwarderPlan (construction IS the gate — no plan for local/unknown/
  no-container). Allow-list imported from provenance so forwarder and manifest
  cannot disagree about what counts as isolated.
- There is no code path in this module that returns an exec prefix for the host;
  containment is structural, not a runtime flag.

The traffic-moving half of R4 (gate item 1: 3-hop self-traffic e2e delivery +
per-hop pcaps across the grid) is deliberately NOT implemented — HELD for a live
isolated engine + grid. This guard is fully verifiable offline.

Acceptance (gate item 5) green: local/unknown/no-container refused; isolated
engine accepted with the correct isolation prefix. Python forwarder suite 12
passed; full SOR Python suite 49 passed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 16:43:10 -07:00
leetcrypt 7de0f57fa6 R5: consent-gated recruitment + per-hop X25519 sealed credentials
Add the in-band, signature-gated consent handshake that governs whether a
node may be recruited into a measured SOR circuit, plus a per-recipient
sealed box so a hop credential decrypts only with the host's X25519 key.

- crypto.rs: seal_to_pubkey/open_sealed (ephemeral X25519 -> HKDF-SHA256 ->
  Fernet AEAD), reusing the existing fernet crate (no new symmetric primitive).
- sor/consent.rs: signed ConsentRequest (Ed25519 persona), node_evaluate
  (reject unless the signature verifies), CircuitBuilder that recruits a hop
  only on an accept it can open; parse_sor_frame with never-panic proptests.
- net.rs: {"_sor":...} control frames are live-only and classified out-of-band
  by the SOR layer (parse_sor), never surfaced as chat/app events.
- cmd_chat/sor/consent.py + bridge _sor case: bit-compatible Python mirror;
  the agent only observes/classifies consent frames — it never auto-accepts
  and stands up no forwarder (forwarding is R4, isolated-engine-only).

Acceptance check (roadmap R5) green both languages: host recruits a hop only
after an explicit accept; a reject leaves no entry; the credential opens only
with the host key (third party cannot); unsigned/forged request -> rejected.
Cross-language KDF parity pinned by a shared known-answer vector.
Rust 75 passed; Python SOR suite 37 passed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 16:35:11 -07:00
leetcrypt a9308edc5d R3: immutable append-only event log sealed into the run manifest
Adds the tamper-evident event stream that makes every DV auditable. Each
measurable moment is appended as one JSON object per line to an append-only
output/sor-runs/<ts>/events.jsonl over the closed vocabulary {consent_request,
consent_accept, consent_reject, circuit_build, hop_add, bridge_forward,
churn_kill, churn_spawn, rebuild_start, rebuild_done}; on close the file is
SHA-256'd and the digest is sealed exactly once into manifest.json (the single
sanctioned None->hash completion of the manifest).

Records carry only metadata (fingerprints, byte counts, latencies, decisions),
never message plaintext, so the zero-knowledge relay property is preserved. The
deterministic replay_fixture_circuit emits a seed-driven event stream with no
engine, socket, or traffic (containment-safe) and is the basis of
instrument-validation gate item 6.

- cmd_chat/sor/events.py: EventLog (append-only, per-record schema),
  replay_fixture_circuit, replay_and_seal.
- cmd_chat/sor/provenance.py: seal_manifest (seal-once events SHA + stop ts).
- tests: replay -> schema-valid JSONL whose SHA matches the manifest;
  append-only (original prefix byte-identical after further appends);
  seed-determinism modulo timestamps; seal-once immutability.

Live emit wiring into the _sor handlers lands with R4/R5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 16:18:38 -07:00
leetcrypt 7ed23704ea R2: run manifest / provenance writer for reproducible, auditable runs
write_manifest() freezes at circuit-experiment start everything needed to
reproduce and audit a SOR run and writes an immutable
output/sor-runs/<ts>/manifest.json: the R1 --sor-seed, topology/selector/churn
schedule id, one persona fingerprint per participating node, worktree git SHA,
isolated engine kind + image digest, pip/cargo dependency freeze, and
start/stop timestamps. The events.jsonl SHA-256 field is reserved for R3.

Provenance only: no forwarder, no engine spawned. Defense-in-depth to keep
containment load-bearing, the schema refuses to record a non-isolated
("local") engine at run or node level; the binding assertion still lands with
the R4 forwarder.

- cmd_chat/sor/provenance.py: Node/RunManifest, node_fingerprint (bit-for-bit
  mirror of persona.rs::fingerprint_of), git/deps capture, explicit
  dependency-free schema validator.
- hh/src/persona.rs: fingerprint_of known-vector parity test.
- tests: R2 acceptance predicate (manifest present + schema-valid, non-empty
  seed, >=1 fingerprint/node), immutability, containment rejection of local
  engines, and cross-language fingerprint parity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 16:15:06 -07:00
leetcrypt c04f9aed23 R1: deterministic --sor-seed core for reproducible measurement
Adds the single stochasticity source for the SOR measurement instrument so
every later stochastic decision (path selection R4, churn/selector R7, padding
jitter R4) is driven by one --sor-seed and is byte-reproducible run-to-run —
the R1 acceptance check and instrument-validation gate item 2.

- hh/src/sor/mod.rs: SplitMix64 + SHA-256 domain-separated sub-streams +
  unbiased Lemire bounded sampling -> deterministic select_path/bringup.
  Pure bookkeeping: no forwarder, no socket, no engine. Isolated-engine
  containment assertions land with the R4 forwarder.
- hh/src/main.rs: `sor-bringup --sor-seed` emits the deterministic
  circuit-build sequence as JSON (observable reproducibility).
- cmd_chat/sor/config.py: bit-for-bit Python mirror so the seed means the
  same thing on both sides.
- Tests (Rust proptest+unit, Python pytest): SplitMix64 known-answer vector,
  same-seed determinism, seed divergence, bounded/no-panic, and a shared
  cross-language parity vector asserted identically in both suites.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-19 14:47:07 -07:00
leetcrypt c9aa4a68ad merge: fold benchmark + pseudonymous-attribution into main
CI / rust client (hh) (macos-latest) (push) Has been cancelled
CI / rust client (hh) (ubuntu-latest) (push) Has been cancelled
CI / rust coverage (push) Has been cancelled
CI / python server (3.10) (push) Has been cancelled
CI / python server (3.11) (push) Has been cancelled
CI / python server (3.12) (push) Has been cancelled
CI / headless e2e smoke (push) Has been cancelled
CI / dependency audit (push) Has been cancelled
CI / secret scanning (push) Has been cancelled
Integrate the laptop feature branch (multi-language capability benchmark,
model picker, and ESA-style pseudonymous file attribution) onto the current
church main (native AI harness, podman/vbox sandboxes, † theme). Only conflict
was the help/status line — kept the newer podman grammar + /help, spliced in
/export-signed, and aligned attribution strings to the † sigil.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:22:58 -07:00
leetcrypt fcb3cb8684 chore(attribution): commit Cargo.lock for ed25519-dalek dep
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:16:46 -07:00
Claude (hack-house) f4180edf61 feat(attribution): pseudonymous file attribution (ESA-style)
Adapt Princess_Pi's Encrypt-Share-Attribution scheme so shared files are
anonymous but provably attributable.

A. In-session: a persistent Ed25519 persona key (~/.config/hack-house/
   persona_ed25519) signs every /send and /sendroom offer over the content
   hash; receivers verify it and see the persona fingerprint. Optional
   --attest <passphrase> attaches a revealable SHA-512(pass||sha256)
   commitment. Additive JSON — wire-compatible with the Python client.

B. Portable: /export-signed <dir> packages a directory into Princess_Pi's
   exact ESA 7z (fresh per-round Ed25519 sig over an inner 7z, SHA-512
   checksums, bundled verify scripts). Builder embedded from
   hh/tools/esa/esa_build.sh; verifiable with just bash+7z+ssh-keygen.

Tests: 45 pass (3 new persona). ESA archive build + verify-everything.sh +
passphrase reveal verified end-to-end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:28:07 -07:00
leetcrypt 7fb3911550 feat(bench): multi-language capability benchmark + model picker
Add bench-lang.py + bench/ package: a third benchmark axis answering
"which open-source model is best for my workflow?" across Python,
JavaScript, Go, Rust and Bash.

- MultiPL-E (Go/Rust/JS/Bash) + original HumanEval (Python), loaded via
  the HF datasets-server REST API with on-disk cache — no datasets/
  pyarrow dependency.
- Completions go straight to Ollama /api/generate with raw=True so
  instruct models continue the code instead of replying with prose.
- Code runs in rootless, network-less podman (safe default) with a
  host-toolchain fallback; pass@1/pass@k via the HumanEval estimator.
- run/score separation: results persist to a scorecard JSON, then
  `pick --workflow ops` re-ranks without re-running any model.
- Extensible: a new language is one Lang entry; a new workflow is one
  block in workflows.json.

Also fix a --runs grant-persistence bug in bench-sandbox.py: the grant
leaked across runs, invalidating the L0-nogrant refusal test on runs 2+.
Each run now revokes the ACL and starts ungranted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-17 09:39:27 -07:00
leetcrypt c5715ba2e3 test(scripts): add E2E AI chat + sandbox code-path benchmarks
bench-ai.py drives the /ai chat path end-to-end (SRP -> Fernet -> WebSocket
-> provider), measuring TTFT/total/tok-s per model, with a --direct provider
mode that isolates raw model throughput from event-loop contention.

bench-sandbox.py benchmarks the /ai <agent> !<task> sandbox code path by
playing the room owner on the zero-knowledge relay: it grants drive, sends
graded tasks (L0 no-grant refusal, file/script/logic/multistep, destructive
gating+confirm, blast-radius cap), captures the agent's injected _sbx:input
frames, and grades correctness behind the same destructive guard. Includes
REPL-aware exec replay (folds python3 sessions into heredocs), prompt-prefix
stripping, model-fail vs replay-limit tagging, --runs N averaging with
per-step timing, and auto-bumped timeouts for reasoning models.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-16 21:41:18 -07:00
leetcrypt c09b428718 feat(ai): /grant ai grants drive to every AI agent at once
CI / rust client (hh) (macos-latest) (push) Has been cancelled
CI / rust client (hh) (ubuntu-latest) (push) Has been cancelled
CI / rust coverage (push) Has been cancelled
CI / python server (3.10) (push) Has been cancelled
CI / python server (3.11) (push) Has been cancelled
CI / python server (3.12) (push) Has been cancelled
CI / headless e2e smoke (push) Has been cancelled
CI / dependency audit (push) Has been cancelled
CI / secret scanning (push) Has been cancelled
So the owner never has to name each model. Tracks an ai_agents set
(populated from `_ai` typing/stream frames and the "(ai) online" announce,
pruned on leave); `/grant ai` intersects it with the live roster and grants
all in one ACL broadcast. Help text gains a /grant ai row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-09 17:02:45 -07:00
leetcrypt 70d6e26b24 feat(ai): prompt-anchor native harness for the fast CPU model
Optimize the native tool-calling loop for qwen2.5:3b on CPU, where it
previously invented paths (/ai/bin/bash), ran scripts it never wrote, and
silently dropped valid actions. Three changes:

- NATIVE_SYSTEM rewritten directive: explicit write→chmod→run workflow,
  relative paths only, never run an uncreated file, never guess interpreter
  paths, fix the cause on non-zero exit.
- New _sandbox_facts() probe injects LIVE SANDBOX STATE (real cwd, bash
  path, current files) into the system prompt so the model anchors to
  ground truth instead of guessing.
- OllamaProvider recovers tool calls qwen emits as <tool_call>{json}</…>
  TEXT in content (brace-balanced JSON scan), so a correct action isn't lost.
- Bump Ollama timeout 120→240s: the tool turn is non-streaming and a long
  write_file can exceed a tighter cap on a contended CPU box.

Live-validated (podman/Kali): 0/3 incoherent → reliable write/run with
self-correction on exit=126 for both single- and multi-script tasks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-09 17:02:39 -07:00
leetcrypt 0c04ac74ee chore(theme): swap ⛧ sigil for † across UI, scripts, docs
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-09 15:44:55 -07:00
leetcrypt 06a87e8e76 docs(readme): Parrot OS docker, Kali podman, AI-acts-in-sandbox
Reflect current backends (local/docker/podman/multipass — Docker=Parrot
OS Security, Podman=Kali rootless no-sudo), the backend-first /sbx
grammar, and the AI agent's ability to drive the sandbox via
/ai <name> !<task> (advisory when ungranted, acting once granted).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-09 15:44:49 -07:00
leetcrypt 0b1d09f0b5 feat(ai): visible native harness — PTY mirror + readable chat
Display-mirror hybrid (docs/plan-harness-visibility.md §2): native tool
calls now show up in the shared sandbox terminal again via inert `# `-
prefixed comment lines (comment-prefix = anti-double-run/anti-escape),
mirroring only each command. Chat de-flooded to opener + final summary.
write_file mkdir -p parent dir so relative/absolute paths both work
(fixes the regression where script creation silently failed). ui.rs
fmt_line returns Vec<Line> splitting on \n so multi-line agent output
renders as an indented block instead of one garbled row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-09 15:44:40 -07:00
leetcrypt 946df65b72 feat(ai): native host-side tool-calling harness (Phase 2)
CI / rust client (hh) (macos-latest) (push) Has been cancelled
CI / rust client (hh) (ubuntu-latest) (push) Has been cancelled
CI / rust coverage (push) Has been cancelled
CI / python server (3.10) (push) Has been cancelled
CI / python server (3.11) (push) Has been cancelled
CI / python server (3.12) (push) Has been cancelled
CI / headless e2e smoke (push) Has been cancelled
CI / dependency audit (push) Has been cancelled
CI / secret scanning (push) Has been cancelled
Implement the bounded native harness from docs/spec-native-harness.md §1.3 and
make it the default granted-!task path. The model runs host-side (no container→
host Ollama hop); only its tool calls exec in the sandbox.

providers.py:
- OllamaProvider.complete_with_tools(system, messages, tools) -> (text, calls):
  one non-streaming /api/chat turn with a `tools` schema; parses message.tool_calls
  (dict or JSON-string arguments). Caches tool capability (_tools_ok / supports_tools).
- ToolsUnsupported raised when the model rejects `tools` ("does not support tools").

bridge.py:
- NATIVE_SYSTEM + a 3-tool schema (run_shell / write_file / read_file), turn/byte caps.
- _run_native: seed transcript window + task → loop up to max_turns; exec each tool
  call in the sandbox, feed captured output back as a `tool` message; stop on a plain
  answer or the cap; stream per-call progress to chat. Degrades to _run_simple when the
  provider has no complete_with_tools or the model rejects tools.
- _exec_prefix/_exec_capture/_exec_tool: <engine> exec into docker/podman/multipass/local;
  paths passed as positional args + content via stdin (no shell interpolation); combined
  stdout+stderr byte-capped + time-bounded. run_shell is the only intentional shell.
- Guards: DESTRUCTIVE run_shell commands are blocked (not run — no human in the loop;
  use simple + /ai confirm for destructive intent); MAX_COMMANDS budget per task.
- _run_in_sandbox dispatches native|simple; default harness flipped to native.

__main__.py: default harness native (self-degrades to simple, so safe).

Offline-tested: full write/run/read loop on the local backend; destructive block
(rm -rf never executed); ToolsUnsupported → simple fallback. Live Ollama wire
validation deferred to Phase 3 bench (daemon was down). py_compile clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 13:17:21 -07:00
leetcrypt e49dbca451 refactor(ai): strip Goose harness (Phase 1) — native/simple host-side only
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Remove the Goose agentic harness across the codebase per
docs/spec-native-harness.md §3. Goose made N sequential model calls inside the
sandbox (slow on CPU-only hardware) and forced an in-container→host Ollama
gateway that tripped the rootless-Podman slirp4netns loopback bug.

- bridge.py: delete _run_goose/_goose_argv/_goose_present + GOOSE_* consts and
  the present-cache; __init__ now takes harness="simple"/max_turns=5; granted
  !task runs _run_simple until the native loop lands (Phase 2).
- __main__.py: --harness {native,simple} (was {goose,simple}); drop
  --goose-max-turns, add --max-turns; default harness simple.
- app.rs: /ai start accepts native|simple (plain aliases simple) instead of a
  bare plain flag; refresh harness comments.
- sbx.rs: remove the in-container Ollama gateway (Docker host-gateway / Podman
  slirp4netns host-loopback) and the dk_bootstrap OLLAMA_HOST env — kills the
  slirp4netns loopback bug; drop Goose comments.
- bootstrap.sh: drop goose from the prereq probe.
- bootstrap-ai.sh: remove the entire Goose install block, --no-goose flag,
  GOOSE_INSTALLER_URL, host config writer, and goose_bin helper.
- sandbox-bootstrap.sh: remove the in-sandbox Goose binary install + config.
- spec-goose-harness.md: banner — harness portion superseded; Podman stays.

cargo check + py_compile clean. No Goose refs remain (headroom/ untouched).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 13:03:41 -07:00
leetcrypt cf6b0b5b73 fix(ai): agent reconnects instead of vanishing; spec the native harness
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
The /ai agent held a single, un-shielded websocket with no retry. Any
close — server restart, ping/idle reap, laptop sleep, a transient blip —
ended the serve loop, so run_async returned and the process exited
silently: the agent dropped from the roster with no /ai stop and no
goodbye.

- run_async now wraps the connection in a backoff-reconnect loop (1s→30s,
  resets after a healthy ≥30s session). The server frees our session+name
  on drop, so each attempt re-runs SRP to mint a fresh token. Only Ctrl-C
  / process kill (KeyboardInterrupt / CancelledError, how /ai stop ends
  us) breaks the loop.
- _serve shields each frame via _handle_frame so one malformed/poisoned
  frame — or a handler error — can't unwind the loop; ConnectionClosed
  and cancellation propagate up to the reconnect loop.
- Forgiving keepalive (ping_interval=20, ping_timeout=60) so a heavy
  CPU-only Ollama generation doesn't trip a false drop.

Also adds docs/spec-native-harness.md: replace the heavyweight Goose
harness with a lightweight host-side Ollama-native tool-calling loop
(model runs host-side, only commands exec in the sandbox — the
slirp4netns→host-Ollama bug disappears), and a file-by-file plan to strip
all Goose integration. Supersedes the harness portion of
spec-goose-harness.md (Podman backend stays).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 12:49:04 -07:00
leetcrypt f93c8c5e4f feat(sandbox): VM library — pointer catalog + local build via /sbx vmlib
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Add an installable-VM catalog that ships pointers only (no multi-GB images
in the repo). When a VM is chosen it is BUILT LOCALLY on the caller's own
machine — nothing is relayed to the room.

- scripts/vbox-library.json: 7-entry manifest (Windows 11, macOS Sonoma,
  Kali, Parrot, Ubuntu 24.04, Fedora 41, Debian 12) with download
  pointers, ostype, cpu/mem/disk, and build kind.
- scripts/vbox-library.sh: --list / --info / --plan / --install. Build
  kinds: iso (download/--iso + createvm + boot installer; EFI+TPM for
  Win11), cloudimg (delegate to vbox-new.sh, unattended), ova (import),
  manual (pointer-only, e.g. macOS per Apple licensing). Detect-first:
  --plan changes nothing, install refuses to clobber and rolls back
  half-built VMs, direct URLs fall back to the page + --iso <path>.
- sbx.rs: vbox_library()/library_vm()/vbox_library_install() loaders +
  running_vms() for live-state markers.
- app.rs: /sbx vmlib (catalog ✓installed/↓available), /sbx vmlib <id>
  (pointer/notes), /sbx vmlib <id> install [--iso path] (local build);
  /sbx vms now flags running VMs (▶). Registered in SBX_SUBCOMMANDS +
  usage.
- ui.rs: help entry for the VM library.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 12:09:54 -07:00
leetcrypt 15aa2027c4 refactor(sandbox): remove container browser-GUI (noVNC), keep vbox VM GUI
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
The docker/podman headless-container desktop (XFCE + TigerVNC + websockify
+ noVNC published on host 127.0.0.1:6080) is removed. It was unreliable: the
desktop stack installed asynchronously during provisioning with every step
wrapped in `|| true` (silent failures), while the host port mapping existed
the moment the container ran — so opening the browser before websockify bound
6080 inside the container reset the connection (ERR_CONNECTION_RESET), with no
readiness signal and no loud failure. Containers also can't be rendered as a
real desktop by VirtualBox (no framebuffer/display), so the only desktop path
that stays is the native VirtualBox VM GUI.

Removed:
- sbx.rs: GUI_PORT const; PortHolder/port_holder()/kill_port_holder() (the
  port-consent gate existed only for the noVNC publish); the `gui` param +
  `-p 127.0.0.1:6080:6080` block in prepare(); HH_SBX_GUI env in dk_bootstrap();
  the `gui` param on provision().
- app.rs: PendingGuiLaunch + PortPrompt structs; the port_prompt App field; the
  `gui` field on PendingSudoLaunch; the port-consent modal + the sudo-submit
  port check; want_gui/gui parsing + the container-GUI launch message; `gui`
  threaded through spawn_launch and all call sites.
- sandbox-bootstrap.sh: the entire HH_SBX_GUI=1 desktop block.
- ui.rs / usage strings: dropped "[gui]"/"noVNC desktop" from the docker/podman
  help and the /sbx usage line.

Kept (unchanged): the VirtualBox VM GUI — gui_launch() (VBoxManage startvm
--type gui), launch_vbox_gui, `/sbx vbox gui <vm>` and the `/sbx gui` alias. The
`gui` keyword is still stripped from positionals so `/sbx vbox gui <vm>` parses.

cargo check passes clean (no warnings).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 11:38:43 -07:00
leetcrypt 18a8936caa feat(sandbox): masked sudo modal for VirtualBox install path
The VBox GUI launch path previously had no in-TUI password capture — it
relied on cached creds (`sudo -n`) and otherwise aborted with guidance.
Generalize the existing masked sudo modal to cover it: `SudoPrompt.pending`
becomes a `PendingPrivileged` enum (container `Launch` | `VboxInstall`), so
the same local-only, never-logged password buffer now authorizes a VBox
install too. On submit the captured password is fed to `ensure_vbox_install`
via `sudo -S`, then the VM boots. Empty/Esc still cancel cleanly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 11:13:18 -07:00
leetcrypt c6eeb9b897 feat(sandbox): port-in-use consent gate + uniform sudo capture
GUI launch (docker/podman) now pre-flights the noVNC port (6080): if it's
already bound, a modal names the holding pid and asks before killing it and
proceeding — never a blind `bind: address already in use` collision.

Sudo capture is now uniform across every backend installer. Previously only
Docker fed the masked-modal password through `--stdin-pass`/`sudo -S`; the
captured password was silently dropped for Podman/Multipass and never wired
for VirtualBox, and those scripts used bare `sudo` (which hangs/corrupts a
raw-mode tty). Now:
- shared `run_ensure()` feeds the password to any ensure-*.sh via stdin
- podman/multipass/vbox scripts gain the docker sudo ladder
  (interactive `sudo` / `--yes` `sudo -n` / `--stdin-pass` `sudo -S -p ''`)
- podman's apt path wrapped in `sh -c` so one sudo covers update+install
- vbox GUI path preflights `sudo_ready()` with actionable guidance, falling
  back to fail-fast `sudo -n` instead of a tty hang

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 11:00:09 -07:00
leetcrypt ad13ec14ba docs(sandbox): specs for goose harness + GUI distros, command ref, themes
Add the goose-harness and sandbox-distros-GUI design specs, a consolidated
command reference and demo-reels plan, the AI-harness planning note, and
two new client themes (blue-orange, pink-red-gray).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 10:38:36 -07:00
leetcrypt 20091a9c26 feat(sandbox): podman backend + goose AI harness + noVNC GUI sandbox
Add Podman as a rootless/daemonless sandbox backend alongside Docker,
Multipass and Local, and wire Goose in as the default agentic harness
for the granted `!task` path (bridge execs `<engine> exec <name> goose
run` and streams output to chat; auto-degrades to the simple one-shot
injector when goose is absent).

Add an optional GUI sandbox track (XFCE + TigerVNC + websockify/noVNC on
:6080) summoned via `/sbx <engine> gui`, plus container-side provisioning
in sandbox-bootstrap.sh and a host-side ensure-podman.sh prereq helper.

Refresh the in-app command help to the backend-led `/sbx <engine> [gui]`
grammar and minor ui tweaks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-08 10:38:18 -07:00
leetcrypt eec1714735 feat(layout): input-bar + chat/clergy resize, masked sudo-for-docker, edit-mode unlock
Make the message-input bar part of the F5 resize cycle so its height is
adjustable without a sandbox (multi-line/wrapped inputs are now readable),
and let chat/clergy borrow height from the compose box when no terminal is
present. Add Option C masked sudo prompt that feeds `sudo -S` over stdin to
install/start Docker — the password never reaches chat, the PTY, or outbound
frames, and Docker Desktop on Linux is detected so no sudo is requested.

Fix a freeze where clicking the compose box entered layout-edit mode and
silently swallowed every keystroke: clicking the input bar no longer enters
edit mode, and typing any printable char now drops out of edit mode and types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 16:10:27 -07:00
leetcrypt 2ae4adfde4 docs(layout): spec for BSP pane tree (resize panes in both dimensions)
Design for replacing the two-scalar layout (pty_pct + roster_width) with a
binary space-partition pane tree so every pane is resizable on both axes,
fixing the "only roster width adjusts" limitation. Rolls a small in-repo tree
(no new dep) and drives the PTY grid from the terminal pane's actual Rect.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 14:07:05 -07:00
leetcrypt 9a038455ca docs: correct /send syntax, add /sendroom + /clear, fix Ctrl+Alt+P note
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
README command table claimed `/send <path>` sends to the room; actual code
(app.rs) makes `/send <user> <path>` a targeted send and `/sendroom <path>`
the room-wide offer. Add the missing `/sendroom` and `/clear` rows (both
already in the in-app help) and drop the inaccurate "save to disk" claim on
Ctrl+Alt+P — saving is `/theme save`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:48:44 -07:00
leetcrypt 556ba5f23a docs: drop inaccurate private-beta note — git.churchofmalware clone is public
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Verified anonymous clone from git.churchofmalware.org succeeds; only the
GitHub mirror is private. Restore the plain public clone instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:37:33 -07:00
leetcrypt 7cba32560c docs: document private-beta clone (token/SSH) for git.churchofmalware.org
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
The repo is private, so anonymous clone 404s. Add token + SSH clone
instructions under the quick-start so invited users can install while we
promote the Gitea instance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:32:29 -07:00
leetcrypt f1467b00ac docs: point clone URL at git.churchofmalware.org; refresh /sbx command list
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
- Update the git clone URL in README and CONTRIBUTING from the old
  GitHub remote to the project's Gitea instance
  (git.churchofmalware.org/trilltechnician/hack-house.git). Verified the
  clone succeeds over HTTPS against that path.
- CONTRIBUTING: fork step now points at the Gitea instance, not GitHub.
- Refresh the /sbx command table to match the client: `/sbx launch` now
  documents the `install` consent token and `--start` daemon boot, and a
  new row covers `/sbx launch vbox [new [name]]` (VM picker / cloud-init
  build).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:24:24 -07:00
leetcrypt 9959e09fe2 docs(scripts): add --help to remaining scripts; document scripts + layout in README
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
- Add a -h/--help guard (prints the usage header) to the five scripts
  that lacked one: smoke.sh, smoke-e2e.sh, test-features.sh,
  demo-save-load.sh, sandbox-bootstrap.sh. All 15 hh/scripts/*.sh now
  respond to --help.
- README: new "Scripts" section detailing every script (setup, hosting,
  sandbox provisioning, tests) and noting each takes --help; plus an
  archive note for the film-* recording scripts.
- README: new "Window layout" section documenting live pane resizing
  (F4 fullscreen, click/F5 to select + arrows to resize) and the
  /layout save/load/list/rm/reset presets, with matching keybinding-table
  rows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:20:07 -07:00
leetcrypt cab266588d chore(scripts): archive film demos, fold join.sh into connect.sh
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Trim newcomer-facing clutter in hh/scripts/ without changing the running
product or CI.

- Move the one-off demo-recording scripts (film-save-load.sh,
  film-virtualbox.sh) to scripts/archive/ — they depend on external
  personal tooling (asciinema, video-toolkit, edge-tts, xdotool) and were
  never wired into the README or CI.
- Delete join.sh: it duplicated connect.sh's join with fewer options
  (hardcoded port, plaintext-only). Its only unique behaviour — a
  pre-join git pull (gitea→origin, ff-only) + rebuild — is now an opt-in
  `--sync` flag on connect.sh, leaving one canonical joiner.

No scripts or docs referenced the removed/moved files, so nothing else
needed updating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 13:12:46 -07:00
leetcrypt 37d5916b2e feat(layout): fullscreen + interactive pane resizing
CI / rust client (hh) (macos-latest) (push) Waiting to run
CI / rust client (hh) (ubuntu-latest) (push) Waiting to run
CI / rust coverage (push) Waiting to run
CI / python server (3.10) (push) Waiting to run
CI / python server (3.11) (push) Waiting to run
CI / python server (3.12) (push) Waiting to run
CI / headless e2e smoke (push) Waiting to run
CI / dependency audit (push) Waiting to run
CI / secret scanning (push) Waiting to run
Add a window-management layer so the chat, roster and sandbox-terminal
panes can be resized live and fullscreened, with named presets for
recall.

- New layout.rs: single source of truth for the body split (pty_pct,
  roster_width) and a Zoom state (Normal/Term/Chat), persisted to
  layouts/<slug>.toml like themes. Both ui::draw and app::sbx_dims read
  from it, so resizing just mutates state and clears announced_dims —
  the per-tick loop re-syncs and broadcasts the new PTY grid.
- F4 cycles terminal/chat fullscreen (F-keys aren't forwarded to the
  shell, so nothing is stolen from in-shell apps).
- Interactive editing: click a pane (or F5 to cycle terminal -> chat ->
  roster) to select it; arrows then resize it live, Esc/Enter finishes.
  The selected pane gets a bold accent border and an ✎ title marker.
  ui::pane_at hit-tests against the same body_areas rects draw() paints.
- /layout slimmed to presets only (save/load/list/rm/reset); the old
  numeric pty/chat/roster and full/chatfull/normal verbs are replaced by
  the interactive flow.
- Help menu updated: LAYOUT cluster + KEYS line document F4, click/F5,
  arrows and Esc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 12:53:44 -07:00