Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2a51518
fix: make storage recovery usable while development stays active
heznpc Sep 9, 2026
3713459
feat: notify sustained CPU load with top processes
heznpc Sep 9, 2026
9dccffe
fix: connect health incidents and stop predicting recovery from file …
heznpc Sep 9, 2026
c51e899
feat: add Modore-owned repository retirement transactions
heznpc Sep 9, 2026
a0edb52
Add shared simulator and external disk work controls
heznpc Sep 9, 2026
7882395
Redesign work resource UI around active environments
heznpc Sep 9, 2026
37a4c00
feat: make Modore environment recovery selectable and resumable
heznpc Sep 10, 2026
f4e1be2
feat: redesign environment recovery around work intentions
heznpc Sep 10, 2026
ab294d4
feat: expose recovery conditions and selection effects visually
heznpc Sep 10, 2026
fb8a726
feat: rebuild Mac home around visible status and direct actions
heznpc Sep 10, 2026
493e859
feat: add storage map navigation and exact app registration cleanup
heznpc Sep 10, 2026
4d7f111
fix: stabilize workbench loading and dashboard navigation
heznpc Sep 10, 2026
4bec386
fix: keep dashboard compact and open tasks in main navigation
heznpc Sep 10, 2026
76fed33
fix: surface transient CPU load and retain incident peaks
heznpc Sep 10, 2026
7b54fd3
fix: show dashboard actions and localize status cards
heznpc Sep 10, 2026
52c2975
fix: complete native localization and language fallback coverage
heznpc Sep 10, 2026
f10ca65
fix: localize persisted disk and cleanup diagnostics
heznpc Sep 10, 2026
d188bf9
feat: add confirmed iPhone media and file cleanup
heznpc Sep 10, 2026
8606ab5
docs: record physical iPhone cleanup validation
heznpc Sep 10, 2026
9063684
feat: connect QuotaPie tasks to responsive session review
heznpc Sep 13, 2026
8c9757e
fix: keep session runtime validation responsive
heznpc Sep 13, 2026
91dfcd9
fix: restore storage alerts across app updates and worsening pressure
heznpc Sep 13, 2026
b9148d8
fix: keep storage and resource pressure alerts responsive
heznpc Sep 13, 2026
e550d8a
fix: shut down managed simulator tests when turns finish
heznpc Sep 13, 2026
2f41fec
fix: close managed Playwright browsers when turns finish
heznpc Sep 14, 2026
f6cd219
fix: make storage recovery actionable and readable
heznpc Sep 15, 2026
a643667
Merge quota work continuity into accumulated recovery changes
heznpc Sep 15, 2026
16b20ff
fix(i18n): cover select-all and explicit conversation localization keys
heznpc Sep 17, 2026
b832492
ci: 모델 테스트 언어 고정과 이전 검사 중단
heznpc Sep 17, 2026
ca9a6cd
ci: 모델 테스트 스크립트를 빌드 전용으로 분류
heznpc Sep 17, 2026
90833ea
fix(ci): 로컬 DMG 빌드에 임시 서명 방식 명시
heznpc Sep 17, 2026
80c836e
feat: CI 실패 묶음과 프로젝트 연결 및 복구 추적
heznpc Sep 17, 2026
5e1d119
fix: 작업 목록 재계산과 CI 시간 경계 불안정성 해소
heznpc Sep 17, 2026
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
9 changes: 5 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
validate:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -177,10 +181,7 @@ jobs:
-Xswiftc -strict-concurrency=complete

- name: Test Mac SwiftUI models and safety state
run: |
swift test --package-path macos/Modore \
-Xswiftc -warnings-as-errors \
-Xswiftc -strict-concurrency=complete
run: bash scripts/test_macos_models.sh

# MothballCore is built transitively by the Modore build above, so a
# compile error would surface -- but its tests never ran anywhere.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ This is the highest-value contribution: adding a legitimate local app that curre

- [ ] `python3 -I -B -m pytest tests/ -q` passes.
- [ ] `python3 -I -B scripts/release_smoke.py --check-only` passes.
- [ ] If you touched the Mac app, `swift test --package-path macos/Modore -Xswiftc -warnings-as-errors -Xswiftc -strict-concurrency=complete` passes.
- [ ] If you touched the Mac app, `bash scripts/test_macos_models.sh` passes. It runs Korean-copy model contracts with process-local language preferences, then checks localization under English and Japanese without changing system settings.
- [ ] If you touched Mac packaging, `scripts/package_macos_release.sh --local` completes and its app, DMG, and sidecar metadata report the intended architectures/minimum OS. This never creates a publishable release.
- [ ] If you touched a PowerShell script, run a parse check:
`pwsh -Command "[System.Management.Automation.Language.Parser]::ParseFile('scripts/<file>.ps1', [ref]\$null, [ref]\$null)"`.
Expand Down
70 changes: 67 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ Today, the Mac app focuses on AI work continuity and storage recovery. The Windo
| Surface | What it provides |
|---|---|
| **Mac app** | Native SwiftUI views for storage, AI work, system evidence, activity history, settings, and approval-gated recovery. |
| **iPhone preview** | Shows device capacity and, after explicit Photo Library permission, counts videos and screen recordings from public metadata. iOS does not expose other apps' caches or System Data, and this preview does not delete media. |
| **iPhone preview** | Shows device capacity, reviews photos and videos after Photo Library permission, and deletes only confirmed selections. Files cleanup is limited to files explicitly chosen through the document picker. Records before/after capacity locally; iOS does not expose other apps' caches or System Data. |
| **AI work protection** | Joins Claude, Codex, Gemini, and supported IDE sessions to repositories and worktrees; flags retention risk, missing workspaces, and unpushed sole copies. |
| **CI incidents** | Groups GitHub Actions failures with evidence, links local projects, tracks verified recovery, and optionally notifies on new issues or recovery while the app runs. [CI workflow](./docs/CI_INCIDENTS.md). |
| **Verified backups** | Creates and verifies original Claude and Codex session archives, then restores them only into a new safe directory. |
| **Asset retirement** | Select GitHub archive and local repository cleanup independently; preserve ignored data, override risk warnings, retry partial operations, and inspect separate mutation/verification/free-space results. [Workflow](./docs/ASSET_RETIREMENT.md). |
| **Storage recovery** | Explains caches, developer runtimes, apps, models, Simulator data, and project residue; safe batches require an exact preview and stop when the free-space goal is met. |
| **Local audits** | Reviews uninstall residue and trust roots, unused model caches, broken MCP registrations, session file access, and user corrections of AI agents. |
| **Read-only MCP** | Makes selected judgments available during an agent session without exposing cleanup, deletion, or scan execution. |
Expand Down Expand Up @@ -62,6 +64,15 @@ inspection.
`search --first` stops at the newest matching turn; ordinary `search` keeps its
full coverage contract for absence claims.

