/** * pop task unclaim — release a CLAIMED task back to the pool (TaskManager v7). * * Two routes reach `unclaimTask(uint256)`, and they have genuinely different * blast radius, so the command treats them differently: * * SELF-RELEASE the claimer gives their own task back. Allowed at ANY time, * with no permission-mask check on-chain (an assignee never * needs CLAIM, and hats get revoked mid-claim — gating this * would trap exactly the people it frees). Non-destructive: * reversible by re-claiming, refunds nothing, destroys nothing. * FORCE-RELEASE someone else releases an ALREADY-EXPIRED claim. Needs ASSIGN * on the project (PM / executor bypass included). Destructive: * it takes a task away from another member, so `--json` is not * consent and `--yes` is required non-interactively. * * SUBMITTED is excluded on purpose — a zeroed claimer would let `completeTask` * mint to address(0) and brick the task. The route out is `pop task review * --action reject` first, then this. * * Budgets and application hashes are untouched on-chain: `cancelTask` stays the * single refund path, and becomes reachable again once a task is released. * * Post-success the receipt logs are parsed: `TaskUnclaimed` names the previous * claimer and the caller (their equality IS the self-vs-forced discriminator), * and `TaskClaimDeadlineSet(id, 0)` follows only when a claim window was * actually running. `TaskClaimExpired` is never emitted — no replacement * claimer is named — so it is deliberately not looked for. */ import type { Argv, ArgumentsCamelCase } from 'yargs'; import { TxResult } from '../../lib/tx'; import { TaskOnChain } from '../../lib/task-lens'; interface UnclaimArgs { org: string; task: string; chain?: number; rpc?: string; 'private-key'?: string; 'dry-run'?: boolean; yes?: boolean; preflight?: boolean; 'idempotency-key'?: string; 'no-idempotency'?: boolean; } /** * Gate a release on the v7 two-route rule. Returns true for a self-release, * false for a permitted third-party release of an expired claim; throws * PreconditionError (exit 4) on every disallowed state, BEFORE any transaction. * * `checkTaskStatus` cannot express this: its `claimerMustBe` is an AND applied * after the status gate, and there is no disjunction operator — so "the claimer * at any time OR a third party once expired" needs a hand-written gate, the * same escape hatch `gateClaimableTask` already is. `gateClaimableTask` itself * is NOT reusable here: it rejects CLAIMED-and-not-expired unconditionally, * which is the single most common unclaim case (a healthy self-release). */ export declare function gateUnclaimableTask(task: TaskOnChain, taskLabel: string, caller: string): boolean; /** * Pull the release facts out of the receipt logs. Deliberately NOT * `claimReceiptFields`: that helper looks for TaskClaimExpired, which unclaim * never emits, and would silently report nothing. */ export declare function unclaimReceiptFields(result: TxResult): Record; /** * Machine-readable companion to the human warnings below. * * `output.warn` is a no-op under `--json`, so every caveat echoed to a human * would otherwise be invisible to automation — which is the audience that most * needs the indexing one. These keys ride in the success payload instead. */ export declare function unclaimAdvisoryFields(chainId: number, raced: boolean): Record; /** * Human echo after a release. The subgraph-indexing warning is the load-bearing * one: TaskManager v7 is live on every chain, but only Gnosis indexes * `TaskUnclaimed` today, so elsewhere the release succeeds on-chain and is then * invisible to every read surface — the task keeps showing as claimed by the * previous assignee. That is not discoverable later, so it is said at the * moment it happens. * * `dryRun` short-circuits everything: nothing was sent, so claiming "the * on-chain release itself succeeded" would be a lie. */ export declare function echoUnclaimReceipt(fields: Record, task: TaskOnChain | null, chainId: number, opts?: { dryRun?: boolean; consentedAsSelfRelease?: boolean; }): void; export declare const unclaimHandler: { builder: (yargs: Argv) => Argv<{ task: string; } & { "idempotency-key": string | undefined; } & { "no-idempotency": boolean; }>; handler: (argv: ArgumentsCamelCase) => Promise; }; export {};