GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix topic cycle detection past 32 nodes by ben564885 · Pull Request #60 · AlmanacCode/codealmanac

Conversation

@ben564885

@ben564885 ben564885 commented Jul 31, 2026

Copy link
Copy Markdown

fixes #59.

ancestors_of counted popped nodes instead of levels, so depth < 32 capped total iterations rather than depth. the walk stopped after 32 nodes and returned an incomplete ancestor set, so reject_cycle reported clean and wrote the cycle to topics.yaml. nothing downstream re-checks it, so the corrupt graph was permanent.

dropping the counter is enough: the existing if parent in ancestors: continue guard already bounds the walk to the node set, so it terminates on graphs that are already cyclic. a real depth cap was the alternative, but it would still miss cycles past the bound, and completeness matters more than parity with the descendants query.

tests/test_architecture.py asserted the literal "depth < 32", which pinned the bug in place. that assertion now checks the termination guard instead.

two regression tests: a 34-topic chain (the smallest that outran the old cap) and a wide two-level graph, which used to pass or fail depending on PYTHONHASHSEED because the frontier is seeded from a set. both fail on main and pass here.

pytest 566 passed, ruff check . clean, git diff --check clean, cli smoke ok.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
chatgpt-codex-connector[bot]
chatgpt-codex-connector Bot reviewed Jul 31, 2026
View reviewed changes

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bd19d43a99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/codealmanac/services/topics/graph.py
depth = 0
while frontier and depth < 32:
depth += 1
while frontier:

@chatgpt-codex-connector chatgpt-codex-connector Bot Jul 31, 2026

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

P2 Badge Update the Almanac depth-cap contract

With the traversal cap removed here, the shipped Almanac pages now describe the opposite contract: almanac/architecture/wiki/topics-dag.md:59, almanac/reference/topics-yaml.md:71, and almanac/guides/maintain-topics.md:95 still say ancestor/cycle traversal has a defensive depth cap of 32. That leaves the repo-local wiki misleading future agents about the mutation invariant and why the walk is safe, so please update those pages to say the walk is bounded by visited topics rather than by depth.

AGENTS.md reference: AGENTS.md:L8-L15

Useful? React with 👍 / 👎.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
ben564885 and others added 2 commits July 31, 2026 00:47
@ben564885 @bennisev-dev
fix(topics): detect cycles beyond 32 topic nodes
9718f85
@bennisev-dev
almanac: drop the removed ancestor depth cap from the topics pages
49f48d5
The parent commit removed the `depth < 32` counter from `ancestors_of`, but
topics-dag.md, topics-yaml.md, and maintain-topics.md still described a
defensive depth cap of 32 as the reason the ancestor walk is safe. That
left the wiki stating the opposite of the shipped mutation invariant.

All three now say the walk is bounded by the visited topic set rather
than by depth, which is what makes it terminate on an already-cyclic
topics.yaml without truncating the ancestor set. topics-dag.md also
records why the old counter was wrong (it counted popped nodes, not
levels) so the cap does not get reintroduced.
@ben564885
ben564885 force-pushed the fix-topic-cycle-detection branch from 26412d4 to 49f48d5 Compare July 31, 2026 07:48
@Hotragn

Hotragn commented Sep 5, 2026

Copy link
Copy Markdown

@ben564885 I reproduced this against ancestors_of directly rather than through the CLI, and your diagnosis is exactly right — including the 33-vs-34 boundary you called out. A/B on the same script:

On main:

chain  33: ancestors= 32/32 OK         reject_cycle -> cycle rejected
chain  34: ancestors= 32/33 INCOMPLETE reject_cycle -> NOT CAUGHT
chain  60: ancestors= 32/59 INCOMPLETE reject_cycle -> NOT CAUGHT
chain 200: ancestors= 32/199 INCOMPLETE reject_cycle -> NOT CAUGHT

On this branch:

chain  33: ancestors= 32/32 OK         reject_cycle -> cycle rejected
chain  34: ancestors= 33/33 OK         reject_cycle -> cycle rejected
chain  60: ancestors= 59/59 OK         reject_cycle -> cycle rejected
chain 200: ancestors=199/199 OK        reject_cycle -> cycle rejected

The removal is safe, and here is the proof a reviewer will want. The obvious worry with deleting a loop bound is non-termination. It cannot happen here: if parent in ancestors: continue plus ancestors.add(parent) means every slug is expanded at most once, so the frontier is bounded by the number of definitions. Confirmed against a graph that already contains a cycle:

pre-existing cycle: ancestors_of(a) = ['a', 'b', 'c'] -> terminated

That terminates identically on main and on this branch — so the visited set was always what guaranteed termination, and depth < 32 was never load-bearing for it. It only ever truncated correct answers.

Why this survived, which is worth flagging for the maintainers: tests/test_architecture.py asserted

assert "depth < 32" in graph_text

so the test suite was actively pinning the defect in place. Anyone who noticed the cap and tried to remove it would have gone red and probably assumed the cap was intentional. Changing that assertion to "if parent in ancestors:" is the honest fix, and I mention it only because an architecture-test change can look like weakening a guard when here it is the opposite.

I suspect the 32 came from CLAUDE.md's "depth cap of 32 on any recursive CTE" non-negotiable. That rule is about the SQL recursive CTEs in the read model, where there is no visited set and a bound is genuinely needed. ancestors_of is an in-Python walk that already has one, so the cap was a misapplication of that rule rather than a second layer of it — the "belt-and-suspenders" here is the visited set. If anyone still wants an explicit bound as defence in depth, len(definitions) would be the correct one; 32 is a magic number unrelated to anything in the graph.

Two small notes, neither blocking: frontier.pop() makes this a DFS, which is fine since you need the full ancestor set rather than shortest paths. And the docs touch-ups in almanac/ are right to be in the same PR, since the old wording described the capped behaviour.

I'd merge this as-is. Verified on Windows 11 / Python 3.13; uv run ruff check . clean and the topics tests pass. I have some unrelated PRs open (#64/#65/#66/#68/#69) and none of them touch services/topics/.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@chatgpt-codex-connector chatgpt-codex-connector[bot] chatgpt-codex-connector[bot] left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

topic cycle detection silently fails past 32 nodes

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@ben564885 @Hotragn @bennisev-dev
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.