From b55697bc4fc7d95f6f74f1be8c7bcdc92ff7eeae Mon Sep 17 00:00:00 2001 From: Hylfrd Date: Tue, 25 Aug 2026 06:41:36 +0800 Subject: [PATCH 1/6] fix(audit-012): repair physical settings key fallback --- .../retrospective-audit/AUDIT-012.json | 116 ++++++++++++++++++ .../FarmHelperSettingsController.java | 47 ++++++- .../FarmHelperSettingsControllerTest.java | 91 ++++++++++++++ 3 files changed, 249 insertions(+), 5 deletions(-) create mode 100644 docs/internal/retrospective-audit/AUDIT-012.json diff --git a/docs/internal/retrospective-audit/AUDIT-012.json b/docs/internal/retrospective-audit/AUDIT-012.json new file mode 100644 index 00000000..279d42ef --- /dev/null +++ b/docs/internal/retrospective-audit/AUDIT-012.json @@ -0,0 +1,116 @@ +{ + "schema_version": 1, + "slice_id": "AUDIT-012", + "baseline_sha": "06d291c1f92ce59c96454fcedf6d2a6250e150c4", + "baseline_tree": "b6a7219c3a673788b21d9463499a5d26b828f230", + "audit_baseline_sha": "10f11c36c1a16f0ee9e896f7696eccc6fbf4e412", + "scope_manifest_sha256": "dee51e602834a18e9db858c1a90c9d437c828adba36ead360ff41fa6ec3fc904", + "scope_paths_sha256": "0f7af7080735013878cce7b182f9e98f54e1cd21c26bc3c2fc7bc256bbe418e5", + "scope_paths_digest_algorithm": "SHA-256 of UTF-8 sorted repository-relative paths joined by LF with a final LF", + "fixed_upstream": { + "commit": "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a", + "tree": "dfbaaf9ce75f9adc625352396acaa9138a8b97f8", + "relevant_behavior": "The fixed upstream uses OneKeyBind openGuiKeybind with default Keyboard.KEY_F and a config.openGui callback; it does not contain the current Minecraft 26.1.2 Fabric KeyMapping client path." + }, + "entries": [ + { + "path": "src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java", + "classification": "INDEPENDENT_REIMPLEMENTATION", + "upstream_anchors": [ + "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a:src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java#openGuiKeybind", + "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a:src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java#registerKeyBind", + "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a:src/main/java/com/jelly/farmhelperv2/command/FarmHelperMainCommand.java#mainCommand" + ], + "finding_ids": ["AUDIT-012-001"], + "file_sha256": "0B0A09628AFD42CC062771FED4E8F7072E8D42E276DC147D3E1C466AE84AEC73", + "disposition": "RESOLVED" + }, + { + "path": "src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java", + "classification": "INDEPENDENT_REIMPLEMENTATION", + "upstream_anchors": [], + "finding_ids": ["AUDIT-012-001"], + "file_sha256": "A98AB739FFBEBD7CF513577DE4E309C64475885FA51C087600E92F77CE5ED8E9", + "disposition": "RESOLVED" + } + ], + "findings": [ + { + "id": "AUDIT-012-001", + "path": "src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java", + "severity": "HIGH", + "summary": "The default Right Shift settings mapping did not open settings when the client delivered the physical key as a scancode event.", + "upstream_behavior": "In Minecraft 26.1.2, KeyboardHandler.keyPress calls InputConstants.getKey(KeyEvent), then KeyMapping.set and KeyMapping.click. InputConstants.getKey selects SCANCODE when KeyEvent.key() is -1. The fixed upstream only provides a legacy OneKeyBind callback and does not define this 26.1.2 boundary.", + "parent_reproduction": { + "minecraft": "26.1.2", + "fabric_loader": "0.19.3", + "fabric_api": "0.153.0+26.1.2", + "base_sha": "06d291c1f92ce59c96454fcedf6d2a6250e150c4", + "base_tree": "b6a7219c3a673788b21d9463499a5d26b828f230", + "default_mapping": "KEYSYM/344", + "right_left_identity": { + "KEY_LSHIFT": 340, + "KEY_RSHIFT": 344, + "right_shift_scancode": 54, + "left_shift_scancode": 42 + }, + "events": [ + { + "event": "KeyEvent(344, 54, 0)", + "input_constants_key": "KEYSYM/344", + "mapping": "KEYSYM/344", + "consume_click": true, + "classification": "parent_control_pass" + }, + { + "event": "KeyEvent(-1, 54, 0)", + "input_constants_key": "SCANCODE/54", + "mapping": "KEYSYM/344", + "consume_click": false, + "classification": "parent_product_fail" + } + ], + "impact": "The controller only drained openKey.consumeClick() at END_CLIENT_TICK, so the scancode event did not reach the settings opener. The same launch still passed /fh open and /farmhelper open, isolating the failure to default Right Shift input handling." + }, + "incompatibility": "InputConstants.Key equality includes both type and value. SCANCODE/54 therefore does not address a KEYSYM/344 mapping, even though the native GLFW state for the configured Right Shift key is down.", + "replacement": "Keep the vanilla KeyMapping click queue as the first path, drain it fully, combine KeyMapping.isDown() with InputConstants.isKeyDown(client.getWindow(), configuredKey), and accept only a rising edge of that combined state. Use the existing null-screen guard for key opens, preserve the command request parent behavior, and reset the edge state when a remap is applied.", + "automated_evidence": [ + "FarmHelperSettingsControllerTest.realClientBoundaryReproducesRightShiftScancodeMissAndFallbackOpensOnce proves the parent SCANCODE/54 -> KEYSYM/344 miss at the actual 26.1.2 KeyEvent/InputConstants/KeyMapping boundary, then proves one fallback opening and no held-key duplicate.", + "FarmHelperSettingsControllerTest.vanillaKeysymQueueAndPhysicalStateShareOneRisingEdgeAndScreenGuard proves KEYSYM/344 delivery, click-queue draining, held/repeat suppression, release/repress behavior, and the existing-screen guard.", + "FarmHelperSettingsControllerTest.unrelatedKeyDoesNotReachMappingOrPhysicalFallbackAndRemapStillUsesKeysym proves unrelated and left-Shift rejection plus standard remap to KEYSYM/65.", + "FarmHelperCommandTreeTest and ClientCommandScreenCloseTest preserve both farmhelper and fh command paths through the shared opener boundary.", + "The focused settings/screen/command Gradle suite passed, the full test suite passed, check passed with verifyDependencyProvenance, validateAccessWidener completed NO-SOURCE, and two clean build runs produced identical JAR SHA-256 93AFD5BECAB39D4CB2BED6B9774DC856F34048E6CE926AA6031B4B48FA15C9F9.", + "The resolved Minecraft client-only jar used for the boundary trace was .gradle-audit-012-repro/caches/fabric-loom/26.1.2/minecraft-client-only.jar with SHA-256 DD501F13C941D63DA332F45B334EA103252224084769EC92027D33AE54C0E579." + ], + "artifact": { + "path": "build/libs/FarmHelper-26.1.2.jar", + "sha256": "93AFD5BECAB39D4CB2BED6B9774DC856F34048E6CE926AA6031B4B48FA15C9F9", + "size_bytes": 891807 + }, + "privacy_boundary": [ + "The Builder performed no GUI, Computer Use, input, relaunch, or Player rerun; the immutable R4 observation is recorded as supplied authority only.", + "Boundary tests use synthetic KeyEvent values and do not capture world, account, chat, screen, or user configuration data.", + "Gradle state was isolated under the worktree-local .gradle-audit-012-repro directory; the user-owned Gradle cache was not mutated.", + "No command behavior, macro behavior, or unrelated product source was changed." + ], + "status": "RESOLVED" + } + ], + "verification": { + "resource_profile": "STANDARD_CLIENT_BOUNDARY", + "java": "25.0.3", + "gradle": "9.5.1", + "gradle_user_home": ".gradle-audit-012-repro", + "daemon_mode": "All Gradle commands used --no-daemon; Gradle stopped each required single-use daemon.", + "commands": [ + ".\\gradlew.bat --no-daemon --console=plain test --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsControllerTest", + ".\\gradlew.bat --no-daemon --console=plain test --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsControllerTest --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsScreenTest --tests dev.hylfrd.farmhelper.ui.command.FarmHelperCommandTreeTest --tests dev.hylfrd.farmhelper.client.ui.command.ClientCommandScreenCloseTest", + ".\\gradlew.bat --no-daemon --console=plain test", + ".\\gradlew.bat --no-daemon --console=plain check validateAccessWidener", + ".\\gradlew.bat --no-daemon --console=plain clean build (run 1)", + ".\\gradlew.bat --no-daemon --console=plain clean build (run 2)" + ], + "status": "LOCAL_GATES_PASSED", + "ci": "Publication and exact-head CI are reported in the handoff after push; no CI result is pre-claimed here." + } +} diff --git a/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java b/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java index 742a570c..d7b826d4 100644 --- a/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java +++ b/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java @@ -16,6 +16,7 @@ public final class FarmHelperSettingsController implements SettingsScreenOpener Identifier.fromNamespaceAndPath(FarmHelper.MOD_ID, "settings")); private final FarmHelperClientRuntime runtime; private final KeyMapping openKey; + private final KeyPressState keyPressState = new KeyPressState(); private int appliedConfigKey; private boolean openRequested; @@ -45,15 +46,36 @@ private void tick(Minecraft client) { syncConfiguredKey(); if (openRequested) { openRequested = false; - client.setScreen(new FarmHelperSettingsScreen(client.screen, runtime, openKey)); + openSettings(client, client.screen); } - while (openKey.consumeClick()) { - if (client.screen == null) { - client.setScreen(new FarmHelperSettingsScreen(null, runtime, openKey)); - } + boolean mappedClick = consumeClicks(openKey); + boolean keyPress = keyPressState.observe( + openKey.isDown() || isConfiguredKeyDown(client, runtime.core().config().openSettingsKey())); + if (shouldOpenFromKey(mappedClick, keyPress, client.screen != null)) { + openSettings(client, null); } } + private void openSettings(Minecraft client, net.minecraft.client.gui.screens.Screen parent) { + client.setScreen(new FarmHelperSettingsScreen(parent, runtime, openKey)); + } + + private static boolean isConfiguredKeyDown(Minecraft client, int configuredKey) { + return configuredKey >= 0 && InputConstants.isKeyDown(client.getWindow(), configuredKey); + } + + static boolean consumeClicks(KeyMapping mapping) { + boolean clicked = false; + while (mapping.consumeClick()) { + clicked = true; + } + return clicked; + } + + static boolean shouldOpenFromKey(boolean mappedClick, boolean keyPress, boolean screenOpen) { + return !screenOpen && (mappedClick || keyPress); + } + private void syncConfiguredKey() { int configuredKey = runtime.core().config().openSettingsKey(); if (!needsKeyMappingUpdate(appliedConfigKey, configuredKey)) { @@ -61,10 +83,25 @@ private void syncConfiguredKey() { } openKey.setKey(InputConstants.Type.KEYSYM.getOrCreate(configuredKey)); KeyMapping.resetMapping(); + keyPressState.reset(); appliedConfigKey = configuredKey; } static boolean needsKeyMappingUpdate(int appliedConfigKey, int configuredKey) { return appliedConfigKey != configuredKey; } + + static final class KeyPressState { + private boolean wasDown; + + boolean observe(boolean isDown) { + boolean pressed = isDown && !wasDown; + wasDown = isDown; + return pressed; + } + + void reset() { + wasDown = false; + } + } } diff --git a/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java b/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java index 9057d2e0..9082bb48 100644 --- a/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java +++ b/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java @@ -1,8 +1,13 @@ package dev.hylfrd.farmhelper.client.ui.settings; +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.input.KeyEvent; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; class FarmHelperSettingsControllerTest { @@ -12,4 +17,90 @@ void liveConfigKeyChangesRequireRegisteredMappingSynchronization() { assertTrue(FarmHelperSettingsController.needsKeyMappingUpdate(65, 344)); assertTrue(FarmHelperSettingsController.needsKeyMappingUpdate(344, -1)); } + + @Test + void realClientBoundaryReproducesRightShiftScancodeMissAndFallbackOpensOnce() { + assertEquals(340, InputConstants.KEY_LSHIFT); + assertEquals(344, InputConstants.KEY_RSHIFT); + assertNotEquals(InputConstants.KEY_LSHIFT, InputConstants.KEY_RSHIFT); + + KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "right-shift"); + KeyEvent computerUseRightShift = new KeyEvent(-1, 54, 0); + InputConstants.Key eventKey = InputConstants.getKey(computerUseRightShift); + + assertEquals(InputConstants.Type.SCANCODE, eventKey.getType()); + assertEquals(54, eventKey.getValue()); + assertFalse(mapping.matches(computerUseRightShift)); + KeyMapping.click(eventKey); + assertFalse(mapping.consumeClick()); + + FarmHelperSettingsController.KeyPressState state = new FarmHelperSettingsController.KeyPressState(); + int openedScreens = 0; + boolean screenOpen = false; + + if (FarmHelperSettingsController.shouldOpenFromKey( + FarmHelperSettingsController.consumeClicks(mapping), state.observe(true), screenOpen)) { + openedScreens++; + screenOpen = true; + } + if (FarmHelperSettingsController.shouldOpenFromKey( + FarmHelperSettingsController.consumeClicks(mapping), state.observe(true), screenOpen)) { + openedScreens++; + } + + assertEquals(1, openedScreens); + } + + @Test + void vanillaKeysymQueueAndPhysicalStateShareOneRisingEdgeAndScreenGuard() { + KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "keysym"); + KeyEvent rightShiftKeysym = new KeyEvent(InputConstants.KEY_RSHIFT, 54, 0); + InputConstants.Key eventKey = InputConstants.getKey(rightShiftKeysym); + + assertEquals(InputConstants.Type.KEYSYM, eventKey.getType()); + assertEquals(InputConstants.KEY_RSHIFT, eventKey.getValue()); + assertTrue(mapping.matches(rightShiftKeysym)); + KeyMapping.click(eventKey); + KeyMapping.click(eventKey); + + assertTrue(FarmHelperSettingsController.consumeClicks(mapping)); + assertFalse(FarmHelperSettingsController.consumeClicks(mapping)); + assertTrue(FarmHelperSettingsController.shouldOpenFromKey(true, false, false)); + assertFalse(FarmHelperSettingsController.shouldOpenFromKey(true, true, true)); + + FarmHelperSettingsController.KeyPressState state = new FarmHelperSettingsController.KeyPressState(); + assertTrue(state.observe(true)); + assertFalse(state.observe(true)); + assertFalse(state.observe(true)); + assertFalse(state.observe(false)); + assertTrue(state.observe(true)); + } + + @Test + void unrelatedKeyDoesNotReachMappingOrPhysicalFallbackAndRemapStillUsesKeysym() { + KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "remap"); + KeyEvent leftShift = new KeyEvent(InputConstants.KEY_LSHIFT, 42, 0); + KeyEvent unrelated = new KeyEvent(InputConstants.KEY_A, 30, 0); + + assertFalse(mapping.matches(leftShift)); + assertFalse(mapping.matches(unrelated)); + KeyMapping.click(InputConstants.getKey(leftShift)); + KeyMapping.click(InputConstants.getKey(unrelated)); + assertFalse(FarmHelperSettingsController.consumeClicks(mapping)); + + mapping.setKey(InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_A)); + KeyMapping.resetMapping(); + assertTrue(mapping.matches(unrelated)); + KeyMapping.click(InputConstants.getKey(unrelated)); + assertTrue(FarmHelperSettingsController.consumeClicks(mapping)); + assertFalse(FarmHelperSettingsController.shouldOpenFromKey(false, false, false)); + } + + private static KeyMapping newMapping(int key, String suffix) { + return new KeyMapping( + "farmhelper.audit012." + suffix + "." + System.nanoTime(), + InputConstants.Type.KEYSYM, + key, + KeyMapping.Category.MISC); + } } From 4ecbd398184ef1fa5609bd9efceda885e6a5660b Mon Sep 17 00:00:00 2001 From: Hylfrd Date: Tue, 25 Aug 2026 07:08:00 +0800 Subject: [PATCH 2/6] test(audit-012): classify Shift_R observation as inconclusive --- .../retrospective-audit/AUDIT-012.json | 143 +++++++++---- .../FarmHelperSettingsController.java | 47 +---- .../FarmHelperSettingsControllerTest.java | 198 ++++++++++++------ 3 files changed, 244 insertions(+), 144 deletions(-) diff --git a/docs/internal/retrospective-audit/AUDIT-012.json b/docs/internal/retrospective-audit/AUDIT-012.json index 279d42ef..e408b58b 100644 --- a/docs/internal/retrospective-audit/AUDIT-012.json +++ b/docs/internal/retrospective-audit/AUDIT-012.json @@ -1,7 +1,9 @@ { "schema_version": 1, "slice_id": "AUDIT-012", - "baseline_sha": "06d291c1f92ce59c96454fcedf6d2a6250e150c4", + "classification": "PLAYER_TOOL_BLOCK/INCONCLUSIVE", + "product_change": "NONE", + "baseline_sha": "06d291c1f92ce59c96454fced06d2a6250e150c4", "baseline_tree": "b6a7219c3a673788b21d9463499a5d26b828f230", "audit_baseline_sha": "10f11c36c1a16f0ee9e896f7696eccc6fbf4e412", "scope_manifest_sha256": "dee51e602834a18e9db858c1a90c9d437c828adba36ead360ff41fa6ec3fc904", @@ -10,7 +12,30 @@ "fixed_upstream": { "commit": "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a", "tree": "dfbaaf9ce75f9adc625352396acaa9138a8b97f8", - "relevant_behavior": "The fixed upstream uses OneKeyBind openGuiKeybind with default Keyboard.KEY_F and a config.openGui callback; it does not contain the current Minecraft 26.1.2 Fabric KeyMapping client path." + "relevant_behavior": "The fixed upstream uses OneKeyBind openGuiKeybind with default Keyboard.KEY_F and a config.openGui callback; it does not contain the current Minecraft 26.1.2 Fabric KeyMapping client path.", + "anchors": [ + "src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java#openGuiKeybind", + "src/main/java/com/jelly/farmhelperv2/config/FarmHelperConfig.java#registerKeyBind", + "src/main/java/com/jelly/farmhelperv2/command/FarmHelperMainCommand.java#mainCommand" + ] + }, + "modern_client_boundary": { + "minecraft": "26.1.2", + "fabric_loader": "0.19.3", + "fabric_api": "0.153.0+26.1.2", + "default_config_key": 344, + "default_config_key_identity": "InputConstants.KEY_RSHIFT / KEYSYM/344", + "modern_difference": "The modern downstream default Right Shift differs from fixed-upstream Keyboard.KEY_F and is undocumented/unreviewed in the fixed upstream. An offhand conflict is a hypothesis only, not a finding.", + "source_identity": { + "controller_matches_baseline": true, + "controller_git_blob_sha1": "742a570ccc47bba19163d0d02ae1ec27d0ad614c" + }, + "vanilla_trace": [ + "KeyboardHandler.keyPress converts KeyEvent with InputConstants.getKey.", + "InputConstants.getKey selects SCANCODE when KeyEvent.key() is -1 and KEYSYM otherwise.", + "KeyboardHandler then calls KeyMapping.set and KeyMapping.click for the resolved InputConstants.Key.", + "The FarmHelper controller consumes the registered mapping click queue at END_CLIENT_TICK and keeps its existing null-screen guard." + ] }, "entries": [ { @@ -22,32 +47,30 @@ "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a:src/main/java/com/jelly/farmhelperv2/command/FarmHelperMainCommand.java#mainCommand" ], "finding_ids": ["AUDIT-012-001"], - "file_sha256": "0B0A09628AFD42CC062771FED4E8F7072E8D42E276DC147D3E1C466AE84AEC73", - "disposition": "RESOLVED" + "file_sha256": "1653F449713F863DBC284D3489509BAD6D7EC7F41E871F6C54C517F9D4E53968", + "disposition": "RETAINED_BASELINE" }, { "path": "src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java", - "classification": "INDEPENDENT_REIMPLEMENTATION", + "classification": "AUDIT_TEST_SEAM", "upstream_anchors": [], "finding_ids": ["AUDIT-012-001"], - "file_sha256": "A98AB739FFBEBD7CF513577DE4E309C64475885FA51C087600E92F77CE5ED8E9", - "disposition": "RESOLVED" + "file_sha256": "9E13B816EE02B6B6F58B07B3FD0C44A1048C30DD28332CFBAFC6287296537C6C", + "disposition": "ADDED_AUDIT_EVIDENCE" } ], "findings": [ { "id": "AUDIT-012-001", "path": "src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java", - "severity": "HIGH", - "summary": "The default Right Shift settings mapping did not open settings when the client delivered the physical key as a scancode event.", - "upstream_behavior": "In Minecraft 26.1.2, KeyboardHandler.keyPress calls InputConstants.getKey(KeyEvent), then KeyMapping.set and KeyMapping.click. InputConstants.getKey selects SCANCODE when KeyEvent.key() is -1. The fixed upstream only provides a legacy OneKeyBind callback and does not define this 26.1.2 boundary.", - "parent_reproduction": { - "minecraft": "26.1.2", - "fabric_loader": "0.19.3", - "fabric_api": "0.153.0+26.1.2", - "base_sha": "06d291c1f92ce59c96454fcedf6d2a6250e150c4", + "severity": "P0-06", + "classification": "PLAYER_TOOL_BLOCK/INCONCLUSIVE", + "summary": "The supplied R4 Shift_R observation does not establish a GLFW or Minecraft KeyEvent identity, so it is not a proven product failure.", + "upstream_behavior": "Fixed upstream opens its GUI from a OneKeyBind whose default is Keyboard.KEY_F and also exposes the shared command callback. The current client is a separate Minecraft 26.1.2 Fabric KeyMapping implementation.", + "current_master_boundary_reproduction": { + "base_sha": "06d291c1f92ce59c96454fced06d2a6250e150c4", "base_tree": "b6a7219c3a673788b21d9463499a5d26b828f230", - "default_mapping": "KEYSYM/344", + "mapping": "KEYSYM/344", "right_left_identity": { "KEY_LSHIFT": 340, "KEY_RSHIFT": 344, @@ -59,58 +82,92 @@ "event": "KeyEvent(344, 54, 0)", "input_constants_key": "KEYSYM/344", "mapping": "KEYSYM/344", - "consume_click": true, - "classification": "parent_control_pass" + "mapping_matches": true, + "key_mapping_click_consumed": true, + "classification": "VANILLA_KEYSYSTEM_PASS" }, { "event": "KeyEvent(-1, 54, 0)", "input_constants_key": "SCANCODE/54", "mapping": "KEYSYM/344", - "consume_click": false, - "classification": "parent_product_fail" + "mapping_matches": false, + "key_mapping_click_consumed": false, + "classification": "DISTINCT_INPUT_IDENTITY" + }, + { + "event": "KeyEvent(-1, 42, 0)", + "input_constants_key": "SCANCODE/42", + "mapping": "SCANCODE/54", + "mapping_matches": false, + "key_mapping_click_consumed": false, + "classification": "LEFT_RIGHT_DISTINCT" } ], - "impact": "The controller only drained openKey.consumeClick() at END_CLIENT_TICK, so the scancode event did not reach the settings opener. The same launch still passed /fh open and /farmhelper open, isolating the failure to default Right Shift input handling." + "outcome": "The current-master event-to-KeyMapping harness passes a KEYSYM/344 delivery and rejects SCANCODE/54 for a KEYSYM/344 mapping. This proves input identity semantics only; it does not prove which event, if any, the Computer Use Shift_R action delivered to Minecraft." }, - "incompatibility": "InputConstants.Key equality includes both type and value. SCANCODE/54 therefore does not address a KEYSYM/344 mapping, even though the native GLFW state for the configured Right Shift key is down.", - "replacement": "Keep the vanilla KeyMapping click queue as the first path, drain it fully, combine KeyMapping.isDown() with InputConstants.isKeyDown(client.getWindow(), configuredKey), and accept only a rising edge of that combined state. Use the existing null-screen guard for key opens, preserve the command request parent behavior, and reset the edge state when a remap is applied.", + "r4_observation": { + "milestone": "1cfb12ed1493614ea8dc2aa44925cd48852f654e", + "state": "disposable singleplayer, stopped/safe, no screen open", + "action": "one exact Computer Use Shift_R action", + "observation": "fresh capture remained world and FarmHelper Settings did not open", + "transport_identity": "INCONCLUSIVE", + "classification": "PLAYER_TOOL_BLOCK/INCONCLUSIVE" + }, + "related_paths": { + "p0_04_fh_open": "PASS", + "p0_05_farmhelper_open": "PASS", + "command_open_and_shared_opener": "PASS", + "controller_tick_path": "PASS in the existing vanilla click-queue/controller seam tests" + }, + "root_cause": "UNPROVEN", + "product_fix": "NONE; production controller behavior is retained exactly from baseline.", "automated_evidence": [ - "FarmHelperSettingsControllerTest.realClientBoundaryReproducesRightShiftScancodeMissAndFallbackOpensOnce proves the parent SCANCODE/54 -> KEYSYM/344 miss at the actual 26.1.2 KeyEvent/InputConstants/KeyMapping boundary, then proves one fallback opening and no held-key duplicate.", - "FarmHelperSettingsControllerTest.vanillaKeysymQueueAndPhysicalStateShareOneRisingEdgeAndScreenGuard proves KEYSYM/344 delivery, click-queue draining, held/repeat suppression, release/repress behavior, and the existing-screen guard.", - "FarmHelperSettingsControllerTest.unrelatedKeyDoesNotReachMappingOrPhysicalFallbackAndRemapStillUsesKeysym proves unrelated and left-Shift rejection plus standard remap to KEYSYM/65.", - "FarmHelperCommandTreeTest and ClientCommandScreenCloseTest preserve both farmhelper and fh command paths through the shared opener boundary.", - "The focused settings/screen/command Gradle suite passed, the full test suite passed, check passed with verifyDependencyProvenance, validateAccessWidener completed NO-SOURCE, and two clean build runs produced identical JAR SHA-256 93AFD5BECAB39D4CB2BED6B9774DC856F34048E6CE926AA6031B4B48FA15C9F9.", - "The resolved Minecraft client-only jar used for the boundary trace was .gradle-audit-012-repro/caches/fabric-loom/26.1.2/minecraft-client-only.jar with SHA-256 DD501F13C941D63DA332F45B334EA103252224084769EC92027D33AE54C0E579." + "FarmHelperSettingsControllerTest.rightShiftEventIdentityIsUnambiguousAtVanillaBoundary proves KEYSYM/344 versus SCANCODE/54 and right-versus-left SCANCODE identity through InputConstants and KeyMapping.matches/click consumption.", + "FarmHelperSettingsControllerTest.controllerTickSeamConsumesOnePressAndSuppressesHeldRepeat proves the existing click-drain loop, one-screen opening, held-state non-triggering, repeat draining, and no repeat storm. Its rising-edge assertion is test-only and adds no production physical-state fallback.", + "FarmHelperSettingsControllerTest.existingScreenAndUnrelatedKeyRemainOutsideTheSettingsTrigger proves the existing-screen guard and unrelated-key rejection.", + "FarmHelperSettingsControllerTest.remappedF6UsesStandardKeysymMappingAndOpensOnce proves the normal remap path with InputConstants.KEY_F6 and one settings opening.", + "FarmHelperCommandTreeTest and ClientCommandScreenCloseTest preserve both farmhelper and fh command paths through the existing shared opener.", + "The current-master boundary probe passed with KEYSYM/344 consumed=true and SCANCODE/54 consumed=false; the disposable probe was removed after the run." ], "artifact": { "path": "build/libs/FarmHelper-26.1.2.jar", - "sha256": "93AFD5BECAB39D4CB2BED6B9774DC856F34048E6CE926AA6031B4B48FA15C9F9", - "size_bytes": 891807 + "sha256": "42A79DC679FBD843FAAF40B601F1A7A5671C6BC1D452DF9E5913ED406C214C25", + "size_bytes": 890472, + "deterministic_rebuild": "Two clean build runs produced this identical SHA-256." }, "privacy_boundary": [ "The Builder performed no GUI, Computer Use, input, relaunch, or Player rerun; the immutable R4 observation is recorded as supplied authority only.", "Boundary tests use synthetic KeyEvent values and do not capture world, account, chat, screen, or user configuration data.", - "Gradle state was isolated under the worktree-local .gradle-audit-012-repro directory; the user-owned Gradle cache was not mutated.", + "Gradle state is isolated from the user-owned Gradle cache.", "No command behavior, macro behavior, or unrelated product source was changed." ], - "status": "RESOLVED" + "status": "INCONCLUSIVE" } ], "verification": { "resource_profile": "STANDARD_CLIENT_BOUNDARY", "java": "25.0.3", "gradle": "9.5.1", - "gradle_user_home": ".gradle-audit-012-repro", - "daemon_mode": "All Gradle commands used --no-daemon; Gradle stopped each required single-use daemon.", - "commands": [ - ".\\gradlew.bat --no-daemon --console=plain test --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsControllerTest", - ".\\gradlew.bat --no-daemon --console=plain test --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsControllerTest --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsScreenTest --tests dev.hylfrd.farmhelper.ui.command.FarmHelperCommandTreeTest --tests dev.hylfrd.farmhelper.client.ui.command.ClientCommandScreenCloseTest", - ".\\gradlew.bat --no-daemon --console=plain test", - ".\\gradlew.bat --no-daemon --console=plain check validateAccessWidener", - ".\\gradlew.bat --no-daemon --console=plain clean build (run 1)", - ".\\gradlew.bat --no-daemon --console=plain clean build (run 2)" + "gradle_user_home": "C:/Users/Apostrophe/AppData/Local/Temp/farmhelper-audit-012-gradle-repro", + "daemon_mode": "Gradle commands use --no-daemon; Gradle stops each required single-use daemon.", + "commands_completed": [ + "Current-master disposable KeyEvent/InputConstants/KeyMapping boundary probe: PASS", + ".\\gradlew.bat --no-daemon --console=plain test --rerun-tasks --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsControllerTest: PASS", + ".\\gradlew.bat --no-daemon --console=plain test --rerun-tasks --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsControllerTest --tests dev.hylfrd.farmhelper.client.ui.settings.FarmHelperSettingsScreenTest --tests dev.hylfrd.farmhelper.ui.command.FarmHelperCommandTreeTest --tests dev.hylfrd.farmhelper.client.ui.command.ClientCommandScreenCloseTest: PASS", + ".\\gradlew.bat --no-daemon --console=plain test --rerun-tasks: PASS; 686 tests, 0 failures, 0 errors", + ".\\gradlew.bat --no-daemon --console=plain check validateAccessWidener --rerun-tasks: PASS; validateAccessWidener NO-SOURCE; dependency provenance PASS", + ".\\gradlew.bat --no-daemon --console=plain clean build --rerun-tasks (run 1): PASS; JAR SHA-256 42A79DC679FBD843FAAF40B601F1A7A5671C6BC1D452DF9E5913ED406C214C25", + ".\\gradlew.bat --no-daemon --console=plain clean build --rerun-tasks (run 2): PASS; JAR SHA-256 42A79DC679FBD843FAAF40B601F1A7A5671C6BC1D452DF9E5913ED406C214C25" + ], + "resource_observations": [ + "The first worktree-local Gradle home bootstrap timed out after 124 seconds without a test result; successful gates then used the pre-provisioned isolated Gradle 9.5.1 home listed above.", + "No user-owned Gradle cache was mutated." + ], + "commands_pending": [ + "Implementation/publication commit identity", + "Branch push and exact-head CI" ], "status": "LOCAL_GATES_PASSED", - "ci": "Publication and exact-head CI are reported in the handoff after push; no CI result is pre-claimed here." + "ci": "No CI result is pre-claimed here." } } diff --git a/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java b/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java index d7b826d4..742a570c 100644 --- a/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java +++ b/src/client/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsController.java @@ -16,7 +16,6 @@ public final class FarmHelperSettingsController implements SettingsScreenOpener Identifier.fromNamespaceAndPath(FarmHelper.MOD_ID, "settings")); private final FarmHelperClientRuntime runtime; private final KeyMapping openKey; - private final KeyPressState keyPressState = new KeyPressState(); private int appliedConfigKey; private boolean openRequested; @@ -46,36 +45,15 @@ private void tick(Minecraft client) { syncConfiguredKey(); if (openRequested) { openRequested = false; - openSettings(client, client.screen); + client.setScreen(new FarmHelperSettingsScreen(client.screen, runtime, openKey)); } - boolean mappedClick = consumeClicks(openKey); - boolean keyPress = keyPressState.observe( - openKey.isDown() || isConfiguredKeyDown(client, runtime.core().config().openSettingsKey())); - if (shouldOpenFromKey(mappedClick, keyPress, client.screen != null)) { - openSettings(client, null); + while (openKey.consumeClick()) { + if (client.screen == null) { + client.setScreen(new FarmHelperSettingsScreen(null, runtime, openKey)); + } } } - private void openSettings(Minecraft client, net.minecraft.client.gui.screens.Screen parent) { - client.setScreen(new FarmHelperSettingsScreen(parent, runtime, openKey)); - } - - private static boolean isConfiguredKeyDown(Minecraft client, int configuredKey) { - return configuredKey >= 0 && InputConstants.isKeyDown(client.getWindow(), configuredKey); - } - - static boolean consumeClicks(KeyMapping mapping) { - boolean clicked = false; - while (mapping.consumeClick()) { - clicked = true; - } - return clicked; - } - - static boolean shouldOpenFromKey(boolean mappedClick, boolean keyPress, boolean screenOpen) { - return !screenOpen && (mappedClick || keyPress); - } - private void syncConfiguredKey() { int configuredKey = runtime.core().config().openSettingsKey(); if (!needsKeyMappingUpdate(appliedConfigKey, configuredKey)) { @@ -83,25 +61,10 @@ private void syncConfiguredKey() { } openKey.setKey(InputConstants.Type.KEYSYM.getOrCreate(configuredKey)); KeyMapping.resetMapping(); - keyPressState.reset(); appliedConfigKey = configuredKey; } static boolean needsKeyMappingUpdate(int appliedConfigKey, int configuredKey) { return appliedConfigKey != configuredKey; } - - static final class KeyPressState { - private boolean wasDown; - - boolean observe(boolean isDown) { - boolean pressed = isDown && !wasDown; - wasDown = isDown; - return pressed; - } - - void reset() { - wasDown = false; - } - } } diff --git a/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java b/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java index 9082bb48..3a5bbf05 100644 --- a/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java +++ b/src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java @@ -1,6 +1,7 @@ package dev.hylfrd.farmhelper.client.ui.settings; import com.mojang.blaze3d.platform.InputConstants; +import dev.hylfrd.farmhelper.config.FarmHelperConfig; import net.minecraft.client.KeyMapping; import net.minecraft.client.input.KeyEvent; import org.junit.jupiter.api.Test; @@ -19,88 +20,167 @@ void liveConfigKeyChangesRequireRegisteredMappingSynchronization() { } @Test - void realClientBoundaryReproducesRightShiftScancodeMissAndFallbackOpensOnce() { + void rightShiftEventIdentityIsUnambiguousAtVanillaBoundary() { assertEquals(340, InputConstants.KEY_LSHIFT); assertEquals(344, InputConstants.KEY_RSHIFT); assertNotEquals(InputConstants.KEY_LSHIFT, InputConstants.KEY_RSHIFT); + assertEquals(54, rightShiftScancode()); + assertEquals(42, leftShiftScancode()); KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "right-shift"); - KeyEvent computerUseRightShift = new KeyEvent(-1, 54, 0); - InputConstants.Key eventKey = InputConstants.getKey(computerUseRightShift); + KeyEvent keysymEvent = new KeyEvent(InputConstants.KEY_RSHIFT, rightShiftScancode(), 0); + InputConstants.Key keysym = InputConstants.getKey(keysymEvent); + + assertEquals(InputConstants.Type.KEYSYM, keysym.getType()); + assertEquals(InputConstants.KEY_RSHIFT, keysym.getValue()); + assertTrue(mapping.matches(keysymEvent)); + KeyMapping.click(keysym); + assertTrue(mapping.consumeClick()); + assertFalse(mapping.consumeClick()); + + KeyEvent scancodeEvent = new KeyEvent(-1, rightShiftScancode(), 0); + InputConstants.Key scancode = InputConstants.getKey(scancodeEvent); - assertEquals(InputConstants.Type.SCANCODE, eventKey.getType()); - assertEquals(54, eventKey.getValue()); - assertFalse(mapping.matches(computerUseRightShift)); - KeyMapping.click(eventKey); + assertEquals(InputConstants.Type.SCANCODE, scancode.getType()); + assertEquals(rightShiftScancode(), scancode.getValue()); + assertFalse(mapping.matches(scancodeEvent)); + KeyMapping.click(scancode); assertFalse(mapping.consumeClick()); - FarmHelperSettingsController.KeyPressState state = new FarmHelperSettingsController.KeyPressState(); - int openedScreens = 0; - boolean screenOpen = false; + KeyMapping scancodeMapping = newMapping( + InputConstants.Type.SCANCODE, rightShiftScancode(), "right-shift-scancode"); + KeyEvent leftScancodeEvent = new KeyEvent(-1, leftShiftScancode(), 0); + assertTrue(scancodeMapping.matches(scancodeEvent)); + assertFalse(scancodeMapping.matches(leftScancodeEvent)); + KeyMapping.click(scancode); + assertTrue(scancodeMapping.consumeClick()); + } - if (FarmHelperSettingsController.shouldOpenFromKey( - FarmHelperSettingsController.consumeClicks(mapping), state.observe(true), screenOpen)) { - openedScreens++; - screenOpen = true; - } - if (FarmHelperSettingsController.shouldOpenFromKey( - FarmHelperSettingsController.consumeClicks(mapping), state.observe(true), screenOpen)) { - openedScreens++; - } + @Test + void controllerTickSeamConsumesOnePressAndSuppressesHeldRepeat() { + KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "tick"); + InputConstants.Key key = InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_RSHIFT); + ControllerTriggerSeam seam = new ControllerTriggerSeam(false); + + assertFalse(seam.observeHeldState(false)); + KeyMapping.set(key, true); + assertTrue(mapping.isDown()); + assertEquals(0, seam.tick(mapping)); + + assertTrue(seam.observeHeldState(true)); + assertFalse(seam.observeHeldState(true)); + assertFalse(seam.observeHeldState(false)); + assertTrue(seam.observeHeldState(true)); + + KeyMapping.click(key); + KeyMapping.click(key); + assertEquals(1, seam.tick(mapping)); + assertEquals(1, seam.openedScreens()); + assertFalse(mapping.consumeClick()); + assertEquals(0, seam.tick(mapping)); - assertEquals(1, openedScreens); + KeyMapping.set(key, false); + assertFalse(mapping.isDown()); } @Test - void vanillaKeysymQueueAndPhysicalStateShareOneRisingEdgeAndScreenGuard() { - KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "keysym"); - KeyEvent rightShiftKeysym = new KeyEvent(InputConstants.KEY_RSHIFT, 54, 0); - InputConstants.Key eventKey = InputConstants.getKey(rightShiftKeysym); - - assertEquals(InputConstants.Type.KEYSYM, eventKey.getType()); - assertEquals(InputConstants.KEY_RSHIFT, eventKey.getValue()); - assertTrue(mapping.matches(rightShiftKeysym)); - KeyMapping.click(eventKey); - KeyMapping.click(eventKey); - - assertTrue(FarmHelperSettingsController.consumeClicks(mapping)); - assertFalse(FarmHelperSettingsController.consumeClicks(mapping)); - assertTrue(FarmHelperSettingsController.shouldOpenFromKey(true, false, false)); - assertFalse(FarmHelperSettingsController.shouldOpenFromKey(true, true, true)); - - FarmHelperSettingsController.KeyPressState state = new FarmHelperSettingsController.KeyPressState(); - assertTrue(state.observe(true)); - assertFalse(state.observe(true)); - assertFalse(state.observe(true)); - assertFalse(state.observe(false)); - assertTrue(state.observe(true)); + void existingScreenAndUnrelatedKeyRemainOutsideTheSettingsTrigger() { + KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "guards"); + ControllerTriggerSeam existingScreen = new ControllerTriggerSeam(true); + InputConstants.Key rightShift = InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_RSHIFT); + InputConstants.Key unrelated = InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_A); + + KeyMapping.click(rightShift); + KeyMapping.click(unrelated); + assertEquals(0, existingScreen.tick(mapping)); + assertEquals(0, existingScreen.openedScreens()); + assertFalse(mapping.consumeClick()); } @Test - void unrelatedKeyDoesNotReachMappingOrPhysicalFallbackAndRemapStillUsesKeysym() { - KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "remap"); - KeyEvent leftShift = new KeyEvent(InputConstants.KEY_LSHIFT, 42, 0); - KeyEvent unrelated = new KeyEvent(InputConstants.KEY_A, 30, 0); - - assertFalse(mapping.matches(leftShift)); - assertFalse(mapping.matches(unrelated)); - KeyMapping.click(InputConstants.getKey(leftShift)); - KeyMapping.click(InputConstants.getKey(unrelated)); - assertFalse(FarmHelperSettingsController.consumeClicks(mapping)); - - mapping.setKey(InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_A)); + void remappedF6UsesStandardKeysymMappingAndOpensOnce() { + assertTrue(FarmHelperSettingsController.needsKeyMappingUpdate( + FarmHelperConfig.DEFAULT_OPEN_SETTINGS_KEY, InputConstants.KEY_F6)); + + KeyMapping mapping = newMapping(InputConstants.KEY_RSHIFT, "f6"); + mapping.setKey(InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_F6)); KeyMapping.resetMapping(); - assertTrue(mapping.matches(unrelated)); - KeyMapping.click(InputConstants.getKey(unrelated)); - assertTrue(FarmHelperSettingsController.consumeClicks(mapping)); - assertFalse(FarmHelperSettingsController.shouldOpenFromKey(false, false, false)); + + try { + KeyEvent f6Event = new KeyEvent(InputConstants.KEY_F6, 0, 0); + InputConstants.Key f6 = InputConstants.getKey(f6Event); + ControllerTriggerSeam seam = new ControllerTriggerSeam(false); + + assertEquals(InputConstants.Type.KEYSYM, f6.getType()); + assertEquals(InputConstants.KEY_F6, f6.getValue()); + assertTrue(mapping.matches(f6Event)); + KeyMapping.click(f6); + assertEquals(1, seam.tick(mapping)); + assertFalse(mapping.consumeClick()); + assertEquals(1, seam.openedScreens()); + + KeyEvent rightShiftEvent = new KeyEvent(InputConstants.KEY_RSHIFT, rightShiftScancode(), 0); + assertFalse(mapping.matches(rightShiftEvent)); + KeyMapping.click(InputConstants.getKey(rightShiftEvent)); + assertEquals(0, seam.tick(mapping)); + assertFalse(mapping.consumeClick()); + } finally { + mapping.setKey(InputConstants.Type.KEYSYM.getOrCreate(InputConstants.KEY_RSHIFT)); + KeyMapping.resetMapping(); + } + } + + private static int rightShiftScancode() { + return 54; + } + + private static int leftShiftScancode() { + return 42; } private static KeyMapping newMapping(int key, String suffix) { + return newMapping(InputConstants.Type.KEYSYM, key, suffix); + } + + private static KeyMapping newMapping(InputConstants.Type type, int key, String suffix) { return new KeyMapping( "farmhelper.audit012." + suffix + "." + System.nanoTime(), - InputConstants.Type.KEYSYM, + type, key, KeyMapping.Category.MISC); } + + /** Test-only seam matching the existing controller's click-drain and screen guard. */ + private static final class ControllerTriggerSeam { + private boolean previousDown; + private boolean screenOpen; + private int openedScreens; + + private ControllerTriggerSeam(boolean screenOpen) { + this.screenOpen = screenOpen; + } + + private boolean observeHeldState(boolean isDown) { + boolean risingEdge = isDown && !previousDown; + previousDown = isDown; + return risingEdge; + } + + private int tick(KeyMapping mapping) { + int openedThisTick = 0; + while (mapping.consumeClick()) { + if (screenOpen) { + continue; + } + screenOpen = true; + openedScreens++; + openedThisTick++; + } + return openedThisTick; + } + + private int openedScreens() { + return openedScreens; + } + } } From d32c5c83476cc3ddfdcacd4f121345996eee23c3 Mon Sep 17 00:00:00 2001 From: Hylfrd Date: Tue, 25 Aug 2026 07:08:40 +0800 Subject: [PATCH 3/6] docs(audit-012): record inconclusive candidate identity --- docs/internal/retrospective-audit/AUDIT-012.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/internal/retrospective-audit/AUDIT-012.json b/docs/internal/retrospective-audit/AUDIT-012.json index e408b58b..05c59eb7 100644 --- a/docs/internal/retrospective-audit/AUDIT-012.json +++ b/docs/internal/retrospective-audit/AUDIT-012.json @@ -146,6 +146,14 @@ ], "verification": { "resource_profile": "STANDARD_CLIENT_BOUNDARY", + "implementation_sha": "4ecbd398184ef1fa5609bd9efceda885e6a5660b", + "implementation_tree": "10c44db8f12a63d6a7a874b5ff70d7b508e802f7", + "candidate_sha": "4ecbd398184ef1fa5609bd9efceda885e6a5660b", + "candidate_tree": "10c44db8f12a63d6a7a874b5ff70d7b508e802f7", + "candidate_artifact_sha256": "42A79DC679FBD843FAAF40B601F1A7A5671C6BC1D452DF9E5913ED406C214C25", + "candidate_artifact_size_bytes": 890472, + "branch": "codex/audit-right-shift-keybinding", + "pull_request": "https://github.com/Hylfrd/FarmHelper/pull/14", "java": "25.0.3", "gradle": "9.5.1", "gradle_user_home": "C:/Users/Apostrophe/AppData/Local/Temp/farmhelper-audit-012-gradle-repro", From b5bcf603430b0c4153f090723b9081b90700e135 Mon Sep 17 00:00:00 2001 From: Hylfrd Date: Tue, 25 Aug 2026 07:12:55 +0800 Subject: [PATCH 4/6] docs(audit-012): record exact-head CI result --- .../retrospective-audit/AUDIT-012.json | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/internal/retrospective-audit/AUDIT-012.json b/docs/internal/retrospective-audit/AUDIT-012.json index 05c59eb7..39aa4516 100644 --- a/docs/internal/retrospective-audit/AUDIT-012.json +++ b/docs/internal/retrospective-audit/AUDIT-012.json @@ -154,6 +154,20 @@ "candidate_artifact_size_bytes": 890472, "branch": "codex/audit-right-shift-keybinding", "pull_request": "https://github.com/Hylfrd/FarmHelper/pull/14", + "publication_sha": "d32c5c83476cc3ddfdcacd4f121345996eee23c3", + "publication_tree": "ada137a5f0f4b0f6179fe4748d4dbc49c1204b7d", + "exact_head_ci": { + "head_sha": "d32c5c83476cc3ddfdcacd4f121345996eee23c3", + "push_run": 32788004207, + "pull_request_run": 32788008275, + "conclusion": "success", + "jobs": [ + "Linux / test", + "Linux / build", + "Windows / test", + "Windows / build" + ] + }, "java": "25.0.3", "gradle": "9.5.1", "gradle_user_home": "C:/Users/Apostrophe/AppData/Local/Temp/farmhelper-audit-012-gradle-repro", @@ -171,11 +185,8 @@ "The first worktree-local Gradle home bootstrap timed out after 124 seconds without a test result; successful gates then used the pre-provisioned isolated Gradle 9.5.1 home listed above.", "No user-owned Gradle cache was mutated." ], - "commands_pending": [ - "Implementation/publication commit identity", - "Branch push and exact-head CI" - ], - "status": "LOCAL_GATES_PASSED", - "ci": "No CI result is pre-claimed here." + "commands_pending": [], + "status": "LOCAL_GATES_PASSED_AND_EXACT_HEAD_CI_PASSED", + "ci": "Exact-head CI for publication head d32c5c83476cc3ddfdcacd4f121345996eee23c3 passed in push run 32788004207 and pull_request run 32788008275." } } From 322b40cb18ae71c07bd3ef3c93968825910d9537 Mon Sep 17 00:00:00 2001 From: Hylfrd Date: Tue, 25 Aug 2026 07:16:41 +0800 Subject: [PATCH 5/6] docs(audit-012): align publication identity --- docs/internal/retrospective-audit/AUDIT-012.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/internal/retrospective-audit/AUDIT-012.json b/docs/internal/retrospective-audit/AUDIT-012.json index 39aa4516..e33e20de 100644 --- a/docs/internal/retrospective-audit/AUDIT-012.json +++ b/docs/internal/retrospective-audit/AUDIT-012.json @@ -154,12 +154,12 @@ "candidate_artifact_size_bytes": 890472, "branch": "codex/audit-right-shift-keybinding", "pull_request": "https://github.com/Hylfrd/FarmHelper/pull/14", - "publication_sha": "d32c5c83476cc3ddfdcacd4f121345996eee23c3", - "publication_tree": "ada137a5f0f4b0f6179fe4748d4dbc49c1204b7d", + "publication_sha": "b5bcf603430b0c4153f090723b9081b90700e135", + "publication_tree": "d71b87076f56c787c3743537d2a1c7fa3b3987da", "exact_head_ci": { - "head_sha": "d32c5c83476cc3ddfdcacd4f121345996eee23c3", - "push_run": 32788004207, - "pull_request_run": 32788008275, + "head_sha": "b5bcf603430b0c4153f090723b9081b90700e135", + "push_run": 32788329026, + "pull_request_run": 32788331861, "conclusion": "success", "jobs": [ "Linux / test", @@ -187,6 +187,6 @@ ], "commands_pending": [], "status": "LOCAL_GATES_PASSED_AND_EXACT_HEAD_CI_PASSED", - "ci": "Exact-head CI for publication head d32c5c83476cc3ddfdcacd4f121345996eee23c3 passed in push run 32788004207 and pull_request run 32788008275." + "ci": "Exact-head CI for publication head b5bcf603430b0c4153f090723b9081b90700e135 passed in push run 32788329026 and pull_request run 32788331861." } } From 0b92dd8e43941e46152c548d6f149f4f1a9b2ee8 Mon Sep 17 00:00:00 2001 From: Hylfrd Date: Sun, 30 Aug 2026 23:05:43 +0800 Subject: [PATCH 6/6] docs(audit-012): correct report identity digests --- docs/internal/retrospective-audit/AUDIT-012.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/internal/retrospective-audit/AUDIT-012.json b/docs/internal/retrospective-audit/AUDIT-012.json index e33e20de..7117d96c 100644 --- a/docs/internal/retrospective-audit/AUDIT-012.json +++ b/docs/internal/retrospective-audit/AUDIT-012.json @@ -47,7 +47,7 @@ "eacb323fbde3eff94d4f2ee7baacb059d84b8e3a:src/main/java/com/jelly/farmhelperv2/command/FarmHelperMainCommand.java#mainCommand" ], "finding_ids": ["AUDIT-012-001"], - "file_sha256": "1653F449713F863DBC284D3489509BAD6D7EC7F41E871F6C54C517F9D4E53968", + "file_sha256": "716A8412A86B61D5BBDF6E03C71047ABE0BEEC653F323AA9446938942BBDFF98", "disposition": "RETAINED_BASELINE" }, { @@ -154,12 +154,12 @@ "candidate_artifact_size_bytes": 890472, "branch": "codex/audit-right-shift-keybinding", "pull_request": "https://github.com/Hylfrd/FarmHelper/pull/14", - "publication_sha": "b5bcf603430b0c4153f090723b9081b90700e135", - "publication_tree": "d71b87076f56c787c3743537d2a1c7fa3b3987da", + "publication_sha": "322b40cb18ae71c07bd3ef3c93968825910d9537", + "publication_tree": "4a8a619692ed9bc7a78e3575cd2d3324815bae37", "exact_head_ci": { - "head_sha": "b5bcf603430b0c4153f090723b9081b90700e135", - "push_run": 32788329026, - "pull_request_run": 32788331861, + "head_sha": "322b40cb18ae71c07bd3ef3c93968825910d9537", + "push_run": 32788617000, + "pull_request_run": 32788620622, "conclusion": "success", "jobs": [ "Linux / test", @@ -187,6 +187,6 @@ ], "commands_pending": [], "status": "LOCAL_GATES_PASSED_AND_EXACT_HEAD_CI_PASSED", - "ci": "Exact-head CI for publication head b5bcf603430b0c4153f090723b9081b90700e135 passed in push run 32788329026 and pull_request run 32788331861." + "ci": "Exact-head CI for publication head 322b40cb18ae71c07bd3ef3c93968825910d9537 passed in push run 32788617000 and pull_request run 32788620622." } }