Portfolio data model
Portfolio data model
This is the canonical schema for Life Itself's Markdown portfolio. Workflow explains how to maintain it; Beads conventions explains how to find executable work. The model adapts ~/src/rufuspollock/planning/docs/data-model.md to the decisions in the infrastructure issue tree.
Records and locations
This schema covers records maintained here, not every document used to start work. Initiatives are maintained here; a project may instead start and remain in an A10 or similar Google Doc without a duplicate repository record or a Tao issue. See start a project. Number allocation below applies to repository project records, not external documents; external-only projects are outside the generated index unless explicitly represented here.
An initiative is an enduring area of work or product. It may have objectives and key results but need not have a completion date or deliverables. A project is bounded work with an intended outcome. A small actionable task can live entirely in Beads when it does not need durable framing.
Initiative records live in initiatives/<slug>.md; project records in projects/YYDD-<slug>.md, for example projects/2605-project-management-infrastructure.md. The numeric filename prefix is the short project ID; the full filename stem remains the key used by portfolio links, parent references and Beads project: labels. A type field makes classification explicit. Slugs must be unique across both folders. Supporting workstream notes, roadmap documents and source reports are not automatically portfolio records merely because they are in projects/ and do not receive project IDs.
Project number allocation
The filename is authoritative; do not duplicate the short ID in frontmatter. YY is the two-digit year the record is created, and DD is a sequence starting at 01 each year. Before creating a project, inspect the current projects/ folder, numerically sort the matching year's project prefixes, and allocate the highest sequence plus one (or 01 if none exist). Use at least two digits for the sequence; after 2699, use 26100. Numeric sequence order matters once the sequence exceeds 99; plain lexicographic sorting is insufficient.
Keep assigned numbers stable when dates, titles or statuses change. Retain closed project records and never reuse their numbers. Recheck the latest project files before committing; if concurrent creation allocated the same number, give the uncommitted new project the next unused number and update its links. If a record was removed, check Git history before allocating a potentially reused number. No separate counter or allocator is required.
The 2026-09-25 migration assigned existing typed projects by recorded creation date, with the old filename breaking ties, and updated local links and current Beads labels/file references together. Existing Bead IDs remain unchanged. Later filename changes must likewise update references explicitly; never assume a rename automatically fixes them.
Uncommitted ideas may be captured in Beads without inventing an initiative. Do not create an ideas/ system as part of the initial consolidation.
Frontmatter
Use YAML frontmatter for metadata and ordinary Markdown for context. Required keys on a migrated record are below; a required key does not mean an unknown fact must be invented.
| Field | Form and meaning |
|---|---|
title | Human title |
type | initiative or project |
description | Short sentence describing its purpose |
created | YYYY-MM-DD: date this portfolio record was created; preserve a known original date, otherwise use migration date and explain it |
owner | Confirmed stable person ID matching people/<id>.md and its id, normally a lowercase first name such as rufus (see people conventions); or null when unknown/unconfirmed. Participation, authorship and Beads creator are not proof of ownership |
status | Lifecycle value from the vocabulary below; unknown for unverified source claims |
parent | Stable initiative slug or null; explain whether null means top-level or relationship not yet confirmed |
tracker | Verified tracker URL, or beads for this repository's database, or null until established |
status_notes | A dated string or list of dated strings stating current position, evidence and uncertainties |
Useful optional fields:
| Field | Meaning |
|---|---|
phase | inbox, shaping, shipping, sharing; phase is separate from lifecycle |
beads | List of relevant Bead IDs (normally a project epic or standalone task); do not mirror every child |
initiative_label | Actual initiative label value without initiative: when it differs from the record slug; preserve established labels during migration and document the mapping |
aliases | Prior names or source identifiers; not additional canonical records |
url, github | Known public home/repository; a repository URL does not automatically prove its issue tracker is authoritative |
start, end | Known real-world start/end date or year, distinct from record creation |
due, completed, tickler | Target date, actual completion date, or review-again date (YYYY-MM-DD) |
tags | Themes or other non-hierarchical groupings |
Store parent as a plain string, not an unquoted wiki-link: parent: example-initiative. Optional unknown fields can be omitted. Keep necessary unknown required fields as explicit nulls, with an explanation in the body or dated note. Keep historical source values in a source-evidence section until confirmed; do not place an old owner or Active claim in current metadata just to fill a field.
Working-material links and task trackers
A project's or initiative's working materials may live in a GitHub repository, a Google Drive folder, or a particular document (for example, an A10). Record the actual location rather than requiring a GitHub repository. Keep github specific to GitHub repositories and url for the public home; for now, add Drive folder/document links with a descriptive label in the record's body. This is a process convention, not a new frontmatter field.
The working-material location and the execution tracker can differ. Set tracker to the confirmed task route; when GitHub Issues is confirmed, use the repository's /issues URL. Multiple initiatives may share a repository or tracker. A repository link alone does not establish tracking authority.
Lifecycle and active work
Reuse the personal model's lifecycle vocabulary: next, in-progress, backlog, someday, paused, done, superseded, dropped, archived. Add unknown for imported or existing records whose present state is unconfirmed.
- Active now:
in-progress, with a dated, supported status note. For initiatives this includes confirmed ongoing maintenance/service, not only projects being built. - Selected next:
next; present separately from active work. - Other open work:
backlog,someday,paused; these do not imply current activity. - Closed:
done,superseded,dropped,archived. Keep records discoverable as history. - Unverified:
unknown; show separately, never silently count it as active.
done means the intended work completed; dropped means an explicit decision to abandon; superseded means replacement by another effort (link it in the body); archived preserves old work without asserting successful completion. An initiative is not done merely because one project finishes. A milestone is not the whole project. A recent edit or a source saying Active is not by itself confirmation of present activity.
Pause by changing status and appending a dated reason; add tickler if a review date is agreed. Close only with evidence of the relevant outcome/decision; use completed for successful completion. Retain the record, links and source history. Update execution state in Beads separately—do not automatically close descendants or whole initiatives.
Paused vs. archived vs. someday
These three are easy to confuse; use the fact pattern, not a guess, to pick between them:
paused— a known, deliberate pause with some expectation or trigger for resuming (aticklerdate, an event, a decision still to be made). The record still reads as "on the board."archived— dormant with no committed return date. Not asserting the work is dead or that it succeeded — just that nobody is currently carrying it forward and there is no agreed plan to. Prefer this overpausedwhen the honest answer to "will this come back, and when?" is "don't know."someday— genuinely speculative/aspirational, closer to an idea than a commitment. Use this for Tao's importedideastatus, since this vocabulary has no separateideavalue.
A record that needs ongoing light upkeep but has no active development (e.g. a residential hub, or infrastructure someone still has to maintain) is usually paused, not a new status — put the "why paused, what upkeep" nuance in status_notes rather than inventing a maintenance value. Adding a new status value is rarely the right fix for a one-off nuance; it changes what every consumer of status has to handle. Only add one when it would change what someone actually does differently, not just how a record reads.
Grouping initiatives
When several related, mostly-untracked sub-efforts don't each need their own file, list them as dated notes inside one grouping initiative's body rather than creating a file per sub-effort — split the notes into an "Active / planned" section and an "Archived / inactive" section so status stays legible at a glance (see initiatives/media-house.md or initiatives/gardens-of-change.md for worked examples). Promote a note to its own initiative file once it clearly has enough independent, ongoing content to warrant one — a real owner, a dedicated repo, recurring output, or its own linked Beads work are the signals to watch for (Courses, Podcast & YouTube, Magazine, Publications and Social Media all started as Media House notes and were promoted this way). When you promote one, keep a link back from the parent and say in the new file's status_notes what it was folded out of.
Body content
Use enough prose to orient another person or AI. Initiatives describe enduring purpose, relationships and optional objectives/key results. Projects state intended outcome and next milestone when known; explicitly say when the milestone remains undecided. Add SCQ, scope, issue tree and decisions when useful, rather than empty template headings.
Include source links and the evidence needed to assess disputed claims. Retain answered issue-tree questions with the answer on the same line as **✅ Answer.**. Record current hypotheses as hypotheses. Markdown may summarize progress; tasks, assignments, dependencies and execution checklists live in the canonical tracker.
Examples
These are illustrative, not records to import. Unknown owners and tracker routes are deliberate.
---
title: Example research initiative
type: initiative
description: An enduring area for shared research.
created: 2026-09-23
owner: null
status: unknown
parent: null
tracker: null
status_notes: "2026-09-23 — Historical source located; current activity, ownership and parent need confirmation."
---
---
title: Example research report
type: project
description: Produce a report answering the agreed research question.
created: 2026-09-23
owner: null
status: backlog
parent: example-research-initiative
tracker: beads
phase: shaping
status_notes: "2026-09-23 — Illustrative agreed backlog project; owner and first milestone not yet decided."
---
The example project's body would describe the report outcome and identify the undecided milestone, with source links. Its parent must exist when used as a real record. Never copy fictional Bead IDs into a live record.
Migration and validation
Read the existing document and matched source records before editing. Preserve prose and links. Translate Status: shaping to phase: shaping, not automatically to status: in-progress; lifecycle needs separate evidence. Replace the old status line with a dated frontmatter note that retains its useful context. If evidence is insufficient, use status: unknown.
Current explicit confirmations and newer project evidence take precedence over outdated source assertions. Preserve superseded claims as history, not as unresolved objections to a confirmed current state.
Tao's active, maintenance, paused and idea values are historical assertions, not a mechanical mapping to current lifecycle. Match source rows and aliases first, then confirm facts. Capture original values and sources in the reconciliation evidence. Import root/ancestor records needed by the sample or explicitly leave an unresolved relationship null; do not create dangling parent links to unmigrated records.
For each batch, parse YAML, check required keys and allowed vocabulary, unique slugs, resolvable acyclic parent links, local Markdown links and real Bead references. Preserve older unconverted files; report them as outside the structured sample rather than declaring the entire portfolio valid or silently omitting them from migration coverage. Supporting notes without type stay readable but are not counted as typed records.