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
1 change: 1 addition & 0 deletions memory/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<!-- paired-edit log (NOT the single-slot latest-marker — that lives on line 3 above): PR #986 lands carved-sentence fixed-point stability + Zeta soul-file executor architecture (Infer.NET-style Bayesian inference, NOT LLMs) + carved sentences ≈ formal specs provable in DST + Deepseek CSAP review absorption (Aaron 2026-04-30 → 2026-05-01, eight-message chain across two autonomous-loop ticks per the file body's section header). Architectural disclosure: substrate IS the priors; alignment IS substrate. The single-slot latest-marker on line 3 (forever-home Aaron 2026-05-01) takes precedence as the chronologically-latest paired edit; this PR's work is earlier. -->
**📌 Fast path: read `CURRENT-aaron.md` and `CURRENT-amara.md` first.** <!-- paired-edit: PR #690 scheduled-workflow-null-result-hygiene-scan tier-1 promotion 2026-04-28 --> These per-maintainer distillations show what's currently in force. Raw memories below are the history; CURRENT files are the projection. (`CURRENT-aaron.md` refreshed 2026-04-28 with sections 26-30 — speculation rule + EVIDENCE-BASED labeling + JVM preference + dependency honesty + threading lineage Albahari/Toub/Fowler + TypeScript/Bun-default discipline.)