**Currently implemented — turn test resources:** opt-in Claude/Codex lifecycle
hooks connect a completed response to simulator runs started by
`modore resources begin-test`. Modore shuts down only its registered test run,
preserves devices and persistent data, and keeps resources with unresolved
consumers or an explicit preview hold. Hook setup requires host review where
applicable; disabled hooks and unregistered processes are outside this coverage.
This does not pause or terminate AI sessions. See the
[command contract](./skills/modore-ops/references/command-contract.md#turn-test-resources).

### Windows

Clone the repository or download its source archive, then run `scan.bat`. See [Installation](#installation) for requirements and troubleshooting.
Expand All @@ -76,6 +87,8 @@ open Modore.xcodeproj

Requires iOS 17 or later. The generated project is committed, so XcodeGen is needed only after changing `project.yml`. Storage thresholds and capacity arithmetic come from `shared/ModoreDomain`, the same Swift package used by the Mac app.

See [iPhone cleanup](./docs/IPHONE_CLEANUP.md) for selection, confirmation, receipt behavior and validation limits.

<details>
<summary><strong>Technical and CLI reference</strong></summary>

Expand Down Expand Up @@ -193,7 +206,7 @@ Modore is the brand. The OS editions are separate products under that brand, not
| Edition | Artifact | Focus | Validation rule |
|---|---|---|---|
| Mac Edition | `modore-v0.3.x-mac-source.zip`, optional notarized Universal 2 DMG | The scree AI-agent session/residue audit, plus macOS security context and decoding of the System Data / Developer / macOS storage bar into real paths and safe next actions | Mac-only features ship after local macOS validation |
| iPhone preview | Source project in `ios/Modore` | Device capacity plus user-authorized video and screen-recording metadata; no cross-app cache inspection or deletion | Public iOS APIs only; Simulator tests and real-device validation before distribution |
| iPhone preview | Source project in `ios/Modore` | Device capacity, confirmed photo/video and user-picked file deletion, and local cleanup receipts; no cross-app cache inspection | Public iOS APIs only; Simulator tests and real-device validation before distribution |
| Windows Edition | `modore-v0.3.x-win.zip` | Korean banking/government security-plugin context, Defender, Sysinternals, autoruns, network, idle CPU monitor | Windows-only features ship only after real Windows-device validation |

Shared rules, whitelist data, i18n strings, and report vocabulary can be reused where they genuinely match. OS-specific collectors stay separate.
Expand Down Expand Up @@ -375,6 +388,32 @@ modore/
└── tests/ pytest service and safety contracts
```

## Local Mac app updates

Run `bash scripts/build_macos_swift_app.sh` to build the native app with two
compiler jobs. Local builds use an available Developer ID Application identity,
or the explicit `PCH_SIGNING_IDENTITY` identity. Reusing the identity preserves
macOS privacy grants across updates; changing from an older ad-hoc build can
require granting access once to the newly signed app. For an intentionally
ad-hoc development build, set `PCH_SIGNING_IDENTITY=-` explicitly.

Deep storage scans are manual by default; enable automatic refresh in Settings
if wanted. Live free-space readings continue independently. Recovery previews
use two concurrent workers with a 30-second preview budget, retain verified
candidates when another candidate fails, and allow retrying excluded candidates.
Chrome clone cleanup checks individual clone directories for open files, keeping
active or unverified clones while offering unused ones. Displayed clone size is
not a promise of reclaimed space because APFS blocks can be shared.

CPU load alerts can be enabled in Modore Settings. While the app is running
(including in the background), native process CPU counters are sampled every
10 seconds, supplemented by the system process reader for protected processes
such as WindowServer. A minute of sustained high CPU usage or macOS thermal pressure
produces a notification with the top three process names, PIDs, and recent CPU
percentages. Bursts are ignored and notifications are at least ten minutes
apart. The monitor allows system sleep, resets sustained-load evidence after
long sampling gaps (including sleep), stores no process history, and stops when Modore quits.

## Landing page

The `docs/` folder is the project landing page, designed for GitHub Pages. It is a static, script-free English page: two HTML/CSS files, no client-side i18n runtime.
Expand Down Expand Up @@ -467,7 +506,7 @@ Distribution mode only runs from a clean `v<version>` tag at `HEAD` verified by
- **No file uploads.** VirusTotal integration uses SHA-256 hashes only.
- **Local cache only.** VT response cache lives in `%LOCALAPPDATA%/PC건강검진/` (Windows) or `~/Library/Caches/PC건강검진/` (macOS).
- **Local cleanup receipts.** Mac cleanup receipts stay under `~/Library/Application Support/Modore/cleanup-receipts/`; they contain local paths and are never uploaded.
- **Local maintenance state.** Simulator keep UUIDs, bounded scan snapshots, and hourly free-space samples stay under `~/Library/Application Support/Modore/` with owner-only permissions. They are never uploaded and can contain local paths, so exported support material should not include them.
- **Local maintenance state.** Simulator keep UUIDs, bounded scan snapshots, and minute free-space samples stay under `~/Library/Application Support/Modore/` with owner-only permissions. They are never uploaded and can contain local paths, so exported support material should not include them.
- **Auditable.** VirusTotal calls are in `scripts/vt-lookup.ps1` / `scripts/scanner_helper.jxa.js`; optional Sysinternals downloads are in `scripts/sigcheck-helper.ps1` / `scripts/autorunsc-helper.ps1`. Grep for `Invoke-RestMethod`, `Invoke-WebRequest`, `curl`, and `virustotal.com/api`.

## Contributing
Expand Down Expand Up @@ -499,3 +538,28 @@ This project depends on — but does not redistribute — Microsoft Sysinternals
---

<sub>Version 0.3 · 2026</sub>

### Currently implemented — local health context

The **지금 이 Mac** home screen observes disk availability, macOS memory
pressure, swap, CPU and thermal pressure every ten seconds while Modore runs.
It records up to 40 local incidents, links notifications back to the screen,
and compares observations before and after an action. Recovery requires a
complete minute below the warning thresholds; restarting or a monitoring gap
never implies recovery. Notification permission does not gate observation.
Process working directories connect to matching session metadata as candidates,
not proof that a session owns a process. Conversation bodies are opened only
through explicit session selection or search. The screen also exposes cleanup
receipts and copying the current diagnostic context.

Cleanup previews report **actual recovery unknown**. Summed directory sizes
may include shared APFS blocks and never establish goal completion. Candidate
review includes remaining eligible recipes rather than stopping when their
sizes add up to the requested gain. Execution still stops based on measured
filesystem availability. A shortfall is explicitly reported after execution.

**Design intent:** preserve evidence from detection through action and observed
outcome without making the user reconstruct it in a prompt.

**Non-goals:** automatic process termination, automatic deletion, inference of
session ownership from an app name, or guaranteed recovery from directory size.
16 changes: 16 additions & 0 deletions bin/modore
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ usage() {
/usr/bin/printf '%s\n' \
'Usage:' \
' modore sessions [--limit N]' \
' modore ci status|refresh [--discover] [--repo owner/name] [--project PATH]' \
' modore sessions current' \
' modore search [--first] [--limit N] [--budget-seconds N] # query on stdin' \
' modore resources status|acquire|claim|heartbeat|release [options]' \
' modore resources begin-test|hold --provider codex|claude --session ID --turn ID [options]' \
' modore resources begin-browser-test --provider codex|claude --session ID --project PATH --turn ID --url URL [--headed]' \
' modore resources install-hooks --provider codex|claude' \
' modore storage status' \
' modore storage recovery' \
' modore cleanup list' \
Expand Down Expand Up @@ -83,9 +88,20 @@ COMMAND="${1:-help}"
[[ "$#" -eq 0 ]] || shift

case "$COMMAND" in
ci)
exec "$PYTHON" -I -B "$PROJECT_ROOT/scripts/ci_watch.py" "$@"
;;
help|-h|--help)
usage
;;
environments)
[[ "${1:-}" == "status" ]] || fail_usage 'environments requires status.'
shift
exec "$PYTHON" -I -B "$PROJECT_ROOT/scripts/environment_retirement.py" --inventory "$@"
;;
resources)
exec "$PYTHON" -I -B "$PROJECT_ROOT/scripts/work_resources.py" "$@"
;;
sessions)
if [[ "${1:-}" == "current" ]]; then
[[ "$#" -eq 1 ]] \
Expand Down
85 changes: 81 additions & 4 deletions data/report_i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,22 @@
"full_disk_note": "macOS privacy settings may hide some personal-data or app-data areas. If the report looks empty, check System Settings > Privacy & Security > Full Disk Access."
},
"tips": {
"defender_update": { "title": "Update antivirus", "desc_key": "explain_tips_defender_update" },
"virustotal": { "title": "Check suspicious files", "desc_key": "explain_tips_virustotal" },
"full_scan": { "title": "Run a full scan", "desc_key": "explain_tips_full_scan" },
"hardware_noise": { "title": "Hardware noise", "desc_key": "explain_tips_hardware_noise" }
"defender_update": {
"title": "Update antivirus",
"desc_key": "explain_tips_defender_update"
},
"virustotal": {
"title": "Check suspicious files",
"desc_key": "explain_tips_virustotal"
},
"full_scan": {
"title": "Run a full scan",
"desc_key": "explain_tips_full_scan"
},
"hardware_noise": {
"title": "Hardware noise",
"desc_key": "explain_tips_hardware_noise"
}
},
"actions": {
"danger": {
Expand Down Expand Up @@ -149,5 +161,70 @@
"defender_unavailable": "Defender info unavailable.",
"storage_unavailable": "Storage information unavailable.",
"storage_empty": "No items to show."
},
"native_fragments": {
"는 큰 용량을 System Data, Developer, macOS 같은 이름으로 뭉뚱그려 보여줍니다. 이 표는 그 막대 뒤에 숨어 있는 캐시, 시뮬레이터, SDK, 앱 덩어리를 실제 경로 기준으로 풀어봅니다.": " groups storage as System Data, Developer, and macOS. This report shows the caches, simulators, SDKs, and apps behind those categories by actual path.",
"개인정보 보호 설정 때문에 일부 개인 데이터/앱 데이터 영역을 읽지 못했을 수 있습니다. 결과가 비어 보이면 시스템 설정 &gt; 개인정보 보호 및 보안 &gt; 전체 디스크 접근 권한을 확인하세요.": "Privacy settings may prevent access to personal and app data. If results are empty, check System Settings &gt; Privacy &amp; Security &gt; Full Disk Access.",
"공유용 리포트입니다. PC 이름, 사용자 이름, 홈 디렉터리 경로를 자동으로 가렸습니다. 공유 전 내용을 한 번 더 확인하세요.": "Shareable report: computer name, user name, and home path are redacted. Review the contents before sharing.",
"도움을 요청하려고 리포트를 공유할 때는 PC 이름, 사용자 이름, 경로에 포함된 개인 정보를 먼저 가리세요.": "Before sharing this report, redact personal information in computer names, user names, and paths.",
"건은 VT 쿼터 소진으로 확인하지 못했습니다. 위험 판정과는 무관하며, 다음 검사에서 이어서 확인됩니다.": " entries were not checked because the VT quota was exhausted. This does not indicate danger; checking resumes on the next scan.",
"공간을 지워도 다시 차게 만드는 실행 중인 브라우저, 시뮬레이터, 개발 세션 신호입니다.": "Running browsers, simulators, and development sessions that may regenerate data after cleanup.",
"알 수 없는 항목은 검색과 VirusTotal 리포트 링크로 맥락을 확인하세요.": "Use search and VirusTotal links to investigate unfamiliar entries.",
"의심 항목을 바로 삭제하지 말고 프로그램 이름과 경로를 확인하세요.": "Check the program name and path before deleting a suspicious entry.",
"현재 수집 범위에서 즉시 조치가 필요한 항목이 보이지 않습니다.": "No immediate action is indicated within the collected data.",
"확인 항목의 프로그램 이름, 게시자, 설치일을 대조하세요.": "Compare the program name, publisher, and installation date.",
"권한 또는 시간 제한 문제를 해결한 뒤 다시 검사하세요.": "Resolve permission or timeout issues, then scan again.",
"정밀 검사를 실행해 유휴 CPU 사용량을 확인하세요.": "Run a detailed scan to check idle CPU usage.",
"느림이나 팬 소음이 계속되면 다시 검사하세요.": "Scan again if slowdowns or fan noise persist.",
"민감한 브라우저 세션을 닫은 뒤 조사하세요.": "Close sensitive browser sessions before investigating.",
"주의가 필요한 항목이 발견되지 않았습니다.": "No entries requiring attention were found.",
"완료하지 못한 필수 수집기를 확인하세요.": "Review required collectors that did not finish.",
"리포트를 안전하게 기록하지 못했습니다: ": "Could not safely write the report: ",
"보안 업데이트를 최신 상태로 유지하세요.": "Keep security updates current.",
"빈 결과를 정상으로 해석하지 마세요.": "An empty result does not establish a healthy state.",
"항목으로 뭉친 개발 도구/시뮬레이터": "tools and simulators",
"백신으로 전체 검사를 실행하세요.": "Run a full antivirus scan.",
"크기가 안전 상한을 초과했습니다.": "size exceeds the safety limit.",
"에 summary가 없습니다.": "is missing its summary.",
"설치 앱 크기 및 제거 검토": "Installed app sizes and removal review",
"로 숨을 수 있는 정리 후보": "cleanup candidates",
"표시할 항목이 없습니다.": "No entries to display.",
"자동 실행 종합 분석": "Startup items",
"최근 설치 프로그램": "Recently installed programs",
"개 완료 · 전체 ": " complete · All: ",
"외부 네트워크 연결": "External network connections",
"사용 상위 프로세스": "top processes",
"건 · 캐시 유지 ": " · Cache hours: ",
"저장공간 막대 해석": "storage breakdown",
"기기별 보존 상태": "device retention",
"이번 검사 조회 ": "Lookups in this scan: ",
"이번 검사에서 ": "In this scan, ",
"리포트 생성: ": "Report generated: ",
"주요 발견 사항": "Key findings",
"필수 수집기 ": "Required collectors: ",
"검사 시각: ": "Scanned at: ",
"삭제 전 확인": "Review before deleting",
"건 · 확인 ": " · Review: ",
"생성 시각 ": "Generated: ",
"남은 공간 ": "Free space: ",
"반복 생성원": "Data regeneration sources",
"열린 포트": "Open ports",
"정상 확인": "Verified healthy",
"확인 필요": "Needs review",
"위험 항목": "Danger entries",
"다음 행동": "Next actions",
"검사 범위": "Scan coverage",
"개 완료": " complete",
"사용률 ": "Used: ",
"에서 ": ": ",
"공유용": "Shareable",
"위험 ": "Danger: ",
"결과": "Results",
"검색": "Search",
"조회": "Lookups",
"항목": "Entry",
"시간": " hours",
"조사": "Investigate",
"건": " entries"
}
}
Loading