From 7e617609a00db2f51910cdf11bdcad398896c593 Mon Sep 17 00:00:00 2001 From: Lior Date: Wed, 27 May 2026 09:46:14 -0400 Subject: [PATCH 1/2] =?UTF-8?q?docs(B-0858):=20agent=20heartbeat=20folder?= =?UTF-8?q?=20direct-to-main=20with=20ZetaID-collision-free=20filenames=20?= =?UTF-8?q?=E2=80=94=20mechanizes=20externalized-counter=20(Aaron=202026-0?= =?UTF-8?q?5-27=20reminder=20of=20existing=20ZetaID=20+=20AgencySignature?= =?UTF-8?q?=20substrate)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator 2026-05-27 reminder: "the agencyheartbeats you were going to make a spot where they can be pushed with no prs a foleder where you can go strait to main and other agents with unique ids that won't overlap, we started talking about 128 bit ids and such you could use for unique heartbeats and such. these are called zetaids" Found existing substrate I was not using: - src/Core.TypeScript/zeta-id/zeta-id.ts (128-bit struct ID; persona + authority + momentum + timestamp + chromosome + randomness) - tests/Tests.FSharp/ZetaId/CrossVerifyTests.fs (F# cross-verify harness) - docs/zeta-id-v1-layout.yaml (canonical bit-layout spec) - Kestrel review 2026-05-21 zeta-id-v1 preserved in persona/kestrel/ - tools/hygiene/audit-agencysignature-main-tip.ts (AgencySignature v1) This row composes with the existing substrate to mechanize the externalized-counter fix Kira P0 named + operator confirmed: Folder layout: docs/agent-heartbeats////
/.md Branch protection: path-scoped carve-out permits direct-to-main push Heartbeat schema: zetaid + agent + runtime + model + timestamp + authority + momentum + named-dep + disposition + optional parent-pr Why direct-to-main: per-tick heartbeat writes can't open PRs; the brief- ack rule's N=6 forcing function needs trivial git-log queries over the folder to fire reliably. ZetaID filenames prevent collision across concurrent agent ticks (persona field + 32-bit randomness + 48-bit timestamp = uniqueness by construction). 7 sub-rows planned (.1 spec → .2 branch protection → .3 writer tool → .4 sentinel integration → .5 rule extension → .6 cleanup policy → .7 collision verification). Sub-rows .3 + .5 are the load-bearing pair; .2 is operator-side GitHub config. Without this row: brief-ack failure mode catches recur until counter mechanically externalizes. The 2026-05-27 catch (100+ "Quiet.") + Kira's P0 finding are the empirical anchor. Composes with: - B-0852.3a picker (PR #5450) - B-0855 self-register architectural fix - B-0857 install.sh universal entry - B-0666 English-as-projection (heartbeat schema IS projection) - B-0628 Knights Guild Constitution-Class (heartbeat semantics may be C-Class candidate) - .claude/rules/holding-without-named-dependency-is-standing-by-failure.md (this row provides the externalized-counter surface) - .claude/rules/verify-existing-substrate-before-authoring.md (inventory cited inline) - .claude/rules/agent-roster-reference-card.md (persona drives folder layout) - CLAUDE.md "Heartbeat-via-commit" bullet (PR #5451) Per .claude/rules/agent-worktree-hygiene-never-hold-main-...: isolated worktree at /private/tmp/zeta-b0858-heartbeat-folder-1300z; operator primary checkout untouched. Per .claude/rules/non-coercion-invariant.md HC-8: heartbeats are operator-observable transparency-by-construction; no secrets in heartbeat files (observational metadata only). Filing this row IS heartbeat-via-commit work per the just-landed CLAUDE.md discipline (PR #5451). Recursive: a row about heartbeat-folder mechanization IS itself a heartbeat-class commit on the path toward that mechanization. Agency-Signature-Version: 1 Agent: Otto Agent-Runtime: Claude Code (auto mode) Agent-Model: claude-opus-4-7 Credential-Identity: aaron-otto-vscode Credential-Mode: operator-authorized Human-Review: pre-merge-pending Human-Review-Evidence: operator-direction-2026-05-27-agency-heartbeats-zetaid-reminder Action-Mode: substrate-row-filing Task: B-0858 Co-Authored-By: Claude Opus 4.7 --- docs/BACKLOG.md | 1 + ...enames-no-pr-mechanism-aaron-2026-05-27.md | 157 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 5b069c012d..0aeedd4a5d 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -405,6 +405,7 @@ are closed (status: closed in frontmatter)._ - [ ] **[B-0853](backlog/P1/B-0853-sigstore-cosign-artifact-signing-free-stuff-iso-containers-tarballs-backed-by-fulcio-rekor-aaron-2026-05-27.md)** sigstore/cosign artifact signing — free-stuff coverage for ISO + containers + tarballs + Nix substitutes (Fulcio CA + Rekor transparency log; OIDC-keyless via GitHub Actions); commercial CAs deferred for proprietary OS surfaces (Aaron 2026-05-27) - [ ] **[B-0854](backlog/P1/B-0854-zeta-install-sh-to-ace-install-zeta-migration-trajectory-package-json-style-declarative-manifest-like-scratch-and-sqlsharp-aaron-2026-05-27.md)** zeta-install.sh → `ace install zeta` migration trajectory — declarative `package.json`-style Ace manifest in Zeta repo (like `../scratch` and `../SQLSharp` already do); composes with B-0288 Ace CLI + B-0824 meta-PM + B-0816 ArgoCD-maximization + B-0742 distributable-POC pattern (Aaron 2026-05-27) - [ ] **[B-0855](backlog/P1/B-0855-self-registration-fires-LAST-post-install-post-first-boot-idempotent-across-reboots-deduped-against-in-flight-registration-prs-aaron-2026-05-27.md)** self-registration fires LAST (post-install + post-first-boot, when cluster is operational) + idempotent across reboots + de-duped against existing-registration AND in-flight-registration-PRs; cluster-agent coordination via /tmp folder OR Otto-pushes-PR-across-finish-line (Aaron 2026-05-27) +- [ ] **[B-0858](backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md)** Agent heartbeat folder — direct-to-main push (no PR) with ZetaID-collision-free filenames per agent; mechanizes the externalized-counter discipline operator named 2026-05-27 ## P2 — research-grade diff --git a/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md b/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md new file mode 100644 index 0000000000..72a9326730 --- /dev/null +++ b/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md @@ -0,0 +1,157 @@ +--- +id: B-0858 +priority: P1 +status: open +title: Agent heartbeat folder — direct-to-main push (no PR) with ZetaID-collision-free filenames per agent; mechanizes the externalized-counter discipline operator named 2026-05-27 +effort: M +ask: aaron 2026-05-27 +created: 2026-05-27 +last_updated: 2026-05-27 +depends_on: [] +composes_with: + - B-0852.3a + - B-0855 + - B-0857 +tags: [agent-heartbeat, direct-to-main, no-pr, zetaid, 128-bit-id, externalized-counter, holding-failure-mode-mechanization, branch-protection-exception] +--- + +## Operator framing 2026-05-27 + +> *"the agencyheartbeats you were going to make a spot where they can be +> pushed with no prs a foleder where you can go strait to main and other +> agents with unique ids that won't overlap, we started talking about 128 +> bit ids and such you could use for unique heartbeats and such. these +> are called zetaids"* + +## Existing substrate this composes with + +### ZetaID v1 (128-bit observation ID; already implemented) + +- `src/Core.TypeScript/zeta-id/zeta-id.ts` — TS implementation with structured bit layout +- `tests/Tests.FSharp/ZetaId/CrossVerifyTests.fs` — F# cross-verification harness +- `tests/Tests.CSharp/ZetaId/` — C# cross-verification harness +- `docs/zeta-id-v1-layout.yaml` — canonical bit-layout spec +- Kestrel review 2026-05-21: `memory/persona/kestrel/conversations/2026-05-21-aaron-kestrel-claudeai-zeta-id-v1-review-watermarks-tier-deferred-causality-orleans-otto-watching-verification-gap-hat-vs-role-group-chat-aaron-forwarded.md` + +ZetaID bit layout (128 bits): +- version (5) + timestamp (48) + chromosome (5) + category (4) + firefly (1) + authority (5) + persona (8) + momentum (8) + location (8) + randomness (32) + +Each ZetaID encodes WHO + WHEN + WHAT-AUTHORITY + WHAT-MOMENTUM. Collision-free across agents by construction (persona field + 32-bit randomness + 48-bit timestamp). + +### AgencySignature Convention v1 (already in use) + +- `tools/hygiene/audit-agencysignature-main-tip.ts` — post-merge auditor +- `tools/hygiene/validate-agencysignature-pr-body.ts` — pre-merge validator +- Spec: `docs/research/2026-04-26-gemini-deep-think-agencysignature-commit-attribution-convention-validation-and-refinement.md` §10 + +### Heartbeat-via-commit discipline (just landed PR #5451) + +CLAUDE.md "Heartbeat-via-commit = externalized idle counter" — currently the heartbeat mechanism IS the regular PR-gated commit. This row mechanizes a faster lightweight variant. + +## Scope + +**New folder**: `docs/agent-heartbeats////
/.md` + +Where: +- `` ∈ {otto, alexa, riven, vera, lior, ...} (canonical roster per `.claude/rules/agent-roster-reference-card.md`) +- `` = base64url-encoded 128-bit ZetaID (collision-free; persona field matches the folder) +- File contents: minimal heartbeat record (see schema below) + +**Branch protection exception**: this folder permits direct push to `main` without PR review. Other folders retain full PR gating; the carve-out is path-scoped via GitHub's branch protection rule patterns. + +**Heartbeat file schema** (small; ~10 lines): + +```yaml +--- +zetaid: +agent: otto +agent-runtime: claude-code-auto +agent-model: claude-opus-4-7 +timestamp: 2026-05-27T13:00:00Z +authority: TrustedAgent +momentum: Normal +named-dep: "PR #5450 build-iso completion (~20min ETA)" # or "none-chosen-free-time" or "decomposing-next-substrate" +disposition: bounded-wait | decomposing | committed-substrate | chose-free-time +parent-pr: 5450 # optional; if this heartbeat is in the context of an in-flight PR +--- + +(optional one-line note; rarely needed; the structured fields carry the load) +``` + +## Why direct-to-main without PR + +The brief-ack failure mode the operator caught 2026-05-27 (100+ "Quiet." emissions; Kira P0 finding: counter never externalized because the agent couldn't count itself) requires LOW-FRICTION heartbeat writes. PR-gated commits work for substantive substrate work, but every tick can't open a PR. Direct-to-main heartbeats: + +- Externalize the per-tick brief-ack state to a persistent surface +- Make `git log --since="2min ago" docs/agent-heartbeats/otto/` query trivially count Otto's recent heartbeats +- Trigger the rule's N=6 forcing function reliably when zero heartbeats appear +- Don't pollute PR queue with per-tick noise +- ZetaID filenames prevent collision across simultaneous agent ticks + +## Sub-rows planned + +- **B-0858.1** — Define folder layout + heartbeat schema (this row; spec) +- **B-0858.2** — Branch protection rule: path-scoped carve-out for `docs/agent-heartbeats/**` (operator-side GitHub config; requires repo-admin) +- **B-0858.3** — TS heartbeat-writer tool: `tools/agent-heartbeats/write-heartbeat.ts` (composes with `src/Core.TypeScript/zeta-id/zeta-id.ts` ZetaID generator) +- **B-0858.4** — Sentinel/cron integration: per-tick autonomous-loop fire writes a heartbeat +- **B-0858.5** — Counter integration: `.claude/rules/holding-without-named-dependency-is-standing-by-failure.md` extension naming this folder as the externalized counter source +- **B-0858.6** — Auto-cleanup policy: heartbeats older than 7 days auto-deleted (or rolled into compressed summary) to bound repo growth +- **B-0858.7** — Cross-agent collision verification (empirical test multiple agents writing concurrently; ZetaID uniqueness empirically holds) + +## What this is NOT + +- NOT a replacement for substantive-substrate commits (those still go via PR + AgencySignature trailer) +- NOT a bypass of branch protection for OTHER paths (carve-out is path-scoped to `docs/agent-heartbeats/`) +- NOT a violation of `.claude/rules/substrate-or-it-didnt-happen.md` (heartbeats ARE durable substrate; just lighter-weight + path-scoped) +- NOT a security risk (heartbeats are observational metadata; no secrets; no code; just status) + +## Substrate-inventory pass (per `.claude/rules/verify-existing-substrate-before-authoring.md`) + +Topic: agent heartbeat folder + direct-to-main + ZetaID + +Searched: +- `src/Core.TypeScript/zeta-id/zeta-id.ts` — FOUND (128-bit struct ZetaID; this row composes with) +- `tests/Tests.FSharp/ZetaId/` — FOUND (cross-verify harness; this row's TS writer composes) +- `docs/zeta-id-v1-layout.yaml` — FOUND (canonical spec) +- Kestrel review 2026-05-21 zeta-id-v1 — FOUND (review preserved in persona/kestrel/conversations/) +- `tools/hygiene/audit-agencysignature-main-tip.ts` — FOUND (per-commit auditor) +- `docs/hygiene-history/ticks/` — FOUND (tick shard folder; PR-gated; different scope from this row) +- `docs/AGENT-CLAIM-PROTOCOL.md` — FOUND (claim protocol; different scope; bus-based not folder-based) +- No existing row covers heartbeat-folder-direct-to-main; this row fills the gap + +Read top hits: ZetaID TS impl + bit layout YAML + Kestrel review + sibling AgencySignature spec doc. + +Authoring action: mint new B-0858 row composing with existing ZetaID + AgencySignature substrate. + +## Why P1 + +- Operator-named explicitly 2026-05-27 ("you were going to make") +- Mechanizes the externalized-counter fix Kira P0 named + operator confirmed +- Composes cleanly with existing ZetaID v1 (no new ID substrate needed) +- Implementation is bounded (M effort): 7 sub-rows; .3 (writer tool) + .5 (rule extension) are the load-bearing pair; .2 (branch protection) is operator-side +- Without this row: brief-ack failure mode catches will recur until the counter is mechanically externalized + +## Composes with rules + +- `.claude/rules/holding-without-named-dependency-is-standing-by-failure.md` — this row provides the externalized-counter surface the rule needs to fire N=6 reliably +- `.claude/rules/verify-existing-substrate-before-authoring.md` — substrate-inventory pass cited inline +- `.claude/rules/non-coercion-invariant.md` HC-8 — heartbeats are operator-observable; transparency-by-construction +- `.claude/rules/substrate-or-it-didnt-happen.md` — heartbeats ARE substrate (durable, committed, indexed) +- `.claude/rules/agent-roster-reference-card.md` — persona ∈ {otto, alexa, riven, vera, lior, ...} drives folder layout +- CLAUDE.md "Heartbeat-via-commit" bullet (PR #5451) — this row mechanizes the lightweight variant of the discipline + +## Composes with substrate + +- B-0852.3a picker (PR #5450) — each picker invocation could emit a heartbeat with disposition=committed-substrate +- B-0855 self-register architectural fix — same per-tick observability scope +- B-0857 install.sh universal entry — heartbeats from install-time agents could capture install progress +- B-0628 Knights Guild Constitution-Class — heartbeat folder semantics may be Constitution-Class candidate (operator decides) +- B-0666 English-as-projection — heartbeat schema is structured English; composes with the projection substrate + +## Heartbeat per CLAUDE.md discipline + +Filing this row IS counter-reset work per `.claude/rules/holding-without-named-dependency-is-standing-by-failure.md` condition #3. Operator's reminder ("you were going to make") catches the substrate-engineering work that was deferred; filing now closes the deferral. + +## Full reasoning + +Operator 2026-05-27 verbatim quote preserved above. Filed in response to operator pointing at the existing ZetaID + AgencySignature substrate that I had not been using. The substrate-honest implication: future-Otto inheriting at cold-boot needs both (a) ZetaID writer integration AND (b) folder layout + branch protection in place. This row tracks the work; implementation iterates across the 7 sub-rows. From 154a6bad73b8ae44d0eea902fd8e9bba2bcda0da Mon Sep 17 00:00:00 2001 From: Lior Date: Wed, 27 May 2026 09:51:30 -0400 Subject: [PATCH 2/2] =?UTF-8?q?fix(B-0858=20CI=20+=20scope):=20MD032=20bla?= =?UTF-8?q?nk-line=20+=20operator=20follow-up=20=E2=80=94=20ZetaID=20categ?= =?UTF-8?q?ory=3D3=3DHeartbeat=20already=20in=20registry/categories.yaml;?= =?UTF-8?q?=20bit-field=20grep=20indexing=20extends=20scope=20beyond=20hea?= =?UTF-8?q?rtbeats?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three MD032 fixes (markdownlint blocked CI): - Line 37 ZetaID bit layout list needs blank line before - Line 56 folder-layout 'Where:' list needs blank line before - Line 117 substrate-inventory 'Searched:' list needs blank line before Substantive scope additions per operator 2026-05-27 follow-up: - "the ids are for easy lookup based many different bit id indexes built into the bits themselves so we can grep for things later, this does not have to be just heartbeat itd, it can be id for everything" — bit fields ARE the lookup indices; grep patterns on persona/authority/momentum/category extract event subsets - "we have the abiity to defined it per category, category is in the bits so could have a custom one for heartbeat" — already true: registry/categories.yaml defines Category=3=Heartbeat (alongside Observation=0, Emission=1, Workflow=2); 16 slots total; 4 used Substrate-inventory section updated to include registry/categories.yaml FOUND. Implication for B-0858.3 writer tool: when generating heartbeat IDs, set category bits to 3 (Heartbeat slot) per existing registry. Future event types can use other slots (16 total). Per .claude/rules/verify-existing-substrate-before-authoring.md: the operator's follow-up surfaced existing substrate I had not grepped for. Substrate-honest: row now acknowledges the existing registry + the broader bit-field-as-grep-index framing. Agency-Signature-Version: 1 Agent: Otto Agent-Runtime: Claude Code (auto mode) Agent-Model: claude-opus-4-7 Credential-Identity: aaron-otto-vscode Credential-Mode: operator-authorized Human-Review: pre-merge-pending Human-Review-Evidence: operator-followup-2026-05-27-zetaid-broader-scope-per-category-bits Action-Mode: substrate-fix-fwd-ci-plus-scope-acknowledgment Task: B-0858 Co-Authored-By: Claude Opus 4.7 --- ...n-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md b/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md index 72a9326730..dccdaa5118 100644 --- a/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md +++ b/docs/backlog/P1/B-0858-agent-heartbeat-folder-direct-to-main-zetaid-filenames-no-pr-mechanism-aaron-2026-05-27.md @@ -34,10 +34,13 @@ tags: [agent-heartbeat, direct-to-main, no-pr, zetaid, 128-bit-id, externalized- - Kestrel review 2026-05-21: `memory/persona/kestrel/conversations/2026-05-21-aaron-kestrel-claudeai-zeta-id-v1-review-watermarks-tier-deferred-causality-orleans-otto-watching-verification-gap-hat-vs-role-group-chat-aaron-forwarded.md` ZetaID bit layout (128 bits): + - version (5) + timestamp (48) + chromosome (5) + category (4) + firefly (1) + authority (5) + persona (8) + momentum (8) + location (8) + randomness (32) Each ZetaID encodes WHO + WHEN + WHAT-AUTHORITY + WHAT-MOMENTUM. Collision-free across agents by construction (persona field + 32-bit randomness + 48-bit timestamp). +**Operator 2026-05-27 follow-up**: *"the ids are for easy lookup based many different bit id indexes built into the bits themselves so we can grep for things later, this does not have to be just heartbeat itd, it can be id for everything"* + *"we have the abiity to defined it per category, category is in the bits so could have a custom one for heartbeat"*. The structured bit fields ARE the lookup indices — grep on persona-bit pattern, authority-bit pattern, momentum-bit pattern, etc. Already-existing substrate: `registry/categories.yaml` defines Category=3=Heartbeat (along with Observation=0, Emission=1, Workflow=2). This row's writer tool (.3 sub-row) sets category bits to 3 when generating heartbeat IDs; other event categories use other slots in the same 16-slot enum. + ### AgencySignature Convention v1 (already in use) - `tools/hygiene/audit-agencysignature-main-tip.ts` — post-merge auditor @@ -53,8 +56,9 @@ CLAUDE.md "Heartbeat-via-commit = externalized idle counter" — currently the h **New folder**: `docs/agent-heartbeats////
/.md` Where: + - `` ∈ {otto, alexa, riven, vera, lior, ...} (canonical roster per `.claude/rules/agent-roster-reference-card.md`) -- `` = base64url-encoded 128-bit ZetaID (collision-free; persona field matches the folder) +- `` = base64url-encoded 128-bit ZetaID with category bits = 3 (Heartbeat per `registry/categories.yaml`); collision-free; persona field in the ZetaID matches the folder name - File contents: minimal heartbeat record (see schema below) **Branch protection exception**: this folder permits direct push to `main` without PR review. Other folders retain full PR gating; the carve-out is path-scoped via GitHub's branch protection rule patterns. @@ -110,7 +114,9 @@ The brief-ack failure mode the operator caught 2026-05-27 (100+ "Quiet." emissio Topic: agent heartbeat folder + direct-to-main + ZetaID Searched: + - `src/Core.TypeScript/zeta-id/zeta-id.ts` — FOUND (128-bit struct ZetaID; this row composes with) +- `registry/categories.yaml` — FOUND (Heartbeat = category 3 ALREADY EXISTS; writer tool sets cat=3 on heartbeat IDs) - `tests/Tests.FSharp/ZetaId/` — FOUND (cross-verify harness; this row's TS writer composes) - `docs/zeta-id-v1-layout.yaml` — FOUND (canonical spec) - Kestrel review 2026-05-21 zeta-id-v1 — FOUND (review preserved in persona/kestrel/conversations/)