User Guide · Built-in Agents · metafine_add

metafine_add

A guided design assistant for new MetaFine artifacts — either a new atomic skill primitive or a new compositional task graph. It walks you through phase classification, affordance contracts, parameter signatures, and success predicates, then produces a code stub or YAML you can drop into the repo.

What it does

metafine_add is a Claude Code skill that lives at ~/.claude/skills/metafine_add/. It accelerates two recurring authoring tasks on the MetaFine platform:

  • Designing a new atomic skill — picks the right phase, the required affordances, and a callable signature; produces a @register_skill stub ready for core/skill.py.
  • Designing a new task graph — decomposes a multi-step procedure into stages with appropriate success predicates; produces a YAML stub for configs/<slug>.yaml.

It produces artifacts; it doesn't ship them. You confirm before any file is written, and nothing is pushed to git.

Invocation

$ /metafine_add skill <one-line description>
$ /metafine_add task <one-line description>
$ /metafine_add <description>   # mode inferred from the description
$ /metafine_add                # interactive — agent asks "skill or task?"

If the description is too thin to act on (e.g. just "rotate"), the agent asks up to two clarifying questions before producing a stub — no endless interrogation.

Skill mode

  1. Phase. Classify into interaction / continuation / bundle from the description's contact semantics.
  2. Affordances. Pick the required subset from the 11-element closed set. If the operation can't be expressed within the existing set, the agent flags it and proposes either a combination or a platform-level extension.
  3. Signature. Standard MetaFine convention: fn(env, target, *, <keyword params with defaults>) returning env.last_step_info.
  4. Stub. Generate a complete @register_skill(...) + function shell with a numbered TODO body for the motion logic — never a fully-implemented body, because the planning math is task-specific.
  5. Smoke test. Suggest python smoke_envs.py after the file lands.

Task mode

  1. Decompose. Break the procedure into an ordered list of stages.
  2. Pick skills. One existing skill per stage, looked up against SKILL_REGISTRY.
  3. Pick targets. An (asset_id, part) per stage. The agent can fetch the target asset's capabilities.json to confirm the part offers the right affordances.
  4. Write predicates. One success predicate per stage from the 6-atom DSL (grasped / joint_value / lifted / pose_near / placed_in / stacked_on) composed with and / or / not.
  5. YAML. Emit a complete YAML stub for configs/<slug>.yaml.
  6. Next. Suggest python record.py --task-graph configs/<slug>.yaml --trials 5.

Built-in validation

Before declaring a stub ready, the agent walks four checks:

  • Skill exists — every named skill resolves in SKILL_REGISTRY (live grep on A100 when needed).
  • Affordance contract holds — each target part declares all the affordances the chosen skill requires (per the asset's capabilities.json).
  • Phase ordering — no continuation skill precedes its interaction; bundle skills stand alone.
  • Predicate atoms in scope — only the 6 documented atoms; the agent refuses to invent new ones.

For a task graph, you can run the live validator the agent suggests:

$ python -m utils.task_graph --validate configs/<slug>.yaml

Worked examples

Skill example

# Invocation
$ /metafine_add skill rotate a screw cap by 90 degrees while holding it

# Agent output (excerpt)
@register_skill(
    phase="continuation",
    requires=("rotatable",),
    defaults={"angle_deg": 90, "velocity": 0.3},
)
def hold_and_rotate(env, target, *, angle_deg=90, velocity=0.3):
    """Rotate the already-grasped part about its revolute joint."""
    # TODO: 1. assert engagement, 2. compute target joint value,
    #       3. drive with PandaArmMotionPlanningSolver at `velocity`.
    raise NotImplementedError

Task example

# Invocation
$ /metafine_add task open the cap of jar 100221 and pour into cup

# Agent output (excerpt)
name: open_jar_and_pour
stages:
  - stage_name: engage_cap
    skill: grasp_part
    target: { object: 100221, part: cap }
    success: grasped("cap")
  - stage_name: twist_open
    skill: pure_rotate
    params: { angle_deg: 120 }
    success: and(grasped("cap"), joint_value("cap", ">=", 2.094))
  - stage_name: lift_clear
    skill: pure_lift
    params: { height_m: 0.05 }
    success: and(grasped("cap"), lifted("cap", height_m: 0.05))

Limits

  • No remote writes. The agent proposes; you confirm; only then it writes a local file. It never modifies anything on A100.
  • Closed-set discipline. 11 affordances. 6 predicate atoms. 3 phases. The agent refuses to invent variants and routes you to the platform extension path if your need is genuinely new.
  • Stubs, not implementations. Skill stubs come with numbered TODO bodies — the motion-planning code is task-specific and the agent won't speculate.
  • Pair with metafine_help. When the design choice depends on platform context ("which skill already does X?", "what does pure_rotate actually return?"), metafine_add calls into the same routing logic as metafine_help.