Skip to content

feat(learn): add macOS learn mode via Seatbelt report-mode#171

Draft
kipz wants to merge 1 commit intoalways-further:mainfrom
kipz:kipz/osx-logs-learn
Draft

feat(learn): add macOS learn mode via Seatbelt report-mode#171
kipz wants to merge 1 commit intoalways-further:mainfrom
kipz:kipz/osx-logs-learn

Conversation

@kipz
Copy link

@kipz kipz commented Feb 26, 2026

This is kind of gross, but seems work work for me. Not sure if it fits with your goals for the project - as mentioned in #170, maybe dylib is a better approach?

  • Parent starts log stream filtered to kernel Sandbox events
  • Forks child, which applies (allow (with report) default) then exec()s the target — allows all ops but logs each to the kernel log
  • Parent drains log events via mpsc channel while polling waitpid
  • Seatbelt sandbox is inherited across exec(), so all child processes are traced including SIP-protected binaries

@kipz kipz force-pushed the kipz/osx-logs-learn branch from d018fff to 9d1af24 Compare February 26, 2026 20:20
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @kipz, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces macOS support to the nono learn command, leveraging Seatbelt's report mode and log stream to trace file system and network activity. It also refactors the codebase to promote code reuse across different platforms, enhancing the project's overall architecture and maintainability.

Highlights

  • macOS Learn Mode: Introduced macOS support for the nono learn command, enabling discovery of file system and network access patterns on macOS.
  • Seatbelt Report Mode: Utilized Seatbelt's report mode to trace system calls, capturing file and network activities of the target command.
  • Log Stream Integration: Integrated log stream to read kernel events, filtering for relevant sandbox events to extract file and network access information.
  • Cross-Platform Compatibility: Refactored learn mode to share common code between Linux and macOS, improving maintainability and reducing code duplication.
Changelog
  • crates/nono-cli/Cargo.toml
    • Added dns-lookup dependency for macOS to resolve hostnames.
  • crates/nono-cli/src/cli.rs
    • Updated the description of the learn command to remove the Linux-only restriction.
  • crates/nono-cli/src/learn.rs
    • Renamed learn.rs to linux.rs and moved it to a new learn subdirectory.
    • Moved shared code to learn/mod.rs.
  • crates/nono-cli/src/learn/macos.rs
    • Added new file macos.rs to implement macOS-specific learn mode using Seatbelt and log stream.
  • crates/nono-cli/src/learn/mod.rs
    • Created mod.rs to house shared code for learn mode across platforms.
  • crates/nono-cli/src/main.rs
    • Added a note to the user about needing admin group membership on macOS.
  • crates/nono-cli/src/policy.rs
    • Removed the Linux-only restriction on get_system_read_paths.
Activity
  • kipz authored the pull request.
  • The pull request implements macOS support for the learn command.
  • The pull request refactors learn mode to share code between Linux and macOS.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a learn mode for macOS using Seatbelt's report-mode, which is a great addition. The refactoring of the existing Linux learn mode to share common code is well-executed and improves the project's structure. I've found one important safety issue in the new macOS implementation regarding the use of std::process::exit in the forked child process, which I've detailed in a review comment.

Converts learn.rs into a learn/ module and adds macOS support using
Seatbelt report-mode + log stream.

How it works:
- Parent starts `log stream` filtered to kernel Sandbox events
- Forks child, which applies `(allow (with report) default)` then exec()s
  the target — allows all ops but logs each to the kernel log
- Parent drains log events via mpsc channel while polling waitpid
- Seatbelt sandbox is inherited across exec(), so all child processes
  are traced including SIP-protected binaries

Architecture:
- learn/mod.rs: shared types (FileAccess, NetworkAccess, LearnResult),
  cross-platform helpers (process_accesses, process_network_accesses,
  expand_home, resolve_*_dns), platform dispatcher, cross-platform tests
- learn/linux.rs: strace implementation (moved from learn.rs unchanged)
- learn/macos.rs: new Seatbelt implementation with log line parser
  and full test coverage

Other changes:
- policy.rs: remove #[cfg(target_os = "linux")] from get_system_read_paths
- Cargo.toml: add dns-lookup = "2" to macOS dependencies
- cli.rs: remove "(Linux only)" from Learn command description
- main.rs: add admin privilege note for macOS learn mode

Signed-off-by: James Carnegie <james.carnegie@datadoghq.com>
@kipz kipz force-pushed the kipz/osx-logs-learn branch from 9d1af24 to 3a17ccd Compare February 26, 2026 20:31
@lukehinds
Copy link
Collaborator

thanks @kipz , going to take a look today, added an initial thoughts in the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants