@@ -171,14 +171,19 @@ Chonk::PublicInputsResult Chonk::process_public_inputs_and_consistency_checks(
171171 << witness_commitments.calldata .get_value ());
172172 kernel_input.kernel_return_data .incomplete_assert_equal (witness_commitments.calldata );
173173
174- // App return data
175- bool app_return_data_match =
176- kernel_input.app_return_data .get_value () == witness_commitments.secondary_calldata .get_value ();
177- BB_ASSERT_DEBUG (app_return_data_match,
178- " app_return_data mismatch: proof contains "
179- << kernel_input.app_return_data .get_value () << " but secondary_calldata commitment is "
180- << witness_commitments.secondary_calldata .get_value ());
181- kernel_input.app_return_data .incomplete_assert_equal (witness_commitments.secondary_calldata );
174+ // App return data. Mega currently exposes a single app calldata witness commitment
175+ // (`secondary_calldata`), so MAX_APPS_PER_KERNEL remains 1.
176+ static_assert (MAX_APPS_PER_KERNEL == 1 , " Multiple app calldata witness columns are not wired yet" );
177+ for (size_t idx = 0 ; idx < MAX_APPS_PER_KERNEL ; ++idx) {
178+ bool app_return_data_match =
179+ kernel_input.app_return_data [idx].get_value () == witness_commitments.secondary_calldata .get_value ();
180+ BB_ASSERT_DEBUG (app_return_data_match,
181+ " app_return_data mismatch: proof contains "
182+ << kernel_input.app_return_data [idx].get_value ()
183+ << " but secondary_calldata commitment is "
184+ << witness_commitments.secondary_calldata .get_value ());
185+ kernel_input.app_return_data [idx].incomplete_assert_equal (witness_commitments.secondary_calldata );
186+ }
182187
183188 // ============= Perform accumulator hash consistency check =========================
184189
@@ -202,7 +207,7 @@ Chonk::PublicInputsResult Chonk::process_public_inputs_and_consistency_checks(
202207 AppIO app_input; // pairing points
203208 app_input.reconstruct_from_public (public_inputs);
204209
205- // Set the app return data commitment to be propagated via the public inputs
210+ // Set the app return data commitment to be propagated via the public inputs. The depot owns slot allocation.
206211 bus_depot.set_app_return_data_commitment (witness_commitments.return_data );
207212
208213 return { std::move (app_input.pairing_inputs ), std::nullopt };
@@ -318,6 +323,9 @@ void Chonk::complete_kernel_circuit_logic(ClientCircuit& circuit)
318323
319324 // Step 2: VERIFICATION LOOP - Recursively verify each proof in the queue
320325
326+ BB_ASSERT (bus_depot.app_return_data_slots_are_empty (),
327+ " DataBusDepot has stale app return-data slots at kernel-completion boundary" );
328+
321329 std::vector<PairingPoints> points_accumulator;
322330 std::optional<RecursiveVerifierAccumulator> current_stdlib_verifier_accumulator;
323331 if (!is_init_kernel) {
@@ -376,9 +384,11 @@ void Chonk::complete_kernel_circuit_logic(ClientCircuit& circuit)
376384 // Extract native verifier accumulator from the stdlib accum to use it in the next round
377385 recursive_verifier_native_accum = current_stdlib_verifier_accumulator->get_value <VerifierAccumulator>();
378386
379- // Get databus commitments
380387 auto kernel_return_data_commitment = bus_depot.get_kernel_return_data_commitment (circuit);
381- auto app_return_data_commitment = bus_depot.get_app_return_data_commitment (circuit);
388+ KernelIO::AppReturnDataCommitments app_return_data_commitments;
389+ for (size_t idx = 0 ; idx < MAX_APPS_PER_KERNEL ; ++idx) {
390+ app_return_data_commitments[idx] = bus_depot.get_app_return_data_commitment (circuit, idx);
391+ }
382392
383393 // Compute hash of output accumulator
384394 RecursiveTranscript hash_transcript;
@@ -394,7 +404,7 @@ void Chonk::complete_kernel_circuit_logic(ClientCircuit& circuit)
394404 // Propagate public inputs
395405 KernelIO kernel_output{ pairing_points_aggregator,
396406 kernel_return_data_commitment,
397- app_return_data_commitment ,
407+ app_return_data_commitments ,
398408 running_hash.value (),
399409 current_verifier_accum_hash };
400410 kernel_output.set_public ();
0 commit comments