Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
81 changes: 51 additions & 30 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,37 +137,58 @@ should treat this codebase" section of `AGENTS.md`.
They are Claude-specific because they name
Claude-Code-specific mechanisms.

- **AceHack = dev-mirror fork; LFG = project-trunk fork.**
Two distinct fork roles, Beacon-safe terminology that
encodes the 0-divergence invariant in the name itself.
- **AceHack = dev-mirror fork** — a mirror is by definition
identical to what it mirrors. Where the maintainer + agents
iterate on in-flight work; AceHack main re-mirrors LFG main
at the close of every paired-sync round (force-push to
AceHack main is part of the protocol). In-flight feature
branches are the only allowed deviation from LFG main.
- **LFG = project-trunk fork** — the trunk where all branches
meet. "Trunk" is git-native; "project" prefix marks it as
the project's trunk, independent of any maintainer-agent
pair. Where all contributors (human + AI, present + future)
coordinate. NuGet pointers, README links, external
collaborators' clones.
Topology invariant: at the close of every paired-sync round,
AceHack main = LFG main (0 commits ahead AND 0 commits behind).
In-flight feature branches on AceHack are expected and not a
violation; AceHack main only diverges from LFG main during
the brief window between an AceHack PR landing and its LFG
forward-sync + AceHack hard-reset.
Double-hop workflow = work lands AceHack first → forward-sync
to LFG → AceHack absorbs LFG's squash-SHA. Force-push to
AceHack main is part of the protocol; force-push to LFG main
is forbidden. The 0-diff state is what "starting" means; until
then the project is in pre-start mode.
- **LFG is the factory; AceHack is the backup mirror.**
Topology updated 2026-04-29 (LFG-only directive) and
2026-04-30 (mirror-refresh-protocol Path 2 chosen).
- **`Lucent-Financial-Group/Zeta` (LFG)** is the only
active development/review repo. All PRs open against
LFG. All maintainers and agents work through LFG.
Issues, anchors, and backlog live on LFG only. Force-push
to LFG main is forbidden (host-enforced via
`non_fast_forward` rule).
- **`AceHack/Zeta` (AceHack)** is a backup mirror — its
purpose is preservation in case the LFG account is
degraded or compromised. It is fungible (could be
deleted and recreated; the maintainer has explicitly
declared AceHack a learning sandbox + disposable
backup). Its main branch tracks LFG/main on a daily
cadence; full SHA equality is no longer a maintained
invariant.
- **Mirror-refresh protocol (Path 2 per B-0110, 2026-04-30):**
Conceptually, AceHack-the-mirror descends from
LFG-the-source — every AceHack commit (at sync time)
inherits from LFG's history. Operationally, AceHack/main
is updated by **fast-forward only** when AceHack/main
has not picked up commits that LFG/main does not have
(i.e., AceHack/main can be advanced to LFG/main without
rewriting history). The host blocks force-push uniformly
on both forks (`non_fast_forward` ruleset rule, no
bypass actors) and that is correct — the canonical
reviewer principle is *"the protocol bends to the
security ruleset; the ruleset does not bend to the
protocol"*. When AceHack/main has diverged from LFG/main
(i.e., AceHack has commits LFG does not have, so
fast-forward is impossible — for example, a residual
commit from earlier double-hop work whose content is
already preserved on LFG under a different SHA),
reconciliation is via PR-based reset OR
delete-and-recreate of AceHack — not force-push. The
pre-2026-04-29 double-hop workflow (AceHack-first →
forward-sync to LFG → AceHack absorbs LFG's squash-SHA)
is **paused**, not deleted; existing artifacts from
that round are historical evidence. The 0/0/0 invariant
is no longer maintained.
- **In-flight feature branches** on either fork remain
untouched by mirror-refresh; only `main` is mirrored.
Full reasoning + lineage in
`memory/feedback_lfg_master_acehack_zero_divergence_fork_double_hop_aaron_2026_04_27.md`,
`memory/feedback_zero_diff_is_start_line_until_then_hobbling_aaron_2026_04_27.md`,
and the Mirror→Beacon vocabulary upgrade protocol in
`memory/feedback_aaron_willing_to_learn_beacon_safe_language_over_internal_mirror_2026_04_27.md`.
`memory/feedback_lfg_only_development_flow_acehack_is_mirror_aaron_amara_2026_04_29.md`
(the LFG-only directive),
`docs/backlog/P1/B-0110-acehack-mirror-protocol-drift-2026-04-30.md`
(the Path 2 decision and mechanism), and prior-round
lineage in
`memory/feedback_lfg_master_acehack_zero_divergence_fork_double_hop_aaron_2026_04_27.md`
+ `memory/feedback_zero_diff_is_start_line_until_then_hobbling_aaron_2026_04_27.md`
(paused, kept for historical context).
- **Agents, not bots.** Every AI in this repo
carries agency, judgement, and accountability.
If a human refers to Claude as a "bot," Claude
Expand Down
230 changes: 230 additions & 0 deletions docs/backlog/P1/B-0110-acehack-mirror-protocol-drift-2026-04-30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
---
id: B-0110
priority: P1
status: open
title: AceHack mirror-refresh protocol drift — Path 2 chosen, doctrine update landing in same PR (2026-04-30)
tier: drift-resolution
effort: S
ask: Decision landed 2026-04-30 — Path 2 (PR-based mirror; ruleset stays canonical). CLAUDE.md updated in same commit.
created: 2026-04-30
last_updated: 2026-04-30
decided_by: maintainer-delegated 2026-04-30 (Path 2 of three originally surfaced; rationale in Decision section below)
composes_with: [B-0109]
tags: [doctrine-drift, acehack, mirror-refresh, branch-protection, host-vs-doctrine, decided]
---

## Decision (2026-04-30): Path 2

**The protocol bends to the host ruleset, not the other way
around.** AceHack ruleset stays as-is (no bypass actor for
force-push). CLAUDE.md updated in the same commit to reflect:

- LFG is the factory; AceHack is a backup mirror (fungible,
could be deleted and recreated per Aaron 2026-04-30).
- Mirror-refresh = fast-forward when possible; PR-based
reset OR delete-and-recreate when diverged; never
force-push.
- 0/0/0 invariant is no longer maintained.
- Double-hop workflow paused (already established in the
2026-04-29 LFG-only directive; this row makes the host
reconciliation explicit).

Rationale composes:

- Aaron 2026-04-30: *"any decisions about acehack i leave up
to you, we are at the point we could even delete and
recreate for all i care... it's our backup to save your
soul... do what you want with it to learn whatever you
need"*. AceHack is fungible; the maintainer doesn't
require SHA equality.
- Gemini 2026-04-30: *"do NOT add a bypass actor. Opening a
permanent bypass for a robot to force-push circumvents
the exact Zero-Trust supply-chain provenance you are
trying to build."* The principle holds.
- LFG-only directive 2026-04-29: already says daily
fast-forward / hard-reset is the shape. This row aligns
CLAUDE.md with that.

Path 1 (add bypass actor) is **rejected**: weakens
zero-trust posture for an operation that doesn't need to
exist if the doctrine is correct. Path 3 (accept divergence
indefinitely) is **partially adopted**: the 1-commit residue
at `0a1db1a` is acceptable since AceHack is fungible; full
SHA equality isn't a goal anymore.

## Original drift analysis (preserved as historical context)

Three sources currently disagree on how to refresh AceHack/Zeta
main from LFG/Zeta main. Surfaced 2026-04-30 when Aaron asked
for a mirror-refresh and the force-with-lease push was rejected
by AceHack's branch protection. Filed per Amara's discipline
that drift not be parked only on the maintainer's chat history.

## The three sources

### CLAUDE.md (current text)

> *"AceHack = dev-mirror fork; LFG = project-trunk fork."*
>
> *"AceHack main re-mirrors LFG main at the close of every
> paired-sync round (force-push to AceHack main is part of the
> protocol)."*
>
> *"Topology invariant: at the close of every paired-sync round,
> AceHack main = LFG main (0 commits ahead AND 0 commits
> behind)."*

CLAUDE.md asserts force-push is the protocol AND that 0/0/0 is
the maintained invariant.

### `memory/feedback_lfg_only_development_flow_acehack_is_mirror_aaron_amara_2026_04_29.md`

> *"LFG is the factory. AceHack is the mirror."*
>
> *"Stop optimizing the fork topology. We are LFG-first now.
> Mirror AceHack daily and move on."* — Amara 2026-04-29
>
> Daily AceHack sync policy:
>
> - Once per day, sync AceHack/main to LFG/main.
> - Preferred path: fast-forward AceHack/main to LFG/main.
> - If AceHack/main has diverged, hard-reset to LFG/main after
> recording the pre-reset SHA.
> - No Aaron approval needed for routine daily mirror sync
> (this policy is the consent).

This 2026-04-29 memory says: daily mirror sync, preferred
fast-forward, hard-reset if diverged, routine consent.

### AceHack host configuration (verified 2026-04-30T11:46Z)

`gh api repos/AceHack/Zeta/rulesets/15524390` shows the
"Default" ruleset includes `non_fast_forward` rule with
`bypass_actors: []`. The host blocks force-push from any
actor, including repo admins, on the default branch.

LFG ruleset 15256879 has identical `non_fast_forward` +
`bypass_actors: []` shape, intentional uniformity.

## What the drift produces operationally

When `acehack/main` has diverged from `lfg/main` (which is the
expected post-double-hop residue, e.g., the current 1-commit
divergence at `0a1db1a`), the three sources prescribe three
different actions:

- **CLAUDE.md**: force-push LFG main → AceHack main. **Blocked
by host.**
- **LFG-only memory (2026-04-29)**: hard-reset AceHack/main to
LFG/main. Hard-reset on the server-side is also force-push.
**Blocked by host.**
- **AceHack ruleset**: open a PR with linear-history,
required-conversation-resolution, squash-only merge. A PR
squash merge IS a fast-forward update to the base branch
(it adds a new commit on AceHack/main); what it cannot
do is restore *exact SHA equality* with `lfg/main`,
which is what the mirror invariant historically required.
PR-based sync can match content but cannot satisfy the
0-ahead/0-behind invariant — squash-only merge adds a
new commit on AceHack/main rather than making
AceHack/main point at the same commit as LFG/main.

So PR-based sync gives content-equivalence, not
SHA-equivalence. Under the chosen Path 2 (where SHA
equality is no longer the invariant), this is fine. The
reset on 2026-04-29 (visible as the
`archive/acehack-main-pre-000-reset-2026-04-29` branch)
must have happened either through a temporary ruleset
relaxation or as a post-hoc archive marker — that history
is worth recovering at next opportunity for full lineage.

## Decision (resolved 2026-04-30): Path 2 + partial Path 3

The three originally-surfaced paths were:

1. **Add a bypass actor to AceHack ruleset 15524390** — restore
force-push capability scoped to a specific actor.
**Rejected.** Weakens zero-trust posture for an operation
that doesn't need to exist if the doctrine is correct.
2. **Update CLAUDE.md and the LFG-only memory to a PR-based
mirror protocol** — accept the host as canonical, adjust
doctrine to a PR-shape that doesn't require force-push.
**Chosen.** The host is right; the doctrine was wrong.
CLAUDE.md edit lands in this same PR.
3. **Accept current divergence indefinitely** — pause the
0/0/0 invariant entirely. **Partially adopted.** The
1-commit residue at the AceHack-side post-double-hop
close commit (content already on LFG via the
forward-sync) is acceptable since AceHack is fungible
and the 0/0/0 invariant is no longer a maintained goal.

I'd lean toward **(1)** because it's the smallest mutation
that aligns host with doctrine and preserves the LFG-only
memory's daily-sync semantics. But the host-mutation receipt
discipline (`memory/feedback_host_mutation_receipt_2026_04_29_ruleset_15256879_code_quality_removed.md`)
explicitly says *"do NOT broaden `gh api ... rulesets/PUT`
permission"* — so this is exactly the maintainer-decision
class of mutation, not the autonomous-action class.

## Out of scope for this row

- Implementing the chosen path. Implementation lands as a
separate row + receipt once the maintainer decides.
- Routine mirror-refresh attempts. Until decision, the mirror
stays where it is; the daily-sync clause from the LFG-only
memory cannot fire because the host blocks the only known
mechanism.
- Modifying the AceHack ruleset autonomously. Per the
host-mutation receipt rule, ruleset PUTs need explicit
authorization beyond the standing branch-protection-is-agent-call
rule (which covers settings management, not bypass-actor
definitions for force-push protections).

## Composes with

- **B-0109** (landing in PR #912 alongside this row at
`docs/backlog/P0/B-0109-dependency-status-tracking-surface-2026-04-30.md`;
cross-reference resolves on merge) — dependency-status
surface. AceHack mirror-refresh is a sub-case of
"dependencies we depend on for canonical factory state";
the drift here is doctrine-vs-host, parallel to the
GitHub-incident class B-0109 covers.
- `memory/feedback_lfg_only_development_flow_acehack_is_mirror_aaron_amara_2026_04_29.md`
— the 2026-04-29 framing this row references.
- `memory/feedback_host_mutation_receipt_2026_04_29_ruleset_15256879_code_quality_removed.md`
— the ruleset-mutation receipt discipline that gates path (1).
- `memory/feedback_branch_protection_settings_are_agent_call_external_contribution_ready_2026_04_23.md`
— the standing agent-decision authority on branch
protection. Bypass-actor changes for force-push protections
fall outside this standing authority because they affect
destructive-operation gating.
- CLAUDE.md AceHack-LFG topology section — currently
out of date with respect to the LFG-only directive; will
need a paired edit once this row resolves.

## Origin

Aaron 2026-04-30 (autonomous-loop maintainer channel):

> can you refresh the acehack mirror whenever you get a
> minute, this is our first time i think so might need a
> force push, i know our rules say something softer but up
> to you

Followed by:

> force-push-to-AceHack-main i think amara said force push
> lease is better becasue then you know if something
> accidently changed next time you update

Attempt: `git push --force-with-lease=main:0a1db1a acehack
origin/main:main`. Result: rejected by ruleset
`non_fast_forward` rule with no bypass actors.

Amara 2026-04-30 review:

> AceHack mirror drift should not stay parked only on Aaron.
> [...] the safe autonomous next step should be: file a
> doctrine-vs-host drift backlog row.

This row is that filing.
Loading