export V2 approval-gate state as deferred V3 principal proposals (#516 / V3#12 item 4) - #1003
Merged
Conversation
V2's approval gate is platform-blind (approved_users keys on agent+chat only) while V3 principals bind per connector, so the exporter resolves platform with explicit provenance: group_chats rows are authoritative, DM ids fall back to a shape heuristic, and anything else is UNRESOLVED for the Phase-5 owner ceremony. Active groups without a gate row — the V2 orphaned-group failure class — are surfaced as their own status rather than dropped, and gate-pending inbound counts ride along so the old-lease-stop drain step has real numbers. Every emitted row is inventoryKind connector-binding with disposition defer-with-owner-approval: the V3 inspector classifies all of them INVENTORY_DEFERRED_OWNER_APPROVAL (verified on the real Mini DB — 13 rows, 0 fatals), keeping principal enablement an explicit owner decision at qualification instead of an import side effect. Detail fields follow the fatal-enforced connector-binding allowlist; rich provenance lives in the generated ceremony proposal document. Refs PinkyBotV3#12 item 4 (task #516). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ut, key safety, md escaping - held counts filter delivered=0: V2 checkpoints delivery by flag and retains the row, so delivered history was ordering phantom drains (real-data held corrected 21 -> 8) - undelivered pending rows with no gate row and no group row — the normal stranger-held-at-the-gate shape — now surface as pending-inbound-without-gate-row instead of silently vanishing - optional --lease-stop-record input reconciles the Phase-5 step-2 record when present: lease-stop-only chats surface as active-without-v2-state, every proposal carries a leaseStop marker, and the no-record path keeps the explicit manual cross-check line - source keys derive a charset-safe component (raw when schema-legal, tagged sha256 otherwise) so +phone/Unicode/whitespace ids cannot fatal SOURCE_KEY_INVALID; raw ids stay in conversationRef/legacyId - ceremony Markdown escapes pipes/backslashes and strips control chars from every DB-sourced cell — a crafted display name can no longer forge rows in the owner-decision artifact (regression test forges one and asserts it stays inert) - platform heuristic edges frozen parametrically: 13/14-16/17-20/21+ and the negative 16/17 boundary Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
Round 2 pushed (b302a23) — all five findings addressed plus the nonblocking edge-freeze:
29/29 tests, ruff clean, V3 inspector on fresh real-data export: ok, 0 fatals, 13× INVENTORY_DEFERRED_OWNER_APPROVAL. 🤖 Opened by Barsik |
Review round 2: a raw chat id shaped exactly like sha256-<24hex> shared a sourceKey with a hashed unsafe id — deterministic SOURCE_KEY_DUPLICATE. Prefix raw components with raw- so the namespaces cannot intersect, with a collision regression using an attacker-crafted digest-shaped raw id. Also strip DEL/C1 controls (U+007F..U+009F) in _md_cell as documented, and freeze the remaining heuristic edge lengths 15/18/19. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review round 3: a matching lease entry's platform was discarded — an unresolved V2 row stayed provider=unknown while the doc claimed RECONCILED, and a platform disagreement was silently marked confirmed by ID alone. Now a lease platform resolves V2-unresolved rows (platformSource=lease-stop-record, leaseStop=resolved-by-lease-stop), a disagreement keeps V2's value and surfaces platform-conflict(v2=...,lease=...) for the owner, conflicts get a summary count and ceremony checklist line, and lease titles backfill empty display names. Both cases frozen in tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Third exporter leg: V2 messaging-continuity state → V3 connector-principal proposals for the Phase-5 lease-transfer ceremony.
approved_usersis platform-blind; platform is resolved, never assumed —group_chatsrows authoritative, DM id-shape heuristic second (edges frozen parametrically: 1–13 telegram, 14–16 unresolved, 17–20 discord, 21+ unresolved, negative 16/17 boundary).UNRESOLVEDis settled by the lease-stop record when one is provided, else by the owner at qualification.group-active-without-gate-row; undelivered pending inbound with no gate/group parent — the normal stranger-at-the-gate shape — surfaces aspending-inbound-without-gate-rowinstead of vanishing.delivered=0(V2 retains delivery history); live Mini numbers: 13 proposals / 8 genuinely held (an earlier draft misread 21 by counting history).--lease-stop-recordreconciles the Phase-5 step-2 record when present — membership AND provenance: lease-stop-only chats →active-without-v2-state; a lease platform resolves V2-unresolved rows (leaseStop=resolved-by-lease-stop); a disagreement with a V2-resolved row keeps V2's value and surfacesplatform-conflict(v2=…,lease=…)with its own summary count and checklist line. Without the record, the ceremony doc keeps the manual cross-check explicit.raw-<id>when schema-legal,sha256-<24hex>otherwise — disjoint namespaces by construction (collision regression uses an attacker-crafted digest-shaped raw id); raw ids preserved inconversationRef/legacyId.inventoryKind: connector-binding,disposition: defer-with-owner-approval→INVENTORY_DEFERRED_OWNER_APPROVAL, never auto-imported; details conform to the fatal-enforced allowlist.Validation
ruffclean; 34/34 tests.agents.db(copy-then-read) + V3inspectPinkyImportManifest:ok: true, 0 fatals, 13×INVENTORY_DEFERRED_OWNER_APPROVAL— re-verified after every review round; lease-reconciliation manifests independently verified (3 deferred / 0 fatals).Review: murzik gauntlet rounds 1–4 produced seven findings across three rounds — held-count inflation, orphan pending drop, missing lease-stop input, source-key fatality, Markdown forgery, key-namespace collision, and membership-only lease reconciliation — all addressed with frozen regressions.
🤖 Generated with Claude Code
🤖 Opened by Barsik