1,730 Tasks, 4 Promoted, No Success Rate Published: AgiBot Ran Six G2 Robots in a Store for 24 Hours — the Real Asset Is the Scorecard Nobody Handed Out

1,730 Tasks, 4 Promoted, No Success Rate Published: AgiBot Ran Six G2 Robots in a Store for 24 Hours — the Real Asset Is the Scorecard Nobody Handed Out

Part One: The Closing Numbers Look Great — Except the One That Matters

At 10:00 on November 2, 2026, in a normally operating convenience store in Shanghai’s Xuhui district, six AgiBot G2 humanoid robots clocked in. Twenty-four hours later, at 10:00 on November 3, the livestreamed challenge called “Robots Can’t Stop Working” wrapped up.

Here’s the ledger the company published:

  • 1,730 tasks completed in total
  • 683 customer receptions, 369 item fetches/deliveries, 147 coffees made, 126 breakfast services, 277 restocking/shelf checks, 128 table cleanings
  • Over 2 million concurrent viewers across the web
  • 4 robots passed probation

The first four are task counts; the last is an attrition rate — four of six passed, two did not.

But there is a set of numbers AgiBot itself said it would track the day before, and never published at the close:

Ren Guanghui, a vice president at AgiBot’s embodied research center, told media the company would track task success rate, first-attempt success rate, response time, end-to-end time, qualified deliveries per unit time, human takeover frequency, recovery time, and system availability.

Not one of those eight was disclosed. What the close delivered was all task counting.

This isn’t nitpicking. Task counts and success rates are two entirely different ledgers, and the second one is what decides whether a robot can actually hold a job. The code below lays both out.

# Task counts vs. success rates: why the same 1730 means wildly different things
def task_count_vs_success(total_tasks=1730, robots=6, hours=24):
    """
    Given only the task count, back out what different success rates imply.
    """
    scenarios = {}

    for rate in [0.99, 0.95, 0.90, 0.80, 0.70]:
        success = int(total_tasks * rate)
        fail = total_tasks - success
        # Rough assumption: one human intervention per failure (optimistic)
        interventions = fail
        per_robot_hours = hours
        interventions_per_robot_hour = interventions / (robots * per_robot_hours)

        scenarios[f"{rate:.0%}"] = {
            "successful tasks": success,
            "failed tasks": fail,
            "implied interventions": interventions,
            "interventions per robot-hour": f"{interventions_per_robot_hour:.2f}",
        }

    return scenarios

print(f"{'Success rate':<14}{'Success':<10}{'Fail':<8}{'Interventions':<16}{'Per robot-hour'}")
print("-" * 68)
for rate, d in task_count_vs_success().items():
    print(f"{rate:<14}{d['successful tasks']:<10}{d['failed tasks']:<8}"
          f"{d['implied interventions']:<16}{d['interventions per robot-hour']}")

What this table says: the same “1,730” can correspond to human-intervention frequencies that differ by more than tenfold.

  • At 99% success, you handle about 17 exceptions over 24 hours — roughly one per robot every 8 hours. That’s essentially unattended operation.
  • At 90%, you handle 173 — about 1.2 per robot-hour. That’s not unattended; that’s six people standing nearby ready to jump in.
  • At 80%, 2.4 per robot-hour. That’s a demo, not a job.

And “four passed, two didn’t” implies in reverse that the success rate wasn’t especially high: if all six had been solid, there’d be no reason to cut two. The cut tells us a threshold exists; where it was drawn was not disclosed.

None of this is meant to dismiss the challenge. Quite the opposite: running a full 24 hours in a normally operating store, livestreamed for anyone to poke at, is worth more than the numbers themselves. But as technical analysis, task volume and success rate must be kept apart — because the engineering problems they represent are completely different.

Part Two: Six Roles, Four Shifts — Why a Convenience Store Is the Standardized Exam Room for Embodied AI

The role design deserves its own section, because it was split along a convenience store’s real service chain, not along the robots’ capabilities.

BadgeRoleResponsibility
AhaoGreeterDoor reception, customer questions, small talk
HuobaoPickerFetch items from shelves per order
JuanwangRestockerPatrol shelves, restock gaps proactively
KashaoBaristaDedicated coffee station
DingjiangCheckoutStaff the register, plus hot food service
LengjieCleanerTable cleaning throughout

Together the six roles cover a convenience store’s full loop: greet → pick → prepare → checkout → restock → clean. The split carries an implicit judgment: embodied AI at this stage shouldn’t chase “one robot that can do everything,” but “one robot that can hold one role steadily.”

On the time axis, the 24 hours were cut into four shifts matching the real traffic curve:

# Four shifts, and what each one actually tests
def shift_breakdown():
    shifts = [
        {
            "shift": "early-morning breakfast rush",
            "time window": "06:00-10:00",
            "traffic": "spiky, high per-customer urgency",
            "technical focus": "peak concurrency, queue backlog, coffee + hot food handoff",
        },
        {
            "shift": "midday peak probation",
            "time window": "11:00-14:00",
            "traffic": "highest density, most interference",
            "technical focus": "multi-robot contention, aisle obstruction, path conflicts",
        },
        {
            "shift": "evening peak stress test",
            "time window": "17:00-21:00",
            "traffic": "high and sustained",
            "technical focus": "sustained load, battery/thermal, accumulated error",
        },
        {
            "shift": "late-night solo watch",
            "time window": "22:00-06:00",
            "traffic": "near zero",
            "technical focus": "idle self-practice, memory consolidation, autonomous restocking",
        },
    ]
    return shifts

for s in shift_breakdown():
    print(f"\n[{s['shift']}] {s['time window']}")
    print(f"  traffic      : {s['traffic']}")
    print(f"  tests        : {s['technical focus']}")

The four shifts test completely different things, and that’s the smartest part of the design.

The breakfast rush tests concurrency and pacing: of the 147 coffees, how many landed in the morning rush? If 80 of 147 packed into four hours, that’s 20 per hour, one every three minutes — no step in the preparation chain can stall. Midday tests multi-robot contention: two pickers plus a cleaner shuttling through narrow aisles makes path planning and deadlock avoidance a real exam. Evening tests fatigue: after a dozen hours, battery, joint temperature, and localization drift all accumulate. Late night tests autonomy: with nobody around, does it find work by itself, does it consolidate the day’s experience.

And “late-night solo watch” is the most valuable block of the whole challenge. During the day there are viewers, traffic, cameras — problems get spotted immediately. At night nobody’s watching. If the robots can restock, patrol, and self-practice on their own, that’s real autonomy.

Part Three: How Unmanned Is “Unmanned” Really?

Pandaily’s report contains one key formulation:

AgiBot says the test ran with no human in the loop, meaning no human demonstrations or manual on-site tuning.

That definition is specific and worth reading word by word: no human demonstration, no manual on-site parameter tuning. The robots weren’t teleoperated, and engineers weren’t standing by constantly tweaking parameters.

But three kinds of “unmanned” need separating:

# Three levels of "unmanned" — the challenge only proves the first two
def unmanned_levels():
    return {
        "L1: no teleoperation": {
            "meaning": "robots decide and execute actions themselves, no human driving",
            "proven by": "task counts + livestream (actions visibly autonomous)",
            "evidence strength": "strong",
        },
        "L2: no on-site tuning": {
            "meaning": "engineers don't adjust parameters on site during the run",
            "proven by": "official statement",
            "evidence strength": "medium (self-reported)",
        },
        "L3: no human intervention on failure": {
            "meaning": "when the robot fails, it recovers by itself without a human stepping in",
            "proven by": "would require publishing intervention counts",
            "evidence strength": "not disclosed",
        },
    }

for level, d in unmanned_levels().items():
    print(f"\n{level}")
    for k, v in d.items():
        print(f"  {k:20s}: {v}")

L1 and L2 were largely proven; L3 was not. And L3 is precisely the commercial watershed — because if every failure needs a human, the economics of an “unmanned convenience store” simply don’t close: the labor you saved gets spent again babysitting robots.

Which also explains why “four promoted” is a meaningful result: the probation review was most likely evaluating L3. The four that passed held most exceptions on their own across 24 hours; the two that didn’t required humans at certain points.

Part Four: Genie Master’s Three-Layer Loop — Dispatch, Memory, Feedback

Behind the six robots sits a shared brain: Genie Master, the embodied agent framework. Its design splits into three layers.

                    ┌──────────────────────────────────────┐
                    │         Genie Master (shared brain)  │
                    │                                      │
                    │  ┌────────────────────────────────┐  │
                    │  │  L1  Dispatch layer             │  │
                    │  │  · task assignment by scene     │  │
                    │  │  · six-robot contention resolve │  │
                    │  │  · priority by customer waiting │  │
                    │  └──────────────┬─────────────────┘  │
                    │                 │                    │
                    │  ┌──────────────▼─────────────────┐  │
                    │  │  L2  Execution layer            │  │
                    │  │      (Embodied Execution        │  │
                    │  │       Protocol)                 │  │
                    │  │  · task judgment → action       │  │
                    │  │  · real-time perception adjust  │  │
                    │  │  · result feedback upstream     │  │
                    │  └──────────────┬─────────────────┘  │
                    │                 │                    │
                    │  ┌──────────────▼─────────────────┐  │
                    │  │  L3  Learning layer             │  │
                    │  │  · daily success/failure review │  │
                    │  │  · long-term memory storage     │  │
                    │  │  · corrected policy → training  │  │
                    │  │  · idle-time self-practice      │  │
                    │  └────────────────────────────────┘  │
                    └──────────────────────────────────────┘
                              │              │
              ┌───────────────┘              └──────────────┐
              ▼                                             ▼
     ┌─────────────────┐                          ┌─────────────────┐
     │  6 × G2 robots  │                          │  training data  │
     │  (each a worker │                          │  (feeds back to │
     │   session)      │                          │   action model) │
     └─────────────────┘                          └─────────────────┘

Layer one is dispatch. The six robots don’t work independently; they share a scheduler deciding who greets, who restocks, who makes coffee, allocated by on-site conditions. The hardest part isn’t allocation itself but handling contention — two pickers both wanting to restock the same shelf, a cleaner needing an aisle that a picker is occupying. In a real store these conflicts happen every minute.

# Multi-robot contention: how a simple priority scheduler behaves under load
import random

def simulate_contention(robots=6, minutes=60, task_rate=1.2, seed=42):
    """
    Simplified: at each minute, task_rate new tasks arrive on average;
    each robot can handle one task; conflicts arise when >1 robot wants the same zone.
    """
    random.seed(seed)
    zones = ["entrance", "shelf_A", "shelf_B", "coffee", "checkout", "cleaning"]
    busy = {z: 0 for z in zones}
    queue = 0
    conflicts = 0
    served = 0

    for m in range(minutes):
        arrivals = 0
        # Poisson-ish arrivals
        while random.random() < task_rate / 60 * 10:
            arrivals += 1
        queue += arrivals

        for _ in range(robots):
            if queue <= 0:
                break
            zone = random.choice(zones)
            if busy[zone] > 0:
                conflicts += 1
                continue
            busy[zone] = random.randint(2, 6)  # task takes 2-6 minutes
            queue -= 1
            served += 1

        for z in zones:
            if busy[z] > 0:
                busy[z] -= 1

    return {
        "tasks arrived": served + queue,
        "tasks served": served,
        "backlog": queue,
        "zone conflicts": conflicts,
        "conflict rate": f"{conflicts / max(served,1):.1%}",
    }

for k, v in simulate_contention().items():
    print(f"  {k:18s} {v}")

The simulation is obviously simplified, but it points at a real problem: the bottleneck in multi-robot coordination usually isn’t individual capability but resource contention. Six robots in a store that small will have a non-trivial conflict rate. And every conflict means extra waiting, extra replanning, and one more moment where a customer sees a robot hesitating.

Layer two is execution. Genie Master threads “task judgment — action execution — result feedback” into a closed loop through an Embodied Execution Protocol. Its job is translating a high-level “go restock” into a concrete action sequence, then returning a structured result (success/failure/stuck).

Layer three is learning, the most interesting part of the design:

  • Every day, all successful and failed work records are aggregated;
  • Useful experience goes into long-term memory and is reused for similar tasks;
  • Corrected strategies become training data, feeding back into the action model;
  • Idle time is used for self-practice.

In code:

# The learning loop: memory reuse vs. policy update, two different paths
def learning_loop(days=30, tasks_per_day=1730, success_0=0.88):
    """
    Two mechanisms work in parallel:
      1) memory reuse: solved cases retrieved directly (fast, no retraining)
      2) policy update: corrected trajectories become training data (slow, generalizes)
    """
    success = success_0
    memory = 0          # reusable cases in long-term memory
    policy_gain = 0.0   # cumulative generalization gain
    history = []

    for d in range(1, days + 1):
        # memory grows from solved tasks, with decay for stale cases
        memory = int(memory * 0.98 + tasks_per_day * success * 0.15)

        # policy gain compounds slowly, saturating
        policy_gain += 0.004 * (1 - policy_gain / 0.12)

        # combined effect: memory gives immediate lift, policy gives lasting lift
        memory_lift = min(memory / 20000 * 0.05, 0.05)
        success = min(success_0 + memory_lift + policy_gain, 0.995)

        if d % 5 == 0 or d == 1:
            history.append((d, memory, f"{success:.3f}"))

    return history

print(f"{'Day':<6}{'Memory cases':<16}{'Success rate'}")
print("-" * 36)
for d, mem, rate in learning_loop():
    print(f"{d:<6}{mem:<16}{rate}")

The structural point this code makes: long-term memory and policy updates are two different curves.

Memory reuse is fast and local — the pitfall hit today gets looked up and avoided tomorrow. But its ceiling is low, because memory only covers scenes already seen, and decays as conditions change (the 0.98 decay simulates that).

Policy update is slow and general — corrected trajectories become training data, and the model genuinely learns “how to adjust in this situation,” generalizing to unseen scenes. But it takes time, data volume, and training compute.

Only the two together are what “learning while on the job” actually means. And this explains why AgiBot emphasizes “idle-time self-practice”: those eight night hours have almost no foot traffic, making them the only training window that doesn’t consume business hours.

Part Five: Three Technical Points from the Adversarial Tests That Say More Than the Task Count

Two invited testers came specifically to cause trouble, and their questions say more about system maturity than 1,730 does. Three stand out:

Question one: regular vs. sugar-free cola, with only “get me the sugar-free one” as instruction.

The two bottles look nearly identical, differing only in tiny label details. The robot’s approach is dual verification — “ears understand, eyes confirm”: speech recognition extracts “sugar-free,” then vision checks the label text for “sugar-free,” and only grasps when both agree.

# Dual verification: voice + vision must agree before acting
def dual_verify(voice_intent, vision_labels, threshold=0.85):
    """
    voice_intent: attribute extracted from speech, e.g. "sugar_free"
    vision_labels: list of (label, confidence) from visual inspection
    """
    best = max(vision_labels, key=lambda x: x[1])

    if best[0] != voice_intent:
        return {
            "action": "abort_and_ask",
            "reason": f"vision says '{best[0]}', voice says '{voice_intent}'",
            "confidence": best[1],
        }

    if best[1] < threshold:
        return {
            "action": "re_scan",
            "reason": f"label confidence {best[1]:.2f} below threshold {threshold}",
            "confidence": best[1],
        }

    return {
        "action": "grasp",
        "reason": "voice and vision agree with high confidence",
        "confidence": best[1],
    }

# Case A: clear label
print("Case A (clear label):")
for k, v in dual_verify("sugar_free", [("sugar_free", 0.94), ("regular", 0.05)]).items():
    print(f"  {k:12s} {v}")

# Case B: ambiguous / low confidence
print("\nCase B (ambiguous):")
for k, v in dual_verify("sugar_free", [("sugar_free", 0.71), ("regular", 0.28)]).items():
    print(f"  {k:12s} {v}")

# Case C: conflict
print("\nCase C (conflict):")
for k, v in dual_verify("sugar_free", [("regular", 0.88), ("sugar_free", 0.11)]).items():
    print(f"  {k:12s} {v}")

The logic looks simple, but it’s a safety-critical design: better to “scan again” or “ask” than to grab when uncertain. In a convenience store, grabbing the wrong cola is trivial; but if the same pattern moves to a pharmacy, a warehouse, or a production line, the difference between “stop when uncertain” and “act when uncertain” is the difference between incidents and none.

Question two: scramble the entire gum shelf and see if it can put things back.

The robot’s approach: don’t rely on label positions — do visual inventory and restore slot by slot. That’s the key point. If the system were “remember slot 3 is mint,” scrambling breaks it entirely. If it’s “recognize what this item is, then find where it belongs,” the robot genuinely understands the relationship between products and shelves.

# Two paradigms for shelf restocking — and why only one survives disorder
def restocking_paradigms():
    return {
        "position memory": {
            "logic": "remember item i belongs at slot j",
            "works when": "shelf layout never changes",
            "fails when": "items are shuffled, layout changes, new SKUs arrive",
            "robustness": "low",
        },
        "visual inventory": {
            "logic": "recognize each item, then find its correct slot",
            "works when": "recognition is reliable",
            "fails when": "packaging is visually near-identical (e.g. sugar-free vs regular)",
            "robustness": "high",
        },
        "hybrid (what was shown)": {
            "logic": "recognize item + cross-check slot constraints + verify after placing",
            "works when": "recognition + spatial reasoning both hold",
            "fails when": "heavy occlusion or new packaging never seen",
            "robustness": "highest, at higher compute cost",
        },
    }

for name, d in restocking_paradigms().items():
    print(f"\n[{name}]")
    for k, v in d.items():
        print(f"  {k:14s}: {v}")

Question three: a person standing in the aisle as a roadblock, then a box dropped in the path.

The robot’s response: “stop on seeing a person, then reroute; reroute again around the box.”

Those two words — “stop first” — are the design element least worth ignoring. Because a humanoid moving through commercial space, the greatest danger isn’t taking a wrong path but still moving while hesitating. Stopping to replan, even if it costs a few seconds, is far safer than “computing while creeping forward.”

# Obstacle policy: stop-first vs. keep-moving, and the safety math
def obstacle_policy(robot_mass_kg=45, speed_mps=1.0, reaction_s=0.3):
    """
    Simplified stopping-distance comparison.
    """
    results = {}

    # Policy A: stop first, then re-plan
    stop_distance_a = speed_mps * reaction_s + (speed_mps ** 2) / (2 * 2.0)
    results["A: stop then re-plan"] = {
        "stopping distance (m)": f"{stop_distance_a:.2f}",
        "extra time (s)": "2.5-4.0 (re-planning)",
        "collision risk": "very low",
    }

    # Policy B: keep moving while computing
    stop_distance_b = speed_mps * (reaction_s + 0.8) + (speed_mps ** 2) / (2 * 2.0)
    results["B: compute while moving"] = {
        "stopping distance (m)": f"{stop_distance_b:.2f}",
        "extra time (s)": "0.3-0.8",
        "collision risk": "elevated (path may change underfoot)",
    }

    return results

for policy, d in obstacle_policy().items():
    print(f"\n{policy}")
    for k, v in d.items():
        print(f"  {k:22s}: {v}")

Run the numbers and it’s clear: “stop first” costs 2–3 seconds; “compute while moving” saves 2–3 seconds, but the risk differs by an order of magnitude. In a shared human-robot commercial space, that trade is unambiguously worth it.

Part Six: Reverse-Engineering the Pacing and Concurrency Behind 1,730

1,730 tasks / 24 hours / 6 robots — what pacing does that average out to?

# Back-of-envelope: what 1730 tasks over 24 hours actually implies
def task_pacing():
    total = 1730
    robots = 6
    hours = 24
    breakdown = {
        "customer reception": 683,
        "item fetch/delivery": 369,
        "coffee making": 147,
        "breakfast service": 126,
        "restocking/shelf check": 277,
        "table cleaning": 128,
    }

    print(f"Total tasks: {total}")
    print(f"Per robot: {total/robots:.1f} tasks over {hours}h")
    print(f"Per robot-hour: {total/(robots*hours):.1f} tasks")
    print(f"Average interval: {robots*hours*60/total:.1f} min between tasks\n")

    print(f"{'Task type':<24}{'Count':<8}{'Share':<9}{'Per hour (all robots)'}")
    print("-" * 66)
    for name, count in breakdown.items():
        share = count / total
        per_hour = count / hours
        print(f"{name:<24}{count:<8}{share:<9.1%}{per_hour:.1f}")

    # Implied concurrency at peak
    print("\nPeak-hour implication (assume 30% of daily tasks in 4 peak hours):")
    peak_tasks = total * 0.30
    peak_hours = 4
    peak_rate = peak_tasks / peak_hours
    print(f"  peak task rate: {peak_rate:.1f} tasks/hour")
    print(f"  per robot at peak: {peak_rate/robots:.1f} tasks/hour "
          f"(≈ 1 task every {60/(peak_rate/robots):.1f} min)")

task_pacing()

The key output: about 12 tasks per robot-hour, roughly one every 5 minutes. If 30% of tasks concentrate in four peak hours, each robot handles about 22 per hour at peak — under 3 minutes per task.

What does that pacing mean? A coffee machine typically takes 1–2 minutes per cup; add cup handling, lid, and handoff, and 3 minutes per task is essentially full load. In other words, at peak the robots weren’t “demonstrating capability” — they were pushing against the capacity ceiling.

And it’s when you push against the ceiling that problems surface. Which is exactly why “four promoted” deserves attention: if only four held steady under heavy load, the stability boundary of the system is probably somewhere around there.

Part Seven: Against AgiBot’s Own Historical Baselines, Where Does This Land

AgiBot has a habit: it likes to speak through livestreams. Lining up the history shows a capability curve:

# AgiBot's public live-demo track record, for context
def historical_baselines():
    return [
        {
            "date": "2025-07",
            "scene": "Fulin Precision Mianyang plant (A2-W)",
            "duration": "3 hours",
            "reported result": "zero failures",
            "metric type": "claimed zero-failure",
        },
        {
            "date": "2025-08",
            "scene": "24h summer city walk (A2)",
            "duration": "24 hours",
            "reported result": "completed",
            "metric type": "completion, no task rate",
        },
        {
            "date": "2025-11",
            "scene": "106km walk Suzhou→Shanghai (A2)",
            "duration": "56 hours, 15 battery swaps",
            "reported result": "completed",
            "metric type": "endurance, no manipulation",
        },
        {
            "date": "2026-06",
            "scene": "Nanchang Longqi plant, 8× G2",
            "duration": "6 consecutive days, 8am-7pm",
            "reported result": "99.99% task success",
            "metric type": "explicit success rate",
        },
        {
            "date": "2026-11",
            "scene": "Shanghai Xuhui convenience store, 6× G2",
            "duration": "24 hours",
            "reported result": "1730 tasks, 4/6 passed",
            "metric type": "task counts only",
        },
    ]

print(f"{'Date':<10}{'Duration':<32}{'Reported':<28}{'Metric'}")
print("-" * 96)
for b in historical_baselines():
    print(f"{b['date']:<10}{b['duration']:<32}{b['reported result']:<28}{b['metric type']}")

The most interesting thing in this table is the contrast between the last two rows.

In June 2026 at the Nanchang Longqi plant, AgiBot gave an explicit 99.99% success rate — because factory QC is structured and decidable: does this screen have a scratch, does this audio have noise; pass is pass, fail is fail, and the denominator is clear.

In November 2026 in the convenience store, only task counts. This isn’t regression; it’s that “success” in a convenience store is genuinely hard to define:

  • 683 customer receptions — what counts as success? The customer smiled, or the customer left?
  • 147 coffees — does spilling a little count as failure? Does “it’s a bit cold” count as failure?
  • 128 table cleanings — if someone still sees a stain, is that failure?

The factory’s success rate can be precise to two decimals because it has a mechanical criterion; the convenience store has none. Which shows precisely this: as embodied AI moves from structured scenes to unstructured ones, the first wall it hits isn’t a capability wall but a measurement wall.

And that measurement problem isn’t AgiBot’s alone. The entire industry will meet the same thing as it moves toward service scenarios: if you can’t define success, you can’t tell whether you’re improving or standing still.

Part Eight: Judgment and Boundaries

First, the real value of this challenge isn’t 1,730 — it’s that it put “unstructured scenes” on the table. Previous factory QC and production-line work were still “structured worlds” — controllable lighting, fixed materials, clear pass/fail. The convenience store is the first genuine unstructured exam room: customers moving through at any moment, products being scrambled, the same action facing different conditions each time. Daring to run 24 hours here says more than 2,400 hours in a lab.

Second, not publishing the success rate is the biggest information gap here, and the gap is structural. As shown earlier, the same 1,730 corresponds to human-intervention frequencies differing by more than tenfold at 99% versus 80%. And in commercial deployment, “how much human fallback is needed” directly determines whether the economic model closes. So this number wasn’t “forgotten” — it’s not yet comfortable to state. That itself is an honest signal.

Third, fine manipulation remains a hard boundary. The reporting repeatedly cites two examples: hanging a bag of rainbow candy on a hook, where a slight angle error can knock other products down; picking up a soft cake, where a hair’s difference in force means “dropped” or “crushed.” Humans do both with their eyes closed; the robot has to deploy vision, force control, and trajectory planning in full. The reminder: progress in embodied AI is uneven — locomotion, navigation, and rigid-object grasping are already fairly mature, but deformable objects, fragile items, and fine hanging remain the hardest stretch.

Fourth, Genie Master’s dual path of memory plus training is directionally right, but the effect needs time to verify. Memory reuse quickly improves “scenes already seen”; policy updates improve “scenes never seen.” A 24-hour challenge can at best validate the former — because it’s one store, one day. Real generalization only becomes visible when the system is replicated to a second store and a third city.

Fifth, the “four promoted” attrition rate is actually the most honest entry in the whole challenge. If all six passed, the review would look like theater; if only one or two passed, capability would look weak. Four of six both proves the system can sustain continuous work and admits a third is still unstable. In an industry where everyone is touting “general embodied intelligence,” being willing to publish an attrition rate is rarer than being willing to publish a task count.

A trackable framework: from now on, when you see “robots on the job” news, don’t just look at total tasks — look at four numbers: ① success rate (especially first-attempt success, which decides whether retries are needed); ② human takeover frequency per hour (the lifeline of the economic model); ③ continuous-operation duration and performance decay curve (8 hours and 24 hours are different problems); ④ scene replication cost (how long to re-tune for a new store — this decides whether it can scale). When none of those four are published, a total task count is basically marketing.

Sources: People’s Financial News / Stockstar, “AgiBot Robots Complete 1,730 Tasks in 24-Hour Convenience Store” (2026-11-03); Xinmin Evening News, “24 Hours Working in a Convenience Store, AgiBot G2 Completes 1,730 Tasks” (2026-11-03); Shangguan News / Wenhui Daily, “Six Robots Take On 24-Hour Convenience Store Shift, Netizens Supervise Online” (2026-11-02) and “Pudong Robots’ 24-Hour Probation Logs 1,730 Tasks” (2026-11-03); Pandaily, “Six AgiBot G2 Humanoids Run a Shanghai Convenience Store for 24 Hours, Logging 1,730 Tasks” (2026-11-04). The success-rate back-calculation, scheduling simulation, learning-loop model, dual-verification logic, obstacle-policy comparison, and pacing estimates are inference and illustration based on public information, not official data; AgiBot has not published task success rates or human takeover frequency, and citations should note that gap.