docs: add PER (projax External Reference) standard v0.1
External-citable references for letters, invoices, filing labels, email subjects, PDF filenames, bank-transfer Verwendungszweck. Format: <area>[.<project>...][.<YYMMDD>][.<collision-tag>] - Date suffix YYMMDD (compact, not ISO). - Collision-tag (.a, .b, ...) only when same <path>[.<date>] repeats. - No doc-type taxonomy in v0.1 — collision-tag covers the disambiguation case at lower memorisation cost. - Lookup case-insensitive; display in m's preferred camelCase. - Rename stability via projax.items.aliases[].
This commit is contained in:
101
docs/standards/per.md
Normal file
101
docs/standards/per.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# projax External Reference (PER) Standard
|
||||
|
||||
**Version**: v0.1
|
||||
**Status**: locked
|
||||
**Authors**: m + head
|
||||
**Date**: 2026-05-15
|
||||
|
||||
A **projax External Reference (PER)** is a short dotted string that m drops into letters, emails, invoices, bank transfers, PDF filenames, physical filing labels — anywhere a project (or a project-event) needs an unambiguous citation. The PER doubles as m's personal Aktenzeichen.
|
||||
|
||||
## Format
|
||||
|
||||
```
|
||||
<area>[.<project>[.<sub-project>...]][.<YYMMDD>][.<collision-tag>]
|
||||
```
|
||||
|
||||
- **Lowercase internally** (slug, used in DB, URLs, search index).
|
||||
- **Display in m's preferred camelCase** (`mFin.house1.260515`).
|
||||
- **Lookup is case-insensitive** — typing `mfin.house1` resolves the same row as `mFin.house1`.
|
||||
- **Slugs are vowel-elided where natural** (`prjx`, `mFin`, `mBrn`).
|
||||
- **Humanly readable UID** is the explicit design goal: each PER is unique within projax (after collision-tag, if needed) AND legible at a glance to a human reading a letter.
|
||||
|
||||
## Components
|
||||
|
||||
| Segment | Required | Example | Notes |
|
||||
|---|---|---|---|
|
||||
| **Area** | yes | `dev`, `mFin`, `home` | Root-level area slug. |
|
||||
| **Project + sub-projects** | optional, dotted | `house1`, `springClean.bathroom` | Nests to any depth. |
|
||||
| **Date stamp** | optional | `260515` | `YYMMDD`. Anchors the PER to an event/document date. |
|
||||
| **Collision tag** | only when needed | `a`, `b`, … | Alpha sequence appended when the same `<path>[.<date>]` would otherwise repeat. See below. |
|
||||
|
||||
## Collision handling
|
||||
|
||||
When more than one artifact would otherwise share the same PER (same project path on the same date — or same project path with no date), append a single-letter tag in registration order: `.a`, `.b`, `.c`, … `.z`, then `.aa`, `.ab` if anyone ever needs it.
|
||||
|
||||
- The first artifact gets the bare PER (no tag).
|
||||
- The second collision triggers `.a` for the new one. The first one **retroactively** gets `.a` only if there's a real risk of ambiguity in already-written documents (otherwise leave the first bare and start the second at `.a` — the registry resolves both).
|
||||
- Alpha (not numeric) is chosen so the tag never reads as an ordinal (.1 / .2 could be misread as "first / second meeting on that day" — alpha avoids that connotation).
|
||||
|
||||
Examples:
|
||||
|
||||
| PER | Meaning |
|
||||
|---|---|
|
||||
| `mFin.house1.260515` | the (only) thing about house1 on that day |
|
||||
| `mFin.house1.260515.a` | one of two+ things; this is the first letter / the buyer's notary draft |
|
||||
| `mFin.house1.260515.b` | the second one; the seller's response on the same day |
|
||||
| `Work.upc.deadlines.a` | one of two undated reference notes on this sub-project |
|
||||
|
||||
## Examples
|
||||
|
||||
| PER | Meaning |
|
||||
|---|---|
|
||||
| `mFin` | the finances area at large |
|
||||
| `mFin.house1` | the project |
|
||||
| `mFin.house1.260515` | the project on 2026-05-15 (a letter, an invoice, a meeting note from that day) |
|
||||
| `Work.upc.deadlines.260520` | a deadline reference on 2026-05-20 |
|
||||
| `Home.springClean.bathroom` | a sub-project — no date |
|
||||
| `dev.prjx.260515` | this very document, cited |
|
||||
|
||||
## Properties
|
||||
|
||||
- **Rename stability** — when a slug is renamed, the previous slug lands in `projax.items.aliases[]`. Letters citing `mFinanzen.house1.260515` continue to resolve after the rename to `mFin`.
|
||||
- **Reverse search** — drop a PER into projax search and it resolves the project (and any dated artifacts linked to that project on that date).
|
||||
- **No primary-key role** — PERs are NOT stored as primary keys. They're projections of `(items.path, optional item_links.event_date)`. Canonical identity remains the UUID.
|
||||
- **Stable over time** — UUIDs are immutable. Slugs change; the PER stays valid via `aliases[]` resolution.
|
||||
|
||||
## Where to use
|
||||
|
||||
- Letter Aktenzeichen
|
||||
- Invoice "Reference" field
|
||||
- Bank transfer Verwendungszweck
|
||||
- Email subject prefix — `[mFin.house1.260515] Kaufpreiszahlung`
|
||||
- Physical document filing labels
|
||||
- PDF filenames — `mfin.house1.260515.pdf`
|
||||
- Calendar event titles where the project is the topic
|
||||
|
||||
## Where NOT to use
|
||||
|
||||
- Sensitive / external-facing contexts where revealing the project tree structure is undesirable (PERs leak m's life areas).
|
||||
- Form fields with strict character limits below ~25–30 chars.
|
||||
- Anywhere ambiguity is a feature (intentionally vague references).
|
||||
|
||||
## Schema implications (Phase 2)
|
||||
|
||||
- `projax.item_links` gains an `event_date timestamptz` column (optional). Dated artifacts linked to an item — CalDAV todos, Gitea issues, document references, PER-cited letters — sit here with a date.
|
||||
- Existing `aliases text[]` on `projax.items` is the rename-stability backbone. Don't drop on archive.
|
||||
- PER resolution = parse the string → match `(area-walk-path, optional date)` → return matching `items_unified` row + linked `item_links` rows with `event_date = parsed-date`.
|
||||
|
||||
## Display & UI
|
||||
|
||||
- The backend stores lowercase. The frontend renders PERs in m's preferred camelCase by reading `items.title` (or a derived `display_slug` field if titles drift far from slugs).
|
||||
- Search input is normalized to lowercase before matching, so users can type either casing.
|
||||
|
||||
## Out of scope (v0.1)
|
||||
|
||||
- **Document-type suffixes** (`.kauf`, `.notar`, `.mtg`, `.rcpt`, etc.). Considered and dropped: the `<area>.<project>.<YYMMDD>[.<collision>]` form is enough granularity for m's use today, and adding a taxonomy of doc-types adds memorization overhead for marginal value. If multiple artifacts share `<path>.<date>`, disambiguation is handled by the collision tag (`.a`, `.b`, …), not by encoding a type into the PER string. Reserved for a future v0.2 if real usage surfaces the need.
|
||||
- **Time-of-day suffixes** — date granularity is enough. If m needs to distinguish "morning meeting" vs "evening call" on the same project on the same day, that's an internal metadata concern, not a PER concern.
|
||||
- **Cross-PER references / linking syntax** — Phase 2+.
|
||||
|
||||
## Versioning
|
||||
|
||||
PER is a forward-compatible additive format. A v0.2 may add suffixes or qualifiers; v0.1 PERs MUST continue to resolve under any future spec. No backwards-incompatible changes without bumping the major version.
|
||||
Reference in New Issue
Block a user