Skip to content

Add channel-neutral responsibility review and lifecycle controls #129

Description

@George-RD

What to build

Owner surface must be channel-neutral: OwnerReviewRequest renders identically on Telegram and WhatsApp, decisions are principal-bound and channel-independent. Inventory the 28 chat-id leaks below the adapter boundary and wire them as independent tracked gaps.

Acceptance criteria

  1. Implement channel-neutral OwnerReviewRequest structure. 2. Support Telegram and WhatsApp adapters simultaneously. 3. Inventory and track all channel-ID-dependent code paths. 4. Route each to a separate tracked issue.

Blocked by

T10 assessment findings; Bell fit review

Fence: Do not start before the Bell fit review lands on build-on. Route through delivery vehicle in DIRECTION.md.

Original report

Why

The progressive-delegation experience is currently being designed as Telegram text plus inline buttons. Telegram is a useful first renderer, but it must not become the product or security model. OpenSpine already supports a local terminal owner channel and anticipates future communication surfaces.

The owner should make one digest-bound decision about a governed review object. Telegram, terminal, web, or another verified owner channel should only render and submit that decision.

The current lifecycle also lacks the complete employee-management controls promised by #123: Reject, narrow/amend, Pause, Resume, and clear post-use receipts.

Scope

1. Owner review object

Implement the OwnerReviewRequest contract settled in #126. It must be stored/content-addressed and bind:

  • review type and proposal provenance/evidence;
  • owner-facing job/responsibility description;
  • exact action descriptor and reviewed scope;
  • budgets, rate, expiry, drift behavior, and any conditional default;
  • effects that become reusable;
  • effects that remain approval-required or denied;
  • artifact/version/digest identities;
  • available decisions;
  • expiry and current lifecycle state.

The review object must be the security-relevant source rendered by every owner surface. A renderer cannot add scope or decisions that are absent from it.

2. Generic owner decisions

Define channel-neutral, principal-bound decision intents:

  • Approve exact reviewed version;
  • Reject without activation;
  • Request a narrower/amended proposal;
  • Pause an active responsibility;
  • Resume the same reviewed version when still compatible;
  • Revoke immediately;
  • inspect provenance/diff/receipt.

A narrow/edit operation must create a new immutable proposal/version and new digest. It must not mutate bytes under an existing approval.

3. Standing-rule lifecycle

Add an owner-controlled paused state distinct from system-triggered needs_review and terminal revoked.

Required behavior:

  • paused rules are absent from live consultation;
  • resume revalidates policy, descriptor, executor, connector/account, reviewed scope, and compatibility before returning active;
  • revoke is immediate and idempotent;
  • rejected proposals never enter live consultation;
  • expired or drifted rules cannot be resumed without a new reviewed version.

4. Renderers

Telegram

Render the generic review object with bounded copy and appropriate buttons. Keep existing verified-private-owner assumptions. Telegram callback data identifies the review/decision, not connector-specific implementation details.

Local terminal

Render the same review as a readable decision card/numbered prompt and submit the same decision intent. This proves the lifecycle is not Telegram-defined.

Future web/mobile surfaces should require no lifecycle rewrite.

5. Truthful proposal language

  • "Lyra noticed repeated work" appears only for repeated-approval evidence.
  • Manual or owner-requested proposals state their real origin.
  • Owner-facing action language comes from reviewed action descriptors, never a guessed leaf verb.
  • Scope is shown from the exact reviewed scope.
  • Copy never says work will happen automatically unless the action is execution-backed and the complete scope is enforceable.
  • Internal terms such as task grant, standing rule, and artifact lifecycle remain available behind details but are not required for the decision.

6. Receipts and exception surface

After reusable admission, send/store a concise receipt containing:

  • what effect occurred;
  • which reviewed responsibility/version covered it;
  • the target in owner-readable form;
  • remaining relevant budget;
  • audit/detail reference.

Scope mismatch, budget exhaustion, pause, expiry, drift, or policy change should surface as a short exception/approval request, not repeat the entire permission model.

TDD matrix

  • Telegram and terminal render the same canonical review fields and produce equivalent decisions.
  • Approve is bound to exact review/artifact/scope digests.
  • Reject consumes/closes the pending decision and activates nothing.
  • Narrow creates a new proposal and invalidates no historical evidence.
  • Pause immediately restores normal approval behavior.
  • Resume succeeds only when compatibility revalidation passes.
  • Revoke removes live consultation immediately and is idempotent.
  • A copied/foreign/replayed callback cannot act for another owner or review.
  • Oversized content cannot leave a persisted unreviewable proposal.
  • Manual proposal copy never claims repeated approval evidence.
  • Unsupported/unexecutable action never receives an Approve-to-automate review.

Invariants

  • Owner channel is presentation and authenticated input, not authority logic.
  • Every decision remains kernel-verified and digest-bound.
  • No model or worker can approve, amend, resume, or revoke authority.
  • Preference review remains visually and semantically separate from authority review.

Done when

  • One stored review object can be rendered and decided through both Telegram and terminal.
  • Approve, Reject, Pause, Resume, and Revoke have owner-path tests.
  • Narrow/amend creates a new immutable reviewed proposal.
  • Proposal text is provenance-, scope-, and execution-truthful.
  • Generic lifecycle code contains no Gmail-specific behavior.

Relationship

Parent: #123.

Requires: #126. Can proceed in parallel with #127/#128 once the contracts are settled.

Blocks the complete Gmail proof.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    fence:post-fit-reviewDo not start before the Bell fit review lands on build-on

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions