Skip to content

Add gated submissions API and agent intake skill - #1776

Merged
JasonWildMe merged 7 commits into
mainfrom
feat/submissions-api-pilot
Sep 28, 2026
Merged

JasonWildMe merged 7 commits into
mainfrom
feat/submissions-api-pilot

Conversation

@JasonWildMe

@JasonWildMe JasonWildMe commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Agents, partner apps and human users need durable uploads, validation previews and retry-safe import acceptance. This adds a disabled-by-default /api/v3/submissions resource alongside bulk import: draft, upload photos, supply JSON rows, validate, commit once, and retrieve source-row-to-record mappings. Existing bulk-import routes and defaults remain unchanged.

New submissions default to detection followed by individual identification matching. Explicit processing.mode=import-only skips both; saved submissions retain their original mode. Matching produces candidates for review, not automatic identity assignment.

Enrollment and human access

  • Site administrators explicitly assign api-submission in the context0 user editor. No UUID configuration or restart is needed for enrollment changes; even administrators need the role.
  • API Access offers Read data (default) and Data import. Data import requests submissions:write after password confirmation. The two token audiences remain separate.
  • Persisted enrollment is checked for writes and before imports execute. Revocation blocks subsequent writes and unstarted imports; owner status reads remain available. Already executing imports and existing records are unaffected.
  • Migration: submissions.allowedUserIds is ignored. Grant the role to existing pilot accounts during rollout. Global admission, commit and worker switches remain unchanged.

Included

  • Reuses existing validators, media/importer and detection pipeline, with strict configured-value validation, owned drafts, revision checks, idempotency keys, private staging and durable worker/recovery state.
  • Separate import, indexing, derivative and AI handoff statuses; dispatched reports handoff, not completed identification.
  • Compose staging mount, commented private settings, OpenAPI, resumable Python client, and operator instructions.
  • Imports page labels the column Source and identifies submission-origin imports as API.
  • Public agent skills explain exact formats, field-specific validation failures, recovery and the new token UI; skills updated last.
  • Actual Claude architecture, implementation and corrective reviews. Final correction approved. Role/UI review disposition.

Verification

  • Full Java regression/WAR build: 1,132 tests, zero failures/errors, seven skipped. Final rename correction then passed 20 affected authorization, PostgreSQL and agent-skill tests and WAR packaging.
  • API Access/token helper: 10 Jest tests passed; React production build completed with existing warnings. Contract checker passed all 11 operations and 21 examples.
  • Prior Flakebook staging test: 150 encounters/media imported; independent Claude audit verified exposed fields and all 150 original-photo hashes/sizes. Detections and embeddings were present. Eight deliberate validation failures returned the expected field errors; invalid commit returned 422 without creating a job.
  • Encounter search summaries remained partially stale after that live test; this is an outstanding indexing-consistency finding. Read-only evidence did not establish completion of every identification task.
  • The role enrollment and token UI follow-up has not yet been deployed or live-tested.

Deployment

Apply SUBMISSION metadata (including nullable AI_STATE and AI_STARTED_AT for earlier pilot schemas), private staging mount/permissions and private global settings. Deploy the frontend build as well as the WAR. The WAR excludes WEB-INF/web.xml, so apply the servlet/Shiro mappings through the installation descriptor process. Restart after first enabling the worker. Assign api-submission to pilot accounts, then verify Data import token issuance, admission and role revocation before widening access.

Pilot runbook · Agent skill

@JasonWildMe JasonWildMe added this to the 11.0 milestone Sep 24, 2026
@codecov-commenter

codecov-commenter commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.89%. Comparing base (dcf6f46) to head (b1408b2).

Files with missing lines Patch % Lines
frontend/src/models/auth/useMintToken.js 50.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1776      +/-   ##
==========================================
+ Coverage   54.84%   54.89%   +0.04%     
==========================================
  Files         314      314              
  Lines       12704    12717      +13     
  Branches     4006     4122     +116     
==========================================
+ Hits         6968     6981      +13     
  Misses       5441     5441              
  Partials      295      295              
Flag Coverage Δ
backend 54.89% <88.88%> (+0.04%) ⬆️
frontend 54.89% <88.88%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JasonWildMe
JasonWildMe marked this pull request as ready for review September 24, 2026 20:13
JasonWildMe and others added 6 commits September 24, 2026 17:07
dateIsInFuture compared submitted dates with the server JVM's local date,
so a submitter who was already a calendar day ahead of the server (for
example Australia or New Zealand against a UTC or U.S. Pacific host) had
their legitimate same-day observation rejected as "in the future". On a
UTC server this rejects Sydney's "today" for 10 hours a day; on a Pacific
server, 17 hours. The same edge rejected New Year's Day while the server
was still on December 31.

Compare against the current date at UTC+14, the earliest civil calendar
date on Earth, so any observer's local current date is accepted while
genuinely future dates are still rejected. Instant-based checks
(dateInMilliseconds) are unaffected. The shared helper also backs the
legacy bulk importer, EncounterForm, EncounterPatchValidator and
Encounter date setters, which all gain the same tolerance.

An overload taking an explicit "today" makes the tests deterministic,
replacing the previous test that depended on the server's local date.

Reviewed by Codex; its test-determinism finding is addressed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
Validation reports turned every legacy bulk-import rejection into
INVALID_VALUE "Value failed bulk-import validation". A future day or
month was reported on Encounter.year, parse failures leaked Java
exception text, and an unconfigured locationID produced two issues. An
agent following the skill could only guess, and tended to "correct" a
year that was right.

INVALID_VALUE issues now carry an optional, additive reason (REQUIRED,
REQUIRES_FIELD, UNPARSEABLE, OUT_OF_RANGE, FUTURE_DATE, NOT_CONFIGURED,
INVALID) and a specific message, for example "'F' is not a configured
sex value; use one of: unknown, male, female" or "2025-02 has no day
29". Where legacy validation replaced a supplied value's own error with
a generic "required value", the original cause is recovered. A future
date is reported on the year, month or day that is actually too late,
judged against the UTC+14 date captured before legacy validation runs.
The duplicate legacy location issue is suppressed only when
INVALID_LOCATION was already reported for that row.

Acceptance is unchanged: each legacy rejection still yields exactly one
issue, and valid, normalizedRows and the digests the importer re-checks
are untouched. Legacy bulk import messages are not modified.

The skill documents reasons and says to check the source observation
rather than change values to pass. Both OpenAPI copies describe reason
as an open list, the contract checker asserts parity with the Java
list, and tests run the real legacy validators so wording drift fails.

Plan and code reviewed by Codex; its findings on recovering
overwritten causes, future-date attribution (including a nonexistent day
that is also in the future), bounded allowed-value lists and a fixed test
clock with report-invariant checks are addressed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>

@naknomum naknomum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@JasonWildMe
JasonWildMe merged commit 51faa7b into main Sep 28, 2026
2 checks passed
@JasonWildMe
JasonWildMe deleted the feat/submissions-api-pilot branch September 28, 2026 19:00
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.

3 participants