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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ records of their own, anchored to a quote of the commented record's Markdown
body and linked to `mdbase.person` authors. Apps that comment embed the
published provision unchanged, as mdbase writer does.

The `mdbase.daily-note` pack defines one record per local calendar day,
identified by its `date` (an RFC 3339 full-date), never by its path. Apps find
daily notes through the contract's type implementations and treat a date held
by several records as ambiguous. The **Daily note** starter stores the date
only in the file name, `Daily/YYYY-MM-DD.md`, with `collection.path.fields`
(path-stored fields, mdbase 0.3.0-rc.6), and matches only date-named files in
that folder so other notes there keep their own types. The pack needs an engine
with path-stored fields: the pinned mdbase-ts and Rust CLI reject the starter
until `sources.json` moves to engines that implement them. See
[`mdbase.daily-note` 1.0.0](contracts/mdbase.daily-note/1.0.0.md).

The `tasknotes.task` pack is the canonical application-provisioned TaskNotes
contract bundle. TaskNotes clients embed the published provision byte-for-byte
and pin its catalog digest so independently deployed clients cannot drift onto
Expand Down
66 changes: 66 additions & 0 deletions contracts/mdbase.daily-note/1.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
kind: mdbase.contract
contract_type: record
id: mdbase.daily-note
version: 1.0.0
name: Daily note
description: One record per local calendar day, identified by its date.
record_schema:
dialect: json-schema-2020-12
ref: ../../schemas/mdbase.daily-note/1.0.0.schema.json
---

# Daily note

A record exposed through `mdbase.daily-note` represents one local calendar day.
`date` is an RFC 3339 full-date such as `2026-10-30`: a civil day with no time
and no time zone. It names the day the user lived, not an instant, so it does
not change when the user or the collection changes time zone.

## Identity

A daily note is identified by its `date` value, never by its path or file name.
An implementing type may store the date in the path, for example with
`collection.path.fields`, but consumers read the contract field and never parse
paths or file names themselves.

## Discovery

Implementing this contract is how a collection declares which of its records
are daily notes. An application discovers daily notes through this contract's
type implementations, not through a folder, a file-name format, or a reserved
type name, path, or frontmatter value.

## One record per day

A collection should hold at most one record per date across all types that
implement this contract. To find the note for a day, an application queries
every implementing type for that date:

- No record: the day has no daily note. This is not an error.
- Exactly one record: that record is the day's note.
- Several records: the date is ambiguous. Applications MUST report the
ambiguity and MUST NOT silently pick one of the records, merge them, or
write to one of them as the day's note.

A partial or failed query cannot establish that a day has no note or exactly
one note. Implementing types may declare `collection.unique` on their date
field so the engine reports duplicates within the type.

## Creating a daily note

An application creates a daily note through the implementing type's ordinary
create operation and path policy. File names, folders, templates and the body
belong to the type and the collection; the contract does not prescribe them.
An application that opens the note for a day, such as today in the user's
time zone, first looks for an existing record for that date and creates one
only when there is none.

## Other day data

Other applications may attach their own data to a day, such as time blocks or
completed pomodoros, through separate contracts implemented by the same type.
This contract defines only the day itself.

This artifact is passive. Implementing it grants no authority to read, create,
or modify any record.
66 changes: 66 additions & 0 deletions dist/artifacts/contracts/mdbase.daily-note/1.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
kind: mdbase.contract
contract_type: record
id: mdbase.daily-note
version: 1.0.0
name: Daily note
description: One record per local calendar day, identified by its date.
record_schema:
dialect: json-schema-2020-12
ref: ../../schemas/mdbase.daily-note/1.0.0.schema.json
---

# Daily note

A record exposed through `mdbase.daily-note` represents one local calendar day.
`date` is an RFC 3339 full-date such as `2026-10-30`: a civil day with no time
and no time zone. It names the day the user lived, not an instant, so it does
not change when the user or the collection changes time zone.

## Identity

A daily note is identified by its `date` value, never by its path or file name.
An implementing type may store the date in the path, for example with
`collection.path.fields`, but consumers read the contract field and never parse
paths or file names themselves.

## Discovery

Implementing this contract is how a collection declares which of its records
are daily notes. An application discovers daily notes through this contract's
type implementations, not through a folder, a file-name format, or a reserved
type name, path, or frontmatter value.

## One record per day

A collection should hold at most one record per date across all types that
implement this contract. To find the note for a day, an application queries
every implementing type for that date:

- No record: the day has no daily note. This is not an error.
- Exactly one record: that record is the day's note.
- Several records: the date is ambiguous. Applications MUST report the
ambiguity and MUST NOT silently pick one of the records, merge them, or
write to one of them as the day's note.

A partial or failed query cannot establish that a day has no note or exactly
one note. Implementing types may declare `collection.unique` on their date
field so the engine reports duplicates within the type.

## Creating a daily note

An application creates a daily note through the implementing type's ordinary
create operation and path policy. File names, folders, templates and the body
belong to the type and the collection; the contract does not prescribe them.
An application that opens the note for a day, such as today in the user's
time zone, first looks for an existing record for that date and creates one
only when there is none.

## Other day data

Other applications may attach their own data to a day, such as time blocks or
completed pomodoros, through separate contracts implemented by the same type.
This contract defines only the day itself.

This artifact is passive. Implementing it grants no authority to read, create,
or modify any record.
18 changes: 18 additions & 0 deletions dist/artifacts/schemas/mdbase.daily-note/1.0.0.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://mdbase.dev/contracts/schemas/mdbase.daily-note/1.0.0.schema.json",
"title": "Daily note",
"description": "A record that represents one local calendar day, identified by its date.",
"type": "object",
"required": [
"date"
],
"properties": {
"date": {
"type": "string",
"format": "date",
"description": "The calendar day this record represents, as an RFC 3339 full-date (YYYY-MM-DD). A civil date with no time or time zone."
}
},
"additionalProperties": false
}
78 changes: 78 additions & 0 deletions dist/artifacts/types/daily-note/1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
kind: mdbase.type
name: daily-note
version: 1
description: One note per calendar day, named by its date in the Daily folder.
match:
path_glob: 'Daily/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].md'
schema:
dialect: json-schema-2020-12
value:
$schema: https://json-schema.org/draft/2020-12/schema
title: Daily note
description: One local calendar day represented by an ordinary note. The date is stored in the file name, not in frontmatter.
type: object
required:
- date
properties:
date:
type: string
format: date
description: The day this note is for, as a full calendar date in YYYY-MM-DD form, with no time or time zone. It is stored in the file name (Daily/2026-10-30.md), so changing it renames the note; do not also write it in frontmatter.
additionalProperties: true
collection:
path:
pattern: 'Daily/{date}.md'
fields:
- date
unique:
- field: date
scope: type
display:
name_field: date
icon: calendar
implements:
- contract: mdbase.daily-note
version: 1.0.0
fields:
date: date
---

# Daily note

One note per day, at `Daily/YYYY-MM-DD.md`. The date lives only in the file
name: apps read it from the path, and creating a note for a date puts it at
that date's path. The rest of the note is yours: write in the body and add any
frontmatter fields you like.

```text
Daily/2026-10-30.md
```

Only files in `Daily/` whose name is a date belong to this type, so other notes
in the folder are left alone. A collection should have one note per date; two
notes with the same date are reported, and apps treat that day as ambiguous
rather than choosing one.

## Use an existing daily-notes folder

To adopt notes another tool already writes, such as Obsidian's daily notes,
change the folder in both `match.path_glob` and `collection.path.pattern`. For
notes in `Journal/`:

```yaml
match:
path_glob: 'Journal/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].md'
collection:
path:
pattern: 'Journal/{date}.md'
fields: [date]
```

Notes are recognised by their path, so existing files need no frontmatter
changes. File names must use the `YYYY-MM-DD` form.

