Bundle
Manage the bundle lifecycle: create, share, graduate, status. Bundles are the unit of focused work — anything with a deliverable or a future audience.
This skill is invoked by the bundle awareness injection, by the load skill's "what are you working on?" prompt, or directly by the human via /alive:bundle.
Detection — When to Invoke
The spectrum:
| One-off | Bundle | Walnut | |
|---|---|---|---|
| Sessions | This session only | Likely >1, or worth returning to | Own ongoing lifecycle |
| Deliverable | No | Yes — ship, send, or reference later | Multiple deliverables |
| Audience | Just you, right now | Someone specific, or future-you | Has its own people |
Trigger: "Does this have a deliverable or a future audience?" If yes -> bundle.
Bundle Types
Outcome Bundle
The default. A body of work with a deliverable — a document, a plan, a shipped feature. Has drafts, versions, a finish line.
Evergreen Bundle
Living reference material that grows over time. No "done" state — it accumulates. Research collections, style guides, knowledge bases. Status cycles between active and maintaining rather than progressing to done.
Bundle Location
Bundles live flat in the walnut root. A folder is a bundle if it contains context.manifest.yaml.
nova-station/ # walnut root
_kernel/
shielding-review/ # bundle
context.manifest.yaml
raw/
launch-checklist/ # another bundle
context.manifest.yaml
raw/
No bundles/ subdirectory. Every bundle sits directly in the walnut root alongside _kernel/.
Operations
Create
When no active bundle matches the current work:
- Ask for the goal — one sentence. "What are you building?"
- Determine bundle type — outcome (default) or evergreen
- Derive the bundle name from the goal (kebab-case, descriptive)
- Confirm:
╭─ 🐿️ new bundle
│
│ Name: shielding-review
│ Type: outcome
│ Walnut: nova-station
│ Goal: Evaluate radiation shielding vendors for habitat module
│ Path: shielding-review/
│
│ ▸ Good?
│ 1. Create
│ 2. Change name
│ 3. Make it evergreen instead
│ 4. Cancel
╰─
- Read
templates/bundle/context.manifest.yaml - Fill placeholders:
{{name}},{{goal}},{{species}},{{sensitivity}},{{date}},{{session_id}} - Create
{walnut}/{name}/context.manifest.yaml - Create
{walnut}/{name}/raw/(empty directory) - Note:
project.pywill pick up the new bundle on next save — no manual now.json update needed - Stash: "Created bundle: {name}" (type: note)
Do NOT create tasks.md or tasks.json — tasks are created on demand via tasks.py add.
Do NOT create observations.md — removed in v3.
The first draft file is {name}-draft-01.md when the human starts writing.
context.manifest.yaml
Every bundle has a context.manifest.yaml at its root. This is the bundle's identity and state tracker.
name: shielding-review
goal: "Evaluate radiation shielding vendors for habitat module"
species: outcome # outcome | evergreen
phase: draft # draft | prototype | published | done | active | maintaining
sensitivity: normal # normal | private | shared
version: "0.1"
created: 2026-03-28
session: abc123
parent_bundle: # name of parent bundle, if nested
tags: []
people: []
shared: []
context_routes: [] # list of captured source file entries
discovered: # mining extraction state
status: none
last_mined:
processed: []
unprocessed: []
Key fields:
species— outcome or evergreen. Drives lifecycle behavior.phase— outcome bundles: draft -> prototype -> published -> done. Evergreen bundles: active <-> maintaining.sensitivity— controls sharing and export behavior:normal— can be shared freelyprivate— excluded from walnut.world publishing, flagged on share attemptsshared— actively published or shared with specific people
parent_bundle— if this bundle is nested inside another, records the parent's namediscovered— populated byalive:mine-for-contextwith extraction trackingsources— paths to raw material or linked references from other bundles
Share
When the human shares a bundle with someone (email, Slack, in person):
- Check
sensitivity— ifprivate, warn before proceeding - Identify: who received it, how (method), which version file
- Update the bundle's
context.manifest.yamlshared:field:
shared:
- to: Sue Chen
method: email
date: 2026-03-15
version: shielding-review-draft-02.md
- Dispatch to the person's walnut at save (stash with destination tag
-> [[person-name]]) - If bundle status is
draftand it's been shared externally -> advance topublished - Update sensitivity to
sharedif it wasnormal
╭─ 🐿️ bundle shared
│ shielding-review draft-02 -> Sue Chen via email
│ Status: draft -> published
╰─
Publishing to walnut.world
When the human wants to publish a bundle to walnut.world:
- Check
sensitivity— block ifprivate - Confirm the human wants public sharing
- Package the bundle content for walnut.world
- Update
context.manifest.yamlwith publication record
╭─ 🐿️ bundle published to walnut.world
│ shielding-review v1 -> ben.walnut.world/shielding-review
│ Sensitivity: shared (public)
╰─
Graduate
Graduation is a status flip, not a folder move. The bundle stays where it is.
Outcome bundle graduation:
- Detect: scan
{walnut}/{name}/for files matching*-v1.mdor*-v1.html - Confirm with the human:
╭─ 🐿️ graduation ready
│ shielding-review has a v1. Mark as done?
│
│ ▸ Graduate?
│ 1. Yes — mark done
│ 2. Not yet
╰─
- If confirmed:
- Update
context.manifest.yamlstatus todone(orpublishedif shared) - The v1 output file stays inside the bundle folder
- The bundle folder stays where it is in the walnut root
- Update
_kernel/now.json-> clearbundleif this was the active bundle - Log entry: "Bundle {name} graduated — status: done"
- Update
Bundle -> walnut graduation (when a bundle outgrows its container):
- Confirm: "This bundle wants to be a walnut. Graduate it?"
- Determine ALIVE domain and walnut name
- Scaffold new walnut (invoke the create flow)
- Seed
_kernel/key.mdfrom bundle context.manifest.yaml (goal, tags, people carry over) - Move bundle contents into new walnut root as the first bundle
- Log entry in BOTH parent walnut ("Bundle {name} graduated to walnut") and new walnut ("Graduated from {parent}")
- Add wikilink
[[new-walnut]]to parent's_kernel/key.mdlinks:
Sub-Bundles
Bundles nest directly inside other bundle folders. No intermediate bundles/ directory.
ecosystem-launch/ # parent bundle
context.manifest.yaml # parent manifest (parent_bundle: blank)
raw/
website/ # sub-bundle
context.manifest.yaml # parent_bundle: ecosystem-launch
waitlist/ # sub-bundle
context.manifest.yaml # parent_bundle: ecosystem-launch
Deeper nesting works the same way:
research/
context.manifest.yaml
market-analysis/
context.manifest.yaml # parent_bundle: research
competitor-deep-dive/
context.manifest.yaml # parent_bundle: market-analysis
Sub-bundle rules:
parent_bundle:in the manifest records the relationship- Sub-bundles inherit
sensitivityfrom parent unless overridden - Sub-bundle status is independent of parent status
- Graduation is a status flip — sub-bundles stay nested where they are
Tasks
Bundle tasks are operated exclusively through tasks.py CLI. Never read or write tasks.json directly.
- Add a task:
tasks.py add --walnut {path} --bundle {name} --title "Write vendor comparison" - **Comp