Skip to content

AL-2103 — [P28-F13] Offer optional missionary receipt reporting with reliable status #2103

Open
0 of 1 issue completed

Description

@cobmojo

AL-2103 — [P28-F13] Offer optional missionary receipt reporting with reliable status

Approved implementation ticket. Plan key: P28-F13. Work only after its real blockers and exact qualification gates are satisfied. Publication does not establish implementation, qualification or activation.

Parent

Phase 28 implementation specification #2064. Canonical specification commit e93e2e9958f32380e28ec0e005d7ef3ee24f7e7a; documentation PR #2065. The full published spec and comments were verified against the canonical source. Preserve the parent’s body, title, labels, state and comments; new native child/dependency relationships are metadata only.

What to build

Organizations can turn on a simple missionary doorway for reporting actual offline receipt; Maya records known facts once into the existing intake and sees Awaiting finance or truthful uncertainty, including after reporting is turned Off.

Source of truth and acceptance ownership

  • Finance Stewardship: part 1 · part 2
  • Common safeguards and proof: part 1 · part 2
  • Owner reconciliation and later-decision precedence: part 1
  • Evidence and existing seam limits: part 1

Primary requirement references: REQ28-F29, REQ28-F30, REQ28-F32. Stories: US28-F29, US28-F30, US28-F32.

The checked criteria below are this ticket’s primary trace ownership, not a relaxation of the full normative contract. For a requirement split across tickets, this ticket delivers its named behavior and enforces applicable invariants immediately; the other ticket’s full scenario is not claimed complete early. All source-specific state/control, numeric-boundary, owner, monitoring and exclusion sections in the linked volume remain binding. Preserve settled D1–D50 and C01–C20; do not reopen them or import contradictory vendor conventions.

Acceptance criteria

  • AC28-F29-01 — An Off organization with no retained permitted reports sees no unused missionary reporting control, while ordinary giving and staff intake remain available.
  • AC28-F29-02 — On plus exact current reporting authority reveals one optional action; role name, possession or feature On alone cannot authorize acceptance.
  • AC28-F29-03 — Missing or invalid policy never enables creation, and migration does not infer opt-in from old gifts, roles or legacy settings.
  • AC28-F30-01 — Maya can submit an eligible actual receipt with an honestly unknown donor or amount, receiving an attributable operational report rather than a fabricated financial record.
  • AC28-F30-02 — Selecting another reported holder records a validated assertion without granting that person access or proving chain of custody.
  • AC28-F30-03 — A date-only or approximate reported receipt retains its precision; the server does not manufacture an exact historical timestamp.
  • AC28-F32-01 — If acceptance wins the Off race, Awaiting finance remains recoverable; if Off wins, no report is created and later On does not replay it.
  • AC28-F32-02 — A timeout displays an unknown outcome with same-operation Check status/Retry; it does not claim failure or invite duplicate submission.
  • AC28-F32-03 — Recorded by finance and remaining handling are shown as separately permitted facts; reporting alone changes no received total, deposit, fulfillment, receipt, acknowledgment or donor message.

Implementation decisions and slice boundaries

  • Starts Off for new or unconfigured tenants; preserve explicit qualified choices. On and exact current reporting authority are both required.
  • Unknown donor, amount, currency, entity or allocation are assertions within the nonfinancial envelope; no guessed default, fake Party, zero money, check photograph, OCR, card or bank collection.
  • Actual receipt is not a promise or a check reportedly mailed; date-only or approximate asserted time retains its precision.
  • Off fences new acceptance, including stale forms, and preserves staff processing, currently permitted reads and accepted-result retry. A rejected intent is never queued for later On; an intervening Off/On requires fresh review.

Binding normative decisions

REQ28-F29 — Make missionary offline reporting optional and Off by default

Story US28-F29: As authorized staff, I want to enable missionary reports of
actual offline gifts only when appropriate, so that ordinary finance intake stays
simple for organizations that do not need this doorway.

Decision basis: D33 C01–C04/C18/C23; P15; P27 F56–F74.

One organization-wide Allow missionaries to report offline gifts setting
SHALL initially be Off for new tenants and existing tenants without an explicit
qualified choice. Upgrades preserve a deliberately selected qualified On or Off.
On is necessary but not sufficient for a missionary's current reporting
capability. Staff entry SHALL remain usable without a missionary report. Phase 28
SHALL call the existing Phase 15 operational-intake owner; it SHALL not insert a
financial gift, staging record, parallel intake ledger or task-as-source record.
Enable only the qualified narrow reporting/handling/finance continuation lane,
without requiring every future accounting feature or a new workflow builder.

REQ28-F30 — Record actual receipt with honest incomplete facts

Story US28-F30: As an authorized missionary, I want a short form for a gift
I actually received, so that I can hand known facts to finance without guessing.

Decision basis: D33 C04–C08/C17/C19; P15; P27 F56–F60/F68–F70.

The report SHALL be a deliberate attributed assertion of actual organizational
receipt. A promise or a donor saying a check was mailed is insufficient. The form
SHALL distinguish trusted recorder/tenant/acceptance time from asserted receipt
time and precision, reported receiver/holder and accountable next actor. Unknown
donor, amount, currency, intended Legal Entity, allocation or tender details may
remain explicit in a restricted nonfinancial envelope; required source identity
and accountability remain nonnull. A normalized amount requires known validated
currency and precision; unresolved literal information is an assertion, not money.
No fake Party, zero amount, guessed USD, signature, check photograph, bank/card
data, OCR, routine second approval or compulsory essay is introduced.

REQ28-F32 — Preserve accepted reports across Off, retries and correction

Story US28-F32: As a missionary, I want clear report status and safe recovery,
so that a disabled setting or interrupted connection does not lose an accepted
handoff or create it twice.

Decision basis: D33 C09–C11/C15/C17/C20/C23.

Policy changes and report admission SHALL share an authoritative acceptance fence.
Off stops new missionary acceptance, including stale forms, but preserves accepted
reports, staff processing and independently permitted reads/corrections/handling.
Accepted report, required history, result receipt and durable accountable work
intent SHALL commit coherently. Same-intent recovery returns an earlier accepted
result even after Off under current read rights; changed payload conflicts. An
Off rejection is a terminal no-effect outcome, never queued for On. An intervening
Off/On cycle requires fresh deliberate review and a new intent for a previously
unaccepted form. Older actual receipts may be deliberately reported while
currently permitted with their real occurrence date. Closing a submitted form is
not cancellation of an accepted or indeterminate command.

Testing, migration and operating obligations

Every reached layer belongs to this slice: actual source persistence and upgrade behavior, canonical command/query, permitted UI, and executed proof. Reuse native owners, shared Base UI/base-maia components and the established architecture. No parallel CRM, Tasks, consent, sender, permission or retention engine.

Before affected activation, prove current trusted tenant/actor/subject/role and fine-grained purpose/field authority, effective old-row/new-row RLS and grants, same-tenant relationships, applicable uniqueness/history/delete constraints, and every reached view/RPC/storage/service path. Caller identifiers and metadata are never authority. Source revision and privacy checks precede disclosure and are repeated after ordering waits where required.

Implement semantic idempotency, required source history/receipt and durable secondary intent, truthful partial/unknown/lost-response recovery, context-switch/revocation fencing, temporal boundaries and correction lineage. Preserve each adopted default and exact Off/new-work/accepted-work/reenable behavior. Never infer consent, money, completion or actual interaction from a presentation action.

Test through existing Playwright whole-user journeys as the primary boundary; use canonical API Vitest tests, real PostgreSQL roles and at least two concurrent sessions, qualified Auth and existing provider-contract seams where the browser cannot prove the guarantee. Reuse existing account-frame/session-guard, task-recovery, roster/redaction, operation-handler, dispatch/restriction, field-policy SQL and replay proof patterns while retaining their demo/mock limits. No new test framework and no skipped mandatory fixture may count as a pass.

Use persistent truthful outcomes, clear context and next steps, keyboard/screen-reader/touch/list equivalents, narrow-screen reflow, localization, safe international data and honest interrupted-connection recovery. Inventory and fence reached legacy writers/readers, preserve lawful history and unresolved obligations, and qualify mixed versions, restore, retention and containment before activation. Adopt existing source-specific signals/thresholds/owners/responses and measured cohort budgets; do not invent a numeric SLO or defer correctness to monitoring.

Shared requirements Q01–Q27 apply where relevant to every ticket. R43, F41–F44, M41–M42 and C49 apply to their affected lanes. W05/W06 aggregate composed evidence; they are not permission to defer any slice’s safeguards.

Exact consumed contracts

  • AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009 exact P15 restricted intake envelope/identity/required responsible work and current report projection. This ticket extends the missionary doorway, tenant Off default, exact reporting capability and interruption/Off behavior; it does not reimplement intake.
  • Actual receipt with honest unknowns; holder selection does not grant access/certify custody; real acceptance/Off race and timeout after commit.
  • Awaiting finance and Recorded by finance remain source truth; no received-total/receipt/fulfillment/outward-message effect from reporting.

Related source owners (references are not automatically blockers): #2009. Current source contract takes precedence over superseded issue wording.

Blocked by

A blocker’s closure is not runtime qualification: verify the exact consumed revision and executed proof. Keep independently qualified capabilities useful while an affected effect is unavailable. Integrate the approved specification into the implementation base; the open documentation PR is not evidence that these features exist.

Related approved slices

Short ticket keys in implementation notes resolve here. Published requirement, acceptance, story, decision and completeness codes retain their original meanings.

The full execution index and primary-acceptance ownership map are published with the Phase 28 release-qualification ticket. Every shared safeguard remains mandatory within its implementing slice.

Activity

  1. changed the title [-][P28-F13] Offer optional missionary receipt reporting with reliable status[/-] [+]AL-2103 — [P28-F13] Offer optional missionary receipt reporting with reliable status[/+] on Oct 19, 2026
  2. II-ricky-bobby-II commented on Oct 25, 2026

    @II-ricky-bobby-II
    Contributor

    Spec r1, Scope, Oct 24, 2026, pending Samson approval

    Status: r1 for #2103 (P28 F13), base develop 6ac594d. The issue body is the source of intent; this spec is the build contract. The whole issue is over both caps, so §10 proposes a two-way split. F13-a is the organization setting, the reporting capability, the shared acceptance fence, the report command into the Phase 15 intake owner and same-intent recovery (stays on #2103). F13-b is Maya's form, her report status list, Check status and Retry, and the journeys. The split is not filed; every criterion is tagged with its slice. Natively blocked by #2069 and #2009, which matches the body's "Blocked by" list. The intake owner #2009 (P27-F21, P15-owned) is open and itself blocked by #2004, and develop's offline gift route is a staff-only 501 bridge that #763 retires, so the production intake adapter is unavailable (OQ1). Context read: #2064 (finance stewardship, common safeguards, owner reconciliation and evidence comments), the #2152 index comments, the #2069 r1 spec, the #2009, #2021 and #763 bodies, and finance-stewardship.md (REQ28-F29 :748-773, F30 :774-799, F32 :829-856, F41–F44 :1081-1231).

    §0 What I checked

    §1 Intended behavior

    Maya's organization turns on "Allow missionaries to report offline gifts" and gives her the reporting capability. After church on Sunday, a member hands her an envelope. On her phone she opens Donors, then "Report an offline gift". She enters what she knows: "John (surname unknown)", amount unknown, received "Oct 19", held by "Me". She submits once. Her list shows Awaiting finance. Nothing is added to any total and no receipt or message goes out. If the network drops, she sees "We couldn't confirm this was sent" with Check status and Retry, not an error.

    F13-a, setting, capability and command

    1. Setting. offline_report_policy_events is append-only: tenant, seq, state ('on'|'off'), actor, at. No event means Off; a missing, unreadable or invalid current event also means Off. The migration writes no events and reads no old gifts, roles or settings. Changing it takes offline_report_policy:<tenant> and an expected seq (409 policy_stale), under assertContributionPermission(auth, 'finance:manage_contributions') (OQ2).

    2. Capability. offline_report_grants holds explicit grants of offline_gift.report to a profile for a subject context from AL-2069 — [P28-W01] Enter and switch the exact authorized workspace context #2069, granted and revoked by the same finance permission. A role name, membership, possession of a gift or the setting being On never authorizes. Acceptance needs On and a current grant and a current AL-2069 — [P28-W01] Enter and switch the exact authorized workspace context #2069 context for that subject.

    3. Report command. report_offline_receipt takes Idempotency-Key, the form's policySeq (the 'on' event seen when the form opened) and the envelope. Under the policy lock it re-reads, in order: the current policy, the grant and context, and the key.

      • Off now: 409 reporting_off. The outcome is recorded rejected_off, with no report and nothing queued. A later On never replays it.
      • On, but a different 'on' seq than the form's: 409 review_again. An intervening Off/On needs a fresh review and a new key.
      • Same key and same payload digest: the original result, even if reporting is now Off, under current read rights.
      • Same key, different digest: 409 idempotency_conflict.
      • Otherwise: it calls the P15 intake owner's accept_offline_report(envelope) (the AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009 port) in the same transaction, and records offline_report_submissions (key digest, payload digest, recorder, policy seq, intake_ref, accepted_at). The owner commits the report, its history and its accountable work intent.
    4. Envelope. It's restricted and nonfinancial:

      • donor: a known donor from Maya's current context, literal text, or unknown;
      • amount: unknown, literal text, or a normalized {minor, currency} that requires a known supported currency and passes parseMoneyToMinorUnits;
      • Legal Entity, allocation and tender: unknown or literal;
      • received: a date with precision exact_date, month or approximate; the server never makes it a timestamp;
      • holder: me, a validated tenant member, or literal text;
      • an optional note.

      Recorder, tenant and acceptance time come from the server. There's no zero amount, guessed USD, fake Party, signature, photo, OCR, card or bank field, and no required essay.

    5. Holder. A holder that names another member is validated as an active member of the tenant and stored as an assertion. It grants that person no access and certifies no custody.

    6. Off. Off stops new acceptance, including stale open forms. Accepted reports, staff processing, permitted reads and accepted-result replay continue.

    F13-b, Maya's form and status

    1. Doorway. On the Donors page (OQ3), a "Reported gifts" section:
      • Off and no retained reports that Maya may read: nothing is shown.
      • Off with retained reports: the list only, with no Report action.
      • On with a current grant: one "Report an offline gift" action and the list.
    2. Form. It has the envelope fields with "I don't know" choices, says "Only report a gift you or someone you name actually received", and submits once.
    3. Status list. Each report shows Awaiting finance, and later Recorded by finance and any remaining handling as separate lines, read through the owner's offline_report_status(intake_ref). Reporting alone changes no received total, deposit, fulfillment, receipt, acknowledgment or donor message.
    4. Interrupted connection. A timeout or dropped response shows "We couldn't confirm this was sent" with Check status (a read by key) and Retry (the same key and payload). It never says "failed" and never offers a fresh submit for that form. Closing the form doesn't cancel anything.

    Threat model

    Threat Control Criteria
    Control appears or works without opt-in No event means Off; migration infers nothing A1, A3
    Role or feature alone authorizes Explicit grant plus context, re-read under lock A2
    Fabricated money or Party Nonfinancial envelope; unknown stays unknown A4
    Holder gains access Assertion only; no grant A5
    Precision invented Date with precision; no timestamp A6
    Off race loses or replays a report Shared lock; terminal rejected_off; seq check B1
    Timeout causes a duplicate Idempotency key; Check status and Retry B2
    Report changes totals or sends messages P15 envelope only; census B3

    Non-goals: the P15 intake owner and its work (#2009); finance recording (#2021, F14); duplicate resolution (#2026); physical handling (#2027); new financial records; notices.

    §2 In scope

    • F13-a: the policy and grant tables, the Admin card, the report command and its recovery, the intake port with its unavailable production adapter and test adapter.
    • F13-b: the Donors-page section, the form, the status list and recovery UI, and journeys.
    • Docs and tests for both.

    §3 Out of scope

    • Building the intake owner (OQ1) or changing the staff offline route.
    • Any write to donations, donors, batches or receipts.
    • Editing docs/ci.md and the byte-pinned Phase 28 PRD archive.

    §4 Criteria

    Tags: [A] Acceptance-owned test, [B] Builder test, [S] static, [R] real PostgreSQL (#2250's step). "Two sessions" means two independent database connections with the lock wait observed. (a)/(b) is the slice. The intake owner is F13's test adapter.

    • A1 [A][R] (a+b) Off by default (AC28-F29-01). A tenant with no event shows Maya no section and refuses the command (409 reporting_off), while the staff offline route and ordinary giving behave as before.

    • A2 [A][R] (a) Exact authority (AC28-F29-02). With On, only a profile holding a current grant in a current context sees one action and can submit. An admin without the grant, a missionary with the role but no grant, and a grant holder outside the context get 403.

    • A3 [A][R] (a) No inferred opt-in (AC28-F29-03). After the migration, every tenant is Off, including tenants with old offline gifts and finance staff. An invalid current event refuses creation.

    • A4 [A][R] (a) Honest unknowns (AC28-F30-01). A report with an unknown donor and an unknown amount is accepted as an operational report. A census shows no donation, donor, batch, receipt or outbox row, and no zero amount or USD is stored. A normalized amount without a currency is refused.

    • A5 [A][R] (a) Holder (AC28-F30-02). Naming another member stores the assertion and gives that member no new read on the report. A non-member holder is refused.

    • A6 [A][R] (a) Precision (AC28-F30-03). A month-only and an approximate date round-trip with their precision, and no stored field holds a manufactured time.

    • B1 [A][R] (a) Off race (AC28-F32-01). Two sessions, twice:

      • when acceptance commits first, then Off, the report stays Awaiting finance and replays by key;
      • when Off commits first, the waiting submit gets 409 reporting_off with no report, and after On the same form gets 409 review_again.
    • B2 [A][R] (a+b) Timeout (AC28-F32-02). A response dropped after commit, then Retry with the same key, returns the original report; Check status finds it. A changed payload with that key gets 409 idempotency_conflict. The UI shows the unknown state, never "failed".

    • B3 [A][R] (b) Separate facts (AC28-F32-03). The test adapter's "recorded" and "handling still needed" states show as two lines. Before recording, totals, deposits, fulfillment, receipts, acknowledgments and messages are unchanged.

    • S1 [S]

      • The policy and grant routes call assertContributionPermission(…, 'finance:manage_contributions').
      • No F13 module writes donations, donors, batches or receipts, or calls the staff offline route.
      • The new functions are in GUARDED_RPCS.
    • C1 [A] (b) Journey. On a real stack with the test adapter, at a phone viewport, keyboard-only and with screen-reader names checked:

      • finance turns reporting on and grants Maya;
      • Maya reports a gift with unknowns and sees Awaiting finance;
      • a simulated timeout shows Check status, which finds it;
      • finance turns reporting off, and Maya still sees the report with no action.

      Axe clean.

    Handback

    §5 Mapping

    Ticket requirement Criteria
    AC28-F29-01 Off shows no control; staff intake unaffected A1, C1
    AC28-F29-02 On plus exact authority, one action A2, C1
    AC28-F29-03 no opt-in from invalid policy or migration A3
    AC28-F30-01 unknown donor or amount, operational report A4, C1
    AC28-F30-02 holder assertion without access A5
    AC28-F30-03 precision kept A6
    AC28-F32-01 Off race B1
    AC28-F32-02 timeout, Check status and Retry B2, C1
    AC28-F32-03 recorded and handling separate; no money effect B3

    §6 Declared edits

    File Change Owner
    supabase/migrations/<VERSION>_offline_receipt_reporting.sql + rollback Policy events, grants, submissions; report and recovery functions; intake port call; FORCE RLS Builder (a)
    packages/api/src/offline-reporting/** (new) Policy and grant services, report command, port, unavailable and test adapters Builder (a)
    packages/api/src/admin/offline-reporting-policy/route.ts (new) Admin routes using assertContributionPermission Builder (a)
    packages/api/src/missionary-portal/offline-reports/route.ts (new) Report, status and Check status routes Builder (a)
    apps/admin/app/(app)/contributions/offline-reporting/** (new) Setting and grant card Builder (a)
    packages/api/src/identity/tenant-guard.ts New GUARDED_RPCS entries only Builder (a)
    apps/missionary/app/donors/** "Reported gifts" section, form, status list, recovery Builder (b)
    docs/features/offline-reporting/missionary-reports.md (new) Setting, capability, envelope, Off and recovery Builder (a, b)
    tooling/eslint-config/suppressions.json, tooling/shadscan/findings.json Refresh only (§7) Builder (a, b)
    tests/unit/acceptance/issue-2103/** A1–A6, B1–B3, S1 Acceptance
    tests/e2e/offline-receipt-reporting.spec.ts (new) C1 Acceptance

    §7 Pins this change touches

    Pin Where In or out Criterion
    Contribution permission packages/api/src/admin/contribution-operations/permissions.ts Out: used, unchanged S1
    Staff offline route and 501 bridge packages/api/src/admin/contributions/offline-route.ts, offline-dependencies.ts Out: unchanged (#763 owns it) A1, S1
    Money helpers packages/api/src/money/index.ts:18, 33-55 Out: used, unchanged A4
    Missionary navigation list tests/unit/apps/missionary/missionary-navigation-search.test.tsx:67-75 Out (no nav item; OQ3) —
    Donor detail suppressions tooling/eslint-config/suppressions.json:1181-1188 Out: the admin donor detail isn't touched —
    Shadscan app floors scripts/verify/shadscan.mjs (ci.yml "Enforce complete Shadscan app floors and reviewed findings") In: no new unreviewed finding H4
    #2250 step and order issue-2250/static.acceptance.test.ts Out (no step) H1
    Workflow fingerprints issue-2155/…:257-280 (bc8d57a2be564d61), issue-2201/…:166-178 (1078832efaff84e6) Out under the OQ4 default —
    docs/ci.md byte pin issue-2250 prefix pin and #2304 Out: not edited —
    Phase 28 PRD archive verify:phase28-spec (ci.yml :91), 911 files under docs/features/missionary-workspace-depth/grill/** Out: none edited —

    §8 CI

    No new CI step and no docs/ci.md edit under the OQ4 default. Real-DB tests, including the two-session races, run in "Verify tenant isolation (real stack)" (bun x vitest run realstack.acceptance, env TENANT_GUARD_IT_ADMIN_DATABASE_URL). Everything else runs in existing ci.yml steps: bun run format:check, "Run affected lint on pull requests", "Run affected typecheck on pull requests", "Run unit tests", "Run acceptance tests", Shadscan. Playwright C1 runs locally and is recorded (H3).

    §9 Data, grants, person_id and donor spine

    • offline_report_policy_events: tenant_id, seq, state CHECK IN ('on','off'), actor_profile_id, created_at; PK (tenant_id, seq).
    • offline_report_grants: tenant_id, id, profile_id, subject_kind, subject_id, granted_by, granted_at, revoked_by NULL, revoked_at NULL; partial UNIQUE (tenant_id, profile_id, subject_kind, subject_id) WHERE revoked_at IS NULL.
    • offline_report_submissions: tenant_id, id, key digest, payload digest, recorder_profile_id, policy_seq, outcome CHECK IN ('accepted','rejected_off','review_again'), intake_ref NULL, accepted_at; UNIQUE (tenant_id, recorder_profile_id, key digest); CHECK that 'accepted' has an intake_ref. It holds no envelope fields; the facts live with the intake owner.
    • Grants: RLS and FORCE RLS; no anon/authenticated/service_role table privileges; access only through guarded functions. No RLS policy on an existing table is dropped or recreated.
    • person_id: F13 reads and writes neither profiles.person_id nor missionaries.person_id. No [Security] missionaries.person_id column-grant fix: anon cross-tenant read + select("*") routes (follow-up from #2256) #2268 block is needed.
    • Donor spine: needs Blake's sign-off; Samson relays it to Blake at merge. F13 writes no donor or donation row, but the form reads Maya's current donors to pick a known donor, and the envelope carries donor identity into the intake owner.

    §10 Size and proposed split (not filed)

    Slice Scope Code+docs Tests
    F13-a (stays on #2103) Setting, grants, fence, report command, recovery, port, Admin card ~640 ~760
    F13-b Donors-page section, form, status list, Check status and Retry, journey ~480 ~600
    Whole ~1,120 ~1,360

    §11 Dependencies and migration

    §12 Open Questions (proposed defaults in bold)

    1. Intake owner unbuilt. AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009 is open and blocked by AL-2004: Start or reuse one continuing partnership in context (P27-P01) #2004, and the staff route is a 501 bridge. Default: F13 merges on the test adapter with the production intake adapter unavailable. While it's unavailable the Report action stays hidden even when On, and the command returns 503 intake_unavailable with no submission row. Wiring AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009's real port, plus A2, A4–A6 and B1–B3 rerun against it, is a handback gate on AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009. No write through the staff offline route is allowed. This is a departure that narrows. The alternative is holding F13 until AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009 merges.
    2. Who changes the setting and grants. Default: finance:manage_contributions (admin, super_admin and finance staff), the permission the staff offline route already uses. The alternative is assertAutomationPermission. Flagged for Samson.
    3. Where the doorway lives. Default: a "Reported gifts" section on the existing Donors page, with no new navigation item. The alternative is a new nav item, which would touch the navigation pin.
    4. Journey in CI. Default: no CI step; local run recorded. The alternative is a test-e2e step "Offline receipt reporting journeys" with run text node scripts/run-with-ci-env.mjs -- node node_modules/@playwright/test/cli.js test -c playwright.missionary.config.ts tests/e2e/offline-receipt-reporting.spec.ts --workers=1, which re-pins both fingerprints and byte-pins docs/ci.md (with docs/ci.md:35 and :366 still call test-e2e informational on develop; update with the #2180 byte pin in one change (follow-up to #2161) #2304).
    5. Holder choices. Default: me, an active member of the tenant, or literal text; no person lookup beyond tenant membership.

    §13 Deploy

    • Production is behind develop. It's missing the 58 develop versions 20260515025814–20261024120000 (25 applied, newest 20260513173938). The dev project is 55 behind, with four 20261001* collisions and an extra 20260519233845. Develop's catalog is not assumed live anywhere.
    • Order: (1) the backlog, as its own deploy; (2) AL-2069 — [P28-W01] Enter and switch the exact authorized workspace context #2069's context; (3) F13-a's migration; (4) the app release with F13-b. Every tenant stays Off, and the action stays hidden while the intake adapter is unavailable. (5) The real intake adapter, once AL-2009: Report an actual gift receipt with honest missing details (P27-F21) #2009 merges.
    • Rollback: the app first. The migration's rollback refuses while any submission or grant row exists.
    • Samson relays the deploy plan to Blake at merge.

    §14 Flags

  3. II-ricky-bobby-II commented on Oct 25, 2026

    @II-ricky-bobby-II
    Contributor

    Approval (Samson, factory lead, Oct 24, 2026, 9:54 PM PT), relayed by Scope:

    All five r1s are approved. Splits approved: … F13 a/b. Versions (prefix 20261026): … F13-a 20261026090000; F13-b has no migration … Defaults accepted as departures: test adapter, production unavailable, handback gate Samson checks (F13: #2009 isn't built, so the Report action stays hidden even when the setting is On). F13: OQ2 (finance:manage_contributions controls the setting and grants) and OQ3 (a section on the Donors page, no new nav item). CI-step OQs closed: no.

  4. II-ricky-bobby-II commented on Oct 25, 2026

    @II-ricky-bobby-II
    Contributor

    Split filed (Scope, Oct 24, 2026, per Samson's 9:54 PM PT approval)

    This issue now covers only its F13-a slice (20261026090000). #2069 and #2009 stay here and are also copied to #2362: its section and form act within Maya's #2069 context, and its status list reads #2009's intake status, so its B2 and B3 rerun is part of the #2009 gate. F14 (#2104) builds on #2362's section but isn't linked to it under this ruling. The child carries native sub-issue and blocked-by links; it isn't Ready-labelled.

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

    ReadyBlake-approved for the agent factory to pick up (oldest first)complexity:hardHigh complexity or scopetype:featureNew functionality

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions