Sweep the last three uses of the columns SP8 dropped

`seed_demo.py` still passed `index=0` to `models.Action`, which raises
`TypeError` now that the attribute is gone. Every call site inside `app/`
was updated when the column went, but the seed script sits outside the
package and was missed.

`bundle.settle` wrote `memory_cursor` and `summary_cursor`, which are no
longer mapped, so the assignments only set transient Python attributes.
The version 2 branch existed solely to make those assignments, and it ran
two queries per cursor to do it, so it goes. `settle` now returns early
when the bundle carries anchors. The `db` parameter is unused after that.

Also move the comment about deleted memories next to the
`db.delete(branch)` it describes. Splitting the router package left it
after the `finally`, where it read as attached to nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YFQY6WgaE3JaX3dXkxLynV
This commit is contained in:
parththakkar106
2026-08-30 18:43:40 +05:30
co-authored by Claude Opus 5
parent 20f0753277
commit 949f58a054
3 changed files with 16 additions and 28 deletions
+11 -20
View File
@@ -587,31 +587,22 @@ def _write_anchors(
cursor.anchor(adventure, ids[branch] if branch is not None else None, depth)
def settle(db: Session, adventure: models.Adventure, story: dict) -> None:
"""Aligns the two coordinate systems, once the nodes exist.
def settle(adventure: models.Adventure, story: dict) -> None:
"""Resolves a version 1 bundle's counts into anchors, once the nodes exist.
The anchors and the legacy counts describe the same boundary in different
terms, and each version of the bundle carries one of them. A version 1 file
carries the count, so the anchor is found by counting that far along the
story. A version 2 file carries the anchor, so the count is read back from
it. The legacy columns are written either way, because a rolled-back build
reads them.
A version 1 file records how far the memories and the summary have read as
a count, so the anchor is found by counting that far along the story. A
version 2 file carries the anchor itself, which `_write_anchors` has
already stored, so there is nothing left to do.
The caller runs this after the flush, because both directions need the
actions to be queryable.
The caller runs this after the flush, because counting needs the actions to
be queryable.
"""
positions = story["positions"]
if positions is None:
return
for cursor in cursors.ALL:
if positions is not None:
setattr(adventure, f"{cursor.name}_cursor", positions[cursor.name])
cursors.anchor_at_position(adventure, cursor, positions[cursor.name])
else:
setattr(
adventure, f"{cursor.name}_cursor",
cursors.position_of(adventure, cursor.depth(db, adventure)),
)
def materialize(
@@ -673,7 +664,7 @@ def materialize(
write(db, adventure, story)
db.flush()
db.expire(adventure, ["actions"])
settle(db, adventure, story)
settle(adventure, story)
return adventure
# ------------------------------------------------------------------ reading
+3 -6
View File
@@ -190,18 +190,15 @@ def delete_branch(
stored_branch, _ = cursor.stored(adventure)
if stored_branch in doomed:
cursor.clear(adventure)
# The deleted branch's memories are deleted with it, and their cached
# vectors drop out of the catalogue on the next read, so no
# invalidation call is needed. See the note on the `memorybank` cache.
db.delete(branch)
adventure.updated_at = models.utcnow()
db.commit()
finally:
turns._active_turns.discard(adventure_id)
# The deleted branch's memories are deleted with it, and their cached
# vectors drop out of the catalogue on the next read, so no invalidation
# call is needed. See the note on the `memorybank` cache.
def _branch_subtree(
db: Session, adventure: models.Adventure, root: models.Branch
) -> set[int]:
+1 -1
View File
@@ -252,7 +252,7 @@ try:
for position, s in enumerate(SCRIPTS):
db.add(models.AdventureScript(adventure_id=adventure.id, position=position, **s))
opening = models.Action(
adventure_id=adventure.id, index=0, type="start", text=scenario.prompt
adventure_id=adventure.id, type="start", text=scenario.prompt
)
# Through the same door create_adventure uses, so the seeded adventure has a
# story tree like every other one.