Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions docs/internal/retrospective-audit/AUDIT-012.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
{
"schema_version": 1,
"slice_id": "AUDIT-012",
"classification": "PLAYER_TOOL_BLOCK/INCONCLUSIVE",
"product_change": "NONE",
"baseline_sha": "06d291c1f92ce59c96454fced06d2a6250e150c4",
"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.",
"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": [
{
"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": "716A8412A86B61D5BBDF6E03C71047ABE0BEEC653F323AA9446938942BBDFF98",
"disposition": "RETAINED_BASELINE"
},
{
"path": "src/test/java/dev/hylfrd/farmhelper/client/ui/settings/FarmHelperSettingsControllerTest.java",
"classification": "AUDIT_TEST_SEAM",
"upstream_anchors": [],
"finding_ids": ["AUDIT-012-001"],
"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": "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",
"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",
"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",
"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"
}
],
"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."
},
"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.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": "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 is isolated from the user-owned Gradle cache.",
"No command behavior, macro behavior, or unrelated product source was changed."
],
"status": "INCONCLUSIVE"
}
],
"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",
"publication_sha": "322b40cb18ae71c07bd3ef3c93968825910d9537",
"publication_tree": "4a8a619692ed9bc7a78e3575cd2d3324815bae37",
"exact_head_ci": {
"head_sha": "322b40cb18ae71c07bd3ef3c93968825910d9537",
"push_run": 32788617000,
"pull_request_run": 32788620622,
"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",
"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": [],
"status": "LOCAL_GATES_PASSED_AND_EXACT_HEAD_CI_PASSED",
"ci": "Exact-head CI for publication head 322b40cb18ae71c07bd3ef3c93968825910d9537 passed in push run 32788617000 and pull_request run 32788620622."
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
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;

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 {
Expand All @@ -12,4 +18,169 @@ void liveConfigKeyChangesRequireRegisteredMappingSynchronization() {
assertTrue(FarmHelperSettingsController.needsKeyMappingUpdate(65, 344));
assertTrue(FarmHelperSettingsController.needsKeyMappingUpdate(344, -1));
}

@Test
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 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, scancode.getType());
assertEquals(rightShiftScancode(), scancode.getValue());
assertFalse(mapping.matches(scancodeEvent));
KeyMapping.click(scancode);
assertFalse(mapping.consumeClick());

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());
}

@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));

KeyMapping.set(key, false);
assertFalse(mapping.isDown());
}

@Test
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 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();

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(),
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;
}
}
}
Loading