- [**actions/cache paths mutually exclusive with git ls-files — silent-clobber bug class (Aaron 2026-05-03 "make it not lucky next time")**](feedback_actions_cache_paths_mutually_exclusive_with_git_ls_files_silent_clobber_class_aaron_2026_05_03.md) — Cache hit OVERWRITES checked-out source content; PR edits silently revert; CI tests OLD content but reports as PR's new state. Surfaced via CircuitRegistration B-0180 fix passing locally + failing CI. Carved-sentence rule + `audit-ci-cache-paths.ts` + CI lint gate prevent recurrence.
- [**Chat is assertion-channel, not fact-channel — push-back-with-evidence is the discipline (Aaron 2026-05-03)**](feedback_chat_is_assertion_channel_not_fact_channel_push_back_for_evidence_aaron_2026_05_03.md) — Chat-claims (maintainer's, architect's, external-AI's) are assertions needing evidence to elevate to architectural fact. *"when i speak i'm making assertions, that's the best way to describe this chat channel"* + push-back-required-even-when-he-asserts. Triggered by #1385 echoing "maybe" as architectural fact.
- [**Carved sentences + specialized index required — memories alone unreliable retrieval (Aaron 2026-05-03)**](feedback_carved_sentences_plus_specialized_index_required_memories_alone_unreliable_aaron_2026_05_03.md) — Memory file ≠ working memory. Empirically self-demonstrated: Otto authored speculative-vs-frontier memo, then ~6h later defaulted to the framing it corrects. CLAUDE.md / AGENTS.md / equivalent are the auto-loaded retrieval index for the beacon-safe layer.
- [**Mirror-vs-beacon-safe register architecture — publication boundary as backpressure (Claude.ai 2026-05-03 verbatim packet)**](../docs/research/2026-05-03-claudeai-mirror-vs-beacon-safe-publication-boundary-as-backpressure.md) — Mirror = internal/named-agent register (overgenerates); beacon-safe = external/end-user-persona register (conversion-pruned). Publication discipline IS the gate; no separate mechanism needed. Diamond framing: mirror=solution, beacon-safe=crystal, conversion=pressure. Multi-AI BFT review = conversion-quality control.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
name: actions/cache paths are mutually exclusive with git ls-files — silent-clobber bug class
description: Carved-sentence discipline rule. actions/cache paths must NOT overlap git-tracked files. Cache hit OVERWRITES checked-out source content with cached versions; PR edits silently revert; CI tests OLD content but reports as PR's new state. Surfaced empirically via CircuitRegistration Safety fix passing locally + failing CI; root-caused by verify-then-claim sweep.
type: feedback
---

**Rule:** `actions/cache` paths in `.github/workflows/*.yml` MUST be
mutually exclusive with `git ls-files`. Cache only DERIVED files
(downloaded jars, built artefacts, user-home tool state), never
source-controlled content.

**Bug-locus disambiguation (Aaron 2026-05-03):**
This is a **usage bug in our workflow configuration**, not a bug in
`actions/cache` or GitHub Actions. The cache action does exactly
what its docs promise: restores cached files at the configured
paths, overwriting whatever's there. We asked it to cache a path
that contained source-controlled files — it did. The fix is on our
side: narrow the cache path so it doesn't overlap source-controlled
content. A reasonable upstream feature request (warning when cache
path overlaps with checked-out git content) would be an
enhancement, not a bug fix, since the existing behavior is
documented.

**Why this is load-bearing:**

When `actions/cache` restores on a cache hit, it OVERWRITES the
freshly-checked-out source files with the cached versions. If the
cache path is a directory and that directory contains source-
controlled files, those files revert to whatever was in the cache
when it was first warmed.

**Failure mode (silent + invisible):**

1. PR modifies a source-controlled file under a cached path
2. CI checkout brings in the PR's new version
3. `actions/cache` step restores → OVERWRITES with cached old version
4. Build / test runs against OLD content
5. Test report claims PR's new content was tested ✓
6. PR merges based on stale test results

The bug only surfaces when the PR's edit introduces a NEW operator
referenced by a config (or analogous fail-loud condition) — because
then the silently-restored old content FAILS the new check, instead
of falsely-passing on stale state. Discovery-by-luck class.

**Triggering case (2026-05-03):**

CircuitRegistration `Safety` invariant fix (B-0180):

- Local: `Model checking completed. No error has been found.`
3538 states / depth 14
- CI: `Error: The invariant Safety specified in the configuration
file is not defined in the specification.`

Diff: local ran the new spec; CI's `actions/cache@v5` step cached
`tools/tla` (whole dir, including `specs/`) and restored old content
that DIDN'T have the `Safety` operator. CI tested the OLD spec.

**How to apply:**

1. **At workflow-author-time:** when adding an `actions/cache` step,
the path MUST be specific to derived files. If the natural-feeling
path is a whole directory, ask: does that directory contain ANY
source-controlled file? If yes, narrow.

2. **At verify-then-claim-time:** when a CI test fails on a config
that works locally with the same toolchain version + same input,
first hypothesis: "is CI testing the same content I'm testing?"
Compare the failure error against pre-PR state. If the failure is
"old behavior", suspect cache clobber.

3. **Structurally enforced:** `tools/hygiene/audit-ci-cache-paths.ts`
parses every `actions/cache` `path:` and flags any overlap with
`git ls-files`. Wired as CI lint via
`.github/workflows/ci-cache-paths-lint.yml`. Future cache-clobber
bugs cannot land silently — this gate fails the workflow with
self-diagnosing output.

**Carved sentence (for retrieval):**

> *"actions/cache paths are mutually exclusive with `git ls-files` —
> cache only DERIVED files (downloaded jars, built artefacts, user-
> home tool state), never source-controlled content."*

**Composes with:**

- **Otto-272 DST-everywhere + Otto-281 DST-exempt-is-deferred-bug:**
cache-clobber is a non-determinism source (CI tests different
content than local); same discipline class as flaky tests.
- **Verify-then-claim:** the failure mode is silent-pass; verify-
then-claim ("does CI actually run what I think it runs?") is the
catch.
- **Test-fidelity contract:** the math-proofs honest assessment's
A-grade rubric requires "Runs in CI on every commit" — but that
presupposes CI runs the COMMIT'S content, not cached content.
Cache clobber breaks the rubric silently.
- **CI-on-CI audit pattern:** the same shape applies to other
meta-properties of CI workflows (e.g., timeouts not being too
short to actually run the work; required-status-checks matching
the workflow's job names; etc.). Future audits in this family
follow the cache-paths audit's pattern: parse YAML, check against
invariant.

**Tooling lineage:**

- `tools/hygiene/audit-ci-cache-paths.ts` — the audit
- `.github/workflows/ci-cache-paths-lint.yml` — the CI gate
- `.github/workflows/gate.yml` (post-fix narrowing) — the canonical
pattern (path: jar files only, not directories)
- `.github/workflows/low-memory.yml` (post-fix narrowing) — same

**Future-Otto reference:**

When tempted to write `path: tools/<dir>` or `path: src/<dir>` in an
`actions/cache` step: STOP. Cache the specific file or files that
are DOWNLOADED or BUILT, not the directory containing them. If the
cache key is currently producing a wide directory cache, rebuild it
narrowly + bump the key suffix to bust stale state.

When CI fails on a test that works locally: suspect cache clobber
BEFORE suspecting test bug. The audit gate should catch new
violations; if you're seeing this on an existing workflow, the gate
may have a parity bug or your PR introduced a new path that the
audit's parser missed.

**Reasoning lineage:** Aaron 2026-05-03 *"lucky catch how can you
make it not lucky next time for same class or similar class"* —
triggered after the CircuitRegistration B-0180 fix surfaced the
silent-clobber bug. Substrate response: audit + lint gate + this
memory file.
Loading