Skip to content

feat(encord): add Encord curation SaaS workbench tool (push/pull) - #339

Open
jonlwowski012 wants to merge 20 commits into
nebius:mainfrom
jonlwowski012:encord-workbench-tool
Open

feat(encord): add Encord curation SaaS workbench tool (push/pull)#339
jonlwowski012 wants to merge 20 commits into
nebius:mainfrom
jonlwowski012:encord-workbench-tool

Conversation

@jonlwowski012

@jonlwowski012 jonlwowski012 commented Aug 24, 2026

Copy link
Copy Markdown

Summary

Adds an encord workbench tool: push media from the Nebius object store into
the Encord curation SaaS, curate headlessly with
quality filters
(or in the Encord app), pull curated media and labels back
to S3, and verify the roundtrip end-to-end — every artifact carrying exact
identity and content checksums.

flowchart LR
    S3[("Your S3 bucket")]
    ENC["Encord dataset<br/>(items carry exact<br/>npa.source_uri identity)"]
    CUR["encord curate<br/>(headless quality filters,<br/>evaluated server-side)"]
    HCUR{{"or: curate in the<br/>Encord app"}}
    COLL["Curated Collection"]
    OUT[("Curated media + labels<br/>+ lineage manifest, in S3")]
    VER["encord verify<br/>(identity + size + checksum,<br/>fail-closed)"]

    S3 -->|"encord push<br/>(bytes stay in your bucket)"| ENC
    ENC --> CUR --> COLL
    ENC -.-> HCUR -.-> COLL
    COLL -->|"encord pull"| OUT
    OUT --> VER
Loading

Two transfer modes:

  • register (the default everywhere: CLI, SDK, seed-demo, and every
    shipped spec but one): Encord references object URLs through an
    S3-compatible integration; source bytes never leave object storage. An
    empty --integration in this mode is rejected before any S3 or Encord I/O.
  • upload: media bytes are copied into Encord-hosted storage. The only
    shipped spec that opts in is encord-cosmos3-augment.yaml, whose default
    source is the packaged public CC-BY-4.0 starter clip; its config comment and
    the docs say to switch to register (plus an integration title) when pointing
    it at your own data.

Docs: docs/workbench/encord.md (setup through troubleshooting) and
docs/workbench/encord-headless-curation.md (the headless-curation design and
the live evidence behind the pinned Encord filter shape).

Identity and integrity (adopts the #363 model)

This PR adopts the exact-identity model from #363 onto the live-validated
transport — thanks to @ for the repro that motivated it:

  • Identity is never a filename. Every pushed item registers namespaced
    npa.source_uri clientMetadata; receipt lineage and dataset linking resolve
    through that metadata or the item's normalized objectUrl, and conflicting
    signals fail the item closed. Same-basename objects (ep_001/frame_0000.png
    vs ep_007/frame_0000.png) resolve to distinct items and percent-encoding
    aliasing (a%2Fb vs a/b) is handled in URI canonicalization — both pinned
    by regression tests. Resolution indexes the folder inventory once per pass,
    so a push over thousands of items stays linear.
  • Content integrity in the durable artifacts. Receipts record per-item
    source size, verbatim ETag, and content checksum (single-part ETag as md5 in
    register mode; streamed sha256 in upload mode); pulls hash downloads
    in-stream and record the destination ETag for zero-egress copies. A
    same-bucket copy that fails falls back to download and records copy_error
    in the manifest row, so paid egress is never silent.
  • encord verify joins receipt to manifest by Encord uuid
    (npa.encord.roundtrip_report.v1) and fails closed on: missing or
    unexpected items, size or checksum mismatches, a receipt whose status is not
    done (a write-ahead planned copy, a failed or timeout push), zero
    attributable items (0/0 is a failure, not a vacuous pass), and matched items
    with neither a comparable checksum nor a size on both sides
    (unverifiable). The report's defects list names receipt-level reasons.
    This is the machine-checkable form of any checksum claim; an overwrite
    between push and pull is exactly what it catches.
  • Write-ahead receipts. Push and curate land a status: planned receipt
    before the first Encord mutation, so an uncatchable kill (OOM, preemption)
    still leaves a durable record of intent — pinned by tests that assert the
    planned receipt is already durable when the first mutating SDK call happens.
  • Caller-side idempotency, both modes. Identities resolve against the
    folder before anything is sent: a retried stage makes zero registration
    round-trips and copies no duplicate bytes. Register mode never falls
    through to upload (pinned by test). Receipt counters (units_done,
    units_error) are one function of the per-item outcomes, so no item is ever
    counted twice or reported done without an attributable uuid.
  • Pull never loses a record. One item's failed signed-URL fetch (or any
    other per-item exception) becomes an error row; the manifest keeps every
    item that landed, so resume and cleanup can see what is in the prefix.

Headless curation

npa workbench encord curate --folder ... --filter brightness:0.2:0.8 --filter width:640:4096 --collection ... maps workbench-declared filters
over Encord's built-in quality metrics onto a run-scoped Encord filter preset
and lets Encord evaluate the selection server-side into a Collection — no
human in the app, no media movement. The undocumented per-metric filter JSON
was pinned by a live spike against the real SaaS (an invalid shape hangs
Encord's evaluation; the verb allowlists live-verified metrics and fails
closed on anything else). Zero selections fail closed with a diagnostic that
names the likely cause. A --collection that already holds items is refused:
Encord's evaluation only adds, so a stale selection could not be told apart
from this run's. The receipt records items_total and items_selected; the
transient preset (npa-curate-<run-id>, or a timestamped random-suffixed
title for ad-hoc runs) is deleted in a finally, after a crash as well as a
success, and preset_deleted records whether that delete went through.

What's included

  • npa.workbench.encord implementation (one module per verb, a SaaS seam that
    returns ResolvedRefs from one shared title-or-id resolution contract, and
    an S3-only artifact writer), the npa workbench encord push|curate|pull|verify|cleanup|seed-demo|system-info CLI on the shared
    workbench CLI helpers, and SDK wrappers for each verb. system-info is the
    management verb CONTRIBUTING asks new tools to expose (SDK pin, API domain,
    configured credential names — never values).
  • Every CLI verb carries @json_stdout_contract: --output json prints
    exactly one JSON document on stdout, including on failure. Only
    EncordToolError and path-contract violations are client errors (exit 1);
    anything else propagates to app_entry as exit 2 with the NPA_DEBUG
    traceback path intact. The contract decorator now reads enum-typed
    output_format values, which also activates it for the other enum-typed
    commands in the repo.
  • toolRefs workbench.encord.{push,curate,pull,verify,seed_demo}, credential
    hints (verify needs no Encord secret and its setup guard says so), and
    npa[encord] dependency support for image-less stages. The
    spec-declared-outputs guardrail pins push, curate, pull, and verify outputs
    to the tool's own *_uri_for helpers.
  • Encord credential preflight via health preflight --checks encord. Exactly
    two credential transports: ENCORD_SSH_KEY_B64 (pods) and
    ENCORD_SSH_KEY_FILE (laptops) — the truncation-prone raw-PEM paste is not
    accepted (pinned by test). A credential with no encord package installed
    is a WARN with a pip remedy, not a failed credential.
  • Pull media transfers run in a bounded parallel pool.
  • encord cleanup --title-prefix <npa-...-> tears down run-scoped Encord
    state (folders, collections, presets; datasets are reported — the SDK
    exposes no dataset deletion). All created titles embed the run id, which
    embeds a UTC timestamp.
  • Workflows: encord-push.yaml, encord-pull.yaml,
    encord-roundtrip-smoke.yaml (push → curate → pull → pull-curated →
    verify), encord-cosmos3-augment.yaml, and
    encord-cosmos3-groot-finetune.yaml (push → headless curate → pull →
    Cosmos 3 augment → materialize LeRobot episodes → GR00T fine-tune). All
    five are registered in the live submit matrix; groot-finetune needs
    --var encord_integration=<title> because it handles customer data in
    register mode.
  • Operator documentation, the headless-curation design note (next to the
    operator doc, since it applies to one tool), tool-catalog rows, skill
    guidance, and the skill-index lines in CLAUDE.md / AGENTS.md.

Also in this PR (small, cross-cutting)

Two fixes surfaced while running the Encord workflows live and were kept
here rather than split out, because each blocked the runs above:

  • StorageClient now bounds every boto network wait (connect_timeout=10,
    read_timeout=60, max_pool_connections=16): a stalled TCP connection
    during workflow-preflight source staging blocked a submit indefinitely.
    Pinned by a unit test; affects every tool that uses the shared client.
  • scripts/build_docs.sh guards an empty-array expansion that bash 3.2 (the
    macOS default) rejects under set -u.

parse_bucket_uri in npa.clients.storage is now public (its two private
importers migrated). The SkyPilot procfs probe on this branch is byte-identical
to main's #367 fix, so merging main is a no-op there.

Validation

Everything below is a checked-in test or a durable S3 artifact from a live
run on Nebius (eu-north1 managed Kubernetes, SkyPilot managed jobs):

  • Encord unit, CLI, and workflow tests cover identity regression (shared
    basenames, percent-encoding aliasing, conflict fail-closed), integrity,
    every verify fail-closed path (receipt status, zero items, unverifiable
    items, mismatches), write-ahead receipts landing before the first mutation,
    raw-PEM rejection, curate's preset lifecycle and populated-collection
    refusal, pull's per-item error rows and copy-fallback reason, push counter
    consistency and early integration validation, idempotency, cleanup,
    seed-demo, and system-info. Catalog argv, doc-sync, three-tier, spec-output,
    live-matrix, and skills-index guardrails are green.
  • Live roundtrip on encord-roundtrip-smoke, run
    encord-roundtrip-smoke-20260902T162808351118Z-ab1bfb (managed jobs
    100–104, all SUCCEEDED, on the code in this PR):
    • push registered 4 fixtures in place, each resolved by the metadata
      identity signal, md5 checksums recorded;
    • curate selected 3 of 4 (items_total 4) — the width filter excluded
      the deliberately low-res fixture, proving server-side filtering; the
      transient preset was deleted (preset_deleted: true);
    • dataset pull returned 4 items and curated pull 3, all zero-egress
      server-side copies, no copy_error;
    • verify passed: 4/4 matched, 4/4 checksums verified, 0 mismatched, 0
      unavailable, 0 unverifiable, no defects
      (verify/roundtrip_report.json
      in the run prefix);
    • encord cleanup then removed the run's folder (4 items) and collection
      and reported the one dataset the SDK cannot delete.
  • Register-mode re-push verified idempotent live (no registration
    round-trips, stable uuids).

Note on earlier evidence wording: a prior commit message claimed checksum
verification before the mechanism existed in-tree; this PR makes that claim
real and machine-checkable — the roundtrip report is the artifact, and the
claim now lives nowhere except where CI and the smoke can enforce it.

Boundaries

  • .mp4, .png, .jpg, and .jpeg are supported push inputs. MCAP cloud
    registration is not supported by the pinned Encord SDK upload format;
    .mcap inputs are recorded as receipt-visible experimental_error rows and
    fail closed rather than sending an inferred schema.
  • Composite Encord items (image groups, DICOM) have no single signed URL;
    pull records them as per-item errors.
  • Curate's computed quality metrics (brightness, sharpness, file-size) match
    nothing until quality metrics are computed for the folder — a one-time
    action in the Encord app with no public API. Intrinsic metrics (width,
    height, area, aspect-ratio) work on any folder immediately; the
    zero-selection error names the cause.
  • Curate populates only an empty or freshly created Collection; use run-scoped
    titles (the shipped specs do) or cleanup a stale one first.
  • The Encord SDK cannot delete datasets; cleanup deletes everything else
    and reports them.

Register-in-place push of S3 media into Encord through an S3-compatible
cloud integration (bytes stay in the bucket), plus an upload mode that
copies bytes into Encord-hosted storage. Pull materializes a curated
Collection, Dataset, or Project's labels back to S3 as media + per-item
JSON + a lineage manifest, with a zero-egress server-side copy fast path
for same-bucket items.

- npa.workbench.encord: schemas, SaaS client seam, push (batched
  registration + polling, synchronous uploads, receipt-first fail-closed),
  pull (per-source enumeration, copy/download transfer, LabelRowV2 export)
- CLI `npa workbench encord push|pull` + SDK wrappers; title-or-id
  resolution with create-if-absent on push only
- toolRefs workbench.encord.push/pull, secret-env hints, npa[encord]
  pip extra for image-less stages, stage setup secret guard
- encord credential preflight check (`health preflight --checks encord`);
  ENCORD_SSH_KEY / ENCORD_SSH_KEY_B64 supported end to end
- specs: encord-push, encord-pull (human curation between them), and
  encord-roundtrip-smoke (live e2e: push -> pull in one run, no human)
- MCAP discovery is receipt-visible experimental_error pending a
  supported cloud-registration format upstream
- scripts/build_docs.sh: guard an empty-array expansion so macOS bash 3.2
  can regenerate the CLI docs

Live-verified against Encord: register-mode roundtrip (3 items, all
server-side copies) and upload-mode roundtrip (3 items, SHA-256 of pulled
bytes matches the originals).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jonlwowski012
jonlwowski012 marked this pull request as draft August 24, 2026 23:25
@jonlwowski012
jonlwowski012 marked this pull request as ready for review August 24, 2026 23:27
@jonlwowski012
jonlwowski012 marked this pull request as draft August 24, 2026 23:27
jonlwowski012 and others added 13 commits August 25, 2026 01:27
Apply the reuse/simplification/efficiency/altitude findings:
- extract _register_items to mirror _upload_items; plain if/else dispatch
  replaces the empty-list loop gating; drop dead conditions and the unused
  StorageClient fallback in the JSON writer
- share _parse_bucket_uri from npa.clients.storage instead of a third S3
  parser; move the JSON writer to encord/storage.py (per-tool sibling norm)
- media filters as one FILTER_CATEGORIES table; unified PushedItem
  construction (mcap rows now never carry an objectUrl)
- pull: bulk-sign collection items via get_storage_items (removes N
  per-item round-trips), list label rows once (PullSource carries them),
  linear expired-URL retry, media_bytes as a comprehension
- single-source CLI/SDK defaults from schemas constants; trim restated
  defaults from the smoke spec
- hydrate ENCORD_* names in load_credentials (env over file, like HF/TF),
  making check_encord a pure tokens-only check and collapsing the client's
  ad-hoc env merge; preflight names now import from the client constants
- drop dead test-fake fields; pin hydration with a credentials test

94 encord/preflight/health tests, 113 guardrail/workflow tests, ruff green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs/workbench/encord.md walks a human through everything needed to use
the Encord tool: API key creation, the S3-compatible integration for
register mode (endpoint, read keys, strict client-only access, CORS),
credentials.yaml wiring (key-file path recommended over PEM paste), the
preflight gate, push/curate/pull usage, the three workflow specs with
secret forwarding, and a troubleshooting table built from failures
observed live (truncated PEM paste, integration read denials, MCAP
boundary, composite items, US domain). Indexed in docs/workbench/README
and cross-linked from the skill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One mermaid figure showing the full loop: S3 media -> push (register
objectUrls by default, upload bytes as the dashed variant) -> Encord
folder/dataset via the read-only cloud integration -> human curation ->
Collection/Dataset/labels -> pull back to S3 (zero-egress server-side
copy for registered media, signed-URL download for Encord-hosted), with
the durable receipt/manifest called out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Guard DataRow.backing_item_uuid: the SDK property RAISES
  NotImplementedError on legacy rows without Storage-API backing, so
  getattr's default alone crashed dataset pulls
- Receipt/manifest now land even when a step throws after Encord or the
  output prefix was mutated (link_items failures, mid-loop S3 errors,
  label-export crashes); the run exception is recorded in a new `error`
  field and re-raised chained
- Re-push now re-links: register mode resolves the folder's items by
  name so skip_duplicate_urls re-pushes still link the dataset instead
  of silently reporting done with linked_count 0; docs narrowed to say
  upload-mode re-push creates new copies
- Remove a merge-resurrected duplicate _resolve_auth_env; empty-value
  guards on resolve_project/resolve_collection; health preflight help
  strings mention the encord check
- New tests: raising backing property, receipt-on-link-crash,
  manifest-on-label-crash, expired-signed-URL refetch retry, re-push
  relink, empty-source manifest-then-raise (33 tool tests green)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Index the encord skill in AGENTS.md and CLAUDE.md (required when the
  skill list changes)
- Add the three encord specs to SUBMIT_LIVE_MATRIX: the roundtrip smoke
  as the executable daily twin, push/pull as rotation-skipped
  human-in-the-loop halves with machine-checked skip reasons; narrow
  SECRET_ENV_HINTS to the base64 transport form the matrix declares
- Python SDK usage example in the operator guide (human-docs contract)
- Workflow tests assert the specs' CPU-only resource blocks
- Drop a merge-stale HF_PROBE_REPO from credential_preflight __all__
  (upstream removed the constant; fixes the ruff F822 lint gate)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
encord-cosmos3-augment.yaml runs the Encord loop's post-curation half in
one submit: pull an Encord source, stage the selected item at a
deterministic URI, augment it with a real Cosmos 3 video2video pass, and
push the result back into Encord as npa-aug-<run-id>.

Runs out of the box on repo-pinned data: a seed stage uploads the
packaged PAIDF starter clip (public, CC-BY-4.0, SHA-256-verified, fetched
through the existing verified-cache machinery) into a run-scoped
npa-demo-src-<run-id> dataset, and the default transfer is upload so no
cloud integration is required — only the Encord API key. Overriding
encord_source_id with a real curated Collection/Dataset id makes the
seed stage a no-op, and encord_transfer=register restores in-place
registration through an integration.

npa.workflows.encord_loop provides the two glue stages: seed_demo_source
(skip-aware seeding via the tool's own SDK) and stage_media_for_augment
(pull names media by item uuid, which a spec cannot know; this bridges
the manifest to the URI cosmos3 generate conditions on, failing closed
on missing/failed/out-of-range items).

Registered as an executable gpu case in SUBMIT_LIVE_MATRIX (self-seeding
makes it standalone), wired into the skill smokes and operator guide.
14 unit/workflow tests; validate-spec/plan-spec render all five states.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The live default-path run caught the gap: the seed stage was run.argv
glue with no toolRef, so TOOL_REF_PIP_EXTRAS never installed npa[encord]
on the default image and the stage died with "encord SDK is not
installed". Promote seeding to a proper CLI verb (`npa workbench encord
seed-demo`) and catalog toolRef (workbench.encord.seed_demo): the
workbench.encord prefix now matches the pip-extra and secret-hint wiring,
the argv guardrail audits the flags, and the skip-when-curated contract
is CLI-testable. Spec, catalog doc row, and tests updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jonlwowski012
jonlwowski012 marked this pull request as ready for review August 31, 2026 17:37
@timothy-le7

Copy link
Copy Markdown
Collaborator

My main workflow comment is that a user should be able to leverage headless encord capabilities from workbench. It makes sense to have the ability to operate in Encord, but we should think from how an agent would drive this and minimize human in the loop

jonlwowski012 and others added 6 commits September 1, 2026 17:12
Close the human-in-the-loop gap and adopt the identity/integrity model
from nebius#363 into the live-validated transport:

- curate: workbench-declared quality filters (brightness, width, ...)
  mapped onto a live-verified Encord filter-preset shape and evaluated
  server-side into a Collection - no human in the app. Fails closed on
  zero selections, empty folders, and unknown metrics; re-issues the
  one-shot evaluation to absorb metric-indexing lag; deletes its
  run-scoped preset after evaluation.
- Exact identity replaces filename matching: every item registers
  namespaced npa.source_uri clientMetadata, lineage resolves through
  metadata or normalized objectUrl only, and conflicting signals fail
  the item closed. Same-basename objects resolve to distinct items.
- Content integrity: receipts record source size/ETag/checksum, pulls
  hash downloads in-stream, and a terminal verify verb joins receipt to
  manifest by uuid and fails closed on missing items or size/checksum
  mismatches (npa.encord.roundtrip_report.v1).
- Write-ahead receipts land before the first Encord mutation (push and
  curate), so an uncatchable kill still leaves a record of intent.
- Caller-side idempotency in both transfer modes: identities resolve
  before anything is sent, so retried stages re-register nothing and
  copy no duplicate bytes.
- Pull transfers run in a bounded parallel pool.
- cleanup verb tears down run-scoped Encord state by title prefix
  (datasets are reported; the SDK cannot delete them).
- Credential transports reduced to ENCORD_SSH_KEY_B64 (pods) and
  ENCORD_SSH_KEY_FILE (laptops); the truncation-prone raw-PEM paste is
  no longer accepted.
- encord-roundtrip-smoke becomes push -> curate -> pull -> pull-curated
  -> verify; encord-cosmos3-groot-finetune curates headlessly between
  push and pull and fine-tunes GR00T on the augmented episodes.

Live evidence (Nebius eu-north1, managed jobs 90-94): all five stages
green; curate selected 3 of 4 fixtures (width filter excluded the
low-res thumbnail); verify passed with 4/4 matched and 4/4 checksums
verified; register-mode re-push confirmed idempotent with stable uuids.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	npa/src/npa/cli/workbench/__init__.py
…buted items

KISS pass over the new transport code:

- Drop the dead (uuid, name) pair accumulation in register/upload — lineage
  has been exact-identity-resolved since the nebius#363 adoption, so the transfer
  helpers now return plain (done, errors, status).
- A registered item that exact identity cannot attribute after the
  post-registration re-list now fails the push closed instead of surviving
  as a silently unlinked receipt row; verify's unresolved branch becomes
  impossible and is removed (relation vocabulary shrinks to
  matched | missing | unexpected).
- Pull's parallel transfers use a plain pool.map: a per-item metadata write
  failure is recorded on the item (fail-closed via media_failed) instead of
  the futures/first-error machinery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The local API daemon cwd probe walks /proc, which does not exist on macOS
operator workstations. procfs-absent meant every Darwin submit failed with
procfs_unavailable before anything launched. Cannot-assess is not
unhealthy: return a healthy procfs_unsupported probe when the proc root
does not exist, restoring pre-probe behavior on platforms where the
poisoned-cwd failure mode was never detectable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace this branch's `procfs_unsupported` short-circuit in
_probe_local_api_daemon_cwd with the fix that landed on main in nebius#367
(`procfs_unavailable_darwin`), file and test byte-identical to origin/main.
Both changes solved the same macOS submit failure; keeping ours would have
merged cleanly but shadowed main's block and failed its test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Standards (CONTRIBUTING, npa-cli-conventions, add-workbench-tool):
- CLI verbs use the shared OutputFormat/emit/fail helpers and carry
  @json_stdout_contract; the contract now reads enum output_format values
- seed-demo moves into the tool (npa.workbench.encord.seed_demo) with an SDK
  wrapper; new system-info management verb (SDK pin, domain, credential
  transport names only)
- resolvers return ResolvedRef through one title-or-id contract; schemas
  type every enumerated field as a Literal; artifacts are S3-only
- parse_bucket_uri is public; ENCORD credential names come from
  npa.clients.credentials; design note moves next to the operator doc

Fail-closed fixes from review:
- curate refuses a Collection that already holds items (add_preset_items
  only adds, so a stale selection would read as this run's) and records
  items_total and preset_deleted; presets are deleted in a finally
- verify fails on planned/failed receipts, zero attributable items, and
  matched items with neither a comparable checksum nor a size
- pull keeps every item's record when one signed-URL fetch raises and
  records copy_error when the zero-egress copy falls back to download
- push derives units_done/units_error from item statuses (no double count),
  always sends identity metadata on upload, resolves identities through an
  indexed inventory (O(N) instead of O(N x inventory)), and rejects an empty
  --integration in register mode before any I/O (seed-demo too)
- preflight reports a missing encord SDK as WARN with a pip remedy;
  the setup credential guard no longer applies to encord.verify;
  verify path errors name --receipt-uri/--manifest-uri
- groot-finetune spec defaults to register (customer data stays in the
  bucket); augment is the one documented upload opt-in; groot-finetune is
  registered in the live submit matrix

Verified live: encord-roundtrip-smoke run
encord-roundtrip-smoke-20260902T162808351118Z-ab1bfb (jobs 100-104), verify
passed 4/4 with 4 checksums verified; curate selected 3 of 4.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

2 participants