Files
harness-tools/skills/tools/nono-profiles/SKILL.md
T

121 lines
7.7 KiB
Markdown

---
name: nono-profiles
description: "Author or revise repository-managed nono sandbox profiles. Use for nono profile changes, additional repository or client-directory access, filesystem grants, Internet access tiers and domain allowlists, Unix sockets, profile inheritance, validation, or troubleshooting profile permissions in this environment."
---
# Nono Profiles
Author reviewed nono profiles from this repository, using `profiles/nono/pi-local.json` as the local starting point and `~/.config/nono/profiles/` only as the activation location.
## Process
### 1. Inspect the live policy
Locate the repository root and read:
- `profiles/nono/pi-local.json`
- the requested target profile, when it exists
- the target's entry under `~/.config/nono/profiles/`, including its resolved symlink target
- the installed parent profile named by `extends`
Run `nono --version` and consult `nono profile --help` when command behavior is uncertain. Read [policy-fields.md](references/policy-fields.md) before changing inheritance, filesystem, network, credentials, or Unix-socket policy.
Summarize the current parent, working-directory policy, extra filesystem grants, network mode, URL-opening policy, service-launch policy, and active-link state. Treat inherited grants as additive unless the installed nono documentation and validator prove otherwise.
Completion criterion: account for every effective capability relevant to the requested change, including inherited capabilities.
### 2. Interview for the intended capability
Treat details already stated by the user as answers. Collect only unresolved choices with `ask_user`; use a short follow-up when exact paths or domains depend on an earlier answer.
Always resolve these decisions before drafting:
1. **Profile strategy** — ask whether to edit `pi-local` or create a named derived profile. Ask for a profile name and description when deriving.
2. **Working set** — ask whether access covers only the launch working directory, a list of exact repositories/directories, or a shared parent containing multiple repositories.
3. **Access mode** — collect read-only, write-only, or read/write access for every additional path, then map those labels to the profile fields. Recommend exact repositories over a broad client or source-code parent. State the broader blast radius before accepting a shared parent.
4. **Internet tier** — offer:
- **Offline**: block Internet access, URL opening, and service launching.
- **Allowlisted**: enable networking only for an explicit hostname list; confirm URL-opening origins separately.
- **Open**: enable unrestricted networking; confirm URL-opening origins separately.
5. **Allowlisted hosts** — for allowlisted mode, identify the operations the project needs, then collect exact hostnames for code hosting, package registries, APIs, model providers, and artifact/CDN downloads. Distinguish required hosts from convenience hosts.
Ask about exact files, credential routes, and Unix sockets only when the request or inspected project indicates they are needed. Keep filesystem, Internet, credential, and Unix-socket decisions separate.
Completion criterion: map every requested capability to an exact path, hostname, credential route, or socket and an explicit access level.
### 3. Choose safe composition
Nono 0.74 accepts either one `extends` parent or an ordered array. Multiple parents merge left to right, deduplicate shared ancestors, append list-valued grants and environment filters, and preserve restrictive decisions such as blocked networking. Use a single parent for ordinary profiles. Use multiple parents only when every additive capability and merge result has been reviewed with `nono profile show` and behavioral tests.
Apply these inheritance rules:
- Extend `pi-local` when its filesystem grants, existing domain allowlist, URL-opening origins, and service-launch policy are acceptable as a minimum.
- Extend `nolabs-ai/pi` for offline mode. Set `network.block` to `true`, clear `open_urls.allow_origins`, disable `open_urls.allow_localhost`, and set `allow_launch_services` to `false`. Do not extend allowlisted `pi-local`: inherited proxy domains conflict with blocked networking.
- Extend `nolabs-ai/pi` rather than `pi-local` when an allowlisted child needs fewer domains than `pi-local`, or when creating an open-network profile. Reproduce only the required local filesystem/socket policy.
- Edit `pi-local` only after showing how the change affects every future project launched with it.
- For trusted generated profiles, materialize the reviewed fragments into one canonical profile and validate that file. Do not rely on multiple inheritance to widen a blocked core with a provider route.
An inherited broad capability cannot reliably be narrowed by an empty child array. Choose a restrictive parent instead.
### 4. Draft the policy
Create a candidate at `~/.config/nono/profile-drafts/<name>.json`. Keep the repository target at `profiles/nono/<name>.json`.
Apply least privilege:
- Use `workdir.access` for the runtime working directory.
- Use directory fields for directory trees and exact-file fields for one file.
- Prefer read-only grants for source or reference trees that need no mutation.
- Use read/write grants only for repositories, caches, build output, or state that must change.
- Use canonical resolved paths for symlinked resources where practical.
- Keep hostname allowlists, URL-opening origins, service launching, and Unix socket allowlists independent.
- Store hostnames, never URL paths, in `network.allow_domain`.
Preserve unrelated keys and user formatting when editing an existing profile.
### 5. Validate and review
Run:
```bash
nono profile validate --draft <name> --strict
nono profile show ~/.config/nono/profile-drafts/<name>.json
```
Show:
- the proposed profile or focused diff
- the resolved policy and selected inherited baseline
- every added or removed filesystem capability
- the selected Internet tier and all allowed domains
- URL-opening origins and service-launch permission
- any credential routes or Unix sockets
- whether the repository target is already active through a symlink
Request explicit approval with `ask_user` before copying the validated draft into `profiles/nono/<name>.json`.
Completion criterion: validation passes and the user approves the exact policy diff.
### 6. Install without bypassing review
After approval, copy the validated candidate into the repository target, then run `nono profile validate --strict profiles/nono/<name>.json`. Do not write directly into `~/.config/nono/profiles/` from an agent running inside nono.
When the active profile already symlinks to the repository target, report that the next nono launch will use the change. Otherwise, provide this outside-sandbox activation step with resolved paths:
```bash
ln -sfn /absolute/repo/profiles/nono/<name>.json ~/.config/nono/profiles/<name>.json
nono profile validate <name>
```
Use `nono profile promote <name>` only when the user wants nono to install the draft as a regular active profile instead of preserving the repository symlink convention. When replacing an existing regular profile, create the draft through nono's edit workflow or supply the required `<name>.base` SHA-256 guard described in [policy-fields.md](references/policy-fields.md); never bypass concurrent-change protection.
For denied paths in the current sandbox, diagnose the concrete operation with:
```bash
nono why --self --path /resolved/path --op read
```
Use `write` or `readwrite` for the corresponding operation. Explain that policy changes apply to a newly launched sandbox, not the current process.
Completion criterion: the repository profile is approved and valid, activation instructions preserve the chosen repository-link convention, and remaining restart steps are explicit.