Skip to content

fix(core): a resource recorded twice replays as one node - #1440

Merged
lex00 merged 1 commit into
mainfrom
fix/dependency-duplicates-managed
Aug 3, 2026
Merged

fix(core): a resource recorded twice replays as one node#1440
lex00 merged 1 commit into
mainfrom
fix/dependency-duplicates-managed

Conversation

@lex00

@lex00 lex00 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

A replay already dropped an ambient entry whose physical resource some stack manages, on this reasoning:

Ambient means "nothing manages this". Another stack managing it makes that false, and reporting it twice would inflate any count over it.

The same is true of a dependency. Being referenced does not stop a resource being managed, and a subnet its own stack declares is also recorded as a dependency because instances point at it:

publicSubnet       physicalId=subnet-9af06b90  referencedBy=None      ← managed
subnet-9af06b90    physicalId=subnet-9af06b90  referencedBy=[webServer, launchTemplateServer]

Two entries, one subnet. An estate holding 13 subnets replayed as 16.

Why it is not cosmetic

kind:EC2::Subnet !<-kind:EC2::NetworkInterface answered 11 where the truth was 8 — and the three extra were the three occupied subnets.

A duplicate always reads as empty. The interface edges resolve to one copy, so the other has nothing pointing at it and passes every "nothing references this" filter. The wrong answer was not a vague over-count; it was three specific false positives, each a subnet that demonstrably had something in it.

This is the second half of what #1437 fixes. That one made the ENI→subnet relationship traversable at all; without this one the query goes from "every subnet" to "every empty subnet plus every duplicate", which is closer and still wrong.

Dropping the node alone would have been a different bug

buildLiveGraphIr discards an edge whose endpoints were not both observed. Removing the duplicate without moving its edges would have left the instance in no subnet at all — trading an over-count for missing topology. The duplicate's edges are re-pointed at the resource that survived it, and a test pins that specifically.

What is deliberately untouched

A dependency that nothing manages — the account's default route table, the archetype the original comment was written for — survives exactly as before. There is a test for it, because it is the case this change could plausibly have broken.

Three tests; the two that assert the fix fail without it, checked by stashing. Full suite 10466 passed, 5 skipped. Typecheck and lint clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_014KoduiMJRyLqjFYBUbMskE

lex00 added a commit to INTENTIUS/chant-bench that referenced this pull request Aug 3, 2026
5/6, up from 3/6. The subnet question went 1/3 to 3/3; the VPC question is
unchanged at 2/3, which was predicted rather than hoped for.

Two more chant defects, both pre-existing and both found by measuring rather
than reading:

- **INTENTIUS/chant#1437** — `AWS::EC2::NetworkInterface -> Subnet` was declared
  as containment with no traversal name, so `reconstructEdges` recorded a
  boundary hint and emitted no edge. `kind:EC2::Subnet
  !<-kind:EC2::NetworkInterface` — the query the grammar exists to express —
  matched 23 of 23 subnets. An inert negation is indistinguishable from one that
  searched and found nothing.
- **INTENTIUS/chant#1440** — a subnet its own stack declares is also recorded as
  a dependency, so 13 subnets replayed as 16. A duplicate always reads as empty,
  because the edges resolve to the other copy: the three false positives were
  the three OCCUPIED subnets.

Each of the four fixes was necessary and none was sufficient. Measured against
the estate at each stage, the query returned 5 (one region visible), 7 (regions
merged), 11 (negation inert), 11 (duplicates read as empty), and finally 8 —
the correct 8, keeping us-east-1's occupied default-c out.

The VPC question stays at 2/3 because containment INTO a VPC is deliberately not
traversable — `reference-catalog.test.ts` asserts it — and flipping that to
improve this number is a decision for its own change, not a side effect of this
one. Left on #1437.

## The page now shows every run

A second run of an arm is usually a different build, and which build produced a
number is the whole question this repo exists to keep answerable. Showing only
the newest quietly dropped the evidence that the number moved, so both runs are
listed with their workspace fingerprints — which is what says they are not the
same experiment.

Refs #27

Claude-Session: https://claude.ai/code/session_014KoduiMJRyLqjFYBUbMskE

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
A replay dropped an AMBIENT entry whose physical resource some stack manages,
on the reasoning that "ambient means nothing manages this — another stack
managing it makes that false, and reporting it twice would inflate any count
over it".

The same is true of a dependency. Being referenced does not stop a resource
being managed, and a subnet its own stack declares is also recorded as a
dependency because instances point at it:

    publicSubnet       physicalId=subnet-9af06b90  referencedBy=None
    subnet-9af06b90    physicalId=subnet-9af06b90  referencedBy=[webServer, …]

Two entries, one subnet. An estate holding 13 subnets replayed as 16.

Not cosmetic. "Which subnets have no network interfaces" answered 11 where the
truth was 8, and the three extra were the three OCCUPIED subnets — a duplicate
always reads as empty, because the interface edges resolve to the other copy.
The wrong answer was three false positives, each one a subnet that demonstrably
had something in it.

Dropping the node alone would have been a different bug: `buildLiveGraphIr`
discards an edge whose endpoints were not both observed, so the instance would
have stopped being in any subnet at all. The duplicate's edges are re-pointed at
the resource that survived it.

A dependency nothing manages — the account's default route table, the archetype
the original comment was written for — is untouched, and a test pins that.

Claude-Session: https://claude.ai/code/session_014KoduiMJRyLqjFYBUbMskE

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lex00
lex00 force-pushed the fix/dependency-duplicates-managed branch from 08c49ab to b14e283 Compare August 3, 2026 21:25
@lex00
lex00 merged commit 3d396cb into main Aug 3, 2026
5 checks passed
@lex00
lex00 deleted the fix/dependency-duplicates-managed branch August 3, 2026 21:37
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.

1 participant