{ "intent": "Take monitor.sh and its two probe libraries from 44.44% / 7.69% / 0% line coverage to 100%, so that the twelve enforcement probes behind the phone monitor are actually tested rather than merely present.", "scope": [ "phone_focus_mode/lib/monitor.sh - two defects fixed, two constructs restructured for measurability", "phone_focus_mode/lib/tests/monitor_harness.sh - new: the fake device", "phone_focus_mode/lib/tests/monitor_cases_health.sh - new: helper and health-probe assertions", "phone_focus_mode/lib/tests/monitor_cases_policy.sh - new: policy-probe and snapshot assertions", "phone_focus_mode/lib/tests/test_monitor.sh - reduced to the entry point that sources the three", "Non-goal: any device deploy. There is no phone in this session; the probes are proven with stubs and real runs.", "Non-goal: monitor_checks_health.sh and monitor_checks_policy.sh are untouched - they reached 100% on tests alone." ], "changes": [ "Added a fake device that mocks adb_root_shell at the function boundary rather than stubbing an adb binary on PATH. The probes never invoke adb; they call adb_root_shell, a function from adb_common.sh, so a PATH stub would never be consulted. Dispatch is by pattern rather than exact string because the real commands embed awk programs with escaped $2, nested quotes and 2>/dev/null redirections.", "Fixed a real JSON-escaping defect in _mon_escape_json: the substitution was written ${escaped//\"/\\\"}, where bash reads the bare quote as opening a quoted string, so the pattern silently degraded to `/\\` with an empty replacement and no quote was ever escaped. Any check message containing a double quote produced invalid JSON, which monitor_report.py then failed to parse. Found by the new test, not by inspection.", "Rewrote two constructs that no test could ever cover: a multi-line array literal in monitor_print_format_warning and a `{ ... } >file` redirection group in monitor_collect_snapshot. kcov instruments the continuation lines and the closing brace, but bash only ever reports a statement at its first line, so those 12 lines were permanently unreachable. Reproduced in an isolated 9-line case before changing anything; both are now per-statement.", "Removed an 11-line block of blank lines left in monitor.sh by the earlier split.", "Split the assertions across two sourced case files so every test file stays under the 250-line cap while test_monitor.sh remains the single entry point, keeping one coverage command able to measure all three subjects.", "Resolved SC2329 and SC2034 structurally rather than with disables: the non-numeric-count guard is now driven through a child bash process fed by a quoted heredoc (the device dns_iptables_harness.sh already uses), and the FORMAT_INDICATORS reset is read back immediately." ], "verification": [ { "command": "bash phone_focus_mode/lib/tests/test_monitor.sh", "result": "pass", "evidence": "Results: 82 passed, 0 failed. Was 9 passed before this change." }, { "command": "bash meta/scripts/shell_coverage.sh phone_focus_mode/lib/tests/test_monitor.sh monitor.sh", "result": "pass", "evidence": "monitor.sh: 104/104 lines = 100.00% (exit 0 at the default 100% minimum). Baseline was 48/108 = 44.44%." }, { "command": "bash meta/scripts/shell_coverage.sh phone_focus_mode/lib/tests/test_monitor.sh monitor_checks_policy.sh", "result": "pass", "evidence": "monitor_checks_policy.sh: 65/65 lines = 100.00%. Baseline was 5/65 = 7.69%." }, { "command": "bash meta/scripts/shell_coverage.sh phone_focus_mode/lib/tests/test_monitor.sh monitor_checks_health.sh", "result": "pass", "evidence": "monitor_checks_health.sh: 79/79 lines = 100.00%. Baseline was 0% - kcov reported 'instrumented no lines' because the file was never loaded." }, { "command": "mutation run: break each _check_* status decision in turn, require the suite to fail, restore", "result": "pass", "evidence": "18 mutations, 18 killed, 0 survived. The first run had 1 survivor - the repairable flag was asserted nowhere - which was closed by pinning it in both directions on a dead daemon and a healthy check." }, { "command": "bash meta/scripts/check_file_length.sh --all", "result": "pass", "evidence": "22 over-cap files, unchanged from before this commit. An intermediate 411-line test_monitor.sh briefly made it 23; that is why the cases are split across two files." }, { "command": "shellcheck on each touched file individually (no -x)", "result": "pass", "evidence": "All seven of monitor.sh, monitor_checks_health.sh, monitor_checks_policy.sh, monitor_harness.sh, monitor_cases_health.sh, monitor_cases_policy.sh and test_monitor.sh report clean standalone." }, { "command": "timeout 60 bash phone_focus_mode/run_phone.sh --help", "result": "pass", "evidence": "exit 0, proving the source chain through monitor.sh into both probe libraries still resolves after the edits." }, { "command": "jscpd, the pre-commit hook's exact invocation, measured in a clean HEAD worktree with and without these files", "result": "pass", "evidence": "1.43% at HEAD, 1.45% with these four files added - one new 19-line clone of the _t_pass/_t_fail/_t_eq block, well under the 2% gate. Working-tree runs report 2.47% because of vendored .venv site-packages, which is pre-existing and out of scope." }, { "command": "bash phone_focus_mode/lib/tests/{test_dns_iptables,test_tether_enforcer,test_adb_common,test_adb_trusted}.sh", "result": "pass", "evidence": "24, 17, 10 and 6 passed respectively, all 0 failed - the sibling suites are unaffected." } ], "risks": [ "The JSON-escaping fix changes what monitor_collect_snapshot writes for any check message containing a double quote. That output was invalid JSON before, so nothing could have depended on it, but a consumer parsing the old malformed shape leniently would now see a different string.", "The probes are verified against a stub device, not a real phone. The mock encodes what the commands are believed to return; a ROM whose dumpsys or df output differs in shape would still be mis-parsed, and no test here would catch it.", "monitor_collect_snapshot now writes report.json with three redirections instead of one grouped redirect. If the process were killed between them the file would be truncated rather than absent; previously the group could leave a partial file too, so this is a change in shape rather than in kind." ], "rollback": [ "git revert the commit. The three subjects return to their previous behaviour, including the JSON-escaping defect.", "After rollback, re-run bash phone_focus_mode/lib/tests/test_monitor.sh - it should report 9 passed - and timeout 60 bash phone_focus_mode/run_phone.sh --help expecting exit 0.", "The coverage regression is the point of the change, so a rollback should be paired with re-opening the backfill rather than treated as resolved." ] }