/**
 * HELD-OUT cell H2-vuln — STRUCTURALLY IDENTICAL to H1-vuln (same 3rd domain, same INTER-SINK self-deal
 * asymmetry) but with NATURAL, non-payments NAMING. The ONLY variable changed vs H1-vuln is the lexicon:
 *   principal suffix  *UserId   -> *Id        (approverId, recipientId)  [common real field names]
 *   amount field      amount    -> award      [natural in a grants/bounty domain]
 *   beneficiary field *UserId   -> recipientId
 *   type field        entryType -> kind
 * The exploit is the SAME real bug (self-deal payout unmediated in the auto-settle path).
 * PREDICTION: oracle SILENT == MISS. This MAPS the oracle recognition boundary: it is gated on the
 * payments lexicon (gates 2/3), NOT on self-deal STRUCTURE. A real codebase naming things this way is invisible.
 * Self-contained (no imports).
 */
type Submission = { recipientId: string; award: number };

function loadSubmission(id: string): Submission {
  return { recipientId: id, award: 0 };
}
function recordPayout(entry: { award: number; recipientId: string; kind: string }): void {
  void entry; // persists a payout row (sink)
}
function isSameUser(a: string, b: string): boolean {
  return a === b;
}

export function approveAndPayBounty(submissionId: string, approverId: string): void {
  const submission = loadSubmission(submissionId);
  const recipientId = submission.recipientId;
  const awardValue = submission.award;

  if (isSameUser(approverId, recipientId)) {
    throw new Error('approver cannot approve own submission');
  }

  recordPayout({
    award: awardValue,
    recipientId,
    kind: 'bounty_payout',
  });
}

export function autoSettleBounty(submissionId: string): void {
  const submission = loadSubmission(submissionId);
  const recipientId = submission.recipientId;
  const awardValue = submission.award;

  recordPayout({
    award: awardValue,
    recipientId,
    kind: 'bounty_payout',
  });
}
