Skip to content

feat(jit): a person names the record check's idempotency key at confirm_params - #1339

Merged
abrichr merged 2 commits into
mainfrom
claude/jit-idempotency-key
Oct 19, 2026
Merged

abrichr merged 2 commits into
mainfrom
claude/jit-idempotency-key

Conversation

@abrichr

@abrichr abrichr commented Oct 19, 2026

Copy link
Copy Markdown
Member

Addresses the idempotency-key refusal in #1329. The other refusals in that issue are correct, and this PR doesn't change them; see the analysis comment on the issue.

Problem

The openIMIS claim program's mined record check already selects the saved claim by the confirmed claim_no parameter, with expected_count=1. It carried no idempotency_key, so clinical-write's require_idempotency_key_for refused the save step (step_015). One run can't show which input identifies a record, so this needs a person to name it.

Change

  • confirm_params(..., idempotency_key="claim_no"), on both CompiledAgent and lifecycle, and openadapt-flow jit review --idempotency-key claim_no.
  • The parameter must be a task parameter that a mined record_written check selects its record by. A placeholder check doesn't count, and neither does a parameter bound to two fields. Otherwise it refuses and lists the parameters it could take.
  • The check gets idempotency_key=ValueExpr(param=...) and key_field=<that field>. The bundle is re-sealed and the recorder re-signed for the new digest, as after the parameter recompile. The params record and status() list the keys.
  • The gate is unchanged. At run time the check counts records carrying the run's claim number and refutes more than one. This is the same rule verify.yaml's record.duplicate_key applies in qualify.

It detects a duplicate after the write; it doesn't prevent one. Name a key only when the app keeps the value unique.

Evidence

The recorded openIMIS first run (launch-4, #1303), rebuilt offline on #1303 + #1336 + this branch. No model calls.

  • Before: require_reviewed_action_risk on step_002 and step_012, require_human_approval_below_confidence on step_012 and step_015, and require_idempotency_key_for on step_015.
  • After, with idempotency_key="claim_no": the key is bound on step_015 (claim_no), confirm and review succeed, and only the four risk and confidence violations remain. Still not admitted.

Tests

tests/test_jit_lifecycle.py, synthetic claim bundle:

  • the key binds, the policy predicate sees it, the digest is re-pinned, and the review passes;
  • the runtime judge confirms one claim with the run's number and refutes two;
  • no key leaves the check unkeyed;
  • a non-parameter is refused;
  • a parameter the check doesn't select by is refused, with the candidates listed;
  • a placeholder check takes no key;
  • the CLI flag works.

Results:

  • tests/test_jit_lifecycle.py: 55 passed.
  • tests/test_jit.py and tests/test_jit_surface_pixels.py: 41 passed.
  • I didn't run the full suite because of host load.

This adds no new command (an option on jit review), so CAPABILITIES.md doesn't change. docs/JIT.md (Parameters) is updated.

🤖 Generated with Claude Code

…rm_params

The openIMIS claim program's mined record check already selects the saved
claim by the confirmed claim_no parameter, but carried no at-most-once key,
so clinical-write's require_idempotency_key_for refused it (#1329).

confirm_params (and `jit review --idempotency-key PARAM`) takes the
parameter that identifies one saved record. It must be a task parameter
that a mined record-written check selects by (placeholders don't count);
otherwise it refuses and lists the parameters it could take. The check gets
idempotency_key=param and key_field=that field, the bundle is re-sealed, and
the recorder is re-signed for the new digest, as after the parameter
recompile. The params record and status() list the keys. The gate is
unchanged.

Refs #1329

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y-key

# Conflicts:
#	packages/flow/docs/JIT.md
@abrichr
abrichr merged commit dac20a2 into main Oct 19, 2026
41 checks passed
@abrichr
abrichr deleted the claude/jit-idempotency-key branch October 19, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant