Skip to content

A reuse keeps what a person decided after the agent read it - #1288

Merged
WaylandYang merged 3 commits into
deeplethe:devfrom
Maya-Kid:fix/reuse-keeps-later-person-decisions
Oct 16, 2026
Merged

WaylandYang merged 3 commits into
deeplethe:devfrom
Maya-Kid:fix/reuse-keeps-later-person-decisions

Conversation

@Maya-Kid

Copy link
Copy Markdown
Contributor

Second of three PRs from my adoption plan on #725; the first merged as #1257.

Problem

0061's decision 3 says "A signature a person decided stays as the person left it", but not against what. On dev 040a533 a reuse (map_to) writes every shape and kind word it names as the adopter's binding. If a colleague binds one of them elsewhere after the agent read it, adopting overwrites that binding (for a shape, also writing a regression case for the proposal's property) and answers {id}. Nothing tells the adopter, and a reuse whose every item was decided that way is still adopted.

Change

  • What the agent read. For a reuse, propose_locked stores the decided_at of each binding it read: seen_decided_at on each shape, and a kind_words_seen_decided_at map in signatures. merge_map_to keeps the first round's values.
  • Keep rule. Adoption locks each binding row FOR UPDATE before reading it. A person's decision whose decided_at differs from the recorded read was made after it. The check is equality, not order: decided_at is the deciding transaction's start, so a decision begun before the read can commit after it. With no recorded read (a proposal saved before this change) every person's decision is kept, with no created_at fallback (Review queues are organised by what a decision changes #725's no-legacy rule).
  • Agreeing and differing. A later decision with the same property and direction, or the same class, counts as written: it is not rewritten or listed, and a shape keeps its regression case. A differing one stays, gets no case, and is listed in skipped with the person's decision. A reuse with nothing left to write answers 409 proposal_stale and writes nothing.
  • Response and workbench. POST /ontology/proposals/adopt answers {id, skipped}. When decisions were kept, the toast says how many; proposal_stale gets en and zh strings.
  • Adopting a proposal commits the element, its follow-up work and the decision together #1257 review follow-ups. A class reuse queues align_phrases only when it wrote a kind word, alignment_busy gets en and zh strings, and api.decideProposal accepts only "rejected".
  • Docs. A dated revision note under 0061's decision 3.

Verification

a_reuse_keeps_what_a_person_decided_after_the_agent_read_it runs two propose rounds against a scripted model, then adopts four reuses and one seeded without read times:

  • a person's none made before the read is replaced, on a shape and on a kind word whose row the second round extended;
  • later bindings elsewhere stay and are listed: a kind word's, and a shape's committed while the adoption waits for its row, its decided_at a day before the read;
  • a later agreeing shape binding is not rewritten and keeps its case;
  • a class reuse whose only kind word was later bound the same way answers 200, lists nothing and queues no align_phrases;
  • the reuse whose only kind word was later bound elsewhere, and the seeded one over a person's binding, answer 409 and add no job or case.

On dev 040a533 with only this test, it fails at the first adoption (200, no skipped): dev rewrites all seven bindings, the colleague's too, and adopts every reuse.

Linux x86_64 container, Rust 1.98.1, PostgreSQL 16.15 + pgvector 0.8.6, Poppler 25.03, DB required (UTOPIA_TEST_REQUIRE_DB=1), node 20 for web, commit 54ac182 on dev 040a533: cargo fmt --all --check and clippy clean; cargo test --locked --workspace 1,576 passed, 0 failed, 6 ignored; web pnpm test 281 passed, pnpm build clean.

Limits

  • No version check yet: a proposal refreshed after the person read it is adopted as it now stands.
  • A binding row deleted since the agent read it (a class or property deletion cascades) cannot be locked; a person's new decision on it committing meanwhile can be overwritten.

@WaylandYang WaylandYang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you. Recording the decided_at the agent read and comparing by equality is right, and locking each binding row before reading it means a colleague's decision that commits during the adoption is kept and listed in skipped rather than overwritten; the test checks that by committing while the adoption waits. The #1257 follow-ups are all in. Two optional simplifications for later: build the skipped shape from the proposal's own shape rather than restating same_shape's four keys, so the regression-case filter can't drift from it; and now that alignment_busy is in the global error table, reviewErrors.ts could use that entry instead of keeping a second translation. Merging.

@WaylandYang
WaylandYang merged commit 86bd5da into deeplethe:dev Oct 16, 2026
6 checks passed
@Maya-Kid
Maya-Kid deleted the fix/reuse-keeps-later-person-decisions branch October 16, 2026 23:29
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.

2 participants