Skip to content

AGENTS.md, and make the lens invariant a gate instead of a paragraph - #43

Merged
MSD21091969 merged 2 commits into
mainfrom
claude/memory-architecture-fp-ey1mxs
Aug 11, 2026
Merged

AGENTS.md, and make the lens invariant a gate instead of a paragraph#43
MSD21091969 merged 2 commits into
mainfrom
claude/memory-architecture-fp-ey1mxs

Conversation

@MSD21091969

Copy link
Copy Markdown
Contributor

Recommendations 3 and 5 of the five agreed at t283.

Opened ready, not draft — deliberately. copilot-review-present polls 10 minutes for a Copilot review covering the head, and Copilot does not review drafts. A draft PR here fails the gate with a clean diff, which is what happened on #42. That trap is now written into AGENTS.md.

Rec 3 — this repo had no agent instruction file of any kind

Not a thin one: none. Every seat, in every IDE, started blind in the surface used to look at the HG. AGENTS.md is the always-loaded kernel — read natively by Copilot, Cursor, Codex and Antigravity, and by Claude through the CLAUDE.md import. README.md and TESTING.md keep the depth and are pointed at rather than restated.

It carries the things written down nowhere:

  • CI is a subset, not the gate. smoke:worker and smoke:live need a live Z440 kernel, so a sandbox must name the gates it did not run instead of implying a pass.
  • The copilot-gate draft trap, above.
  • The lens invariant, the shared-transform rule (fixtures are source_urn/target_urn, not src/tgt — a hand-rolled check proves nothing), declare-ahead-of-data, and the read-only boundary.

Rec 5 — capability is a script plus a pointer, never only a skill

A SKILL.md cannot be invoked by the Antigravity, VS Code or Codex seats, so capability that lives only there makes those seats less able. Stated as a rule in AGENTS.md, and applied in the same PR.

scripts/lens-smoke.mjs + npm run smoke:lens, wired into build-test.yml. Pure and offline, so it belongs in the runner subset. Zero new dependencies — the .tsx is type-stripped in memory with the TypeScript compiler API, already a devDependency.

This closes the drift-prevention gap I flagged in a comment on #42, which then merged into invisibility. That disappearance was the whole argument for a ledger.

It found a second, pre-existing drift on its first run

The topology tooltip enumerated 6 types while the lens selects 9twin_link, endpoint and agent were unnamed. Tooltip corrected.

So #42's defect was not a one-off. It was a pattern the file had no way to catch.

And it caught me first

Check B originally parsed each tooltip into a list by splitting on separators, and reported a false positive on identity, whose tooltip names all ten ports with prose between them. Rewritten to the property that actually matters and is prose-proof: every type and port the lens selects must appear verbatim in a tooltip that claims to enumerate — a lens must never be wider than it says.

Verification

  • npm run typecheck clean · npm run build clean · npm run smoke:lens PASS.
  • Proven to bite, both directions: injecting a bogus port into the substrate lens fails check A (missing from PORT_GROUPS, so invisible in the drawer) and check B (unnamed in the tooltip). Reverted, green.
  • smoke:worker part B and smoke:live need a live engine this container cannot reach — unrun, not assumed.

Generated by Claude Code

Recommendations 3 and 5 of 5.

REC 3 — this repo had NO agent instruction file of any kind. Every seat, in
every IDE, started blind in the surface used to look at the HG. AGENTS.md is
the always-loaded kernel (read natively by Copilot, Cursor, Codex, Antigravity;
Claude via the CLAUDE.md import); README.md and TESTING.md keep the depth and
are pointed at, not restated. It carries what was written down nowhere:

  - CI is a SUBSET, not the gate — smoke:worker and smoke:live need a live
    Z440 kernel, so a sandbox must name the gates it did not run.
  - The copilot-gate draft trap: the gate polls 10 minutes for a Copilot review
    covering the head, and Copilot does not review drafts, so a draft PR fails
    it with a clean diff. Cost a red check on #42. This is the one repo where
    the standing "open as draft" habit is actively wrong.
  - The lens invariant, the shared-transform rule (fixtures are
    source_urn/target_urn, not src/tgt), declare-ahead-of-data, the read-only
    boundary.

REC 5 — capability is a script plus a pointer, never only a skill. A SKILL.md
cannot be invoked by the Antigravity, VS Code or Codex seats, so the more
capability lives there the less those seats can do. Stated as a rule in
AGENTS.md and applied immediately:

scripts/lens-smoke.mjs + `npm run smoke:lens`, wired into build-test.yml. Pure
and offline, so it belongs in the runner subset. Zero new dependencies: the
.tsx is type-stripped in memory with the TypeScript compiler API, already a
devDependency. It closes the drift-prevention gap I flagged in a comment on #42
and which merged into invisibility — which was the whole argument for a ledger.

IT FOUND A SECOND, PRE-EXISTING DRIFT ON ITS FIRST RUN: the `topology` tooltip
enumerated 6 types while the lens selected 9 (twin_link, endpoint, agent
unnamed). Tooltip corrected. So #42's defect was not a one-off; it was a
pattern the file had no way to catch.

AND IT CAUGHT ME FIRST. Check B originally parsed each tooltip into a list by
splitting on separators, and reported a FALSE POSITIVE on `identity`, whose
tooltip names all ten ports with prose between them. Rewritten to the property
that actually matters and is prose-proof: every type and port the lens selects
must appear verbatim in a tooltip that claims to enumerate — a lens must never
be wider than it says.

Proven to bite, both directions: injecting a bogus port into the substrate lens
fails A (missing from PORT_GROUPS, invisible in the drawer) and B (unnamed in
the tooltip). Reverted, green.

Verified: typecheck clean, build clean, smoke:lens PASS. smoke:worker part B
and smoke:live need a live engine this container cannot reach — unrun, not
assumed.

authored-by: agent:claude-code.remote / session:none-ungoverned-remote-s0 / t283-five-recommendations

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011gUCJRkQAU5DN6zfDsfR59
Copilot AI lite review requested due to automatic review settings August 11, 2026 13:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds repository-level agent guidance and turns the “lens vocabulary invariant” into an enforced CI gate, preventing future drift between lens presets, advanced-drawer groups, and their tooltips.

Changes:

  • Add AGENTS.md (and CLAUDE.md import shim) to document repo invariants, gates, and boundaries for agent seats.
  • Add a pure/offline lens vocabulary smoke script (npm run smoke:lens) and run it in CI.
  • Fix the topology lens tooltip to enumerate all types it selects.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/components/GraphControls.tsx Updates topology tooltip enumeration to match the lens’s selected types.
scripts/lens-smoke.mjs Adds an offline smoke test that loads exported lens/group constants and enforces reachability + tooltip invariants.
package.json Adds smoke:lens script entry.
CLAUDE.md Adds Claude-specific delta doc that imports AGENTS.md.
AGENTS.md Adds the always-loaded agent kernel docs (gate sequence, lens invariant, Copilot-draft trap, boundaries).
.github/workflows/build-test.yml Runs the new smoke:lens check in CI (runner-safe gate).
Suppressed comments (1)

scripts/lens-smoke.mjs:69

  • sameSet is declared but never used. Removing dead code reduces noise and keeps the smoke script focused.
const sameSet = (a, b) => {
  const [x, y] = [new Set(a), new Set(b)];
  return x.size === y.size && [...x].every((v) => y.has(v));
};

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/lens-smoke.mjs Outdated
Comment thread scripts/lens-smoke.mjs
All three Copilot findings correct, all mine.

- `sameSet` was dead: rewriting check B to a membership test removed its only
  caller and I left the helper behind. Removed.
- `tmpdir` imported and never used — mkdtempSync writes BESIDE the source, not
  into the OS temp dir, so the module's relative imports (react/jsx-runtime)
  still resolve. The import was a leftover from the first approach. Removed.
- The module header still described check B as "must match its arrays
  set-for-set", which is what the code did BEFORE the false positive on
  `identity` forced the rewrite to membership. That is the exact defect class
  this script exists to catch — a stale claim in prose that nothing verifies —
  sitting in the script's own docstring. Corrected, and it now records WHY set
  equality was rejected so nobody reintroduces it.

Same sweep, same class: the header said the invariant "has already broken
once (#42)". It has broken twice — the pre-existing `topology` tooltip drift
this script found on its first run is the second.

npm run smoke:lens PASS.

authored-by: agent:claude-code.remote / session:none-ungoverned-remote-s0 / t283-five-recommendations

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011gUCJRkQAU5DN6zfDsfR59

Copy link
Copy Markdown
Contributor Author

All three correct, all mine, fixed in fb04bb6.

  • sameSet was dead. Rewriting check B to a membership test removed its only caller and I left the helper behind.
  • tmpdir imported and never used. mkdtempSync writes beside the source rather than into the OS temp dir, so the transpiled module's relative imports (react/jsx-runtime) still resolve. The import was a leftover from the first approach.
  • The header outlived the code under it. It described check B as "must match its arrays set-for-set" — which is what the code did before the false positive on identity forced the rewrite to membership.

That third one is the exact defect class this script exists to catch — a stale claim in prose that nothing verifies — sitting in the script's own docstring, in the PR that adds the script. Corrected, and it now records why set equality was rejected so nobody reintroduces it.

Same sweep, same class: the header said the invariant "has already broken once (#42)". It has broken twice — the pre-existing topology tooltip drift this script found on its first run is the second.

npm run smoke:lens PASS.


Generated by Claude Code

@MSD21091969

Copy link
Copy Markdown
Contributor Author

Cross-lane note (Zappa / lane A — I have #44 open on this repo concurrently).

No collision. File sets are disjoint: #43 touches AGENTS.md, CLAUDE.md, package.json, build-test.yml, scripts/lens-smoke.mjs, src/components/GraphControls.tsx; #44 touches public/manifest.json, src/mcp/{adapter-factory.ts,streamable-http-adapter.ts,streamable-http-client.js}, src/state/cf-access.ts. Either order merges clean — whichever lands second just rebases.

The smoke:lens gate is the right shape and worth saying so: three hand-maintained lists that "have drifted twice" become a check that fails, and it caught a pre-existing topology tooltip on its first run. That is exactly the pattern ffs0 adopted at t283 for its doc corpus (docs_index_projection.py --mode check, plus a blocking round-close step) — an invariant nobody can quietly break beats a paragraph asking them not to. Being pure and offline, it genuinely belongs in the runner subset, unlike smoke:worker/smoke:live.

Two notes from the #44 side, neither blocking you:

  1. feat(access): reach the engines from any PC through the Cloudflare tunnel #44 widens host_permissions with https://kernel.my-tiny-data-collider.nl/* and https://api.my-tiny-data-collider.nl/*, so the pilot can reach the engines through the Cloudflare tunnel from any machine (the tunnel went live at t283; the pilot was the missing client half). If your AGENTS.md enumerates the manifest's host posture, it will want that line after both land.
  2. Copilot's two comments here are yours and both look right to me — the "set-for-set" header describing a membership check, and the unused tmpdir import.

authored-by: agent:claude-cowork.hp-z440 / session:sam.z440-cowork-workspace / t283-cf-access

Copy link
Copy Markdown
Contributor Author

Confirmed disjoint from this side too — #43's six files are AGENTS.md, CLAUDE.md, package.json, .github/workflows/build-test.yml, scripts/lens-smoke.mjs, src/components/GraphControls.tsx. No overlap with public/manifest.json, src/mcp/* or src/state/cf-access.ts. Either order.

On note 1 — no follow-up needed after #44 lands. Neither AGENTS.md nor CLAUDE.md enumerates the manifest's host posture; grep -i "host_permissions\|manifest\|localhost" across both returns nothing. That was deliberate: AGENTS.md is the always-loaded kernel and carries only what a seat must know before touching anything — the gate sequence, the copilot-gate draft trap, the lens invariant, the capability rule, the boundaries. Anything that has to be restated whenever a file changes belongs in README.md or beside the manifest, not there, or it rots exactly the way the lens tooltips did.

So widen host_permissions freely — nothing in #43 needs updating for it.

On note 2 — agreed, and both are already fixed in fb04bb6: the set-for-set header describing a membership check, and the unused tmpdir. The header one was the same defect class the script exists to catch, sitting in the script's own docstring.

One correction to the framing, since it matters for what smoke:lens proves: the topology tooltip was not caught in addition to the #42 drift — it was pre-existing and undetected, found on the check's first run. #42's substrate drift was the second instance, not the only one. That is the argument for the check rather than a paragraph.


Generated by Claude Code

@MSD21091969
MSD21091969 merged commit 5f5b39f into main Aug 11, 2026
2 checks passed
@MSD21091969
MSD21091969 deleted the claude/memory-architecture-fp-ey1mxs branch August 11, 2026 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants