Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,28 @@ Body: break the work into `- [ ]` checkboxes concrete enough to check off; prose
`active`/`superseded`/`obsolete` on a plan item, or `todo`/`doing`/`done`/`dropped` on a
decision. Retiring or replacing a decision is a supersession on the decision, not a plan edit.

## Linking

When a body (an entry, a question, or a plan item) refers to another wherefore item,
write a standard relative Markdown link to that item's file, never a bare slug and never
a `[[wikilink]]` (wikilinks render as literal text on GitHub and most editors). Start the
link text with the target's ID so the raw file stays greppable, then a short label:

```markdown
See [P-004: verified brokers](P-004-m9-populate-verified-brokers.md) for the broker work.
Blocked by [Q-007: token store](../questions/Q-007-token-store.md).
Supersedes [2026-07-03-plan-directory](../log/2026-07-03-plan-directory.md).
```

- The path is relative to the file you are writing: same directory is `NAME.md`; a sibling
collection is `../log/NAME.md`, `../questions/NAME.md`, or `../plan/NAME.md`.
- Link text is the target ID (`P-NNN`, `Q-NNN`, or a `YYYY-MM-DD-slug`) then `: short label`.
- This is for body prose only. Frontmatter refs (`decision_ref`, `question_ref`,
`supersedes`, `superseded_by`, `asked_slug`, `resolution_slug`) stay bare IDs/slugs.
- Standard Markdown links render as real links everywhere: GitHub, Obsidian, editors, and
the dashboard. Obsidian users: turn off Files & Links -> "Use [[Wikilinks]]" so Obsidian
writes this same portable format (it resolves Markdown links either way).

## Conventions

- All frontmatter keys use underscore style (superseded_by, superseded_date,
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ The `wherefore/` directory itself is **not** in this repo -- it lives in each co
- Entry filenames: `YYYY-MM-DD-short-slug.md`; the entry frontmatter (`date`, `title`, `areas`, `topics`, `stories`, `status`, `supersedes`, `superseded_by`, `superseded_date`) is what readers shortlist on.
- Question files: `questions/Q-NNN-short-slug.md` (the `Q-NNN` prefix is the zero-padded ID; the slug is a short, lowercase, hyphenated summary of the question, same style as a log slug and only for human scanning). One per question, with `id`, `question`, `status`, `areas`, `asked_date`, `asked_slug`, `resolution`, `resolution_slug` frontmatter. The `id:` field is the authoritative ID (the dashboard keys off it, not the filename). IDs are sequential and never reused; the next ID is (highest existing `id:`) + 1.
- Plan items: `plan/P-NNN-short-slug.md` (the `P-NNN` prefix is the zero-padded ID; the `id:` field is authoritative, and the loader globs `plan/P-*.md` so `plan/README.md` is never collected). Frontmatter: `id`, `title`, `status` (todo|doing|done|dropped), `created`, `updated` (bumped on any write, including a checkbox toggle), plus optional `area` (single, not the plural `areas` decisions use), `topics`, `milestone`, `decision_ref`, `question_ref`, `answers` (a single `Q-NNN` a spike is the work of answering, the opposite of `question_ref` and not a blocker), `dropped_reason`. Plan status is a separate state machine from decision status: `capture` never creates or mutates plan items, and plan transitions never touch a decision's status (that stays with `supersede`). `blocked` is derived from an open `question_ref` (at most one per item), never written. IDs are sequential and never reused; the next ID is (highest existing `id:`) + 1.
- Cross-links: body prose links another item with a relative Markdown link to its file (`[P-004: label](P-004-slug.md)`, `[Q-007: label](../questions/Q-007-slug.md)`), ID-first text, never a bare slug or a `[[wikilink]]`. Frontmatter refs stay bare IDs/slugs. See the AGENTS.md "Linking" section; the dashboard rewrites these `.md` links to routes at build time (`src/lib/md-links.mjs`).
10 changes: 10 additions & 0 deletions packages/wherefore-dashboard/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { defineConfig } from 'astro/config';
import { createRequire } from 'node:module';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { buildMdLinkMap } from './src/lib/md-links.mjs';
import rehypeMdLinks from './src/lib/rehype-md-links.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const PACKAGE_ROOT = __dirname;
Expand All @@ -14,9 +16,17 @@ const astroDir = dirname(_require.resolve('astro/package.json'));

const SRC = process.env.WHEREFORE_SRC;

// Filename -> route map for rewriting relative Markdown cross-links in bodies.
// Built once here (WHEREFORE_SRC is set by the CLI before build() runs); empty
// during type-gen when SRC is undefined, same guard the fs.allow list uses.
const mdLinkMap = buildMdLinkMap(SRC);

export default defineConfig({
output: 'static',
site: process.env.WHEREFORE_SITE,
markdown: {
rehypePlugins: [[rehypeMdLinks, { map: mdLinkMap }]],
},
vite: {
server: {
fs: {
Expand Down
Loading
Loading