This type belongs to your collection once installed. Apps find daily notes
through the `mdbase.daily-note` contract, not through this folder or file name,
so you can move them, or add other types that implement the contract, as long
as each date has one note.
48 changes: 48 additions & 0 deletions dist/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@
"artifact": "./artifacts/contracts/mdbase.contact/1.0.0.md",
"standards": []
},
{
"id": "mdbase.daily-note",
"version": "1.0.0",
"name": "Daily note",
"description": "One record per local calendar day, identified by its date.",
"contract_type": "record",
"digest": "sha256:797ad463925497c07a42d364e513116ad3495792927087370be776e73bbe65b7",
"artifact": "./artifacts/contracts/mdbase.daily-note/1.0.0.md",
"standards": []
},
{
"id": "mdbase.person",
"version": "1.0.0",
Expand Down Expand Up @@ -566,6 +576,44 @@
]
}
},
{
"id": "mdbase.daily-note",
"version": "1.0.0",
"name": "Daily notes",
"description": "The mdbase.daily-note contract and an editable Daily note type with one note per calendar day.",
"digest": "sha256:cb93c368c2bdbeb99dfb92a19d535da42221715a665d2047ed1fff3ef30d8c9b",
"provision": "./packs/mdbase.daily-note/1.0.0.json",
"provides": [
{
"id": "mdbase.daily-note",
"version": "1.0.0",
"digest": "sha256:8ef734d7eeee420fd9c5c1b25f26bfde8bb72ab9e96bc5c3f9923ba251d69ea6"
}
],
"resource_count": 3,
"display": {
"name": "Daily notes",
"summary": "Keep one note per day that any daily-note-aware app can find and open.",
"category": "calendar",
"audience": "general",
"icon": "calendar",
"badges": [
"Portable daily notes"
]
},
"installation": {
"visibility": "default",
"recommendation": "optional",
"primary_type": "daily-note",
"caution": "Requires an mdbase engine with path-stored fields (mdbase 0.3.0-rc.6). Older engines reject the Daily note type, which keeps each note's date in its file name.",
"types": [
{
"name": "daily-note",
"label": "Daily note"
}
]
}
},
{
"id": "mdbase.runtime.standard",
"version": "0.2.0",
Expand Down
53 changes: 53 additions & 0 deletions dist/packs/mdbase.daily-note/1.0.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"manifest": {
"kind": "mdbase.type-pack",
"id": "mdbase.daily-note",
"version": "1.0.0",
"name": "Daily notes",
"description": "The mdbase.daily-note contract and an editable Daily note type with one note per calendar day.",
"resources": [
{
"kind": "schema",
"mode": "managed",
"source": "schemas/mdbase.daily-note/1.0.0.schema.json",
"target": "schemas/mdbase.daily-note/1.0.0.schema.json",
"digest": "sha256:a71471a2a941fe39ca6052ecf9189ac8156d76127d8792be49c29ab35d385080"
},
{
"kind": "contract",
"mode": "managed",
"source": "contracts/mdbase.daily-note/1.0.0.md",
"target": "_contracts/mdbase.daily-note/1.0.0.md",
"digest": "sha256:797ad463925497c07a42d364e513116ad3495792927087370be776e73bbe65b7"
},
{
"kind": "type",
"mode": "seed",
"source": "types/daily-note/1.md",
"target": "_types/daily-note.md",
"digest": "sha256:e9800bb1c091b0e0c6df01f773afdb4346473d379b5738b22d0c31139d18635e"
}
]
},
"resources": [
{
"source": "schemas/mdbase.daily-note/1.0.0.schema.json",
"document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.daily-note/1.0.0.schema.json\",\n \"title\": \"Daily note\",\n \"description\": \"A record that represents one local calendar day, identified by its date.\",\n \"type\": \"object\",\n \"required\": [\n \"date\"\n ],\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"format\": \"date\",\n \"description\": \"The calendar day this record represents, as an RFC 3339 full-date (YYYY-MM-DD). A civil date with no time or time zone.\"\n }\n },\n \"additionalProperties\": false\n}\n"
},
{
"source": "contracts/mdbase.daily-note/1.0.0.md",
"document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.daily-note\nversion: 1.0.0\nname: Daily note\ndescription: One record per local calendar day, identified by its date.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.daily-note/1.0.0.schema.json\n---\n\n# Daily note\n\nA record exposed through `mdbase.daily-note` represents one local calendar day.\n`date` is an RFC 3339 full-date such as `2026-10-30`: a civil day with no time\nand no time zone. It names the day the user lived, not an instant, so it does\nnot change when the user or the collection changes time zone.\n\n## Identity\n\nA daily note is identified by its `date` value, never by its path or file name.\nAn implementing type may store the date in the path, for example with\n`collection.path.fields`, but consumers read the contract field and never parse\npaths or file names themselves.\n\n## Discovery\n\nImplementing this contract is how a collection declares which of its records\nare daily notes. An application discovers daily notes through this contract's\ntype implementations, not through a folder, a file-name format, or a reserved\ntype name, path, or frontmatter value.\n\n## One record per day\n\nA collection should hold at most one record per date across all types that\nimplement this contract. To find the note for a day, an application queries\nevery implementing type for that date:\n\n- No record: the day has no daily note. This is not an error.\n- Exactly one record: that record is the day's note.\n- Several records: the date is ambiguous. Applications MUST report the\n ambiguity and MUST NOT silently pick one of the records, merge them, or\n write to one of them as the day's note.\n\nA partial or failed query cannot establish that a day has no note or exactly\none note. Implementing types may declare `collection.unique` on their date\nfield so the engine reports duplicates within the type.\n\n## Creating a daily note\n\nAn application creates a daily note through the implementing type's ordinary\ncreate operation and path policy. File names, folders, templates and the body\nbelong to the type and the collection; the contract does not prescribe them.\nAn application that opens the note for a day, such as today in the user's\ntime zone, first looks for an existing record for that date and creates one\nonly when there is none.\n\n## Other day data\n\nOther applications may attach their own data to a day, such as time blocks or\ncompleted pomodoros, through separate contracts implemented by the same type.\nThis contract defines only the day itself.\n\nThis artifact is passive. Implementing it grants no authority to read, create,\nor modify any record.\n"
},
{
"source": "types/daily-note/1.md",
"document": "---\nkind: mdbase.type\nname: daily-note\nversion: 1\ndescription: One note per calendar day, named by its date in the Daily folder.\nmatch:\n path_glob: 'Daily/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].md'\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n title: Daily note\n description: One local calendar day represented by an ordinary note. The date is stored in the file name, not in frontmatter.\n type: object\n required:\n - date\n properties:\n date:\n type: string\n format: date\n description: The day this note is for, as a full calendar date in YYYY-MM-DD form, with no time or time zone. It is stored in the file name (Daily/2026-10-30.md), so changing it renames the note; do not also write it in frontmatter.\n additionalProperties: true\ncollection:\n path:\n pattern: 'Daily/{date}.md'\n fields:\n - date\n unique:\n - field: date\n scope: type\n display:\n name_field: date\n icon: calendar\nimplements:\n - contract: mdbase.daily-note\n version: 1.0.0\n fields:\n date: date\n---\n\n# Daily note\n\nOne note per day, at `Daily/YYYY-MM-DD.md`. The date lives only in the file\nname: apps read it from the path, and creating a note for a date puts it at\nthat date's path. The rest of the note is yours: write in the body and add any\nfrontmatter fields you like.\n\n```text\nDaily/2026-10-30.md\n```\n\nOnly files in `Daily/` whose name is a date belong to this type, so other notes\nin the folder are left alone. A collection should have one note per date; two\nnotes with the same date are reported, and apps treat that day as ambiguous\nrather than choosing one.\n\n## Use an existing daily-notes folder\n\nTo adopt notes another tool already writes, such as Obsidian's daily notes,\nchange the folder in both `match.path_glob` and `collection.path.pattern`. For\nnotes in `Journal/`:\n\n```yaml\nmatch:\n path_glob: 'Journal/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].md'\ncollection:\n path:\n pattern: 'Journal/{date}.md'\n fields: [date]\n```\n\nNotes are recognised by their path, so existing files need no frontmatter\nchanges. File names must use the `YYYY-MM-DD` form.\n\nThis type belongs to your collection once installed. Apps find daily notes\nthrough the `mdbase.daily-note` contract, not through this folder or file name,\nso you can move them, or add other types that implement the contract, as long\nas each date has one note.\n"
}
],
"provides": [
{
"id": "mdbase.daily-note",
"version": "1.0.0",
"digest": "sha256:8ef734d7eeee420fd9c5c1b25f26bfde8bb72ab9e96bc5c3f9923ba251d69ea6"
}
]
}
18 changes: 18 additions & 0 deletions dist/schemas/mdbase.daily-note/1.0.0.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://mdbase.dev/contracts/schemas/mdbase.daily-note/1.0.0.schema.json",
"title": "Daily note",
"description": "A record that represents one local calendar day, identified by its date.",
"type": "object",
"required": [
"date"
],
"properties": {
"date": {
"type": "string",
"format": "date",
"description": "The calendar day this record represents, as an RFC 3339 full-date (YYYY-MM-DD). A civil date with no time or time zone."
}
},
"additionalProperties": false
}
Loading
Loading