Repository navigation
Conversation
Replace approved live actor and recipient roles with ADVOCATE_CODEX while preserving opaque session IDs, payloads, history, and test expectations. Keep the priority-source fixture and all governance consumers on hold.
Update five approved fixtures, preserve historical SQL and protocol roles, and use an explicitly suppressed OBSERVER in zero-paste tests. Production authority and pump defaults remain unchanged.
…roles, v3.10 lifecycle) Convert the three mechanics-only fixture files that still created live-style CONDUCTOR rosters to the branch convention (CONDUCTOR -> ADVOCATE_CODEX, same session ids), so the retired-role gate no longer fails them at setup. The init metadata round-trip test now expects the server-stamped governance candidate record next to the caller's keys (C3 F06 contract). Tests that assert CONDUCTOR-specific production behaviour stay RED on purpose and belong to later phases: conductor_override_msg_id paths (phase A), set_topic_priority and bin/task fb self-heal (phase B), the priority source label (phase B5). No production file changes; the F0 governance tests are untouched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…/post guards, serializer) Add stdlib-only debate_governance.py: canonical JSON with domain-separated digests, the bounded strict payload decoder (UTF-8 byte bound measured before parsing, duplicate keys and non-finite constants rejected, object root only), migration-manifest normalization and digest check, the frozen binding version fingerprint, stored-payload recognition and the one legacy read serializer shared by read_messages and debate_signal_check. schema.py gains the append-only debate_authorization_spends ledger (composite key, manifest CHECK, update/delete abort triggers) in the base DDL, so every init_db path including the debate/v1 rebuild carries it. debate.py: init_debate refuses caller-supplied governance authority fields before the idempotency lookup and stamps the server-derived legacy candidate record on creation; post_message validates governance candidates on unconfigured topics after author provenance and before the v1 preflight, with typed zero-row rejections (authority_unconfigured for a well-formed grant, since no authority can be pinned yet). No positive persistence path exists in this phase; issuer stamping belongs to the next phase. Intentionally still RED for later phases: conductor_override paths in test_debate_flexible_roles and test_debate_v3_10_lifecycle (phase A), test_debate_priority and test_daily_dashboard::test_bin_task_fb_* (phase B), the priority source label in test_debate_init (phase B5). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… gate) The F0 governance module is a new top-level module; the editable-install manifest gate requires every top-level .py file to be listed so the production MCP entrypoints import the same mapping CI tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…audited contract Restore signature parity with the ROOT-audited foundation delta: validate_legacy_governance_post(conn, *, topic_id, role, kind, reply_to, payload_json, body_mode, author_session_id, recipients). The extra authority keyword is removed; the function now resolves the topic's governance mode itself through the caller's transaction (_pinned_authority), which is the only DB read in the module and still yields authority_unconfigured for every topic, since no pin operation exists yet. The single call site in post_message passes the connection it already holds. Behaviour and error spellings are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Completes the signature-parity change of the previous commit: the module imports sqlite3 for the connection annotation and the final branch calls _pinned_authority(conn, topic_id) instead of the removed authority keyword. ruff F821 x3 cleared; behaviour unchanged (authority_unconfigured for every topic until a pin operation exists). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ce record Adds tests/test_debate_governance_legacy_topics.py (test-only): a hand-seeded historical topic whose metadata is NULL, empty, lacks the governance key, carries a non-object governance value, or carries a plain legacy record must refuse a well-formed authorize DECISION through both public writers with the typed authority_unconfigured error and zero writes. A second node pins the current contract that a DECISION with an opaque, non-governance payload on an unpinned legacy topic is refused typed (governance_schema_unsupported) rather than posted with the payload silently dropped; recorded as a decision item for ROOT. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ller governance key Round-2 items from the peer review of the F0 foundation: - is_legacy_governance_candidate no longer parses a non-DECISION payload that carries the governance marker but exceeds the 65536-byte bound; it is a candidate by size alone and the strict decoder refuses it as too large (no unbounded json.loads before the bound). - reject_caller_governance refuses the whole caller-supplied governance key, not only server fields: the record is server-derived and a partial object would otherwise be silently overwritten. - expires_at message reworded to what is checked in this phase (shape only; parsed where a grant is consumed). - Test nodes: oversize marker payload on STATUS -> governance_payload_too_large; authority-looking seeded metadata (mode only / complete record) -> governance_action_not_implemented; caller governance object at init -> governance_server_field_supplied; debate/v1 topic + issuer-stamped-looking DECISION -> SEMANTIC_KIND_REQUIRED (characterization for ROOT Q5). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…6/M3) - reject_caller_governance details now carry value_is_null so a caller passing "governance": null can tell the refusal from a field supply. - New nodes: "governance": null at init -> governance_server_field_supplied with fields ["governance"] and value_is_null true, zero rows; a same-roster re-init that echoes the STORED metadata (server governance record) is refused before the idempotent short-circuit, while a re-init with the caller's original metadata still returns the existing row unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Test-only commit; intentional per-node RED until A2 implements the chain. - tests/test_debate_governance_f1.py (new, 51 nodes): P0 inventory, P1 HUMAN bootstrap via private manifest, F19 loader refusals (symlink, non-regular, mode, parent mode, digest, expiry, expiry bound, owner=geteuid, topic drift, win32 gate), P2 approve_pin as a manifest tool (single-use digest, reader cannot replay, pin epoch 0->1, one spend, fault injection, pin_record_backed), P3 authorize + consume (one spend, authorization_required, alias + conflict, F13 mismatches, F14 replay, F15 re-pin stale, F17 race + rollback), F18 immutability by the server-only governance_schema column (update/delete, nested quote deletable, migration ordering, repeat init_db), M-A2, M-A3, D-A2. - lifecycle/flexible: the four override tests use the real chain (bootstrap -> approve_pin -> pin -> authorize -> bind with authorization_msg_id); the invariant guard now expects authorization_required. - foundation F09: stored-format fixture carries governance_schema; new negative id shape_without_column (shape alone is never authority). Every governance import is inside fixtures/nodes: missing surfaces fail per node, never at collection. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… fixture fix Test-only follow-up to 29710ba (EXECUTOR R1 06ff4fce261e, DA W40 3233bd5f1b68): - fixture: topic metadata carries priority_reason (the A1 run failed every node at debate_init with topic_priority_reason_required) - M1: exactly one error_type per node (governance_payload_invalid, governance_action_not_implemented, governance_server_field_supplied) - M3: test_p2_approve_to_pin_window_is_cas_guarded x4 (authority retired / rotated -> authorization_target_changed; HUMAN retired / rotated -> authorization_issuer_stale), zero spends, epoch unchanged Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the type Test-only follow-up to 0ba239c (DA W42 §3(a)/(b), W44 placement (i)): - M-A2 node: the internal_error must come from the unknown-keyword TypeError (asserts "unexpected keyword argument" and the key name in `error`) - generic-bootstrap nodes: the refusal must name the reserved type (details.type == "bootstrap_human") No node added, removed or renamed; pinned line unchanged (61F/4E/1899P). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ned topic Test-only follow-up to e2c96b3 (DA W45 §2(a) stop-and-post e5f52491234d): test_f13_grant_mismatches_apply_nothing[foreign_topic] could never turn green because the grant was posted on the default topic with a payload naming C3F1B (and C3F1B was never pinned). Now `_chain` threads the topic through the bootstrap/approve/pin helpers and `_grant` posts on the topic its payload names, so the case issues a REAL grant from C3F1B's own pinned authority and consumes it on C3F1 → authorization_not_found. No node added, removed or renamed; pinned line unchanged (61F/4E/1899P). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…de, signal helper Test-only follow-up to c02221c (DA W47/W48, addendum v1.3.1): - legacy_topics: a raw-SQL authority record is not a pin (D-A1) — the well-formed authorize on it is refused governance_pin_unbacked, before any actor/issuer check (was governance_action_not_implemented in F0) - f1: test_f13_authorize_payload_naming_another_topic_is_refused_by_the_validator keeps the validator refusal ("authorize topic_id must equal the posting topic") under its own id (W47 §2) - f1: the `_signal` helper reads debate_signal_check's `pending` list Pinned line: 65F/4E/1896P (1965 nodes). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… v1.3.1) Implementation only; the RED matrix (29710ba, 0ba239c, e2c96b3, c02221c, efe39c1) is untouched. - debate_governance.py: private-manifest loader (platform gate first, O_NOFOLLOW, st_uid == geteuid, mode/parent/size, bounded read, digest, expiry ≤ 24 h), projections (binding version/issuer, topic fingerprint, spend target key), pin_record_backed / require_pin_record_backed (governance_pin_unbacked, v1.3.1), stamp_authorize (server-stamped issuer, validity bound), column-based serializer - schema.py: debate_messages.governance_schema (base + rebuild DDL, ALTER migration in the A0 pattern, copy statement); immutability triggers (UPDATE without column list + DELETE, WHEN old.governance_schema IS NOT NULL) created only in _create_debate_message_indexes_and_triggers, after the ALTER; rebuild drop list names all six triggers - debate.py: governance_inventory / governance_bootstrap_human / governance_approve_pin / governance_pin / authorize_and_apply / governance_receipt; bind_role_session consumes grants (retire_binding, diagnostic_uncover) through authorize_and_apply with exactly one spend, authorization_required otherwise, conductor_override_msg_id as a deprecated alias; post_message internal_governance (DAO-internal) and the governance_schema INSERT column; both readers select the column; row ts parsed with fromisoformat (fractional seconds), grant expires_at strict - intel_server.py: debate_governance_inventory / _bootstrap_human / _approve_pin / _pin / _receipt tools; debate_bind_role gains author_session_id and authorization_msg_id - debate_ops.py: governance-inventory / -bootstrap-human / -approve-pin / -pin subcommands (thin wrappers) - CHANGELOG.md: Added / Changed entries (ownership_gap_override alias note) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…uard, changelog scope EXECUTOR round 1 7e67fb325d48 + DA W49 2ca92fc41dc3; implementation only: - M1: bind_role_session consumes a supplied grant ONLY when the call uncovers the ACTIVE owner (diagnostic and retire branches); otherwise the grant stays unspent and the result carries authorization_msg_id=None, spend=None. Contract line: ownership_gap_override True ⇔ a grant was consumed. - M3: the three manifest WRITE tools share one topic loader that refuses configured debate/v1 topics (governance_action_not_implemented, details.reason=protocol_topic). - M5: CHANGELOG narrowed to bind_role_session; the diagnostic-recipient override in debate_post_with_recipients is unchanged in this phase. Serializer untouched (v1.3 C1 as committed in 0610355). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…F17) DA W51 ruling 3c95b5f3d05c on top of A2b (W49 M1): with a grant supplied and nothing to uncover, the FIRST and ONLY lookup is the consume path's own _spend_row(authorization_msg_id, SPEND_TARGET_SINGLE) — spent → authorization_consumed; unspent → grant left untouched, authorization_msg_id None, spend None, ownership_gap_override False. Both bind branches (diagnostic, retire) and the conductor_override_msg_id alias route. No new error name. The lenient consequence is written into the bind_role_session docstring: on the no-uncover path the grant is ignored, not validated — the r4 consume chain does not run there. Implementation only (zero hunks under tests/). Pinned before the run: 5 failed / 4 errors / 1956 passed (F09 v1 shape + surface guard + dashboard 2 + init 1; priority 4 E). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…tools), F09 v1 row without the column Separately pinned test change after A2 (DA W47/W49/W51): the frozen-matrix regime forbids test hunks inside implementation commits, so the two findings from the A2 readback land here on their own. 1. tests/fixtures/surface_contract_snapshot.json: regenerated with `python tests/test_surface_contract_guard.py --regenerate` — exactly the five new names, each twice (per-server + aggregate): debate_governance_approve_pin, debate_governance_bootstrap_human, debate_governance_inventory, debate_governance_pin, debate_governance_receipt. +10 lines, nothing removed. 2. tests/test_debate_governance_foundation.py::test_f09_v1_read_shape_is_unchanged: the debate/v1 fixture row no longer carries governance_schema — a v1 row is never classified by the server column (phase A serializer rule, ruled to stay). One line. Pinned before the run: 3 failed / 4 errors / 1958 passed (dashboard 2 + init 1; priority 4 E) — the seven residual nodes of phases B1/B4/B5. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Docstring only, no behaviour change: bind_role_session now states exactly what the no-uncover path checks — replay of a spent single-target grant (a debate_authorization_spends row for the id with target_key 'single') is refused with authorization_consumed even when no uncover occurs; no other property of the grant is checked there. The earlier 'IGNORED, not validated' wording overstated the leniency (W54 C-A). Zero hunks under tests/. Pinned: 3 failed / 4 errors / 1958 passed, 30 skipped (F+E+P+S = 1995, unchanged since A1e). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-uncover path (DA W57) Docstring only, no behaviour change (OPTION K ruled: a grant-attached retry after the first attempt landed stays authorization_consumed; idempotency belongs to the client read of debate_binding_list, a grant-less retry cannot uncover). Disclosure direction stated: spent-vs-unspent of a grant id is observable to any caller holding the id, existence is not; the error carries only the error name and the id (every authorization_consumed raise in debate.py passes no details). Zero hunks under tests/. Pinned: 3 failed / 4 errors / 1958 passed, 30 skipped (F+E+P+S = 1995). Co-Authored-By: Claude Fable 5.1 <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
Adds two isolated tests through the real public debate wrappers:
The fixture uses a temporary database, real transaction boundaries, and synthetic identities; it disables external wake signaling.
Verification intent
This is an intentional RED characterization, not a production implementation. The expected failure is the retired-roster assertion because current code accepts the INIT roster. The positive availability guard and existing suite must continue to pass. A setup, import, priority, or authorization error is not acceptable RED evidence.
No production files, role bindings, live database, runtime configuration, or deployments are changed. This draft must not be merged while intentionally RED.