content-workflow-articulation
Use this workflow skill to sequence four reusable atomic skills:
content-articulation-inspection, content-articulation-proposal,
content-articulation-review, and content-articulation-authoring. usd-cli
provides source inspection; Joint Agent is an optional proposal leaf and owns
Stage 2 readiness only when selected; deterministic workflow code owns exact
saved-readback preparation, review bindings, accepted-only authoring, resume,
cancellation, saved-stage readback, and publication.
The default public CLI launches exactly one long-running child with a compact
task. The child invokes focused prepare and apply steps through the shared
runner. --execution-mode fixed is an explicit compatibility controller only.
For a shared outer-selected asset graph, obtain the stable
articulation.preparation-publisher.v1 and
articulation.proposal-provider.v1 descriptors from
articulation_asset_leaf_catalog(). The domain adapter binds their exact
invocation/result schemas and the proposal-to-preparation dependency only. It
does not select, order, invoke, or terminalize graph nodes;
those operations remain owned by the sole outer coordinator. Put the selected
typed invocation below its leaf-attempt directory and call the descriptor
entrypoint with --invocation; preparation derives
articulation-preparation-publication/ and proposal derives
articulation-proposal-attempt/ beside that host-chosen envelope. Both are
create-only, so retry or replacement requires a fresh host-selected attempt
directory. Never put an output path, HTTP endpoint, or credential source in
selected-leaf data, and never mix that artifact with direct CLI flags.
When embedded under content-workflow-asset, the outer asset coordinator is
the only reasoning loop. Invoke the first articulation run with the active
--embedded-run-state, inspect articulation_agent_observation.json, and use
the same focused apply step. The native request binds the exact outer request,
coordinator plan, attempt, input handoff, and nested domain-run root. Never
launch a nested coding agent or replace the bound request after its exact outer
review or any selected human review.
When to Use
Use for prompt-driven articulation work that must expose uncertain candidates,
survive interruption, or prove that the saved joint graph exactly matches the
approved candidate set. Typical requests mention drawers, hinges, sliders,
doors, mechanisms, joints, or articulated components.
Limitations
- Articulation-v1 authors only revolute and prismatic joints.
- Provider-neutral preparation does not create render or usd-cli evidence. Its
public producer derives all six preparation records from an exact retained
source/dependency/configuration closure plus complete saved readback. Exact
per-prim ownership/disposition authority comes from the retained
configuration and must match the saved observation. The create-only publisher
fails closed on unsafe paths, links, stale bytes, incomplete coverage,
destination reuse, or readback drift.
- A selected replacement proposal provider is a separate public leaf. Its
invocation binds one retained
artifact-json payload; trusted standalone
operators may instead call the explicit http-json direct adapter. Both are
advisory only and never fall back to Joint inference or classic execution.
Every invoked attempt writes one immutable terminal receipt for success,
provider failure, invalid response, or bound replacement while create-only
storage remains writable. Irrecoverable terminal storage failure is an
infrastructure error that poisons the root. Preserve a failed attempt root
and use a new root for every retry or replacement.
- Current provider-neutral runs must produce canonical post-authoring visual evidence
through the shared OVRTX leaf, bind its exact output/dependency/report/image
identities, and include those image digests in the outer post-readback review.
This evidence is a review input, never a deterministic visual pass.
- Human approval does not promote a native Stage 2
review_required candidate.
Re-run Joint Agent adjudication or reject that candidate.
- Authoring is topology-only: masses and colliders remain false.
- Provider-backed preparation requires a healthy workflow-owned usd-cli session and captures
digest-bound source, topology, property, camera, response, and focused-render
evidence before review.
- Source inspection is fail-closed at 4,096 snapshot prims. Split or simplify a
larger inspection scope before retrying; renders do not start for a truncated
snapshot.
- One collection supports at most 8 configured view directions and 256 focused
renders. Reduce directions or candidate moving-part coverage before retrying.
- Skill-routed execution sends every candidate through its evidence-bound agent
decision patch.
--review-policy none publishes that decision as the review
receipt; both uncertain and all retain the fail-closed all-candidate
operator review gate. Frozen v1/v2 deserialization retains its historical
review semantics; the current provider-neutral leaf does not emit that legacy
compatibility shape.
- usd-cli and the workflow host must resolve the same source and run paths.
- Provider-backed inference and rendering still depend on the backends selected by the
copied Joint Agent config.
Prerequisites
From the repository root, set up and activate the Python 3.12 environment:
./scripts/setup_content_agent.sh
uv pip install --python .venv/bin/python -e "apps/joint_agent[dev]"
mkdir -p runs/configs
cp apps/joint_agent/configs/byoa_joint_rigger.yaml \
runs/configs/file-cabinet-joint.yaml
source .venv/bin/activate
For provider-backed runs, load usd-cli for source inspection and evidence
renders. The workflow owns one local sidecar for the session.
Load usd-cli and the four atomic Articulation skills named above.
Provide a local USD-family source. For provider-backed runs, also provide a
copied Joint Agent BYOA config and configure its model/render backends. For a
provider-neutral standalone or embedded run, provide either a validated
EmbeddedArticulationPreparation or publish one from a complete retained
ArticulationPreparationInspectionReadback.
Instructions
Before the numbered workflow, provider-neutral callers that begin from saved
inspection readback run:
content-workflow-cli articulation publish-preparation \
--readback path/to/articulation_preparation_readback.json \
--retained-root path/to/retained-inspection \
--output-dir runs/preparation-publication
content-workflow-cli articulation validate-preparation \
--publication runs/preparation-publication/articulation_preparation_publication.json
The producer takes no source_members or authoritative_owners arguments; it
derives both from exact retained configuration membership rows, rejects a saved
readback observation that differs from them, and publishes
articulation_preparation_publication.json beside the preparation in a fresh
directory. Revalidate the returned publication path before passing its
preparation onward. The exact models, artifacts, and terminal rules are
specified in agentic/docs/articulation_preparation_attempt_contract.md.
- If the outer reasoner explicitly selected an alternate proposal provider,
start from a preparation with
proposal_status=not_evaluated and run
content-workflow-cli articulation propose with exactly one adapter. Use its
separately written bound preparation and terminal receipt. A provider,
transport, HTTP, response-schema, request-drift, or local-publication failure
is a typed terminal failure, not unavailable or pass. Validate the terminal
through content-workflow-cli articulation validate-attempt. For an
explicit replacement, bind the exact prior terminal receipt and use a fresh
attempt root. If no provider was selected, retain not_requested and skip
the proposal leaf.
- Run
content-workflow-cli articulation run with the exact prompt, source,
run directory, review policy, motion types, and candidate-count bounds. Use
--joint-config for provider-backed compatibility, --preparation for a
provider-neutral standalone run, or --embedded-preparation together with
--embedded-run-state for outer Asset custody. Standalone launches exactly
one child through workflow=articulation.author; embedded launches none.
Neither provider-neutral route constructs JointAgentLocalClient or invokes
joint_agent.api.pipeline.
- Inspect
articulation_agent_observation.json and its bound evidence. In
standalone mode the sole child writes the complete typed decision patch. In
embedded mode the outer coordinator authors the complete ordered canonical
graph. Any provider candidate document is optional proposal evidence only.
- Persist an explicit outer
accept, reject, or revise disposition in the
patch for the exact canonical graph. Also select not_requested human review
or human_required with a frozen task-policy or fail-closed escalation
reason. Neither human status is an outer-review disposition or implicit pass.
- Apply the patch through the focused step. It fails before publication on a
stale revision, changed digest, incomplete IDs, unsafe edit, unbound path, or
absent exact outer review. Outer rejection or revision blocks mutation.
Standalone
parent_unresolved, axis_missing, endpoint, frame/limit,
membership, or readback issues produce an immutable candidate-bound packet
and permit only one focused replacement attempt. Exhausting that cap is a
conditional terminal result, never success.
- If
human_required leaves the result at needs_review, inspect
agent_reviewed_articulation_candidates.json together with the original
articulation_candidates.json and scene_evidence/manifest.json.
Human review must cover the exact agent-reviewed document that authoring
will consume. Review each candidate's endpoints, axis, confidence,
readiness, unresolved reasons, properties, and focused renders.
- Write one human
accept, reject, or revise decision for every ID printed
under review_required_candidate_ids. Never accept a candidate that is not
native-ready for its requested articulation-v1 motion type.
- Run
content-workflow-cli articulation review. It binds the decisions, the
exact agent-reviewed candidate digest, and the usd-cli evidence digest
into one receipt and immediately resumes. An all-accept decision proceeds;
reject remains terminal. For revise, preserve the conditional checkpoint and
use the refreshed v4 observation's graph_revision_inputs to bind the exact
persisted human decision and complete outer decision file, then create a
typed immutable graph revision patch. Run
content-workflow-cli articulation revise-graph --run-dir <run> --revision-patch <patch>; it archives the exact parent graph/review,
publishes a revised graph without authoring, and reopens complete human
review at the revised digest. Do not edit the parent graph or reuse its
acceptance.
- After an interruption, run
content-workflow-cli articulation resume with
the same run directory. Repeating the exact original run command also
resumes. Do not change source, intent, config, or evidence policy in place.
- After deterministic authoring and saved-stage readback pause at
awaiting_post_review, run
content-workflow-cli validate produce-canonical-visual-evidence on the
exact authored output with the original source and an explicitly selected
remote or ovrtx shared backend. Then run
content-workflow-cli articulation bind-output-evidence with the emitted
verified_operation_envelope.json. A standalone visual payload is not
sufficient because Joint must retain and reverify the shared producer,
tool, backend, verifier, and projector chain.
- Inspect every bound canonical image. Persist the mode-specific post-review
patch that
accepts, rejects, or revises the exact execution result, accepted graph,
output-evidence digest, and complete ordered image-digest list; apply it
through the focused finalization step. Absence or substitution of any output,
dependency, render report, image, or metadata binding fails closed.
Populate every digest from the exact bound artifact or receipt with
deterministic shell or structured-JSON tooling; never retype, reconstruct,
or copy a shortened digest from prose or terminal display. Before invoking
finalization, validate that every required SHA-256 value is exactly 64
lowercase hexadecimal characters and matches the current artifact bytes.
- Treat only
completed as success. Provider-neutral standalone completion
uses the v5 checkpoint and terminal receipt. It means owned_core authored the exact
accepted IDs, the saved output passed exact graph readback, canonical OVRTX
evidence remained intact through outer review, and the terminal receipt
binds all of them. Mock completion uses simulated validation and is test
evidence only.
- When separately selected, project completed graph/apply, retained Gate 3A,
retained Gate 3B, or trusted dynamic results with the corresponding public
articulation project-* leaf. Feed each emitted envelope to
validate ingest-verified-operation-result; projection revalidates native
Joint facts but never runs inference, simulation, rendering, or shared
Validation execution. Gate 3A/3B projection requires the canonical retained
root layout, exact plan, intake, authoring receipt, closeout, and report. The
authoring receipt supplies the generated identities published by the real
static workflow; do not synthesize a standalone identities document or
substitute source/output bytes.
- For
conditional, retain the output and inspect unresolved IDs plus
validation_evidence.json when validation ran; pre-authoring conditionals
have no output or validation artifact. For cancelled or failed, preserve
the run for diagnosis and restart with a new run directory; those
checkpoints are terminal.
File-Cabinet Scenario
Run the practical six-drawer acceptance scenario:
ARTICULATION_INTENT="Identify the six drawers, present every candidate for "
ARTICULATION_INTENT+="review, then author exactly six prismatic drawer joints "
ARTICULATION_INTENT+="and no masses or colliders."
content-workflow-cli articulation run \
--usd /data/sm_filecabinet_d01_01.usdz \
--joint-config runs/configs/file-cabinet-joint.yaml \
--output-dir runs/file-cabinet-articulation \
--intent "$ARTICULATION_INTENT" \
--review-policy all \
--allowed-motion-type prismatic \
--expected-candidate-count 6 \
--max-candidate-count 6
After inspecting the candidates and usd-cli renders, create
runs/file-cabinet-decisions.json with every printed candidate ID:
{
"candidate_0001": "accept",
"candidate_0002": "accept",
"candidate_0003": "accept",
"candidate_0004": "accept",
"candidate_0005": "accept",
"candidate_0006": "accept"
}
Use the exact IDs printed by the run; the file must contain one decision for
every review_required_candidate_ids value. Resume through the review command:
content-workflow-cli articulation review \
--run-dir runs/file-cabinet-articulation \
--decisions-json runs/file-cabinet-decisions.json \
--reviewer asset-owner
The --review-policy all setting prevents silent auto-approval. A native Stage
2 review_required candidate remains non-authorable even if the receipt says
accept; reject it or rerun Joint Agent adjudication with stronger evidence.
Python Interactive API
For a long-running Python host, call
content_agent_workflows.articulation.run_interactive_articulation_workflow,
build digest-bound decisions with build_articulation_review_receipt, and pass
an Articulationusd-cliEvidenceCollector implementation when usd-cli
evidence is required. Keep the same request, client configuration, collector
configuration, and run directory across calls.
CLI-created runs are batch-mode checkpoints and are resumed with the CLI
commands above. The CLI does not adopt a separately constructed Python
interactive checkpoint.
Embedded interactive and batch callers use the same public
EmbeddedArticulationPreparation and
prepare_embedded_articulation_workflow API. Proposal fields may be absent; the
preparation records that optional leaf as not_requested or not_evaluated,
never as a pass. The outer coordinator must explicitly accept, reject, or revise
the exact persisted graph. Human review is not_requested by default and is
human_required only when frozen task policy selects it or ambiguity,
unsupported facts, or contradictory evidence require fail-closed escalation.
Graph-derived authoring, saved-stage readback, and outer post-review remain
mandatory in both modes. Current public embedded runs additionally require the
shared canonical OVRTX payload and a v2 output-bound post-review; v1/v2
compatibility artifacts retain their historical post-review contract.
Use select_embedded_articulation_human_review_policy from deterministic
Python workflow code for the current v3 outer patch; it is an SDK policy
helper, not a launcher subcommand. It returns not_requested when no live task-policy, ambiguity,
unsupported-fact, or contradictory-evidence gate exists, and human_required
with exact reasons otherwise. Do not serialize those current fields into frozen
v1/v2 patches; their compatibility behavior remains an unconditional human
gate.
Output Format
request.json
articulation_preparation_publication.json and
embedded_articulation_preparation.json when preparation is published from
complete retained saved readback
embedded_articulation_preparation.json for provider-neutral embedded runs
- replacement-provider request, native payload, v2 proposal, and bound
preparation artifacts when the optional public proposal leaf was selected
articulation_proposal_attempt_terminal.json for every invoked provider
attempt, including failures and explicitly bound replacement attempts
- optional
inference_result.json and provider proposal for provider-backed runs
- Joint Agent predictions and candidate report referenced by
inference_result.json
articulation_candidates.json
scene_evidence/manifest.json, source snapshot, topology and property
inspection, and candidate-focused image, response, and camera artifacts
articulation_agent_observation.json, decision patch, reviewed candidates,
and immutable decision ledger
embedded_articulation_outer_review.json after exact outer graph review
graph_revisions/revision-NNN/graph_revision.json plus immutable revised
graph, outer review, and coordinator decision after a human revision
- optional
review_receipt.json after selected human review
approved_articulation_candidates.json after approval
authoring_request.json and authoring_result.json after authoring starts
joint_rigger/authoring_attempt.json, diagnostics.json, and result.json
validation_evidence.json after validation
embedded_articulation_output_evidence.json after binding shared canonical
OVRTX output evidence
embedded_articulation_post_review_patch.json and
embedded_articulation_terminal_receipt.json after accepted output review
- optional Joint verified-operation projection/envelope artifacts for
graph/apply, Gate 3A, Gate 3B, or dynamic results when those leaves are
separately selected
checkpoint.json
workflow_progress.json
final_summary.json
joint_rigger/rigged.usdz plus Joint Rigger diagnostics and result evidence
Troubleshooting
- If a receipt or usd-cli evidence digest differs, do not edit it in place.
Reopen the current evidence and build a new run or valid receipt.
- If a proposal attempt is terminally failed, invalid, or replaced, preserve
that root. Never add a success artifact to it or reuse it; start a fresh root
and bind the prior terminal receipt when replacement is explicit.
- A failed or interrupted usd-cli capture may retry from checkpointed Joint
Agent inference and candidate artifacts. Only a complete, verified manifest
skips collection; incomplete capture artifacts may be replaced during retry.
- A workflow
failed result is a terminal, diagnostic checkpoint. resume
returns the same verified failure instead of retrying a possibly
non-idempotent backend phase. Preserve that run and use a new run directory
after correcting a transient backend problem.
- For a Joint provider terminal, follow the exact
recovery_action. resume
with resume: true and clean: false reuses the named checkpoint and its
digest-bound provider journal in the same work directory. restart with
resume: false and clean: true means the evidence is unavailable or
untrusted: preserve the failed directory for diagnosis and start the same
request in a new clean run directory. Never reinterpret one mode as the other
or delete the failed evidence in place.
- Changing the usd-cli evidence policy or another digest-bound collector
setting invalidates evidence reuse. The collector configuration digest
is bound into the request. Preserve the old run and start a new request when
changing it.
- If a candidate is native
review_required, do not flip its status. Correct
the source evidence through Joint Agent adjudication.
- If resume reports source, configuration, candidate, or output drift, preserve
the run for diagnosis and start a new run for changed inputs.
- If exact readback fails, keep the conditional artifact but do not claim
completion.
1---2name: content-workflow-articulation3description: Run durable Joint Agent articulation-v1 workflows that bind usd-cli inspection evidence, pause for explicit review, resume without repeating completed phases, author only approved revolute or prismatic joints, and verify exact saved USDZ readback. Use when prompt-driven joint, drawer, hinge, slider, mechanism, or articulation work needs the isolated agentic workspace.4---56# content-workflow-articulation78Use this workflow skill to sequence four reusable atomic skills:9`content-articulation-inspection`, `content-articulation-proposal`,10`content-articulation-review`, and `content-articulation-authoring`. usd-cli11provides source inspection; Joint Agent is an optional proposal leaf and owns12Stage 2 readiness only when selected; deterministic workflow code owns exact13saved-readback preparation, review bindings, accepted-only authoring, resume,14cancellation, saved-stage readback, and publication.1516The default public CLI launches exactly one long-running child with a compact17task. The child invokes focused prepare and apply steps through the shared18runner. `--execution-mode fixed` is an explicit compatibility controller only.1920For a shared outer-selected asset graph, obtain the stable21`articulation.preparation-publisher.v1` and22`articulation.proposal-provider.v1` descriptors from23`articulation_asset_leaf_catalog()`. The domain adapter binds their exact24invocation/result schemas and the proposal-to-preparation dependency only. It25does not select, order, invoke, or terminalize graph nodes;26those operations remain owned by the sole outer coordinator. Put the selected27typed invocation below its leaf-attempt directory and call the descriptor28entrypoint with `--invocation`; preparation derives29`articulation-preparation-publication/` and proposal derives30`articulation-proposal-attempt/` beside that host-chosen envelope. Both are31create-only, so retry or replacement requires a fresh host-selected attempt32directory. Never put an output path, HTTP endpoint, or credential source in33selected-leaf data, and never mix that artifact with direct CLI flags.3435When embedded under `content-workflow-asset`, the outer asset coordinator is36the only reasoning loop. Invoke the first `articulation run` with the active37`--embedded-run-state`, inspect `articulation_agent_observation.json`, and use38the same focused apply step. The native request binds the exact outer request,39coordinator plan, attempt, input handoff, and nested `domain-run` root. Never40launch a nested coding agent or replace the bound request after its exact outer41review or any selected human review.4243## When to Use4445Use for prompt-driven articulation work that must expose uncertain candidates,46survive interruption, or prove that the saved joint graph exactly matches the47approved candidate set. Typical requests mention drawers, hinges, sliders,48doors, mechanisms, joints, or articulated components.4950## Limitations5152- Articulation-v1 authors only revolute and prismatic joints.53- Provider-neutral preparation does not create render or usd-cli evidence. Its54 public producer derives all six preparation records from an exact retained55 source/dependency/configuration closure plus complete saved readback. Exact56 per-prim ownership/disposition authority comes from the retained57 configuration and must match the saved observation. The create-only publisher58 fails closed on unsafe paths, links, stale bytes, incomplete coverage,59 destination reuse, or readback drift.60- A selected replacement proposal provider is a separate public leaf. Its61 invocation binds one retained `artifact-json` payload; trusted standalone62 operators may instead call the explicit `http-json` direct adapter. Both are63 advisory only and never fall back to Joint inference or classic execution.64 Every invoked attempt writes one immutable terminal receipt for success,65 provider failure, invalid response, or bound replacement while create-only66 storage remains writable. Irrecoverable terminal storage failure is an67 infrastructure error that poisons the root. Preserve a failed attempt root68 and use a new root for every retry or replacement.69- Current provider-neutral runs must produce canonical post-authoring visual evidence70 through the shared OVRTX leaf, bind its exact output/dependency/report/image71 identities, and include those image digests in the outer post-readback review.72 This evidence is a review input, never a deterministic visual pass.73- Human approval does not promote a native Stage 2 `review_required` candidate.74 Re-run Joint Agent adjudication or reject that candidate.75- Authoring is topology-only: masses and colliders remain false.76- Provider-backed preparation requires a healthy workflow-owned usd-cli session and captures77 digest-bound source, topology, property, camera, response, and focused-render78 evidence before review.79- Source inspection is fail-closed at 4,096 snapshot prims. Split or simplify a80 larger inspection scope before retrying; renders do not start for a truncated81 snapshot.82- One collection supports at most 8 configured view directions and 256 focused83 renders. Reduce directions or candidate moving-part coverage before retrying.84- Skill-routed execution sends every candidate through its evidence-bound agent85 decision patch. `--review-policy none` publishes that decision as the review86 receipt; both `uncertain` and `all` retain the fail-closed all-candidate87 operator review gate. Frozen v1/v2 deserialization retains its historical88 review semantics; the current provider-neutral leaf does not emit that legacy89 compatibility shape.90- usd-cli and the workflow host must resolve the same source and run paths.91- Provider-backed inference and rendering still depend on the backends selected by the92 copied Joint Agent config.9394## Prerequisites9596- From the repository root, set up and activate the Python 3.12 environment:9798 ```bash99 ./scripts/setup_content_agent.sh100 uv pip install --python .venv/bin/python -e "apps/joint_agent[dev]"101 mkdir -p runs/configs102 cp apps/joint_agent/configs/byoa_joint_rigger.yaml \103 runs/configs/file-cabinet-joint.yaml104 source .venv/bin/activate105 ```106107- For provider-backed runs, load `usd-cli` for source inspection and evidence108 renders. The workflow owns one local sidecar for the session.109- Load usd-cli and the four atomic Articulation skills named above.110- Provide a local USD-family source. For provider-backed runs, also provide a111 copied Joint Agent BYOA config and configure its model/render backends. For a112 provider-neutral standalone or embedded run, provide either a validated113 `EmbeddedArticulationPreparation` or publish one from a complete retained114 `ArticulationPreparationInspectionReadback`.115116## Instructions117118Before the numbered workflow, provider-neutral callers that begin from saved119inspection readback run:120121```bash122content-workflow-cli articulation publish-preparation \123 --readback path/to/articulation_preparation_readback.json \124 --retained-root path/to/retained-inspection \125 --output-dir runs/preparation-publication126127content-workflow-cli articulation validate-preparation \128 --publication runs/preparation-publication/articulation_preparation_publication.json129```130131The producer takes no `source_members` or `authoritative_owners` arguments; it132derives both from exact retained configuration membership rows, rejects a saved133readback observation that differs from them, and publishes134`articulation_preparation_publication.json` beside the preparation in a fresh135directory. Revalidate the returned publication path before passing its136preparation onward. The exact models, artifacts, and terminal rules are137specified in `agentic/docs/articulation_preparation_attempt_contract.md`.1381391. If the outer reasoner explicitly selected an alternate proposal provider,140 start from a preparation with `proposal_status=not_evaluated` and run141 `content-workflow-cli articulation propose` with exactly one adapter. Use its142 separately written bound preparation and terminal receipt. A provider,143 transport, HTTP, response-schema, request-drift, or local-publication failure144 is a typed terminal failure, not unavailable or pass. Validate the terminal145 through `content-workflow-cli articulation validate-attempt`. For an146 explicit replacement, bind the exact prior terminal receipt and use a fresh147 attempt root. If no provider was selected, retain `not_requested` and skip148 the proposal leaf.1492. Run `content-workflow-cli articulation run` with the exact prompt, source,150 run directory, review policy, motion types, and candidate-count bounds. Use151 `--joint-config` for provider-backed compatibility, `--preparation` for a152 provider-neutral standalone run, or `--embedded-preparation` together with153 `--embedded-run-state` for outer Asset custody. Standalone launches exactly154 one child through `workflow=articulation.author`; embedded launches none.155 Neither provider-neutral route constructs `JointAgentLocalClient` or invokes156 `joint_agent.api.pipeline`.1573. Inspect `articulation_agent_observation.json` and its bound evidence. In158 standalone mode the sole child writes the complete typed decision patch. In159 embedded mode the outer coordinator authors the complete ordered canonical160 graph. Any provider candidate document is optional proposal evidence only.1614. Persist an explicit outer `accept`, `reject`, or `revise` disposition in the162 patch for the exact canonical graph. Also select `not_requested` human review163 or `human_required` with a frozen task-policy or fail-closed escalation164 reason. Neither human status is an outer-review disposition or implicit pass.1655. Apply the patch through the focused step. It fails before publication on a166 stale revision, changed digest, incomplete IDs, unsafe edit, unbound path, or167 absent exact outer review. Outer rejection or revision blocks mutation.168 Standalone `parent_unresolved`, `axis_missing`, endpoint, frame/limit,169 membership, or readback issues produce an immutable candidate-bound packet170 and permit only one focused replacement attempt. Exhausting that cap is a171 conditional terminal result, never success.1726. If `human_required` leaves the result at `needs_review`, inspect173 `agent_reviewed_articulation_candidates.json` together with the original174 `articulation_candidates.json` and `scene_evidence/manifest.json`.175 Human review must cover the exact agent-reviewed document that authoring176 will consume. Review each candidate's endpoints, axis, confidence,177 readiness, unresolved reasons, properties, and focused renders.1787. Write one human `accept`, `reject`, or `revise` decision for every ID printed179 under `review_required_candidate_ids`. Never accept a candidate that is not180 native-ready for its requested articulation-v1 motion type.1818. Run `content-workflow-cli articulation review`. It binds the decisions, the182 exact agent-reviewed candidate digest, and the usd-cli evidence digest183 into one receipt and immediately resumes. An all-accept decision proceeds;184 reject remains terminal. For revise, preserve the conditional checkpoint and185 use the refreshed v4 observation's `graph_revision_inputs` to bind the exact186 persisted human decision and complete outer decision file, then create a187 typed immutable graph revision patch. Run188 `content-workflow-cli articulation revise-graph --run-dir <run>189 --revision-patch <patch>`; it archives the exact parent graph/review,190 publishes a revised graph without authoring, and reopens complete human191 review at the revised digest. Do not edit the parent graph or reuse its192 acceptance.1939. After an interruption, run `content-workflow-cli articulation resume` with194 the same run directory. Repeating the exact original `run` command also195 resumes. Do not change source, intent, config, or evidence policy in place.19610. After deterministic authoring and saved-stage readback pause at197 `awaiting_post_review`, run198 `content-workflow-cli validate produce-canonical-visual-evidence` on the199 exact authored output with the original source and an explicitly selected200 `remote` or `ovrtx` shared backend. Then run201 `content-workflow-cli articulation bind-output-evidence` with the emitted202 `verified_operation_envelope.json`. A standalone visual payload is not203 sufficient because Joint must retain and reverify the shared producer,204 tool, backend, verifier, and projector chain.20511. Inspect every bound canonical image. Persist the mode-specific post-review206 patch that207 accepts, rejects, or revises the exact execution result, accepted graph,208 output-evidence digest, and complete ordered image-digest list; apply it209 through the focused finalization step. Absence or substitution of any output,210 dependency, render report, image, or metadata binding fails closed.211 Populate every digest from the exact bound artifact or receipt with212 deterministic shell or structured-JSON tooling; never retype, reconstruct,213 or copy a shortened digest from prose or terminal display. Before invoking214 finalization, validate that every required SHA-256 value is exactly 64215 lowercase hexadecimal characters and matches the current artifact bytes.21612. Treat only `completed` as success. Provider-neutral standalone completion217 uses the v5 checkpoint and terminal receipt. It means `owned_core` authored the exact218 accepted IDs, the saved output passed exact graph readback, canonical OVRTX219 evidence remained intact through outer review, and the terminal receipt220 binds all of them. Mock completion uses simulated validation and is test221 evidence only.22213. When separately selected, project completed graph/apply, retained Gate 3A,223 retained Gate 3B, or trusted dynamic results with the corresponding public224 `articulation project-*` leaf. Feed each emitted envelope to225 `validate ingest-verified-operation-result`; projection revalidates native226 Joint facts but never runs inference, simulation, rendering, or shared227 Validation execution. Gate 3A/3B projection requires the canonical retained228 root layout, exact plan, intake, authoring receipt, closeout, and report. The229 authoring receipt supplies the generated identities published by the real230 static workflow; do not synthesize a standalone identities document or231 substitute source/output bytes.23214. For `conditional`, retain the output and inspect unresolved IDs plus233 `validation_evidence.json` when validation ran; pre-authoring conditionals234 have no output or validation artifact. For `cancelled` or `failed`, preserve235 the run for diagnosis and restart with a new run directory; those236 checkpoints are terminal.237238## File-Cabinet Scenario239240Run the practical six-drawer acceptance scenario:241242```bash243ARTICULATION_INTENT="Identify the six drawers, present every candidate for "244ARTICULATION_INTENT+="review, then author exactly six prismatic drawer joints "245ARTICULATION_INTENT+="and no masses or colliders."246247content-workflow-cli articulation run \248 --usd /data/sm_filecabinet_d01_01.usdz \249 --joint-config runs/configs/file-cabinet-joint.yaml \250 --output-dir runs/file-cabinet-articulation \251 --intent "$ARTICULATION_INTENT" \252 --review-policy all \253 --allowed-motion-type prismatic \254 --expected-candidate-count 6 \255 --max-candidate-count 6256```257258After inspecting the candidates and usd-cli renders, create259`runs/file-cabinet-decisions.json` with every printed candidate ID:260261```json262{263 "candidate_0001": "accept",264 "candidate_0002": "accept",265 "candidate_0003": "accept",266 "candidate_0004": "accept",267 "candidate_0005": "accept",268 "candidate_0006": "accept"269}270```271272Use the exact IDs printed by the run; the file must contain one decision for273every `review_required_candidate_ids` value. Resume through the review command:274275```bash276content-workflow-cli articulation review \277 --run-dir runs/file-cabinet-articulation \278 --decisions-json runs/file-cabinet-decisions.json \279 --reviewer asset-owner280```281282The `--review-policy all` setting prevents silent auto-approval. A native Stage2832 `review_required` candidate remains non-authorable even if the receipt says284`accept`; reject it or rerun Joint Agent adjudication with stronger evidence.285286## Python Interactive API287288For a long-running Python host, call289`content_agent_workflows.articulation.run_interactive_articulation_workflow`,290build digest-bound decisions with `build_articulation_review_receipt`, and pass291an `Articulationusd-cliEvidenceCollector` implementation when usd-cli292evidence is required. Keep the same request, client configuration, collector293configuration, and run directory across calls.294295CLI-created runs are batch-mode checkpoints and are resumed with the CLI296commands above. The CLI does not adopt a separately constructed Python297interactive checkpoint.298299Embedded interactive and batch callers use the same public300`EmbeddedArticulationPreparation` and301`prepare_embedded_articulation_workflow` API. Proposal fields may be absent; the302preparation records that optional leaf as `not_requested` or `not_evaluated`,303never as a pass. The outer coordinator must explicitly accept, reject, or revise304the exact persisted graph. Human review is `not_requested` by default and is305`human_required` only when frozen task policy selects it or ambiguity,306unsupported facts, or contradictory evidence require fail-closed escalation.307Graph-derived authoring, saved-stage readback, and outer post-review remain308mandatory in both modes. Current public embedded runs additionally require the309shared canonical OVRTX payload and a v2 output-bound post-review; v1/v2310compatibility artifacts retain their historical post-review contract.311312Use `select_embedded_articulation_human_review_policy` from deterministic313Python workflow code for the current v3 outer patch; it is an SDK policy314helper, not a launcher subcommand. It returns `not_requested` when no live task-policy, ambiguity,315unsupported-fact, or contradictory-evidence gate exists, and `human_required`316with exact reasons otherwise. Do not serialize those current fields into frozen317v1/v2 patches; their compatibility behavior remains an unconditional human318gate.319320## Output Format321322- `request.json`323- `articulation_preparation_publication.json` and324 `embedded_articulation_preparation.json` when preparation is published from325 complete retained saved readback326- `embedded_articulation_preparation.json` for provider-neutral embedded runs327- replacement-provider request, native payload, v2 proposal, and bound328 preparation artifacts when the optional public proposal leaf was selected329- `articulation_proposal_attempt_terminal.json` for every invoked provider330 attempt, including failures and explicitly bound replacement attempts331- optional `inference_result.json` and provider proposal for provider-backed runs332- Joint Agent predictions and candidate report referenced by333 `inference_result.json`334- `articulation_candidates.json`335- `scene_evidence/manifest.json`, source snapshot, topology and property336 inspection, and candidate-focused image, response, and camera artifacts337- `articulation_agent_observation.json`, decision patch, reviewed candidates,338 and immutable decision ledger339- `embedded_articulation_outer_review.json` after exact outer graph review340- `graph_revisions/revision-NNN/graph_revision.json` plus immutable revised341 graph, outer review, and coordinator decision after a human revision342- optional `review_receipt.json` after selected human review343- `approved_articulation_candidates.json` after approval344- `authoring_request.json` and `authoring_result.json` after authoring starts345- `joint_rigger/authoring_attempt.json`, `diagnostics.json`, and `result.json`346- `validation_evidence.json` after validation347- `embedded_articulation_output_evidence.json` after binding shared canonical348 OVRTX output evidence349- `embedded_articulation_post_review_patch.json` and350 `embedded_articulation_terminal_receipt.json` after accepted output review351- optional Joint verified-operation projection/envelope artifacts for352 graph/apply, Gate 3A, Gate 3B, or dynamic results when those leaves are353 separately selected354- `checkpoint.json`355- `workflow_progress.json`356- `final_summary.json`357- `joint_rigger/rigged.usdz` plus Joint Rigger diagnostics and result evidence358359## Troubleshooting360361- If a receipt or usd-cli evidence digest differs, do not edit it in place.362 Reopen the current evidence and build a new run or valid receipt.363- If a proposal attempt is terminally failed, invalid, or replaced, preserve364 that root. Never add a success artifact to it or reuse it; start a fresh root365 and bind the prior terminal receipt when replacement is explicit.366- A failed or interrupted usd-cli capture may retry from checkpointed Joint367 Agent inference and candidate artifacts. Only a complete, verified manifest368 skips collection; incomplete capture artifacts may be replaced during retry.369- A workflow `failed` result is a terminal, diagnostic checkpoint. `resume`370 returns the same verified failure instead of retrying a possibly371 non-idempotent backend phase. Preserve that run and use a new run directory372 after correcting a transient backend problem.373- For a Joint provider terminal, follow the exact `recovery_action`. `resume`374 with `resume: true` and `clean: false` reuses the named checkpoint and its375 digest-bound provider journal in the same work directory. `restart` with376 `resume: false` and `clean: true` means the evidence is unavailable or377 untrusted: preserve the failed directory for diagnosis and start the same378 request in a new clean run directory. Never reinterpret one mode as the other379 or delete the failed evidence in place.380- Changing the usd-cli evidence policy or another digest-bound collector381 setting invalidates evidence reuse. The collector configuration digest382 is bound into the request. Preserve the old run and start a new request when383 changing it.384- If a candidate is native `review_required`, do not flip its status. Correct385 the source evidence through Joint Agent adjudication.386- If resume reports source, configuration, candidate, or output drift, preserve387 the run for diagnosis and start a new run for changed inputs.388- If exact readback fails, keep the conditional artifact but do not claim389 completion.