@rafinery/cli 0.8.11 → 0.8.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,10 +17,10 @@ try {
17
17
  if (!existsSync(join(ROOT, "rafa.json"))) process.exit(0);
18
18
  if (!existsSync(join(ROOT, ".rafa", ".git"))) process.exit(0);
19
19
 
20
- const sh = (cmd, cwd = ROOT) =>
21
- execSync(cmd, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
20
+ const sh = (cmd, cwd = ROOT, timeout) =>
21
+ execSync(cmd, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], ...(timeout ? { timeout } : {}) }).trim();
22
22
  const rafa = join(ROOT, ".rafa");
23
- const shR = (cmd) => sh(cmd, rafa);
23
+ const shR = (cmd, timeout) => sh(cmd, rafa, timeout);
24
24
 
25
25
  // DISPOSAL (MIRRORS working-set.isDisposableHydration — the ONE rule, both planes):
26
26
  // an UNEDITED hydration must never enter a brain commit, or we re-push org content as a
@@ -135,6 +135,16 @@ try {
135
135
  `git commit --allow-empty -q -m "brain(${branch}): ${subject}" ` +
136
136
  `-m "code-commit: ${fullSha}" -m "code-branch: ${branch}"`,
137
137
  );
138
+ // Keep the REMOTE mirror branch current (owner 2026-07-23: the branch is visible
139
+ // in the brain repo) — best-effort, bounded; a failed push retries on the next
140
+ // commit. Never the trunk (single writer = the reconciler).
141
+ if (branch !== "main" && branch !== "master") {
142
+ try {
143
+ shR(`git push -q -u origin "${branch}"`, 10000);
144
+ } catch {
145
+ /* offline / no permission — stays local until a later push succeeds */
146
+ }
147
+ }
138
148
  } catch {
139
149
  /* silent by design — the heartbeat carries sensor health */
140
150
  }
@@ -4,15 +4,16 @@
4
4
  // surfaces are committed to the OLD branch first (switch-carryover) —
5
5
  // deterministic, nothing lost, nothing blocks.
6
6
  //
7
- // FRESH-SLATE RULE (owner 2026-07-23): a NEW branch's mirror is cut FROM THE
8
- // REMOTE TRUNK (the published org brain), never from whatever branch the local
9
- // mirror happened to sit on. That makes the slate exact no session leftovers
10
- // from other branches, no local-vs-remote drift and keeps the branch's diff
11
- // vs trunk equal to precisely what the branch captures (the reconciler's
12
- // git-plane semantic). Cutting an EMPTY tree instead would read as mass
13
- // deletion of the org brain in that diff never that.
7
+ // EMPTY-SLATE RULE (owner 2026-07-23): a NEW branch's mirror is cut at the
8
+ // trunk's ROOT COMMIT — the empty genesis base every brain trunk begins with
9
+ // so the branch starts with an EMPTY .rafa and code agents HYDRATE what they
10
+ // need during development. Rooting at genesis (not an orphan) keeps ancestry
11
+ // with main, so the reconciler's main...branch diff = exactly what the branch
12
+ // captured (an unrooted empty branch would diff as mass deletion of the org
13
+ // brain never that). The new mirror branch is also PUSHED to the brain
14
+ // remote (best-effort, bounded) so the branch is VISIBLE in the brain repo.
14
15
  // Fallback ladder (offline-safe, never blocks a checkout):
15
- // origin/<trunk> (freshly fetched, bounded) → local <trunk> → current HEAD.
16
+ // root of origin/<trunk> (freshly fetched) → root of local <trunk> → current HEAD.
16
17
  //
17
18
  // argv: <prevHEAD> <newHEAD> <flag> (git's post-checkout contract;
18
19
  // flag "1" = branch checkout, "0" = file checkout → no-op).
@@ -104,7 +105,8 @@ try {
104
105
  }
105
106
  } catch {
106
107
  // CUT — no mirror branch yet. Never mirror-cut the trunk itself; for any other
107
- // branch, base the new mirror on the freshest trunk we can reach.
108
+ // branch, base the new mirror at the ROOT of the freshest trunk we can reach
109
+ // the empty genesis base ⇒ an EMPTY .rafa slate, hydrated on demand during dev.
108
110
  if (branch !== "main" && branch !== "master") {
109
111
  const trunk = trunkOf();
110
112
  let base = null;
@@ -113,7 +115,9 @@ try {
113
115
  for (const ref of [`refs/remotes/origin/${trunk}`, `refs/heads/${trunk}`]) {
114
116
  try {
115
117
  shR(`git rev-parse --verify -q "${ref}"`);
116
- base = ref;
118
+ // The trunk-line root (first-parent chain has exactly one root) — the
119
+ // empty genesis commit the reconciler authors the org brain from.
120
+ base = shR(`git rev-list --max-parents=0 --first-parent "${ref}"`).split("\n").pop();
117
121
  break;
118
122
  } catch {
119
123
  /* next */
@@ -122,6 +126,14 @@ try {
122
126
  }
123
127
  if (base) shR(`git checkout -q -b "${branch}" "${base}"`);
124
128
  else shR(`git checkout -q -b "${branch}"`); // last resort: old behavior, current HEAD
129
+ // Make the branch VISIBLE in the brain repo (owner 2026-07-23) — best-effort,
130
+ // bounded; a push failure never blocks the checkout (remote lands on the next
131
+ // brain-commit push instead).
132
+ try {
133
+ shR(`git push -q -u origin "${branch}"`, 10000);
134
+ } catch {
135
+ /* offline / no permission — mirror stays local until a later push succeeds */
136
+ }
125
137
  }
126
138
  }
127
139
  } catch {
package/lib/releases.mjs CHANGED
@@ -246,7 +246,7 @@ export const RELEASES = [
246
246
  "`git merge` + push to main reconciles too. `rafa update` re-vendors the scan SOP.",
247
247
  },
248
248
  {
249
- version: "0.8.11",
249
+ version: "0.8.12",
250
250
  contract: 1,
251
251
  plans: 2,
252
252
  requires: "update",
@@ -259,7 +259,7 @@ export const RELEASES = [
259
259
  "No session leftovers cross branches, local-vs-remote drift can't leak into a " +
260
260
  "new branch, and the branch's diff vs trunk stays exactly what the branch " +
261
261
  "captured. Switching TO the trunk ff-freshens it from remote (divergence stays " +
262
- "loud — `rafa pull --full --force` is the explicit adopt). SELF-HEAL: a repo " +
262
+ "loud — `rafa pull --full --force` is the explicit adopt). EMPTY-SLATE: a new branch's mirror is cut at the trunk's ROOT (the empty genesis base) — .rafa starts EMPTY and agents hydrate during dev; the mirror branch is PUSHED to the brain remote (visible on GitHub) at cut + after every brain commit. SELF-HEAL: a repo " +
263
263
  "with rafa.json but no materialized .rafa bootstraps it automatically on the " +
264
264
  "first branch checkout (bounded; a failure never breaks the checkout). " +
265
265
  "`rafa update` re-vendors the post-checkout hook.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rafinery/cli",
3
- "version": "0.8.11",
3
+ "version": "0.8.12",
4
4
  "description": "rafa — the AI engineer CLI. Vendors the rafa blueprint into your repo (shadcn-style) and runs the deterministic contract gates.",
5
5
  "type": "module",
6
6
  "bin": {