diff --git a/public/contracts/artifacts/contracts/mdbase.person/1.0.0.md b/public/contracts/artifacts/contracts/mdbase.person/1.0.0.md new file mode 100644 index 0000000..a029a53 --- /dev/null +++ b/public/contracts/artifacts/contracts/mdbase.person/1.0.0.md @@ -0,0 +1,86 @@ +--- +kind: mdbase.contract +contract_type: record +id: mdbase.person +version: 1.0.0 +name: Person +description: A portable person reference with editable account identity associations. +record_schema: + dialect: json-schema-2020-12 + ref: ../../schemas/mdbase.person/1.0.0.schema.json +--- + +# Person + +A person is collection data, independent of an account or collection membership. +Applications reference the stable `id`, not a name, file path, email address, +account subject, or membership ID. Collections choose their own local type and +field names through explicit `implements` mappings. + +`name` is a collection-owned display label. `identities` optionally associates +this person with one or more accounts through issuer/subject pairs. A person +without a Connect account is valid. The same record can travel between hosted, +relay, local, and exported collections without rewriting its identity references. + +## Identity matching + +An identity service supplies the authenticated caller's issuer and subject. +Subjects are opaque, account-wide identifiers, stable across email changes, +collection memberships, and removal/rejoining. Different identity issuers may +use the same subject; both fields must match exactly. Consumers must not trim, +case-fold, resolve redirects, or otherwise normalize either field when matching. +Copy the issuer value supplied by the service, including its trailing-slash +convention. Never derive the issuer from the current collection authority URL. +HTTP issuers support explicitly configured development and self-hosted instances; +production deployments should use HTTPS. + +An application resolves an identity across all implementing person records: + +- No matching person: unlinked, not anonymous authentication and not an error. +- Exactly one matching record with an unambiguous person ID: linked. +- Multiple matching records, or multiple records with that person's ID: + ambiguous. Do not pick the first match, merge records, or overwrite a link. + +A partial or failed query cannot establish that a match is unique. Cross-record +uniqueness is a collection/application invariant, not something this JSON Schema +can prove. Consumers must handle ambiguity even if a starter type has a local +uniqueness constraint: several local types can implement this contract. + +## Editable data, not security authority + +Identity associations have exactly the same trust as other editable collection +data. Editing one may change an application's "Assigned to me" view. It must +never change authentication, membership, permissions, authenticated audit +attribution, or proof of identity to another service. Schema conformance proves +shape, not that an identity association is truthful. + +"Link this person to me" is an ordinary record update using the authenticated +caller's identity. Never infer a link from a matching email or display name. +Membership and current account display names come from the identity service, +not frontmatter. A person association must never invite someone or grant access. + +## Lifecycle and portability + +Renaming or moving a record does not change its ID. Removing a member does not +delete their person record or task assignments. Deleting a record leaves +unresolved references; consumers should preserve these rather than silently +unassigning work. Reusing an ID for a different person changes every reference +and should not be treated as a routine rename. + +Copying records preserves account associations, but never copies collection +access. Multiple issuer/subject entries let one person represent accounts at +different identity services. Account deletion or an issuer migration may leave +an unresolved identity association; do not automatically rebind it to a newly +created account. Stored names and identity references remain collection data +subject to that collection's retention and editing policies. + +Account-wide subjects deliberately allow correlation across collections. This +is a portability trade-off, not an anonymity guarantee. Never store passwords, +access tokens, refresh tokens, or other credentials in these fields. + +## Contact information + +This contract does not define another address book. A local type can also +implement `mdbase.contact` for compact contact semantics, or +`mdbase.jscontact.card` when it intentionally stores that interchange shape. +The starter Person type implements both Person and Contact. diff --git a/public/contracts/artifacts/contracts/mdbase.person/2.0.0.md b/public/contracts/artifacts/contracts/mdbase.person/2.0.0.md new file mode 100644 index 0000000..166b75a --- /dev/null +++ b/public/contracts/artifacts/contracts/mdbase.person/2.0.0.md @@ -0,0 +1,93 @@ +--- +kind: mdbase.contract +contract_type: record +id: mdbase.person +version: 2.0.0 +name: Person +description: A person record, referenced by links, with editable account identity associations. +record_schema: + dialect: json-schema-2020-12 + ref: ../../schemas/mdbase.person/2.0.0.schema.json +--- + +# Person + +A person is collection data, independent of an account or collection membership. +Other records refer to a person with an ordinary mdbase link to the person's +record, such as `"[[Alex Rivera]]"`, declared in the referring type's +`collection.links` and resolved with the collection's own link rules. Never +refer to a person by name text, email address, account subject, or membership +ID. Collections choose their own local type and field names through explicit +`implements` mappings. + +Version 2.0.0 removes the separate `id` field of 1.0.0. Link resolution already +identifies the record, and rename reference updates keep links current, so a +second identifier only created a way for the two to disagree. + +`name` is a collection-owned display label. `identities` optionally associates +this person with one or more accounts through issuer/subject pairs. A person +without a Connect account is valid. The same record can travel between hosted, +relay, local, and exported collections without rewriting its identity references. + +## Identity matching + +An identity service supplies the authenticated caller's issuer and subject. +Subjects are opaque, account-wide identifiers, stable across email changes, +collection memberships, and removal/rejoining. Different identity issuers may +use the same subject; both fields must match exactly. Consumers must not trim, +case-fold, resolve redirects, or otherwise normalize either field when matching. +Copy the issuer value supplied by the service, including its trailing-slash +convention. Never derive the issuer from the current collection authority URL. +HTTP issuers support explicitly configured development and self-hosted instances; +production deployments should use HTTPS. + +An application resolves an identity across all implementing person records: + +- No matching person: unlinked, not anonymous authentication and not an error. +- Exactly one matching record: linked. +- Multiple matching records: ambiguous. Do not pick the first match, merge + records, or overwrite a link. + +A partial or failed query cannot establish that a match is unique. Consumers +must handle ambiguity: several records, possibly of several local types, can +claim the same identity. + +## Editable data, not security authority + +Identity associations have exactly the same trust as other editable collection +data. Editing one may change an application's "Assigned to me" view. It must +never change authentication, membership, permissions, authenticated audit +attribution, or proof of identity to another service. Schema conformance proves +shape, not that an identity association is truthful. + +"Link this person to me" is an ordinary record update using the authenticated +caller's identity. Never infer a link from a matching email or display name. +Membership and current account display names come from the identity service, +not frontmatter. A person association must never invite someone or grant access. + +## Lifecycle and portability + +Renaming or moving a person record through mdbase or an editor that updates +references keeps links to it current. Removing a member does not delete their +person record or task assignments. Deleting a record leaves unresolved links; +consumers should preserve these rather than silently unassigning work. Giving a +different person's record the old record's name or path redirects existing +links and should not be treated as a routine rename. + +Copying records preserves account associations, but never copies collection +access. Multiple issuer/subject entries let one person represent accounts at +different identity services. Account deletion or an issuer migration may leave +an unresolved identity association; do not automatically rebind it to a newly +created account. Stored names and identity references remain collection data +subject to that collection's retention and editing policies. + +Account-wide subjects deliberately allow correlation across collections. This +is a portability trade-off, not an anonymity guarantee. Never store passwords, +access tokens, refresh tokens, or other credentials in these fields. + +## Contact information + +This contract does not define another address book. A local type can also +implement `mdbase.contact` for compact contact semantics, or +`mdbase.jscontact.card` when it intentionally stores that interchange shape. +The starter Person type implements both Person and Contact. diff --git a/public/contracts/artifacts/contracts/tasknotes.task/0.3.0-rc.4.md b/public/contracts/artifacts/contracts/tasknotes.task/0.3.0-rc.4.md new file mode 100644 index 0000000..60f0ae0 --- /dev/null +++ b/public/contracts/artifacts/contracts/tasknotes.task/0.3.0-rc.4.md @@ -0,0 +1,487 @@ +--- +kind: mdbase.contract +contract_type: record +id: tasknotes.task +version: 0.3.0-rc.4 +name: TaskNotes task +description: Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.4. +record_schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + $id: https://tasknotes.dev/schemas/tasknotes-task.schema.json + title: TaskNotes portable task view + description: The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract. + type: object + required: + - status + - dateCreated + additionalProperties: false + properties: + id: + type: string + minLength: 1 + title: + type: string + minLength: 1 + status: + type: string + minLength: 1 + priority: + type: string + minLength: 1 + due: + anyOf: + - type: string + format: date + - type: string + format: date-time + scheduled: + anyOf: + - type: string + format: date + - type: string + format: date-time + contexts: + type: array + items: + type: string + projects: + type: array + items: + type: string + assignees: + type: array + uniqueItems: true + items: + type: string + minLength: 1 + pattern: \S + description: Stable mdbase.person IDs. These references never grant collection access. + attachments: + type: array + uniqueItems: true + items: + type: string + minLength: 1 + timeEstimate: + type: integer + minimum: 0 + completedDate: + type: string + format: date + dateCreated: + type: string + format: date-time + dateModified: + type: string + format: date-time + recurrence: + type: string + recurrenceAnchor: + enum: + - scheduled + - completion + recurrenceParent: + type: string + occurrenceDate: + type: string + format: date + occurrenceMaterialization: + enum: + - manual + - on_completion + - rolling + occurrenceNextTrigger: + enum: + - completion + - completion_or_skip + occurrenceTemplate: + type: string + occurrencePastHorizon: + type: string + occurrenceFutureHorizon: + type: string + tags: + type: array + items: + type: string + timeEntries: + type: array + items: + type: object + reminders: + type: array + items: + type: object + blockedBy: + type: array + items: + type: object + completeInstances: + type: array + items: + type: string + format: date + skippedInstances: + type: array + items: + type: string + format: date + icsEventId: + type: array + items: + type: string + googleCalendarEventId: + type: string + googleCalendarExceptionEventId: + type: string + googleCalendarExceptionOriginalScheduled: + type: string + format: date + googleCalendarMovedOriginalDates: + type: array + items: + type: string + format: date + sortOrder: + type: string +binding_schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + $id: https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json + title: TaskNotes task data-contract binding + description: Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3. + type: object + required: + - profiles + - capabilities + - title + - status + - priority + - recurrence + - occurrences + - links + - archive + - time_tracking + - templating + properties: + profiles: + type: array + minItems: 1 + uniqueItems: true + items: + enum: + - core-lite + - recurrence + - templating + - materialized-occurrences + - extended + capabilities: + type: array + uniqueItems: true + items: + enum: + - dependencies + - reminders + - attachments + - links + - time-tracking + - materialized-occurrences + - rename + - archive + - batch + - concurrency + - dry-run + - migration + - templating + title: + $ref: "#/$defs/titlePolicy" + status: + $ref: "#/$defs/statusPolicy" + priority: + $ref: "#/$defs/priorityPolicy" + recurrence: + $ref: "#/$defs/recurrencePolicy" + occurrences: + $ref: "#/$defs/occurrencePolicy" + links: + $ref: "#/$defs/linkPolicy" + archive: + $ref: "#/$defs/archivePolicy" + time_tracking: + $ref: "#/$defs/timeTrackingPolicy" + templating: + $ref: "#/$defs/templatingPolicy" + nlp: + $ref: "#/$defs/nlpPolicy" + additionalProperties: false + $defs: + nonEmptyString: + type: string + minLength: 1 + stringSet: + type: array + uniqueItems: true + items: + $ref: "#/$defs/nonEmptyString" + titlePolicy: + type: object + required: + - storage + properties: + storage: + enum: + - filename + - frontmatter + filename_format: + enum: + - title + - zettel + - timestamp + - uuid + - custom + custom_filename_template: + $ref: "#/$defs/nonEmptyString" + allOf: + - if: + properties: + filename_format: + const: custom + required: + - filename_format + then: + properties: + custom_filename_template: + $ref: "#/$defs/nonEmptyString" + required: + - custom_filename_template + additionalProperties: true + statusDefinition: + type: object + required: + - value + - label + - color + - is_completed + - is_skipped + - exclude_from_cycle + - order + - auto_archive + - auto_archive_delay_minutes + properties: + value: + $ref: "#/$defs/nonEmptyString" + label: + type: string + color: + type: string + icon: + $ref: "#/$defs/nonEmptyString" + is_completed: + type: boolean + is_skipped: + type: boolean + exclude_from_cycle: + type: boolean + next_status: + $ref: "#/$defs/nonEmptyString" + order: + type: number + auto_archive: + type: boolean + auto_archive_delay_minutes: + type: number + minimum: 0 + additionalProperties: true + statusPolicy: + type: object + required: + - values + - default + - completed_values + - definitions + properties: + values: + $ref: "#/$defs/stringSet" + default: + $ref: "#/$defs/nonEmptyString" + completed_values: + $ref: "#/$defs/stringSet" + skipped_values: + $ref: "#/$defs/stringSet" + default_skipped: + $ref: "#/$defs/nonEmptyString" + definitions: + type: array + items: + $ref: "#/$defs/statusDefinition" + additionalProperties: false + priorityDefinition: + type: object + required: + - value + - label + - color + - weight + properties: + value: + $ref: "#/$defs/nonEmptyString" + label: + type: string + color: + type: string + icon: + $ref: "#/$defs/nonEmptyString" + weight: + type: number + additionalProperties: true + priorityPolicy: + type: object + required: + - values + - default + - definitions + properties: + values: + $ref: "#/$defs/stringSet" + default: + $ref: "#/$defs/nonEmptyString" + definitions: + type: array + items: + $ref: "#/$defs/priorityDefinition" + additionalProperties: false + recurrencePolicy: + type: object + required: + - syntax + - maintain_due_date_offset + - reset_body_checkboxes + properties: + syntax: + const: tasknotes + maintain_due_date_offset: + type: boolean + reset_body_checkboxes: + type: boolean + additionalProperties: false + occurrencePolicy: + type: object + required: + - identity_roles + - default_materialization + - default_next_trigger + properties: + identity_roles: + const: + - recurrenceParent + - occurrenceDate + default_materialization: + enum: + - manual + - on_completion + - rolling + default_next_trigger: + enum: + - completion + - completion_or_skip + past_horizon: + $ref: "#/$defs/nonEmptyString" + future_horizon: + $ref: "#/$defs/nonEmptyString" + additionalProperties: false + linkPolicy: + type: object + required: + - accepted_formats + - write_format + properties: + accepted_formats: + type: array + minItems: 1 + uniqueItems: true + items: + enum: + - wikilink + - markdown + write_format: + enum: + - wikilink + - markdown + additionalProperties: false + archivePolicy: + type: object + required: + - archived_tag + - move_on_archive + properties: + archived_tag: + $ref: "#/$defs/nonEmptyString" + move_on_archive: + type: boolean + folder: + $ref: "#/$defs/nonEmptyString" + additionalProperties: false + timeTrackingPolicy: + type: object + required: + - auto_stop_on_complete + properties: + auto_stop_on_complete: + type: boolean + additionalProperties: false + templatingPolicy: + type: object + required: + - enabled + - occurrence_enabled + properties: + enabled: + type: boolean + template_path: + $ref: "#/$defs/nonEmptyString" + occurrence_enabled: + type: boolean + occurrence_template_path: + $ref: "#/$defs/nonEmptyString" + failure_mode: + enum: + - error + - warning_fallback + unknown_variable_policy: + enum: + - preserve + - empty + additionalProperties: false + nlpTrigger: + type: object + required: + - property_id + - trigger + - enabled + properties: + property_id: + $ref: "#/$defs/nonEmptyString" + trigger: + $ref: "#/$defs/nonEmptyString" + enabled: + type: boolean + additionalProperties: false + nlpPolicy: + type: object + required: + - triggers + properties: + triggers: + type: array + items: + $ref: "#/$defs/nlpTrigger" + additionalProperties: false +--- + +# TaskNotes task contract + +Types implement this contract through `implements`; applications consume +the normalized contract view rather than assuming frontmatter names. diff --git a/public/contracts/artifacts/contracts/tasknotes.task/0.3.0-rc.5.md b/public/contracts/artifacts/contracts/tasknotes.task/0.3.0-rc.5.md new file mode 100644 index 0000000..1f0a626 --- /dev/null +++ b/public/contracts/artifacts/contracts/tasknotes.task/0.3.0-rc.5.md @@ -0,0 +1,487 @@ +--- +kind: mdbase.contract +contract_type: record +id: tasknotes.task +version: 0.3.0-rc.5 +name: TaskNotes task +description: Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.5. +record_schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + $id: https://tasknotes.dev/schemas/tasknotes-task.schema.json + title: TaskNotes portable task view + description: The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.5 record contract. + type: object + required: + - status + - dateCreated + additionalProperties: false + properties: + id: + type: string + minLength: 1 + title: + type: string + minLength: 1 + status: + type: string + minLength: 1 + priority: + type: string + minLength: 1 + due: + anyOf: + - type: string + format: date + - type: string + format: date-time + scheduled: + anyOf: + - type: string + format: date + - type: string + format: date-time + contexts: + type: array + items: + type: string + projects: + type: array + items: + type: string + assignees: + type: array + uniqueItems: true + items: + type: string + minLength: 1 + pattern: \S + description: Links to records implementing mdbase.person, such as [[Alex Rivera]]. Implementing types declare this field in collection.links. These references never grant collection access. + attachments: + type: array + uniqueItems: true + items: + type: string + minLength: 1 + timeEstimate: + type: integer + minimum: 0 + completedDate: + type: string + format: date + dateCreated: + type: string + format: date-time + dateModified: + type: string + format: date-time + recurrence: + type: string + recurrenceAnchor: + enum: + - scheduled + - completion + recurrenceParent: + type: string + occurrenceDate: + type: string + format: date + occurrenceMaterialization: + enum: + - manual + - on_completion + - rolling + occurrenceNextTrigger: + enum: + - completion + - completion_or_skip + occurrenceTemplate: + type: string + occurrencePastHorizon: + type: string + occurrenceFutureHorizon: + type: string + tags: + type: array + items: + type: string + timeEntries: + type: array + items: + type: object + reminders: + type: array + items: + type: object + blockedBy: + type: array + items: + type: object + completeInstances: + type: array + items: + type: string + format: date + skippedInstances: + type: array + items: + type: string + format: date + icsEventId: + type: array + items: + type: string + googleCalendarEventId: + type: string + googleCalendarExceptionEventId: + type: string + googleCalendarExceptionOriginalScheduled: + type: string + format: date + googleCalendarMovedOriginalDates: + type: array + items: + type: string + format: date + sortOrder: + type: string +binding_schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + $id: https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json + title: TaskNotes task data-contract binding + description: Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3. + type: object + required: + - profiles + - capabilities + - title + - status + - priority + - recurrence + - occurrences + - links + - archive + - time_tracking + - templating + properties: + profiles: + type: array + minItems: 1 + uniqueItems: true + items: + enum: + - core-lite + - recurrence + - templating + - materialized-occurrences + - extended + capabilities: + type: array + uniqueItems: true + items: + enum: + - dependencies + - reminders + - attachments + - links + - time-tracking + - materialized-occurrences + - rename + - archive + - batch + - concurrency + - dry-run + - migration + - templating + title: + $ref: "#/$defs/titlePolicy" + status: + $ref: "#/$defs/statusPolicy" + priority: + $ref: "#/$defs/priorityPolicy" + recurrence: + $ref: "#/$defs/recurrencePolicy" + occurrences: + $ref: "#/$defs/occurrencePolicy" + links: + $ref: "#/$defs/linkPolicy" + archive: + $ref: "#/$defs/archivePolicy" + time_tracking: + $ref: "#/$defs/timeTrackingPolicy" + templating: + $ref: "#/$defs/templatingPolicy" + nlp: + $ref: "#/$defs/nlpPolicy" + additionalProperties: false + $defs: + nonEmptyString: + type: string + minLength: 1 + stringSet: + type: array + uniqueItems: true + items: + $ref: "#/$defs/nonEmptyString" + titlePolicy: + type: object + required: + - storage + properties: + storage: + enum: + - filename + - frontmatter + filename_format: + enum: + - title + - zettel + - timestamp + - uuid + - custom + custom_filename_template: + $ref: "#/$defs/nonEmptyString" + allOf: + - if: + properties: + filename_format: + const: custom + required: + - filename_format + then: + properties: + custom_filename_template: + $ref: "#/$defs/nonEmptyString" + required: + - custom_filename_template + additionalProperties: true + statusDefinition: + type: object + required: + - value + - label + - color + - is_completed + - is_skipped + - exclude_from_cycle + - order + - auto_archive + - auto_archive_delay_minutes + properties: + value: + $ref: "#/$defs/nonEmptyString" + label: + type: string + color: + type: string + icon: + $ref: "#/$defs/nonEmptyString" + is_completed: + type: boolean + is_skipped: + type: boolean + exclude_from_cycle: + type: boolean + next_status: + $ref: "#/$defs/nonEmptyString" + order: + type: number + auto_archive: + type: boolean + auto_archive_delay_minutes: + type: number + minimum: 0 + additionalProperties: true + statusPolicy: + type: object + required: + - values + - default + - completed_values + - definitions + properties: + values: + $ref: "#/$defs/stringSet" + default: + $ref: "#/$defs/nonEmptyString" + completed_values: + $ref: "#/$defs/stringSet" + skipped_values: + $ref: "#/$defs/stringSet" + default_skipped: + $ref: "#/$defs/nonEmptyString" + definitions: + type: array + items: + $ref: "#/$defs/statusDefinition" + additionalProperties: false + priorityDefinition: + type: object + required: + - value + - label + - color + - weight + properties: + value: + $ref: "#/$defs/nonEmptyString" + label: + type: string + color: + type: string + icon: + $ref: "#/$defs/nonEmptyString" + weight: + type: number + additionalProperties: true + priorityPolicy: + type: object + required: + - values + - default + - definitions + properties: + values: + $ref: "#/$defs/stringSet" + default: + $ref: "#/$defs/nonEmptyString" + definitions: + type: array + items: + $ref: "#/$defs/priorityDefinition" + additionalProperties: false + recurrencePolicy: + type: object + required: + - syntax + - maintain_due_date_offset + - reset_body_checkboxes + properties: + syntax: + const: tasknotes + maintain_due_date_offset: + type: boolean + reset_body_checkboxes: + type: boolean + additionalProperties: false + occurrencePolicy: + type: object + required: + - identity_roles + - default_materialization + - default_next_trigger + properties: + identity_roles: + const: + - recurrenceParent + - occurrenceDate + default_materialization: + enum: + - manual + - on_completion + - rolling + default_next_trigger: + enum: + - completion + - completion_or_skip + past_horizon: + $ref: "#/$defs/nonEmptyString" + future_horizon: + $ref: "#/$defs/nonEmptyString" + additionalProperties: false + linkPolicy: + type: object + required: + - accepted_formats + - write_format + properties: + accepted_formats: + type: array + minItems: 1 + uniqueItems: true + items: + enum: + - wikilink + - markdown + write_format: + enum: + - wikilink + - markdown + additionalProperties: false + archivePolicy: + type: object + required: + - archived_tag + - move_on_archive + properties: + archived_tag: + $ref: "#/$defs/nonEmptyString" + move_on_archive: + type: boolean + folder: + $ref: "#/$defs/nonEmptyString" + additionalProperties: false + timeTrackingPolicy: + type: object + required: + - auto_stop_on_complete + properties: + auto_stop_on_complete: + type: boolean + additionalProperties: false + templatingPolicy: + type: object + required: + - enabled + - occurrence_enabled + properties: + enabled: + type: boolean + template_path: + $ref: "#/$defs/nonEmptyString" + occurrence_enabled: + type: boolean + occurrence_template_path: + $ref: "#/$defs/nonEmptyString" + failure_mode: + enum: + - error + - warning_fallback + unknown_variable_policy: + enum: + - preserve + - empty + additionalProperties: false + nlpTrigger: + type: object + required: + - property_id + - trigger + - enabled + properties: + property_id: + $ref: "#/$defs/nonEmptyString" + trigger: + $ref: "#/$defs/nonEmptyString" + enabled: + type: boolean + additionalProperties: false + nlpPolicy: + type: object + required: + - triggers + properties: + triggers: + type: array + items: + $ref: "#/$defs/nlpTrigger" + additionalProperties: false +--- + +# TaskNotes task contract + +Types implement this contract through `implements`; applications consume +the normalized contract view rather than assuming frontmatter names. diff --git a/public/contracts/artifacts/schemas/mdbase.person/1.0.0.schema.json b/public/contracts/artifacts/schemas/mdbase.person/1.0.0.schema.json new file mode 100644 index 0000000..6116dff --- /dev/null +++ b/public/contracts/artifacts/schemas/mdbase.person/1.0.0.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/contracts/schemas/mdbase.person/1.0.0.schema.json", + "title": "Person", + "description": "A portable person reference with editable account identity associations. Not an authentication or access-control assertion.", + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { + "type": "string", + "pattern": "\\S", + "description": "Stable person identifier used by references such as task assignments; independent of file path, name, account, and membership." + }, + "name": { + "type": "string", + "pattern": "\\S", + "description": "Collection-owned display name, not a verified account name." + }, + "identities": { + "type": "array", + "uniqueItems": true, + "description": "Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.", + "items": { + "type": "object", + "required": ["issuer", "subject"], + "properties": { + "issuer": { + "type": "string", + "format": "uri", + "pattern": "^https?://", + "description": "Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL." + }, + "subject": { + "type": "string", + "pattern": "\\S", + "description": "Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential." + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/public/contracts/artifacts/schemas/mdbase.person/2.0.0.schema.json b/public/contracts/artifacts/schemas/mdbase.person/2.0.0.schema.json new file mode 100644 index 0000000..65e3dff --- /dev/null +++ b/public/contracts/artifacts/schemas/mdbase.person/2.0.0.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/contracts/schemas/mdbase.person/2.0.0.schema.json", + "title": "Person", + "description": "A person represented by a record, referenced by links to that record, with editable account identity associations. Not an authentication or access-control assertion.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "pattern": "\\S", + "description": "Collection-owned display name, not a verified account name." + }, + "identities": { + "type": "array", + "uniqueItems": true, + "description": "Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.", + "items": { + "type": "object", + "required": [ + "issuer", + "subject" + ], + "properties": { + "issuer": { + "type": "string", + "format": "uri", + "pattern": "^https?://", + "description": "Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL." + }, + "subject": { + "type": "string", + "pattern": "\\S", + "description": "Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential." + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/public/contracts/artifacts/schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json b/public/contracts/artifacts/schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json new file mode 100644 index 0000000..af2bcc9 --- /dev/null +++ b/public/contracts/artifacts/schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json @@ -0,0 +1,469 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json", + "title": "TaskNotes task data-contract binding", + "description": "Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.", + "type": "object", + "required": [ + "profiles", + "capabilities", + "title", + "status", + "priority", + "recurrence", + "occurrences", + "links", + "archive", + "time_tracking", + "templating" + ], + "properties": { + "profiles": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "core-lite", + "recurrence", + "templating", + "materialized-occurrences", + "extended" + ] + } + }, + "capabilities": { + "type": "array", + "uniqueItems": true, + "items": { + "enum": [ + "dependencies", + "reminders", + "attachments", + "links", + "time-tracking", + "materialized-occurrences", + "rename", + "archive", + "batch", + "concurrency", + "dry-run", + "migration", + "templating" + ] + } + }, + "title": { + "$ref": "#/$defs/titlePolicy" + }, + "status": { + "$ref": "#/$defs/statusPolicy" + }, + "priority": { + "$ref": "#/$defs/priorityPolicy" + }, + "recurrence": { + "$ref": "#/$defs/recurrencePolicy" + }, + "occurrences": { + "$ref": "#/$defs/occurrencePolicy" + }, + "links": { + "$ref": "#/$defs/linkPolicy" + }, + "archive": { + "$ref": "#/$defs/archivePolicy" + }, + "time_tracking": { + "$ref": "#/$defs/timeTrackingPolicy" + }, + "templating": { + "$ref": "#/$defs/templatingPolicy" + }, + "nlp": { + "$ref": "#/$defs/nlpPolicy" + } + }, + "additionalProperties": false, + "$defs": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "stringSet": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "titlePolicy": { + "type": "object", + "required": [ + "storage" + ], + "properties": { + "storage": { + "enum": [ + "filename", + "frontmatter" + ] + }, + "filename_format": { + "enum": [ + "title", + "zettel", + "timestamp", + "uuid", + "custom" + ] + }, + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "allOf": [ + { + "if": { + "properties": { + "filename_format": { + "const": "custom" + } + }, + "required": [ + "filename_format" + ] + }, + "then": { + "properties": { + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "required": [ + "custom_filename_template" + ] + } + } + ], + "additionalProperties": true + }, + "statusDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "is_completed", + "is_skipped", + "exclude_from_cycle", + "order", + "auto_archive", + "auto_archive_delay_minutes" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "is_completed": { + "type": "boolean" + }, + "is_skipped": { + "type": "boolean" + }, + "exclude_from_cycle": { + "type": "boolean" + }, + "next_status": { + "$ref": "#/$defs/nonEmptyString" + }, + "order": { + "type": "number" + }, + "auto_archive": { + "type": "boolean" + }, + "auto_archive_delay_minutes": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": true + }, + "statusPolicy": { + "type": "object", + "required": [ + "values", + "default", + "completed_values", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "completed_values": { + "$ref": "#/$defs/stringSet" + }, + "skipped_values": { + "$ref": "#/$defs/stringSet" + }, + "default_skipped": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/statusDefinition" + } + } + }, + "additionalProperties": false + }, + "priorityDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "weight" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "weight": { + "type": "number" + } + }, + "additionalProperties": true + }, + "priorityPolicy": { + "type": "object", + "required": [ + "values", + "default", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/priorityDefinition" + } + } + }, + "additionalProperties": false + }, + "recurrencePolicy": { + "type": "object", + "required": [ + "syntax", + "maintain_due_date_offset", + "reset_body_checkboxes" + ], + "properties": { + "syntax": { + "const": "tasknotes" + }, + "maintain_due_date_offset": { + "type": "boolean" + }, + "reset_body_checkboxes": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "occurrencePolicy": { + "type": "object", + "required": [ + "identity_roles", + "default_materialization", + "default_next_trigger" + ], + "properties": { + "identity_roles": { + "const": [ + "recurrenceParent", + "occurrenceDate" + ] + }, + "default_materialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "default_next_trigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "past_horizon": { + "$ref": "#/$defs/nonEmptyString" + }, + "future_horizon": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "linkPolicy": { + "type": "object", + "required": [ + "accepted_formats", + "write_format" + ], + "properties": { + "accepted_formats": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "write_format": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "additionalProperties": false + }, + "archivePolicy": { + "type": "object", + "required": [ + "archived_tag", + "move_on_archive" + ], + "properties": { + "archived_tag": { + "$ref": "#/$defs/nonEmptyString" + }, + "move_on_archive": { + "type": "boolean" + }, + "folder": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "timeTrackingPolicy": { + "type": "object", + "required": [ + "auto_stop_on_complete" + ], + "properties": { + "auto_stop_on_complete": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "templatingPolicy": { + "type": "object", + "required": [ + "enabled", + "occurrence_enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "occurrence_enabled": { + "type": "boolean" + }, + "occurrence_template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "failure_mode": { + "enum": [ + "error", + "warning_fallback" + ] + }, + "unknown_variable_policy": { + "enum": [ + "preserve", + "empty" + ] + } + }, + "additionalProperties": false + }, + "nlpTrigger": { + "type": "object", + "required": [ + "property_id", + "trigger", + "enabled" + ], + "properties": { + "property_id": { + "$ref": "#/$defs/nonEmptyString" + }, + "trigger": { + "$ref": "#/$defs/nonEmptyString" + }, + "enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "nlpPolicy": { + "type": "object", + "required": [ + "triggers" + ], + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/$defs/nlpTrigger" + } + } + }, + "additionalProperties": false + } + } +} diff --git a/public/contracts/artifacts/schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json b/public/contracts/artifacts/schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json new file mode 100644 index 0000000..af2bcc9 --- /dev/null +++ b/public/contracts/artifacts/schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json @@ -0,0 +1,469 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json", + "title": "TaskNotes task data-contract binding", + "description": "Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.", + "type": "object", + "required": [ + "profiles", + "capabilities", + "title", + "status", + "priority", + "recurrence", + "occurrences", + "links", + "archive", + "time_tracking", + "templating" + ], + "properties": { + "profiles": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "core-lite", + "recurrence", + "templating", + "materialized-occurrences", + "extended" + ] + } + }, + "capabilities": { + "type": "array", + "uniqueItems": true, + "items": { + "enum": [ + "dependencies", + "reminders", + "attachments", + "links", + "time-tracking", + "materialized-occurrences", + "rename", + "archive", + "batch", + "concurrency", + "dry-run", + "migration", + "templating" + ] + } + }, + "title": { + "$ref": "#/$defs/titlePolicy" + }, + "status": { + "$ref": "#/$defs/statusPolicy" + }, + "priority": { + "$ref": "#/$defs/priorityPolicy" + }, + "recurrence": { + "$ref": "#/$defs/recurrencePolicy" + }, + "occurrences": { + "$ref": "#/$defs/occurrencePolicy" + }, + "links": { + "$ref": "#/$defs/linkPolicy" + }, + "archive": { + "$ref": "#/$defs/archivePolicy" + }, + "time_tracking": { + "$ref": "#/$defs/timeTrackingPolicy" + }, + "templating": { + "$ref": "#/$defs/templatingPolicy" + }, + "nlp": { + "$ref": "#/$defs/nlpPolicy" + } + }, + "additionalProperties": false, + "$defs": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "stringSet": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "titlePolicy": { + "type": "object", + "required": [ + "storage" + ], + "properties": { + "storage": { + "enum": [ + "filename", + "frontmatter" + ] + }, + "filename_format": { + "enum": [ + "title", + "zettel", + "timestamp", + "uuid", + "custom" + ] + }, + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "allOf": [ + { + "if": { + "properties": { + "filename_format": { + "const": "custom" + } + }, + "required": [ + "filename_format" + ] + }, + "then": { + "properties": { + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "required": [ + "custom_filename_template" + ] + } + } + ], + "additionalProperties": true + }, + "statusDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "is_completed", + "is_skipped", + "exclude_from_cycle", + "order", + "auto_archive", + "auto_archive_delay_minutes" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "is_completed": { + "type": "boolean" + }, + "is_skipped": { + "type": "boolean" + }, + "exclude_from_cycle": { + "type": "boolean" + }, + "next_status": { + "$ref": "#/$defs/nonEmptyString" + }, + "order": { + "type": "number" + }, + "auto_archive": { + "type": "boolean" + }, + "auto_archive_delay_minutes": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": true + }, + "statusPolicy": { + "type": "object", + "required": [ + "values", + "default", + "completed_values", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "completed_values": { + "$ref": "#/$defs/stringSet" + }, + "skipped_values": { + "$ref": "#/$defs/stringSet" + }, + "default_skipped": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/statusDefinition" + } + } + }, + "additionalProperties": false + }, + "priorityDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "weight" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "weight": { + "type": "number" + } + }, + "additionalProperties": true + }, + "priorityPolicy": { + "type": "object", + "required": [ + "values", + "default", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/priorityDefinition" + } + } + }, + "additionalProperties": false + }, + "recurrencePolicy": { + "type": "object", + "required": [ + "syntax", + "maintain_due_date_offset", + "reset_body_checkboxes" + ], + "properties": { + "syntax": { + "const": "tasknotes" + }, + "maintain_due_date_offset": { + "type": "boolean" + }, + "reset_body_checkboxes": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "occurrencePolicy": { + "type": "object", + "required": [ + "identity_roles", + "default_materialization", + "default_next_trigger" + ], + "properties": { + "identity_roles": { + "const": [ + "recurrenceParent", + "occurrenceDate" + ] + }, + "default_materialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "default_next_trigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "past_horizon": { + "$ref": "#/$defs/nonEmptyString" + }, + "future_horizon": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "linkPolicy": { + "type": "object", + "required": [ + "accepted_formats", + "write_format" + ], + "properties": { + "accepted_formats": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "write_format": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "additionalProperties": false + }, + "archivePolicy": { + "type": "object", + "required": [ + "archived_tag", + "move_on_archive" + ], + "properties": { + "archived_tag": { + "$ref": "#/$defs/nonEmptyString" + }, + "move_on_archive": { + "type": "boolean" + }, + "folder": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "timeTrackingPolicy": { + "type": "object", + "required": [ + "auto_stop_on_complete" + ], + "properties": { + "auto_stop_on_complete": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "templatingPolicy": { + "type": "object", + "required": [ + "enabled", + "occurrence_enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "occurrence_enabled": { + "type": "boolean" + }, + "occurrence_template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "failure_mode": { + "enum": [ + "error", + "warning_fallback" + ] + }, + "unknown_variable_policy": { + "enum": [ + "preserve", + "empty" + ] + } + }, + "additionalProperties": false + }, + "nlpTrigger": { + "type": "object", + "required": [ + "property_id", + "trigger", + "enabled" + ], + "properties": { + "property_id": { + "$ref": "#/$defs/nonEmptyString" + }, + "trigger": { + "$ref": "#/$defs/nonEmptyString" + }, + "enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "nlpPolicy": { + "type": "object", + "required": [ + "triggers" + ], + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/$defs/nlpTrigger" + } + } + }, + "additionalProperties": false + } + } +} diff --git a/public/contracts/artifacts/schemas/tasknotes.task/0.3.0-rc.4.schema.json b/public/contracts/artifacts/schemas/tasknotes.task/0.3.0-rc.4.schema.json new file mode 100644 index 0000000..56c1803 --- /dev/null +++ b/public/contracts/artifacts/schemas/tasknotes.task/0.3.0-rc.4.schema.json @@ -0,0 +1,202 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task.schema.json", + "title": "TaskNotes portable task view", + "description": "The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract.", + "type": "object", + "required": [ + "status", + "dateCreated" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "title": { + "type": "string", + "minLength": 1 + }, + "status": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "string", + "minLength": 1 + }, + "due": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "scheduled": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "contexts": { + "type": "array", + "items": { + "type": "string" + } + }, + "projects": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "pattern": "\\S" + }, + "description": "Stable mdbase.person IDs. These references never grant collection access." + }, + "attachments": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "timeEstimate": { + "type": "integer", + "minimum": 0 + }, + "completedDate": { + "type": "string", + "format": "date" + }, + "dateCreated": { + "type": "string", + "format": "date-time" + }, + "dateModified": { + "type": "string", + "format": "date-time" + }, + "recurrence": { + "type": "string" + }, + "recurrenceAnchor": { + "enum": [ + "scheduled", + "completion" + ] + }, + "recurrenceParent": { + "type": "string" + }, + "occurrenceDate": { + "type": "string", + "format": "date" + }, + "occurrenceMaterialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "occurrenceNextTrigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "occurrenceTemplate": { + "type": "string" + }, + "occurrencePastHorizon": { + "type": "string" + }, + "occurrenceFutureHorizon": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "timeEntries": { + "type": "array", + "items": { + "type": "object" + } + }, + "reminders": { + "type": "array", + "items": { + "type": "object" + } + }, + "blockedBy": { + "type": "array", + "items": { + "type": "object" + } + }, + "completeInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "skippedInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "icsEventId": { + "type": "array", + "items": { + "type": "string" + } + }, + "googleCalendarEventId": { + "type": "string" + }, + "googleCalendarExceptionEventId": { + "type": "string" + }, + "googleCalendarExceptionOriginalScheduled": { + "type": "string", + "format": "date" + }, + "googleCalendarMovedOriginalDates": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "sortOrder": { + "type": "string" + } + } +} diff --git a/public/contracts/artifacts/schemas/tasknotes.task/0.3.0-rc.5.schema.json b/public/contracts/artifacts/schemas/tasknotes.task/0.3.0-rc.5.schema.json new file mode 100644 index 0000000..8944161 --- /dev/null +++ b/public/contracts/artifacts/schemas/tasknotes.task/0.3.0-rc.5.schema.json @@ -0,0 +1,202 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task.schema.json", + "title": "TaskNotes portable task view", + "description": "The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.5 record contract.", + "type": "object", + "required": [ + "status", + "dateCreated" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "title": { + "type": "string", + "minLength": 1 + }, + "status": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "string", + "minLength": 1 + }, + "due": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "scheduled": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "contexts": { + "type": "array", + "items": { + "type": "string" + } + }, + "projects": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "pattern": "\\S" + }, + "description": "Links to records implementing mdbase.person, such as [[Alex Rivera]]. Implementing types declare this field in collection.links. These references never grant collection access." + }, + "attachments": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "timeEstimate": { + "type": "integer", + "minimum": 0 + }, + "completedDate": { + "type": "string", + "format": "date" + }, + "dateCreated": { + "type": "string", + "format": "date-time" + }, + "dateModified": { + "type": "string", + "format": "date-time" + }, + "recurrence": { + "type": "string" + }, + "recurrenceAnchor": { + "enum": [ + "scheduled", + "completion" + ] + }, + "recurrenceParent": { + "type": "string" + }, + "occurrenceDate": { + "type": "string", + "format": "date" + }, + "occurrenceMaterialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "occurrenceNextTrigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "occurrenceTemplate": { + "type": "string" + }, + "occurrencePastHorizon": { + "type": "string" + }, + "occurrenceFutureHorizon": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "timeEntries": { + "type": "array", + "items": { + "type": "object" + } + }, + "reminders": { + "type": "array", + "items": { + "type": "object" + } + }, + "blockedBy": { + "type": "array", + "items": { + "type": "object" + } + }, + "completeInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "skippedInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "icsEventId": { + "type": "array", + "items": { + "type": "string" + } + }, + "googleCalendarEventId": { + "type": "string" + }, + "googleCalendarExceptionEventId": { + "type": "string" + }, + "googleCalendarExceptionOriginalScheduled": { + "type": "string", + "format": "date" + }, + "googleCalendarMovedOriginalDates": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "sortOrder": { + "type": "string" + } + } +} diff --git a/public/contracts/artifacts/types/person/1.md b/public/contracts/artifacts/types/person/1.md new file mode 100644 index 0000000..1ef6e5d --- /dev/null +++ b/public/contracts/artifacts/types/person/1.md @@ -0,0 +1,109 @@ +--- +kind: mdbase.type +name: person +version: 1 +description: A portable person with optional account identities and contact information +match: + where: + type: person +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + title: Person + type: object + required: [type, id, name] + properties: + type: + const: person + id: + type: string + pattern: '\S' + description: Stable person ID; keep this when moving or renaming the note. + name: + type: string + minLength: 1 + pattern: '\S' + identities: + type: array + uniqueItems: true + items: + type: object + required: [issuer, subject] + properties: + issuer: + type: string + format: uri + pattern: '^https?://' + subject: + type: string + pattern: '\S' + additionalProperties: false + kind: + const: individual + default: individual + email: + type: string + format: email + phone: + type: string + minLength: 1 + organisation: + type: string + minLength: 1 + birthday: + type: string + format: date + additionalProperties: true +collection: + display: + name_field: name + description_field: organisation + icon: user + unique: + - field: id + scope: collection +implements: + - contract: mdbase.person + version: 1.0.0 + fields: + id: id + name: name + identities: identities + - contract: mdbase.contact + version: 1.0.0 + fields: + name: name + kind: kind + primary_email: email + primary_phone: phone + organisation: organisation + birthday: birthday +--- + +# Person + +Create a stable ID when adding a person, for example `person_` followed by a +random UUID. Keep it when copying the note to another collection or renaming +its file. Apps use this ID for assignments and other person references. + +```yaml +type: person +id: person_2c1343ec-cac1-4d58-98c9-41736f4de7db +name: Callum +identities: + - issuer: https://connect.example + subject: usr_789 +``` + +Use the actual issuer and subject supplied by Connect, not the example values. +Omit `identities` for people without accounts. Email is contact information, +not a way to establish an identity association. Linking a person does not +invite them or grant access to this collection. + +Identity associations and contact labels are ordinary editable data. They are +not proof of authentication. Avoid duplicate person IDs or identity pairs +across person notes; applications must report ambiguity rather than guess. + +The inline schema belongs to the collection. Add local fields or rename them +and update the explicit contract mappings without editing published contracts. diff --git a/public/contracts/artifacts/types/person/2.md b/public/contracts/artifacts/types/person/2.md new file mode 100644 index 0000000..095224e --- /dev/null +++ b/public/contracts/artifacts/types/person/2.md @@ -0,0 +1,148 @@ +--- +kind: mdbase.type +name: person +version: 2 +description: An individual that other notes link to, with a collection-owned display name and optional contact details and account associations. +match: + where: + type: person +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + title: Person + description: One person represented by an ordinary note. Contact details and account associations are optional; this record never grants access or membership. + type: object + required: [type, name] + properties: + type: + const: person + description: Identifies this note as a Person. Usually set by the application; changing it changes which type validates the note. + name: + type: string + minLength: 1 + pattern: '\S' + description: The display name to use in this collection. Use a full name, preferred name, or single name as appropriate; no first/last-name split is required. It can differ from an account's name and is not automatically synchronised with it. + identities: + type: array + description: Optional accounts associated with this person, each identified by an exact issuer and subject pair. Omit this field for someone without an account. These editable associations help applications find your person record; they are not proof of identity and never grant access. Avoid linking the same account to multiple person notes. + uniqueItems: true + items: + type: object + description: One account association supplied by its identity service. Both issuer and subject must match exactly; never infer them from a name or email. + required: [issuer, subject] + properties: + issuer: + type: string + format: uri + pattern: '^https?://' + description: The exact identity-service issuer URL reported for this account. Preserve its scheme, case, path, and trailing slash; do not guess it from the collection's hosting address. + subject: + type: string + pattern: '\S' + description: The opaque account identifier reported by that issuer, not a display name, email, password, or access token. Copy it exactly; a different issuer may use the same subject for a different account. + additionalProperties: false + kind: + const: individual + default: individual + description: This Person starter represents an individual. The organisation field describes their affiliation, not a different record kind. Existing organisation or group contacts can keep their own Contact-compatible type. + email: + type: string + format: email + description: The preferred email address for contacting this person. Optional contact information only; it does not establish an account association or grant access. + phone: + type: string + minLength: 1 + description: The preferred telephone number, stored as text so country codes, formatting, and extensions can be preserved. Include a country code when useful; omit if unknown. + organisation: + type: string + minLength: 1 + description: The person's main affiliation, such as an employer, school, or community. A collection-owned display label, not a membership or access-control setting; omit if not relevant. + birthday: + type: string + format: date + description: A known birthday as a full calendar date in YYYY-MM-DD form. Omit if unknown or if only the month and day are known; do not invent a year. Consider whether this collection needs this personal information. + additionalProperties: true +collection: + display: + name_field: name + description_field: organisation + icon: user +implements: + - contract: mdbase.person + version: 2.0.0 + fields: + name: name + identities: identities + - contract: mdbase.contact + version: 1.0.0 + fields: + name: name + kind: kind + primary_email: email + primary_phone: phone + organisation: organisation + birthday: birthday +--- + +# Person + +Use one note per individual, whether or not they have a Connect account. This +single type supplies both a Person record and optional Contact details. You do +not need a second Contact note for the same person. + +## Start with a name + +```yaml +type: person +name: Alex Rivera +``` + +Other notes refer to this person with an ordinary link to this note, such as +`[[Alex Rivera]]` in a task's `assignees`. Links to this note appear in its +backlinks. Rename or move the note with a tool that updates references, as mdbase +and Obsidian do, so those links stay current. Reusing a person's file name for +somebody else redirects existing links to the wrong person. + +The name is your collection's display label. Full names, preferred names and +single names are equally valid. There is no required first-name/last-name split. + +## Add only the contact details you need + +Email, phone, organisation and birthday are optional. Omit unknown values rather +than filling them with empty strings or guesses. Store phone numbers as text, +including an international prefix or extension when helpful. Birthday currently +requires a complete date; partial dates need a separately configured local field. +Keep free-form context in the Markdown body and be deliberate about sensitive +personal information in shared collections. + +This starter describes individuals. Existing organisation and group records can +continue using their Contact-compatible type; setting someone's affiliation does +not turn their Person note into an organisation record. + +## Link accounts deliberately + +The editor's **Link this record to me** action uses the authenticated account's +actual issuer and subject. If configuring these manually, copy both exact values +from the identity service. Do not guess them from an email, display name, or the +server hosting this collection. Multiple entries may represent the same person +at different identity services. Omit `identities` when there is no account to link. + +Associations are ordinary editable data, not authentication or proof of identity. +Linking never invites someone, grants access, or changes collection membership. +Never put credentials in a person record. Avoid linking the same account from +several notes: applications should report ambiguity, not guess which +record to use. Account deletion or recreation is not permission to reassign an +old association automatically. + +## Keep the collection's own shape + +The inline schema belongs to this collection. You may add local fields, or rename +fields and update their explicit `implements` mappings. Apps use those mappings +for the Person and Contact contracts; they need not assume your local field names. +Additional fields remain part of the note but do not automatically become shared +contract fields. Do not edit published contracts to customise this type. + +Installing a newer starter does not overwrite an existing customised type or +migrate your address book. Converting an existing individual Contact to Person +should be a reviewed edit of that one note, preserving its path, fields and body. diff --git a/public/contracts/artifacts/types/tasknotes-task/2.md b/public/contracts/artifacts/types/tasknotes-task/2.md new file mode 100644 index 0000000..3402453 --- /dev/null +++ b/public/contracts/artifacts/types/tasknotes-task/2.md @@ -0,0 +1,468 @@ +--- +kind: mdbase.type +name: task +version: 2 +description: A task managed by TaskNotes. +match: + where: + tags: + contains: task +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + type: object + additionalProperties: true + properties: + id: + type: string + minLength: 1 + title: + type: string + minLength: 1 + status: + enum: &a1 + - none + - open + - in-progress + - done + default: open + priority: + enum: &a3 + - none + - low + - normal + - high + default: normal + due: + anyOf: + - type: string + format: date + - type: string + format: date-time + scheduled: + anyOf: + - type: string + format: date + - type: string + format: date-time + contexts: + type: array + items: + type: string + projects: + type: array + items: + type: string + assignees: + type: array + items: + type: string + minLength: 1 + pattern: \S + uniqueItems: true + attachments: + type: array + items: + type: string + minLength: 1 + uniqueItems: true + timeEstimate: + type: integer + minimum: 0 + completedDate: + type: string + format: date + dateCreated: + type: string + format: date-time + dateModified: + type: string + format: date-time + recurrence: + type: string + recurrence_anchor: + enum: + - scheduled + - completion + default: scheduled + occurrence_materialization: + enum: + - manual + - on_completion + - rolling + default: manual + occurrence_next_trigger: + enum: + - completion + - completion_or_skip + default: completion + occurrence_template: + type: string + occurrence_past_horizon: + type: string + occurrence_future_horizon: + type: string + recurrence_parent: + type: string + occurrence_date: + type: string + format: date + tags: + type: array + items: + type: string + timeEntries: + type: array + items: + type: object + additionalProperties: false + properties: + startTime: + type: string + format: date-time + endTime: + type: string + format: date-time + description: + type: string + duration: + type: integer + reminders: + type: array + items: + oneOf: + - type: object + required: + - id + - type + - absoluteTime + additionalProperties: false + properties: + id: + type: string + type: + const: absolute + description: + type: string + absoluteTime: + type: string + format: date-time + - type: object + required: + - id + - type + - relatedTo + - offset + additionalProperties: false + properties: + id: + type: string + type: + const: relative + description: + type: string + relatedTo: + enum: + - due + - scheduled + offset: + type: string + blockedBy: + type: array + items: + type: object + additionalProperties: false + properties: + uid: + type: string + reltype: + type: string + gap: + type: string + required: + - uid + complete_instances: + type: array + items: + type: string + format: date + skipped_instances: + type: array + items: + type: string + format: date + icsEventId: + type: array + items: + type: string + googleCalendarEventId: + type: string + googleCalendarExceptionEventId: + type: string + googleCalendarExceptionOriginalScheduled: + type: string + format: date + googleCalendarMovedOriginalDates: + type: array + items: + type: string + format: date + tasknotes_manual_order: + type: string + allOf: + - if: + required: + - status + properties: + status: + enum: &a2 + - done + not: + required: + - recurrence + then: + required: + - completedDate + required: + - title + - status + - dateCreated +collection: + read_defaults: + status: open + priority: normal + recurrence_anchor: scheduled + occurrence_materialization: manual + occurrence_next_trigger: completion + links: + projects[]: + target_type: any + validate_exists: false + attachments[]: + validate_exists: false + occurrence_template: + target_type: any + validate_exists: false + recurrence_parent: + target_type: task + validate_exists: false + blockedBy[].uid: + target_type: task + validate_exists: false + path: + runtime: tasknotes + template: "{{zettel}}" + folder: tasks + generated_by: tasknotes.filename.create + display: + name_field: title + unique: + - field: id + scope: type +lifecycle: + on_create: + set: + id: + uuid: true + dateCreated: + now: true + dateModified: + now: true + on_update: + set: + dateModified: + now: true +implements: + - contract: tasknotes.task + version: 0.3.0-rc.4 + fields: + id: id + title: title + status: status + priority: priority + due: due + scheduled: scheduled + contexts: contexts + projects: projects + assignees: assignees + attachments: attachments + timeEstimate: timeEstimate + completedDate: completedDate + dateCreated: dateCreated + dateModified: dateModified + recurrence: recurrence + recurrenceAnchor: recurrence_anchor + occurrenceMaterialization: occurrence_materialization + occurrenceNextTrigger: occurrence_next_trigger + occurrenceTemplate: occurrence_template + occurrencePastHorizon: occurrence_past_horizon + occurrenceFutureHorizon: occurrence_future_horizon + recurrenceParent: recurrence_parent + occurrenceDate: occurrence_date + tags: tags + timeEntries: timeEntries + reminders: reminders + blockedBy: blockedBy + completeInstances: complete_instances + skippedInstances: skipped_instances + icsEventId: icsEventId + googleCalendarEventId: googleCalendarEventId + googleCalendarExceptionEventId: googleCalendarExceptionEventId + googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled + googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates + sortOrder: tasknotes_manual_order + binding: + profiles: + - core-lite + - recurrence + - templating + - materialized-occurrences + - extended + capabilities: + - dependencies + - reminders + - attachments + - links + - time-tracking + - materialized-occurrences + - archive + - templating + title: + storage: frontmatter + filename_format: zettel + status: + values: *a1 + default: open + completed_values: *a2 + skipped_values: [] + definitions: + - value: none + label: None + color: "#cccccc" + is_completed: false + is_skipped: false + exclude_from_cycle: false + order: 0 + auto_archive: false + auto_archive_delay_minutes: 5 + - value: open + label: Open + color: "#808080" + is_completed: false + is_skipped: false + exclude_from_cycle: false + order: 1 + auto_archive: false + auto_archive_delay_minutes: 5 + - value: in-progress + label: In progress + color: "#0066cc" + is_completed: false + is_skipped: false + exclude_from_cycle: false + order: 2 + auto_archive: false + auto_archive_delay_minutes: 5 + - value: done + label: Done + color: "#00aa00" + is_completed: true + is_skipped: false + exclude_from_cycle: false + order: 3 + auto_archive: false + auto_archive_delay_minutes: 5 + priority: + values: *a3 + default: normal + definitions: + - value: none + label: None + color: "#cccccc" + weight: 0 + - value: low + label: Low + color: "#00aa00" + weight: 1 + - value: normal + label: Normal + color: "#ffaa00" + weight: 2 + - value: high + label: High + color: "#ff0000" + weight: 3 + recurrence: + syntax: tasknotes + maintain_due_date_offset: true + reset_body_checkboxes: false + occurrences: + identity_roles: + - recurrenceParent + - occurrenceDate + default_materialization: manual + default_next_trigger: completion + past_horizon: P0D + future_horizon: P14D + links: + accepted_formats: + - wikilink + - markdown + write_format: wikilink + archive: + archived_tag: archived + move_on_archive: false + time_tracking: + auto_stop_on_complete: false + templating: + enabled: false + occurrence_enabled: false +x-tasknotes-generator: + managed_fields: + - assignees + - attachments + - blockedBy + - complete_instances + - completedDate + - contexts + - dateCreated + - dateModified + - due + - googleCalendarEventId + - googleCalendarExceptionEventId + - googleCalendarExceptionOriginalScheduled + - googleCalendarMovedOriginalDates + - icsEventId + - id + - occurrence_date + - occurrence_future_horizon + - occurrence_materialization + - occurrence_next_trigger + - occurrence_past_horizon + - occurrence_template + - priority + - projects + - recurrence + - recurrence_anchor + - recurrence_parent + - reminders + - scheduled + - skipped_instances + - status + - tags + - tasknotes_manual_order + - timeEntries + - timeEstimate + - title +--- + +# Task + +This type definition implements the TaskNotes contract for this mdbase collection. +Its JSON Schema describes persisted task frontmatter; collection and lifecycle +metadata describe generic mdbase behavior; `implements` maps the portable +TaskNotes task view and supplies TaskNotes behavior. + +Changes made here are loaded by TaskNotes. Portable changes made in TaskNotes +settings are written back while unknown extensions are preserved. diff --git a/public/contracts/artifacts/types/tasknotes-task/3.md b/public/contracts/artifacts/types/tasknotes-task/3.md new file mode 100644 index 0000000..c876083 --- /dev/null +++ b/public/contracts/artifacts/types/tasknotes-task/3.md @@ -0,0 +1,470 @@ +--- +kind: mdbase.type +name: task +version: 3 +description: A task managed by TaskNotes. +match: + where: + tags: + contains: task +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + type: object + additionalProperties: true + properties: + id: + type: string + minLength: 1 + title: + type: string + minLength: 1 + status: + enum: &a1 + - none + - open + - in-progress + - done + default: open + priority: + enum: &a3 + - none + - low + - normal + - high + default: normal + due: + anyOf: + - type: string + format: date + - type: string + format: date-time + scheduled: + anyOf: + - type: string + format: date + - type: string + format: date-time + contexts: + type: array + items: + type: string + projects: + type: array + items: + type: string + assignees: + type: array + items: + type: string + minLength: 1 + pattern: \S + uniqueItems: true + attachments: + type: array + items: + type: string + minLength: 1 + uniqueItems: true + timeEstimate: + type: integer + minimum: 0 + completedDate: + type: string + format: date + dateCreated: + type: string + format: date-time + dateModified: + type: string + format: date-time + recurrence: + type: string + recurrence_anchor: + enum: + - scheduled + - completion + default: scheduled + occurrence_materialization: + enum: + - manual + - on_completion + - rolling + default: manual + occurrence_next_trigger: + enum: + - completion + - completion_or_skip + default: completion + occurrence_template: + type: string + occurrence_past_horizon: + type: string + occurrence_future_horizon: + type: string + recurrence_parent: + type: string + occurrence_date: + type: string + format: date + tags: + type: array + items: + type: string + timeEntries: + type: array + items: + type: object + additionalProperties: false + properties: + startTime: + type: string + format: date-time + endTime: + type: string + format: date-time + description: + type: string + duration: + type: integer + reminders: + type: array + items: + oneOf: + - type: object + required: + - id + - type + - absoluteTime + additionalProperties: false + properties: + id: + type: string + type: + const: absolute + description: + type: string + absoluteTime: + type: string + format: date-time + - type: object + required: + - id + - type + - relatedTo + - offset + additionalProperties: false + properties: + id: + type: string + type: + const: relative + description: + type: string + relatedTo: + enum: + - due + - scheduled + offset: + type: string + blockedBy: + type: array + items: + type: object + additionalProperties: false + properties: + uid: + type: string + reltype: + type: string + gap: + type: string + required: + - uid + complete_instances: + type: array + items: + type: string + format: date + skipped_instances: + type: array + items: + type: string + format: date + icsEventId: + type: array + items: + type: string + googleCalendarEventId: + type: string + googleCalendarExceptionEventId: + type: string + googleCalendarExceptionOriginalScheduled: + type: string + format: date + googleCalendarMovedOriginalDates: + type: array + items: + type: string + format: date + tasknotes_manual_order: + type: string + allOf: + - if: + required: + - status + properties: + status: + enum: &a2 + - done + not: + required: + - recurrence + then: + required: + - completedDate + required: + - title + - status + - dateCreated +collection: + read_defaults: + status: open + priority: normal + recurrence_anchor: scheduled + occurrence_materialization: manual + occurrence_next_trigger: completion + links: + projects[]: + target_type: any + validate_exists: false + assignees[]: + validate_exists: false + attachments[]: + validate_exists: false + occurrence_template: + target_type: any + validate_exists: false + recurrence_parent: + target_type: task + validate_exists: false + blockedBy[].uid: + target_type: task + validate_exists: false + path: + runtime: tasknotes + template: "{{zettel}}" + folder: tasks + generated_by: tasknotes.filename.create + display: + name_field: title + unique: + - field: id + scope: type +lifecycle: + on_create: + set: + id: + uuid: true + dateCreated: + now: true + dateModified: + now: true + on_update: + set: + dateModified: + now: true +implements: + - contract: tasknotes.task + version: 0.3.0-rc.5 + fields: + id: id + title: title + status: status + priority: priority + due: due + scheduled: scheduled + contexts: contexts + projects: projects + assignees: assignees + attachments: attachments + timeEstimate: timeEstimate + completedDate: completedDate + dateCreated: dateCreated + dateModified: dateModified + recurrence: recurrence + recurrenceAnchor: recurrence_anchor + occurrenceMaterialization: occurrence_materialization + occurrenceNextTrigger: occurrence_next_trigger + occurrenceTemplate: occurrence_template + occurrencePastHorizon: occurrence_past_horizon + occurrenceFutureHorizon: occurrence_future_horizon + recurrenceParent: recurrence_parent + occurrenceDate: occurrence_date + tags: tags + timeEntries: timeEntries + reminders: reminders + blockedBy: blockedBy + completeInstances: complete_instances + skippedInstances: skipped_instances + icsEventId: icsEventId + googleCalendarEventId: googleCalendarEventId + googleCalendarExceptionEventId: googleCalendarExceptionEventId + googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled + googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates + sortOrder: tasknotes_manual_order + binding: + profiles: + - core-lite + - recurrence + - templating + - materialized-occurrences + - extended + capabilities: + - dependencies + - reminders + - attachments + - links + - time-tracking + - materialized-occurrences + - archive + - templating + title: + storage: frontmatter + filename_format: zettel + status: + values: *a1 + default: open + completed_values: *a2 + skipped_values: [] + definitions: + - value: none + label: None + color: "#cccccc" + is_completed: false + is_skipped: false + exclude_from_cycle: false + order: 0 + auto_archive: false + auto_archive_delay_minutes: 5 + - value: open + label: Open + color: "#808080" + is_completed: false + is_skipped: false + exclude_from_cycle: false + order: 1 + auto_archive: false + auto_archive_delay_minutes: 5 + - value: in-progress + label: In progress + color: "#0066cc" + is_completed: false + is_skipped: false + exclude_from_cycle: false + order: 2 + auto_archive: false + auto_archive_delay_minutes: 5 + - value: done + label: Done + color: "#00aa00" + is_completed: true + is_skipped: false + exclude_from_cycle: false + order: 3 + auto_archive: false + auto_archive_delay_minutes: 5 + priority: + values: *a3 + default: normal + definitions: + - value: none + label: None + color: "#cccccc" + weight: 0 + - value: low + label: Low + color: "#00aa00" + weight: 1 + - value: normal + label: Normal + color: "#ffaa00" + weight: 2 + - value: high + label: High + color: "#ff0000" + weight: 3 + recurrence: + syntax: tasknotes + maintain_due_date_offset: true + reset_body_checkboxes: false + occurrences: + identity_roles: + - recurrenceParent + - occurrenceDate + default_materialization: manual + default_next_trigger: completion + past_horizon: P0D + future_horizon: P14D + links: + accepted_formats: + - wikilink + - markdown + write_format: wikilink + archive: + archived_tag: archived + move_on_archive: false + time_tracking: + auto_stop_on_complete: false + templating: + enabled: false + occurrence_enabled: false +x-tasknotes-generator: + managed_fields: + - assignees + - attachments + - blockedBy + - complete_instances + - completedDate + - contexts + - dateCreated + - dateModified + - due + - googleCalendarEventId + - googleCalendarExceptionEventId + - googleCalendarExceptionOriginalScheduled + - googleCalendarMovedOriginalDates + - icsEventId + - id + - occurrence_date + - occurrence_future_horizon + - occurrence_materialization + - occurrence_next_trigger + - occurrence_past_horizon + - occurrence_template + - priority + - projects + - recurrence + - recurrence_anchor + - recurrence_parent + - reminders + - scheduled + - skipped_instances + - status + - tags + - tasknotes_manual_order + - timeEntries + - timeEstimate + - title +--- + +# Task + +This type definition implements the TaskNotes contract for this mdbase collection. +Its JSON Schema describes persisted task frontmatter; collection and lifecycle +metadata describe generic mdbase behavior; `implements` maps the portable +TaskNotes task view and supplies TaskNotes behavior. + +Changes made here are loaded by TaskNotes. Portable changes made in TaskNotes +settings are written back while unknown extensions are preserved. diff --git a/public/contracts/catalog.json b/public/contracts/catalog.json index 60fc628..940b713 100644 --- a/public/contracts/catalog.json +++ b/public/contracts/catalog.json @@ -19,6 +19,26 @@ "artifact": "./artifacts/contracts/mdbase.contact/1.0.0.md", "standards": [] }, + { + "id": "mdbase.person", + "version": "1.0.0", + "name": "Person", + "description": "A portable person reference with editable account identity associations.", + "contract_type": "record", + "digest": "sha256:e2a9435ad01a2c06c151bf6af62a9d04aa30faa8e6128e4b5fe39378c767465c", + "artifact": "./artifacts/contracts/mdbase.person/1.0.0.md", + "standards": [] + }, + { + "id": "mdbase.person", + "version": "2.0.0", + "name": "Person", + "description": "A person record, referenced by links, with editable account identity associations.", + "contract_type": "record", + "digest": "sha256:2899b149b1602bd4e51ff8e87c82dc92da3f690f4e89b1a6caf5b2b555540fe5", + "artifact": "./artifacts/contracts/mdbase.person/2.0.0.md", + "standards": [] + }, { "id": "mdbase.record.created", "version": "1.0.0", @@ -188,6 +208,16 @@ "digest": "sha256:4761ee78615882170cae6e52590f98917f549bd89d852a0c40568583394d7264", "artifact": "./artifacts/contracts/tasknotes.task/0.3.0-rc.3.md", "standards": [] + }, + { + "id": "tasknotes.task", + "version": "0.3.0-rc.5", + "name": "TaskNotes task", + "description": "Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.5.", + "contract_type": "record", + "digest": "sha256:ecadd00700e249940f4244aaa5b5985a96557d13340463ec491dfa5e89b032a4", + "artifact": "./artifacts/contracts/tasknotes.task/0.3.0-rc.5.md", + "standards": [] } ], "packs": [ @@ -217,13 +247,101 @@ ] }, "installation": { - "visibility": "default", + "visibility": "hidden", + "recommendation": "user", + "primary_type": "contact", + "types": [ + { + "name": "contact", + "label": "Contact" + } + ] + } + }, + { + "id": "mdbase.contact", + "version": "1.1.0", + "name": "People and contacts type pack", + "description": "Portable people, editable account identity associations, and familiar contact fields.", + "digest": "sha256:14bba55df0574401b46ae08e5ef1e41e615d1477f70c3cc202eb9ff179287864", + "provision": "./packs/mdbase.contact/1.1.0.json", + "provides": [ + { + "id": "mdbase.person", + "version": "1.0.0", + "digest": "sha256:cda32ead27eaf70440efe3fadd8b5334df9af82f378b2af1bc786f7ab0bd0fc3" + }, + { + "id": "mdbase.contact", + "version": "1.0.0", + "digest": "sha256:49cfe15403dfc741a693e89a2f4d2857de306f391d02cb03e67bfaf0aa1d6b0d" + } + ], + "resource_count": 6, + "display": { + "name": "People and contacts", + "summary": "Reference people across apps and collections without tying records to account membership.", + "category": "people", + "audience": "general", + "icon": "user", + "badges": [ + "Portable person references" + ] + }, + "installation": { + "visibility": "hidden", "recommendation": "user", "primary_type": "contact", "types": [ { "name": "contact", "label": "Contact" + }, + { + "name": "person", + "label": "Person" + } + ] + } + }, + { + "id": "mdbase.contact", + "version": "1.2.0", + "name": "People type pack", + "description": "Portable people, editable account identity associations, and familiar contact fields.", + "digest": "sha256:dbbb3a874cfc5d69a2a5793c86dab801c16438d58a270b48bc7376fc8bbdfa2d", + "provision": "./packs/mdbase.contact/1.2.0.json", + "provides": [ + { + "id": "mdbase.person", + "version": "2.0.0", + "digest": "sha256:f16c462a1fd422f44ed055002f8476ec53c164107647fec782aeb74adeab2f9d" + }, + { + "id": "mdbase.contact", + "version": "1.0.0", + "digest": "sha256:49cfe15403dfc741a693e89a2f4d2857de306f391d02cb03e67bfaf0aa1d6b0d" + } + ], + "resource_count": 7, + "display": { + "name": "People", + "summary": "Reference people across apps and collections without tying records to account membership.", + "category": "people", + "audience": "general", + "icon": "user", + "badges": [ + "Portable person references" + ] + }, + "installation": { + "visibility": "default", + "recommendation": "user", + "primary_type": "person", + "types": [ + { + "name": "person", + "label": "Person" } ] } @@ -384,6 +502,44 @@ } ] } + }, + { + "id": "tasknotes.task", + "version": "0.3.0-rc.15", + "name": "TaskNotes task type pack", + "description": "Portable tasks whose assignments link to person records, with a reviewed, atomic starter upgrade.", + "digest": "sha256:db3b0b28c6fb286bc8c7bbbee9f4b01f567078c208187d17ce049d1e62a9a8cb", + "provision": "./packs/tasknotes.task/0.3.0-rc.15.json", + "provides": [ + { + "id": "tasknotes.task", + "version": "0.3.0-rc.5", + "digest": "sha256:dde71d0d776aa0069ee627fe3c10b1a20f87ba36929a16790598ebfb4e8ebf04" + } + ], + "resource_count": 4, + "display": { + "name": "TaskNotes tasks", + "summary": "Manage portable Markdown tasks, assignments, dates, recurrence, reminders, and time tracking.", + "category": "work", + "audience": "general", + "icon": "square-check-big", + "badges": [ + "TaskNotes compatible" + ] + }, + "installation": { + "visibility": "default", + "recommendation": "integration-managed", + "primary_type": "task", + "caution": "Upgrades the previous starter type while preserving independent customizations. Conflicts or other references to the previous contract block the whole upgrade.", + "types": [ + { + "name": "task", + "label": "Task" + } + ] + } } ] } diff --git a/public/contracts/packs/mdbase.contact/1.1.0.json b/public/contracts/packs/mdbase.contact/1.1.0.json new file mode 100644 index 0000000..822f636 --- /dev/null +++ b/public/contracts/packs/mdbase.contact/1.1.0.json @@ -0,0 +1,91 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "mdbase.contact", + "version": "1.1.0", + "name": "People and contacts type pack", + "description": "Portable people, editable account identity associations, and familiar contact fields.", + "resources": [ + { + "kind": "schema", + "mode": "managed", + "source": "schemas/mdbase.person/1.0.0.schema.json", + "target": "schemas/mdbase.person/1.0.0.schema.json", + "digest": "sha256:3254afaa98c895e84fdc0aba299e67a0f3b594681c5581313ece5fcf4e2c6d93" + }, + { + "kind": "contract", + "mode": "managed", + "source": "contracts/mdbase.person/1.0.0.md", + "target": "_contracts/mdbase.person/1.0.0.md", + "digest": "sha256:e2a9435ad01a2c06c151bf6af62a9d04aa30faa8e6128e4b5fe39378c767465c" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/mdbase.contact/1.0.0.schema.json", + "target": "schemas/mdbase.contact/1.0.0.schema.json", + "digest": "sha256:bd8a011d18c71164b633f4e82cb33faa5b658cdba4f89312a34c13bf46a350d2" + }, + { + "kind": "contract", + "mode": "managed", + "source": "contracts/mdbase.contact/1.0.0.md", + "target": "_contracts/mdbase.contact/1.0.0.md", + "digest": "sha256:e3634a35737ada5eb62e3e15f1c0c9d2e27c55a3f98dfab94bbc14c40404903d" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/contact/2.md", + "target": "_types/contact.md", + "digest": "sha256:c925ac22674b5fa9b1a7b8b3af827e5ce3ba15e423b64487f626f5ab4cc1c80a" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/person/1.md", + "target": "_types/person.md", + "digest": "sha256:18896ac3086c7fdcb64748babd7dd8263dbece4fcc6bcf43a53f74d51bcece5e" + } + ] + }, + "resources": [ + { + "source": "schemas/mdbase.person/1.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.person/1.0.0.schema.json\",\n \"title\": \"Person\",\n \"description\": \"A portable person reference with editable account identity associations. Not an authentication or access-control assertion.\",\n \"type\": \"object\",\n \"required\": [\"id\", \"name\"],\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Stable person identifier used by references such as task assignments; independent of file path, name, account, and membership.\"\n },\n \"name\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Collection-owned display name, not a verified account name.\"\n },\n \"identities\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"description\": \"Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"issuer\", \"subject\"],\n \"properties\": {\n \"issuer\": {\n \"type\": \"string\",\n \"format\": \"uri\",\n \"pattern\": \"^https?://\",\n \"description\": \"Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL.\"\n },\n \"subject\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential.\"\n }\n },\n \"additionalProperties\": false\n }\n }\n },\n \"additionalProperties\": false\n}\n" + }, + { + "source": "contracts/mdbase.person/1.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.person\nversion: 1.0.0\nname: Person\ndescription: A portable person reference with editable account identity associations.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.person/1.0.0.schema.json\n---\n\n# Person\n\nA person is collection data, independent of an account or collection membership.\nApplications reference the stable `id`, not a name, file path, email address,\naccount subject, or membership ID. Collections choose their own local type and\nfield names through explicit `implements` mappings.\n\n`name` is a collection-owned display label. `identities` optionally associates\nthis person with one or more accounts through issuer/subject pairs. A person\nwithout a Connect account is valid. The same record can travel between hosted,\nrelay, local, and exported collections without rewriting its identity references.\n\n## Identity matching\n\nAn identity service supplies the authenticated caller's issuer and subject.\nSubjects are opaque, account-wide identifiers, stable across email changes,\ncollection memberships, and removal/rejoining. Different identity issuers may\nuse the same subject; both fields must match exactly. Consumers must not trim,\ncase-fold, resolve redirects, or otherwise normalize either field when matching.\nCopy the issuer value supplied by the service, including its trailing-slash\nconvention. Never derive the issuer from the current collection authority URL.\nHTTP issuers support explicitly configured development and self-hosted instances;\nproduction deployments should use HTTPS.\n\nAn application resolves an identity across all implementing person records:\n\n- No matching person: unlinked, not anonymous authentication and not an error.\n- Exactly one matching record with an unambiguous person ID: linked.\n- Multiple matching records, or multiple records with that person's ID:\n ambiguous. Do not pick the first match, merge records, or overwrite a link.\n\nA partial or failed query cannot establish that a match is unique. Cross-record\nuniqueness is a collection/application invariant, not something this JSON Schema\ncan prove. Consumers must handle ambiguity even if a starter type has a local\nuniqueness constraint: several local types can implement this contract.\n\n## Editable data, not security authority\n\nIdentity associations have exactly the same trust as other editable collection\ndata. Editing one may change an application's \"Assigned to me\" view. It must\nnever change authentication, membership, permissions, authenticated audit\nattribution, or proof of identity to another service. Schema conformance proves\nshape, not that an identity association is truthful.\n\n\"Link this person to me\" is an ordinary record update using the authenticated\ncaller's identity. Never infer a link from a matching email or display name.\nMembership and current account display names come from the identity service,\nnot frontmatter. A person association must never invite someone or grant access.\n\n## Lifecycle and portability\n\nRenaming or moving a record does not change its ID. Removing a member does not\ndelete their person record or task assignments. Deleting a record leaves\nunresolved references; consumers should preserve these rather than silently\nunassigning work. Reusing an ID for a different person changes every reference\nand should not be treated as a routine rename.\n\nCopying records preserves account associations, but never copies collection\naccess. Multiple issuer/subject entries let one person represent accounts at\ndifferent identity services. Account deletion or an issuer migration may leave\nan unresolved identity association; do not automatically rebind it to a newly\ncreated account. Stored names and identity references remain collection data\nsubject to that collection's retention and editing policies.\n\nAccount-wide subjects deliberately allow correlation across collections. This\nis a portability trade-off, not an anonymity guarantee. Never store passwords,\naccess tokens, refresh tokens, or other credentials in these fields.\n\n## Contact information\n\nThis contract does not define another address book. A local type can also\nimplement `mdbase.contact` for compact contact semantics, or\n`mdbase.jscontact.card` when it intentionally stores that interchange shape.\nThe starter Person type implements both Person and Contact.\n" + }, + { + "source": "schemas/mdbase.contact/1.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.contact/1.0.0.schema.json\",\n \"title\": \"Contact\",\n \"description\": \"A compact application-facing contact view.\",\n \"type\": \"object\",\n \"required\": [\"name\"],\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The name applications should use when presenting this contact.\"\n },\n \"kind\": {\n \"type\": \"string\",\n \"enum\": [\"individual\", \"organisation\", \"group\"],\n \"description\": \"The broad kind of contact when the collection distinguishes it.\"\n },\n \"primary_email\": {\n \"type\": \"string\",\n \"format\": \"email\",\n \"description\": \"The preferred email address for this contact.\"\n },\n \"primary_phone\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The preferred telephone number for this contact.\"\n },\n \"organisation\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The organisation most closely associated with this contact.\"\n },\n \"birthday\": {\n \"type\": \"string\",\n \"format\": \"date\",\n \"description\": \"The contact's birthday when known.\"\n }\n },\n \"additionalProperties\": false\n}\n" + }, + { + "source": "contracts/mdbase.contact/1.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.contact\nversion: 1.0.0\nname: Contact\ndescription: A compact application-facing view of a person or organisation.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.contact/1.0.0.schema.json\n---\n\n# Contact\n\nThis contract exposes the small set of contact semantics commonly shared by\naddress books, relationship tools, and other applications. A collection keeps\nits own field names and may store richer local data; the implementing type maps\nonly the fields it wants applications to see.\n\nThe contract is deliberately not an interchange format. Exporters can convert\nthis view to JSContact, vCard, or another wire representation without requiring\nMarkdown records to store that representation directly.\n" + }, + { + "source": "types/contact/2.md", + "document": "---\nkind: mdbase.type\nname: contact\nversion: 1\ndescription: A person or organisation you want to stay in touch with\nmatch:\n where:\n type: contact\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n title: Contact\n description: A friendly local contact with room for collection-specific fields.\n type: object\n required:\n - type\n - name\n properties:\n type:\n const: contact\n name:\n type: string\n minLength: 1\n description: The name shown in contact lists.\n kind:\n type: string\n enum:\n - individual\n - organisation\n - group\n default: individual\n description: The broad kind of contact.\n email:\n type: string\n format: email\n description: The preferred email address.\n phone:\n type: string\n minLength: 1\n description: The preferred telephone number.\n organisation:\n type: string\n minLength: 1\n description: The contact's main organisation.\n birthday:\n type: string\n format: date\n description: The contact's birthday.\n additionalProperties: true\ncollection:\n display:\n name_field: name\n description_field: organisation\n icon: address-book\nimplements:\n - contract: mdbase.contact\n version: 1.0.0\n fields:\n name: name\n kind: kind\n primary_email: email\n primary_phone: phone\n organisation: organisation\n birthday: birthday\n---\n\n# Contact\n\nContact notes use familiar frontmatter fields and leave the Markdown body free\nfor history, context, and anything else worth remembering. Applications using\nthe `mdbase.contact` contract see only the mapped contact fields.\n\nYou can rename or extend the local fields in mdbase-editor. Keep the contract\nmapping aligned so other contact-aware applications continue to understand\nthe type.\n" + }, + { + "source": "types/person/1.md", + "document": "---\nkind: mdbase.type\nname: person\nversion: 1\ndescription: A portable person with optional account identities and contact information\nmatch:\n where:\n type: person\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n title: Person\n type: object\n required: [type, id, name]\n properties:\n type:\n const: person\n id:\n type: string\n pattern: '\\S'\n description: Stable person ID; keep this when moving or renaming the note.\n name:\n type: string\n minLength: 1\n pattern: '\\S'\n identities:\n type: array\n uniqueItems: true\n items:\n type: object\n required: [issuer, subject]\n properties:\n issuer:\n type: string\n format: uri\n pattern: '^https?://'\n subject:\n type: string\n pattern: '\\S'\n additionalProperties: false\n kind:\n const: individual\n default: individual\n email:\n type: string\n format: email\n phone:\n type: string\n minLength: 1\n organisation:\n type: string\n minLength: 1\n birthday:\n type: string\n format: date\n additionalProperties: true\ncollection:\n display:\n name_field: name\n description_field: organisation\n icon: user\n unique:\n - field: id\n scope: collection\nimplements:\n - contract: mdbase.person\n version: 1.0.0\n fields:\n id: id\n name: name\n identities: identities\n - contract: mdbase.contact\n version: 1.0.0\n fields:\n name: name\n kind: kind\n primary_email: email\n primary_phone: phone\n organisation: organisation\n birthday: birthday\n---\n\n# Person\n\nCreate a stable ID when adding a person, for example `person_` followed by a\nrandom UUID. Keep it when copying the note to another collection or renaming\nits file. Apps use this ID for assignments and other person references.\n\n```yaml\ntype: person\nid: person_2c1343ec-cac1-4d58-98c9-41736f4de7db\nname: Callum\nidentities:\n - issuer: https://connect.example\n subject: usr_789\n```\n\nUse the actual issuer and subject supplied by Connect, not the example values.\nOmit `identities` for people without accounts. Email is contact information,\nnot a way to establish an identity association. Linking a person does not\ninvite them or grant access to this collection.\n\nIdentity associations and contact labels are ordinary editable data. They are\nnot proof of authentication. Avoid duplicate person IDs or identity pairs\nacross person notes; applications must report ambiguity rather than guess.\n\nThe inline schema belongs to the collection. Add local fields or rename them\nand update the explicit contract mappings without editing published contracts.\n" + } + ], + "provides": [ + { + "id": "mdbase.person", + "version": "1.0.0", + "digest": "sha256:cda32ead27eaf70440efe3fadd8b5334df9af82f378b2af1bc786f7ab0bd0fc3" + }, + { + "id": "mdbase.contact", + "version": "1.0.0", + "digest": "sha256:49cfe15403dfc741a693e89a2f4d2857de306f391d02cb03e67bfaf0aa1d6b0d" + } + ] +} diff --git a/public/contracts/packs/mdbase.contact/1.2.0.json b/public/contracts/packs/mdbase.contact/1.2.0.json new file mode 100644 index 0000000..06214b7 --- /dev/null +++ b/public/contracts/packs/mdbase.contact/1.2.0.json @@ -0,0 +1,102 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "mdbase.contact", + "version": "1.2.0", + "name": "People type pack", + "description": "Portable people, editable account identity associations, and familiar contact fields.", + "resources": [ + { + "kind": "schema", + "mode": "managed", + "source": "schemas/mdbase.person/1.0.0.schema.json", + "target": "schemas/mdbase.person/1.0.0.schema.json", + "digest": "sha256:3254afaa98c895e84fdc0aba299e67a0f3b594681c5581313ece5fcf4e2c6d93" + }, + { + "kind": "contract", + "mode": "managed", + "source": "contracts/mdbase.person/1.0.0.md", + "target": "_contracts/mdbase.person/1.0.0.md", + "digest": "sha256:e2a9435ad01a2c06c151bf6af62a9d04aa30faa8e6128e4b5fe39378c767465c" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/mdbase.person/2.0.0.schema.json", + "target": "schemas/mdbase.person/2.0.0.schema.json", + "digest": "sha256:f9705e5869a2814086b907323749f63dce60de535728d6725601f02901ae60ac" + }, + { + "kind": "contract", + "mode": "managed", + "source": "contracts/mdbase.person/2.0.0.md", + "target": "_contracts/mdbase.person/2.0.0.md", + "digest": "sha256:2899b149b1602bd4e51ff8e87c82dc92da3f690f4e89b1a6caf5b2b555540fe5" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/mdbase.contact/1.0.0.schema.json", + "target": "schemas/mdbase.contact/1.0.0.schema.json", + "digest": "sha256:bd8a011d18c71164b633f4e82cb33faa5b658cdba4f89312a34c13bf46a350d2" + }, + { + "kind": "contract", + "mode": "managed", + "source": "contracts/mdbase.contact/1.0.0.md", + "target": "_contracts/mdbase.contact/1.0.0.md", + "digest": "sha256:e3634a35737ada5eb62e3e15f1c0c9d2e27c55a3f98dfab94bbc14c40404903d" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/person/2.md", + "target": "_types/person.md", + "digest": "sha256:aa81c2964285ecc69fcb96bca4b6ae80bbddeb648908d840d7c7be50df15b362" + } + ] + }, + "resources": [ + { + "source": "schemas/mdbase.person/1.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.person/1.0.0.schema.json\",\n \"title\": \"Person\",\n \"description\": \"A portable person reference with editable account identity associations. Not an authentication or access-control assertion.\",\n \"type\": \"object\",\n \"required\": [\"id\", \"name\"],\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Stable person identifier used by references such as task assignments; independent of file path, name, account, and membership.\"\n },\n \"name\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Collection-owned display name, not a verified account name.\"\n },\n \"identities\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"description\": \"Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"issuer\", \"subject\"],\n \"properties\": {\n \"issuer\": {\n \"type\": \"string\",\n \"format\": \"uri\",\n \"pattern\": \"^https?://\",\n \"description\": \"Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL.\"\n },\n \"subject\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential.\"\n }\n },\n \"additionalProperties\": false\n }\n }\n },\n \"additionalProperties\": false\n}\n" + }, + { + "source": "contracts/mdbase.person/1.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.person\nversion: 1.0.0\nname: Person\ndescription: A portable person reference with editable account identity associations.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.person/1.0.0.schema.json\n---\n\n# Person\n\nA person is collection data, independent of an account or collection membership.\nApplications reference the stable `id`, not a name, file path, email address,\naccount subject, or membership ID. Collections choose their own local type and\nfield names through explicit `implements` mappings.\n\n`name` is a collection-owned display label. `identities` optionally associates\nthis person with one or more accounts through issuer/subject pairs. A person\nwithout a Connect account is valid. The same record can travel between hosted,\nrelay, local, and exported collections without rewriting its identity references.\n\n## Identity matching\n\nAn identity service supplies the authenticated caller's issuer and subject.\nSubjects are opaque, account-wide identifiers, stable across email changes,\ncollection memberships, and removal/rejoining. Different identity issuers may\nuse the same subject; both fields must match exactly. Consumers must not trim,\ncase-fold, resolve redirects, or otherwise normalize either field when matching.\nCopy the issuer value supplied by the service, including its trailing-slash\nconvention. Never derive the issuer from the current collection authority URL.\nHTTP issuers support explicitly configured development and self-hosted instances;\nproduction deployments should use HTTPS.\n\nAn application resolves an identity across all implementing person records:\n\n- No matching person: unlinked, not anonymous authentication and not an error.\n- Exactly one matching record with an unambiguous person ID: linked.\n- Multiple matching records, or multiple records with that person's ID:\n ambiguous. Do not pick the first match, merge records, or overwrite a link.\n\nA partial or failed query cannot establish that a match is unique. Cross-record\nuniqueness is a collection/application invariant, not something this JSON Schema\ncan prove. Consumers must handle ambiguity even if a starter type has a local\nuniqueness constraint: several local types can implement this contract.\n\n## Editable data, not security authority\n\nIdentity associations have exactly the same trust as other editable collection\ndata. Editing one may change an application's \"Assigned to me\" view. It must\nnever change authentication, membership, permissions, authenticated audit\nattribution, or proof of identity to another service. Schema conformance proves\nshape, not that an identity association is truthful.\n\n\"Link this person to me\" is an ordinary record update using the authenticated\ncaller's identity. Never infer a link from a matching email or display name.\nMembership and current account display names come from the identity service,\nnot frontmatter. A person association must never invite someone or grant access.\n\n## Lifecycle and portability\n\nRenaming or moving a record does not change its ID. Removing a member does not\ndelete their person record or task assignments. Deleting a record leaves\nunresolved references; consumers should preserve these rather than silently\nunassigning work. Reusing an ID for a different person changes every reference\nand should not be treated as a routine rename.\n\nCopying records preserves account associations, but never copies collection\naccess. Multiple issuer/subject entries let one person represent accounts at\ndifferent identity services. Account deletion or an issuer migration may leave\nan unresolved identity association; do not automatically rebind it to a newly\ncreated account. Stored names and identity references remain collection data\nsubject to that collection's retention and editing policies.\n\nAccount-wide subjects deliberately allow correlation across collections. This\nis a portability trade-off, not an anonymity guarantee. Never store passwords,\naccess tokens, refresh tokens, or other credentials in these fields.\n\n## Contact information\n\nThis contract does not define another address book. A local type can also\nimplement `mdbase.contact` for compact contact semantics, or\n`mdbase.jscontact.card` when it intentionally stores that interchange shape.\nThe starter Person type implements both Person and Contact.\n" + }, + { + "source": "schemas/mdbase.person/2.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.person/2.0.0.schema.json\",\n \"title\": \"Person\",\n \"description\": \"A person represented by a record, referenced by links to that record, with editable account identity associations. Not an authentication or access-control assertion.\",\n \"type\": \"object\",\n \"required\": [\n \"name\"\n ],\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Collection-owned display name, not a verified account name.\"\n },\n \"identities\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"description\": \"Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\n \"issuer\",\n \"subject\"\n ],\n \"properties\": {\n \"issuer\": {\n \"type\": \"string\",\n \"format\": \"uri\",\n \"pattern\": \"^https?://\",\n \"description\": \"Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL.\"\n },\n \"subject\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\S\",\n \"description\": \"Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential.\"\n }\n },\n \"additionalProperties\": false\n }\n }\n },\n \"additionalProperties\": false\n}\n" + }, + { + "source": "contracts/mdbase.person/2.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.person\nversion: 2.0.0\nname: Person\ndescription: A person record, referenced by links, with editable account identity associations.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.person/2.0.0.schema.json\n---\n\n# Person\n\nA person is collection data, independent of an account or collection membership.\nOther records refer to a person with an ordinary mdbase link to the person's\nrecord, such as `\"[[Alex Rivera]]\"`, declared in the referring type's\n`collection.links` and resolved with the collection's own link rules. Never\nrefer to a person by name text, email address, account subject, or membership\nID. Collections choose their own local type and field names through explicit\n`implements` mappings.\n\nVersion 2.0.0 removes the separate `id` field of 1.0.0. Link resolution already\nidentifies the record, and rename reference updates keep links current, so a\nsecond identifier only created a way for the two to disagree.\n\n`name` is a collection-owned display label. `identities` optionally associates\nthis person with one or more accounts through issuer/subject pairs. A person\nwithout a Connect account is valid. The same record can travel between hosted,\nrelay, local, and exported collections without rewriting its identity references.\n\n## Identity matching\n\nAn identity service supplies the authenticated caller's issuer and subject.\nSubjects are opaque, account-wide identifiers, stable across email changes,\ncollection memberships, and removal/rejoining. Different identity issuers may\nuse the same subject; both fields must match exactly. Consumers must not trim,\ncase-fold, resolve redirects, or otherwise normalize either field when matching.\nCopy the issuer value supplied by the service, including its trailing-slash\nconvention. Never derive the issuer from the current collection authority URL.\nHTTP issuers support explicitly configured development and self-hosted instances;\nproduction deployments should use HTTPS.\n\nAn application resolves an identity across all implementing person records:\n\n- No matching person: unlinked, not anonymous authentication and not an error.\n- Exactly one matching record: linked.\n- Multiple matching records: ambiguous. Do not pick the first match, merge\n records, or overwrite a link.\n\nA partial or failed query cannot establish that a match is unique. Consumers\nmust handle ambiguity: several records, possibly of several local types, can\nclaim the same identity.\n\n## Editable data, not security authority\n\nIdentity associations have exactly the same trust as other editable collection\ndata. Editing one may change an application's \"Assigned to me\" view. It must\nnever change authentication, membership, permissions, authenticated audit\nattribution, or proof of identity to another service. Schema conformance proves\nshape, not that an identity association is truthful.\n\n\"Link this person to me\" is an ordinary record update using the authenticated\ncaller's identity. Never infer a link from a matching email or display name.\nMembership and current account display names come from the identity service,\nnot frontmatter. A person association must never invite someone or grant access.\n\n## Lifecycle and portability\n\nRenaming or moving a person record through mdbase or an editor that updates\nreferences keeps links to it current. Removing a member does not delete their\nperson record or task assignments. Deleting a record leaves unresolved links;\nconsumers should preserve these rather than silently unassigning work. Giving a\ndifferent person's record the old record's name or path redirects existing\nlinks and should not be treated as a routine rename.\n\nCopying records preserves account associations, but never copies collection\naccess. Multiple issuer/subject entries let one person represent accounts at\ndifferent identity services. Account deletion or an issuer migration may leave\nan unresolved identity association; do not automatically rebind it to a newly\ncreated account. Stored names and identity references remain collection data\nsubject to that collection's retention and editing policies.\n\nAccount-wide subjects deliberately allow correlation across collections. This\nis a portability trade-off, not an anonymity guarantee. Never store passwords,\naccess tokens, refresh tokens, or other credentials in these fields.\n\n## Contact information\n\nThis contract does not define another address book. A local type can also\nimplement `mdbase.contact` for compact contact semantics, or\n`mdbase.jscontact.card` when it intentionally stores that interchange shape.\nThe starter Person type implements both Person and Contact.\n" + }, + { + "source": "schemas/mdbase.contact/1.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/contracts/schemas/mdbase.contact/1.0.0.schema.json\",\n \"title\": \"Contact\",\n \"description\": \"A compact application-facing contact view.\",\n \"type\": \"object\",\n \"required\": [\"name\"],\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The name applications should use when presenting this contact.\"\n },\n \"kind\": {\n \"type\": \"string\",\n \"enum\": [\"individual\", \"organisation\", \"group\"],\n \"description\": \"The broad kind of contact when the collection distinguishes it.\"\n },\n \"primary_email\": {\n \"type\": \"string\",\n \"format\": \"email\",\n \"description\": \"The preferred email address for this contact.\"\n },\n \"primary_phone\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The preferred telephone number for this contact.\"\n },\n \"organisation\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The organisation most closely associated with this contact.\"\n },\n \"birthday\": {\n \"type\": \"string\",\n \"format\": \"date\",\n \"description\": \"The contact's birthday when known.\"\n }\n },\n \"additionalProperties\": false\n}\n" + }, + { + "source": "contracts/mdbase.contact/1.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.contact\nversion: 1.0.0\nname: Contact\ndescription: A compact application-facing view of a person or organisation.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.contact/1.0.0.schema.json\n---\n\n# Contact\n\nThis contract exposes the small set of contact semantics commonly shared by\naddress books, relationship tools, and other applications. A collection keeps\nits own field names and may store richer local data; the implementing type maps\nonly the fields it wants applications to see.\n\nThe contract is deliberately not an interchange format. Exporters can convert\nthis view to JSContact, vCard, or another wire representation without requiring\nMarkdown records to store that representation directly.\n" + }, + { + "source": "types/person/2.md", + "document": "---\nkind: mdbase.type\nname: person\nversion: 2\ndescription: An individual that other notes link to, with a collection-owned display name and optional contact details and account associations.\nmatch:\n where:\n type: person\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n title: Person\n description: One person represented by an ordinary note. Contact details and account associations are optional; this record never grants access or membership.\n type: object\n required: [type, name]\n properties:\n type:\n const: person\n description: Identifies this note as a Person. Usually set by the application; changing it changes which type validates the note.\n name:\n type: string\n minLength: 1\n pattern: '\\S'\n description: The display name to use in this collection. Use a full name, preferred name, or single name as appropriate; no first/last-name split is required. It can differ from an account's name and is not automatically synchronised with it.\n identities:\n type: array\n description: Optional accounts associated with this person, each identified by an exact issuer and subject pair. Omit this field for someone without an account. These editable associations help applications find your person record; they are not proof of identity and never grant access. Avoid linking the same account to multiple person notes.\n uniqueItems: true\n items:\n type: object\n description: One account association supplied by its identity service. Both issuer and subject must match exactly; never infer them from a name or email.\n required: [issuer, subject]\n properties:\n issuer:\n type: string\n format: uri\n pattern: '^https?://'\n description: The exact identity-service issuer URL reported for this account. Preserve its scheme, case, path, and trailing slash; do not guess it from the collection's hosting address.\n subject:\n type: string\n pattern: '\\S'\n description: The opaque account identifier reported by that issuer, not a display name, email, password, or access token. Copy it exactly; a different issuer may use the same subject for a different account.\n additionalProperties: false\n kind:\n const: individual\n default: individual\n description: This Person starter represents an individual. The organisation field describes their affiliation, not a different record kind. Existing organisation or group contacts can keep their own Contact-compatible type.\n email:\n type: string\n format: email\n description: The preferred email address for contacting this person. Optional contact information only; it does not establish an account association or grant access.\n phone:\n type: string\n minLength: 1\n description: The preferred telephone number, stored as text so country codes, formatting, and extensions can be preserved. Include a country code when useful; omit if unknown.\n organisation:\n type: string\n minLength: 1\n description: The person's main affiliation, such as an employer, school, or community. A collection-owned display label, not a membership or access-control setting; omit if not relevant.\n birthday:\n type: string\n format: date\n description: A known birthday as a full calendar date in YYYY-MM-DD form. Omit if unknown or if only the month and day are known; do not invent a year. Consider whether this collection needs this personal information.\n additionalProperties: true\ncollection:\n display:\n name_field: name\n description_field: organisation\n icon: user\nimplements:\n - contract: mdbase.person\n version: 2.0.0\n fields:\n name: name\n identities: identities\n - contract: mdbase.contact\n version: 1.0.0\n fields:\n name: name\n kind: kind\n primary_email: email\n primary_phone: phone\n organisation: organisation\n birthday: birthday\n---\n\n# Person\n\nUse one note per individual, whether or not they have a Connect account. This\nsingle type supplies both a Person record and optional Contact details. You do\nnot need a second Contact note for the same person.\n\n## Start with a name\n\n```yaml\ntype: person\nname: Alex Rivera\n```\n\nOther notes refer to this person with an ordinary link to this note, such as\n`[[Alex Rivera]]` in a task's `assignees`. Links to this note appear in its\nbacklinks. Rename or move the note with a tool that updates references, as mdbase\nand Obsidian do, so those links stay current. Reusing a person's file name for\nsomebody else redirects existing links to the wrong person.\n\nThe name is your collection's display label. Full names, preferred names and\nsingle names are equally valid. There is no required first-name/last-name split.\n\n## Add only the contact details you need\n\nEmail, phone, organisation and birthday are optional. Omit unknown values rather\nthan filling them with empty strings or guesses. Store phone numbers as text,\nincluding an international prefix or extension when helpful. Birthday currently\nrequires a complete date; partial dates need a separately configured local field.\nKeep free-form context in the Markdown body and be deliberate about sensitive\npersonal information in shared collections.\n\nThis starter describes individuals. Existing organisation and group records can\ncontinue using their Contact-compatible type; setting someone's affiliation does\nnot turn their Person note into an organisation record.\n\n## Link accounts deliberately\n\nThe editor's **Link this record to me** action uses the authenticated account's\nactual issuer and subject. If configuring these manually, copy both exact values\nfrom the identity service. Do not guess them from an email, display name, or the\nserver hosting this collection. Multiple entries may represent the same person\nat different identity services. Omit `identities` when there is no account to link.\n\nAssociations are ordinary editable data, not authentication or proof of identity.\nLinking never invites someone, grants access, or changes collection membership.\nNever put credentials in a person record. Avoid linking the same account from\nseveral notes: applications should report ambiguity, not guess which\nrecord to use. Account deletion or recreation is not permission to reassign an\nold association automatically.\n\n## Keep the collection's own shape\n\nThe inline schema belongs to this collection. You may add local fields, or rename\nfields and update their explicit `implements` mappings. Apps use those mappings\nfor the Person and Contact contracts; they need not assume your local field names.\nAdditional fields remain part of the note but do not automatically become shared\ncontract fields. Do not edit published contracts to customise this type.\n\nInstalling a newer starter does not overwrite an existing customised type or\nmigrate your address book. Converting an existing individual Contact to Person\nshould be a reviewed edit of that one note, preserving its path, fields and body.\n" + } + ], + "provides": [ + { + "id": "mdbase.person", + "version": "2.0.0", + "digest": "sha256:f16c462a1fd422f44ed055002f8476ec53c164107647fec782aeb74adeab2f9d" + }, + { + "id": "mdbase.contact", + "version": "1.0.0", + "digest": "sha256:49cfe15403dfc741a693e89a2f4d2857de306f391d02cb03e67bfaf0aa1d6b0d" + } + ] +} diff --git a/public/contracts/packs/tasknotes.task/0.3.0-rc.13.json b/public/contracts/packs/tasknotes.task/0.3.0-rc.13.json new file mode 100644 index 0000000..9bdbdb7 --- /dev/null +++ b/public/contracts/packs/tasknotes.task/0.3.0-rc.13.json @@ -0,0 +1,64 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "tasknotes.task", + "version": "0.3.0-rc.13", + "name": "TaskNotes task type pack", + "description": "Portable TaskNotes tasks with person-ID assignments.", + "resources": [ + { + "kind": "contract", + "mode": "managed", + "source": "contracts/tasknotes.task/0.3.0-rc.4.md", + "target": "_contracts/tasknotes.task.md", + "digest": "sha256:91165b7664f936bba9289aca984e2638901db7fedf68642ab755e8d0b424e734" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/tasknotes-task/2.md", + "target": "_types/task.md", + "digest": "sha256:ade71117bd31e571f403511c48d432bab7a05dfd25e730ca2931f3afda7f7cd5" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/tasknotes.task/0.3.0-rc.4.schema.json", + "target": "_schemas/tasknotes/tasknotes-task.schema.json", + "digest": "sha256:2ea0d6b968ec2329e87ed60c2685d490e0f66f2bc7b3a23547d8fc55a7936fbe" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json", + "target": "_schemas/tasknotes/tasknotes-task-binding.schema.json", + "digest": "sha256:5b38e8a1c426b7f7fa92d8353fe35dd98e632305cbb15ffccde387473166b267" + } + ] + }, + "resources": [ + { + "source": "contracts/tasknotes.task/0.3.0-rc.4.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: tasknotes.task\nversion: 0.3.0-rc.4\nname: TaskNotes task\ndescription: Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.4.\nrecord_schema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n $id: https://tasknotes.dev/schemas/tasknotes-task.schema.json\n title: TaskNotes portable task view\n description: The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract.\n type: object\n required:\n - status\n - dateCreated\n additionalProperties: false\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n type: string\n minLength: 1\n priority:\n type: string\n minLength: 1\n due:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n assignees:\n type: array\n uniqueItems: true\n items:\n type: string\n minLength: 1\n pattern: \\S\n description: Stable mdbase.person IDs. These references never grant collection access.\n attachments:\n type: array\n uniqueItems: true\n items:\n type: string\n minLength: 1\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrenceAnchor:\n enum:\n - scheduled\n - completion\n recurrenceParent:\n type: string\n occurrenceDate:\n type: string\n format: date\n occurrenceMaterialization:\n enum:\n - manual\n - on_completion\n - rolling\n occurrenceNextTrigger:\n enum:\n - completion\n - completion_or_skip\n occurrenceTemplate:\n type: string\n occurrencePastHorizon:\n type: string\n occurrenceFutureHorizon:\n type: string\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n reminders:\n type: array\n items:\n type: object\n blockedBy:\n type: array\n items:\n type: object\n completeInstances:\n type: array\n items:\n type: string\n format: date\n skippedInstances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n sortOrder:\n type: string\nbinding_schema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n $id: https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json\n title: TaskNotes task data-contract binding\n description: Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.\n type: object\n required:\n - profiles\n - capabilities\n - title\n - status\n - priority\n - recurrence\n - occurrences\n - links\n - archive\n - time_tracking\n - templating\n properties:\n profiles:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n enum:\n - core-lite\n - recurrence\n - templating\n - materialized-occurrences\n - extended\n capabilities:\n type: array\n uniqueItems: true\n items:\n enum:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - rename\n - archive\n - batch\n - concurrency\n - dry-run\n - migration\n - templating\n title:\n $ref: \"#/$defs/titlePolicy\"\n status:\n $ref: \"#/$defs/statusPolicy\"\n priority:\n $ref: \"#/$defs/priorityPolicy\"\n recurrence:\n $ref: \"#/$defs/recurrencePolicy\"\n occurrences:\n $ref: \"#/$defs/occurrencePolicy\"\n links:\n $ref: \"#/$defs/linkPolicy\"\n archive:\n $ref: \"#/$defs/archivePolicy\"\n time_tracking:\n $ref: \"#/$defs/timeTrackingPolicy\"\n templating:\n $ref: \"#/$defs/templatingPolicy\"\n nlp:\n $ref: \"#/$defs/nlpPolicy\"\n additionalProperties: false\n $defs:\n nonEmptyString:\n type: string\n minLength: 1\n stringSet:\n type: array\n uniqueItems: true\n items:\n $ref: \"#/$defs/nonEmptyString\"\n titlePolicy:\n type: object\n required:\n - storage\n properties:\n storage:\n enum:\n - filename\n - frontmatter\n filename_format:\n enum:\n - title\n - zettel\n - timestamp\n - uuid\n - custom\n custom_filename_template:\n $ref: \"#/$defs/nonEmptyString\"\n allOf:\n - if:\n properties:\n filename_format:\n const: custom\n required:\n - filename_format\n then:\n properties:\n custom_filename_template:\n $ref: \"#/$defs/nonEmptyString\"\n required:\n - custom_filename_template\n additionalProperties: true\n statusDefinition:\n type: object\n required:\n - value\n - label\n - color\n - is_completed\n - is_skipped\n - exclude_from_cycle\n - order\n - auto_archive\n - auto_archive_delay_minutes\n properties:\n value:\n $ref: \"#/$defs/nonEmptyString\"\n label:\n type: string\n color:\n type: string\n icon:\n $ref: \"#/$defs/nonEmptyString\"\n is_completed:\n type: boolean\n is_skipped:\n type: boolean\n exclude_from_cycle:\n type: boolean\n next_status:\n $ref: \"#/$defs/nonEmptyString\"\n order:\n type: number\n auto_archive:\n type: boolean\n auto_archive_delay_minutes:\n type: number\n minimum: 0\n additionalProperties: true\n statusPolicy:\n type: object\n required:\n - values\n - default\n - completed_values\n - definitions\n properties:\n values:\n $ref: \"#/$defs/stringSet\"\n default:\n $ref: \"#/$defs/nonEmptyString\"\n completed_values:\n $ref: \"#/$defs/stringSet\"\n skipped_values:\n $ref: \"#/$defs/stringSet\"\n default_skipped:\n $ref: \"#/$defs/nonEmptyString\"\n definitions:\n type: array\n items:\n $ref: \"#/$defs/statusDefinition\"\n additionalProperties: false\n priorityDefinition:\n type: object\n required:\n - value\n - label\n - color\n - weight\n properties:\n value:\n $ref: \"#/$defs/nonEmptyString\"\n label:\n type: string\n color:\n type: string\n icon:\n $ref: \"#/$defs/nonEmptyString\"\n weight:\n type: number\n additionalProperties: true\n priorityPolicy:\n type: object\n required:\n - values\n - default\n - definitions\n properties:\n values:\n $ref: \"#/$defs/stringSet\"\n default:\n $ref: \"#/$defs/nonEmptyString\"\n definitions:\n type: array\n items:\n $ref: \"#/$defs/priorityDefinition\"\n additionalProperties: false\n recurrencePolicy:\n type: object\n required:\n - syntax\n - maintain_due_date_offset\n - reset_body_checkboxes\n properties:\n syntax:\n const: tasknotes\n maintain_due_date_offset:\n type: boolean\n reset_body_checkboxes:\n type: boolean\n additionalProperties: false\n occurrencePolicy:\n type: object\n required:\n - identity_roles\n - default_materialization\n - default_next_trigger\n properties:\n identity_roles:\n const:\n - recurrenceParent\n - occurrenceDate\n default_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default_next_trigger:\n enum:\n - completion\n - completion_or_skip\n past_horizon:\n $ref: \"#/$defs/nonEmptyString\"\n future_horizon:\n $ref: \"#/$defs/nonEmptyString\"\n additionalProperties: false\n linkPolicy:\n type: object\n required:\n - accepted_formats\n - write_format\n properties:\n accepted_formats:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n enum:\n - wikilink\n - markdown\n write_format:\n enum:\n - wikilink\n - markdown\n additionalProperties: false\n archivePolicy:\n type: object\n required:\n - archived_tag\n - move_on_archive\n properties:\n archived_tag:\n $ref: \"#/$defs/nonEmptyString\"\n move_on_archive:\n type: boolean\n folder:\n $ref: \"#/$defs/nonEmptyString\"\n additionalProperties: false\n timeTrackingPolicy:\n type: object\n required:\n - auto_stop_on_complete\n properties:\n auto_stop_on_complete:\n type: boolean\n additionalProperties: false\n templatingPolicy:\n type: object\n required:\n - enabled\n - occurrence_enabled\n properties:\n enabled:\n type: boolean\n template_path:\n $ref: \"#/$defs/nonEmptyString\"\n occurrence_enabled:\n type: boolean\n occurrence_template_path:\n $ref: \"#/$defs/nonEmptyString\"\n failure_mode:\n enum:\n - error\n - warning_fallback\n unknown_variable_policy:\n enum:\n - preserve\n - empty\n additionalProperties: false\n nlpTrigger:\n type: object\n required:\n - property_id\n - trigger\n - enabled\n properties:\n property_id:\n $ref: \"#/$defs/nonEmptyString\"\n trigger:\n $ref: \"#/$defs/nonEmptyString\"\n enabled:\n type: boolean\n additionalProperties: false\n nlpPolicy:\n type: object\n required:\n - triggers\n properties:\n triggers:\n type: array\n items:\n $ref: \"#/$defs/nlpTrigger\"\n additionalProperties: false\n---\n\n# TaskNotes task contract\n\nTypes implement this contract through `implements`; applications consume\nthe normalized contract view rather than assuming frontmatter names.\n" + }, + { + "source": "types/tasknotes-task/2.md", + "document": "---\nkind: mdbase.type\nname: task\nversion: 2\ndescription: A task managed by TaskNotes.\nmatch:\n where:\n tags:\n contains: task\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n type: object\n additionalProperties: true\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n enum: &a1\n - none\n - open\n - in-progress\n - done\n default: open\n priority:\n enum: &a3\n - none\n - low\n - normal\n - high\n default: normal\n due:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n assignees:\n type: array\n items:\n type: string\n minLength: 1\n pattern: \\S\n uniqueItems: true\n attachments:\n type: array\n items:\n type: string\n minLength: 1\n uniqueItems: true\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrence_anchor:\n enum:\n - scheduled\n - completion\n default: scheduled\n occurrence_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default: manual\n occurrence_next_trigger:\n enum:\n - completion\n - completion_or_skip\n default: completion\n occurrence_template:\n type: string\n occurrence_past_horizon:\n type: string\n occurrence_future_horizon:\n type: string\n recurrence_parent:\n type: string\n occurrence_date:\n type: string\n format: date\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n startTime:\n type: string\n format: date-time\n endTime:\n type: string\n format: date-time\n description:\n type: string\n duration:\n type: integer\n reminders:\n type: array\n items:\n oneOf:\n - type: object\n required:\n - id\n - type\n - absoluteTime\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: absolute\n description:\n type: string\n absoluteTime:\n type: string\n format: date-time\n - type: object\n required:\n - id\n - type\n - relatedTo\n - offset\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: relative\n description:\n type: string\n relatedTo:\n enum:\n - due\n - scheduled\n offset:\n type: string\n blockedBy:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n uid:\n type: string\n reltype:\n type: string\n gap:\n type: string\n required:\n - uid\n complete_instances:\n type: array\n items:\n type: string\n format: date\n skipped_instances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n tasknotes_manual_order:\n type: string\n allOf:\n - if:\n required:\n - status\n properties:\n status:\n enum: &a2\n - done\n not:\n required:\n - recurrence\n then:\n required:\n - completedDate\n required:\n - title\n - status\n - dateCreated\ncollection:\n read_defaults:\n status: open\n priority: normal\n recurrence_anchor: scheduled\n occurrence_materialization: manual\n occurrence_next_trigger: completion\n links:\n projects[]:\n target_type: any\n validate_exists: false\n attachments[]:\n validate_exists: false\n occurrence_template:\n target_type: any\n validate_exists: false\n recurrence_parent:\n target_type: task\n validate_exists: false\n blockedBy[].uid:\n target_type: task\n validate_exists: false\n path:\n runtime: tasknotes\n template: \"{{zettel}}\"\n folder: tasks\n generated_by: tasknotes.filename.create\n display:\n name_field: title\n unique:\n - field: id\n scope: type\nlifecycle:\n on_create:\n set:\n id:\n uuid: true\n dateCreated:\n now: true\n dateModified:\n now: true\n on_update:\n set:\n dateModified:\n now: true\nimplements:\n - contract: tasknotes.task\n version: 0.3.0-rc.4\n fields:\n id: id\n title: title\n status: status\n priority: priority\n due: due\n scheduled: scheduled\n contexts: contexts\n projects: projects\n assignees: assignees\n attachments: attachments\n timeEstimate: timeEstimate\n completedDate: completedDate\n dateCreated: dateCreated\n dateModified: dateModified\n recurrence: recurrence\n recurrenceAnchor: recurrence_anchor\n occurrenceMaterialization: occurrence_materialization\n occurrenceNextTrigger: occurrence_next_trigger\n occurrenceTemplate: occurrence_template\n occurrencePastHorizon: occurrence_past_horizon\n occurrenceFutureHorizon: occurrence_future_horizon\n recurrenceParent: recurrence_parent\n occurrenceDate: occurrence_date\n tags: tags\n timeEntries: timeEntries\n reminders: reminders\n blockedBy: blockedBy\n completeInstances: complete_instances\n skippedInstances: skipped_instances\n icsEventId: icsEventId\n googleCalendarEventId: googleCalendarEventId\n googleCalendarExceptionEventId: googleCalendarExceptionEventId\n googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled\n googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates\n sortOrder: tasknotes_manual_order\n binding:\n profiles:\n - core-lite\n - recurrence\n - templating\n - materialized-occurrences\n - extended\n capabilities:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - archive\n - templating\n title:\n storage: frontmatter\n filename_format: zettel\n status:\n values: *a1\n default: open\n completed_values: *a2\n skipped_values: []\n definitions:\n - value: none\n label: None\n color: \"#cccccc\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 0\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: open\n label: Open\n color: \"#808080\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 1\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: in-progress\n label: In progress\n color: \"#0066cc\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 2\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: done\n label: Done\n color: \"#00aa00\"\n is_completed: true\n is_skipped: false\n exclude_from_cycle: false\n order: 3\n auto_archive: false\n auto_archive_delay_minutes: 5\n priority:\n values: *a3\n default: normal\n definitions:\n - value: none\n label: None\n color: \"#cccccc\"\n weight: 0\n - value: low\n label: Low\n color: \"#00aa00\"\n weight: 1\n - value: normal\n label: Normal\n color: \"#ffaa00\"\n weight: 2\n - value: high\n label: High\n color: \"#ff0000\"\n weight: 3\n recurrence:\n syntax: tasknotes\n maintain_due_date_offset: true\n reset_body_checkboxes: false\n occurrences:\n identity_roles:\n - recurrenceParent\n - occurrenceDate\n default_materialization: manual\n default_next_trigger: completion\n past_horizon: P0D\n future_horizon: P14D\n links:\n accepted_formats:\n - wikilink\n - markdown\n write_format: wikilink\n archive:\n archived_tag: archived\n move_on_archive: false\n time_tracking:\n auto_stop_on_complete: false\n templating:\n enabled: false\n occurrence_enabled: false\nx-tasknotes-generator:\n managed_fields:\n - assignees\n - attachments\n - blockedBy\n - complete_instances\n - completedDate\n - contexts\n - dateCreated\n - dateModified\n - due\n - googleCalendarEventId\n - googleCalendarExceptionEventId\n - googleCalendarExceptionOriginalScheduled\n - googleCalendarMovedOriginalDates\n - icsEventId\n - id\n - occurrence_date\n - occurrence_future_horizon\n - occurrence_materialization\n - occurrence_next_trigger\n - occurrence_past_horizon\n - occurrence_template\n - priority\n - projects\n - recurrence\n - recurrence_anchor\n - recurrence_parent\n - reminders\n - scheduled\n - skipped_instances\n - status\n - tags\n - tasknotes_manual_order\n - timeEntries\n - timeEstimate\n - title\n---\n\n# Task\n\nThis type definition implements the TaskNotes contract for this mdbase collection.\nIts JSON Schema describes persisted task frontmatter; collection and lifecycle\nmetadata describe generic mdbase behavior; `implements` maps the portable\nTaskNotes task view and supplies TaskNotes behavior.\n\nChanges made here are loaded by TaskNotes. Portable changes made in TaskNotes\nsettings are written back while unknown extensions are preserved.\n" + }, + { + "source": "schemas/tasknotes.task/0.3.0-rc.4.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://tasknotes.dev/schemas/tasknotes-task.schema.json\",\n \"title\": \"TaskNotes portable task view\",\n \"description\": \"The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract.\",\n \"type\": \"object\",\n \"required\": [\n \"status\",\n \"dateCreated\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"status\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"priority\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"due\": {\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n ]\n },\n \"scheduled\": {\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n ]\n },\n \"contexts\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"projects\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"assignees\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"\\\\S\"\n },\n \"description\": \"Stable mdbase.person IDs. These references never grant collection access.\"\n },\n \"attachments\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1\n }\n },\n \"timeEstimate\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"completedDate\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"dateCreated\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"dateModified\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"recurrence\": {\n \"type\": \"string\"\n },\n \"recurrenceAnchor\": {\n \"enum\": [\n \"scheduled\",\n \"completion\"\n ]\n },\n \"recurrenceParent\": {\n \"type\": \"string\"\n },\n \"occurrenceDate\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"occurrenceMaterialization\": {\n \"enum\": [\n \"manual\",\n \"on_completion\",\n \"rolling\"\n ]\n },\n \"occurrenceNextTrigger\": {\n \"enum\": [\n \"completion\",\n \"completion_or_skip\"\n ]\n },\n \"occurrenceTemplate\": {\n \"type\": \"string\"\n },\n \"occurrencePastHorizon\": {\n \"type\": \"string\"\n },\n \"occurrenceFutureHorizon\": {\n \"type\": \"string\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"timeEntries\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"reminders\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"blockedBy\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"completeInstances\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"skippedInstances\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"icsEventId\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"googleCalendarEventId\": {\n \"type\": \"string\"\n },\n \"googleCalendarExceptionEventId\": {\n \"type\": \"string\"\n },\n \"googleCalendarExceptionOriginalScheduled\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"googleCalendarMovedOriginalDates\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"sortOrder\": {\n \"type\": \"string\"\n }\n }\n}\n" + }, + { + "source": "schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json\",\n \"title\": \"TaskNotes task data-contract binding\",\n \"description\": \"Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.\",\n \"type\": \"object\",\n \"required\": [\n \"profiles\",\n \"capabilities\",\n \"title\",\n \"status\",\n \"priority\",\n \"recurrence\",\n \"occurrences\",\n \"links\",\n \"archive\",\n \"time_tracking\",\n \"templating\"\n ],\n \"properties\": {\n \"profiles\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"core-lite\",\n \"recurrence\",\n \"templating\",\n \"materialized-occurrences\",\n \"extended\"\n ]\n }\n },\n \"capabilities\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"dependencies\",\n \"reminders\",\n \"attachments\",\n \"links\",\n \"time-tracking\",\n \"materialized-occurrences\",\n \"rename\",\n \"archive\",\n \"batch\",\n \"concurrency\",\n \"dry-run\",\n \"migration\",\n \"templating\"\n ]\n }\n },\n \"title\": {\n \"$ref\": \"#/$defs/titlePolicy\"\n },\n \"status\": {\n \"$ref\": \"#/$defs/statusPolicy\"\n },\n \"priority\": {\n \"$ref\": \"#/$defs/priorityPolicy\"\n },\n \"recurrence\": {\n \"$ref\": \"#/$defs/recurrencePolicy\"\n },\n \"occurrences\": {\n \"$ref\": \"#/$defs/occurrencePolicy\"\n },\n \"links\": {\n \"$ref\": \"#/$defs/linkPolicy\"\n },\n \"archive\": {\n \"$ref\": \"#/$defs/archivePolicy\"\n },\n \"time_tracking\": {\n \"$ref\": \"#/$defs/timeTrackingPolicy\"\n },\n \"templating\": {\n \"$ref\": \"#/$defs/templatingPolicy\"\n },\n \"nlp\": {\n \"$ref\": \"#/$defs/nlpPolicy\"\n }\n },\n \"additionalProperties\": false,\n \"$defs\": {\n \"nonEmptyString\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"stringSet\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"titlePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"storage\"\n ],\n \"properties\": {\n \"storage\": {\n \"enum\": [\n \"filename\",\n \"frontmatter\"\n ]\n },\n \"filename_format\": {\n \"enum\": [\n \"title\",\n \"zettel\",\n \"timestamp\",\n \"uuid\",\n \"custom\"\n ]\n },\n \"custom_filename_template\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"allOf\": [\n {\n \"if\": {\n \"properties\": {\n \"filename_format\": {\n \"const\": \"custom\"\n }\n },\n \"required\": [\n \"filename_format\"\n ]\n },\n \"then\": {\n \"properties\": {\n \"custom_filename_template\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"required\": [\n \"custom_filename_template\"\n ]\n }\n }\n ],\n \"additionalProperties\": true\n },\n \"statusDefinition\": {\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"label\",\n \"color\",\n \"is_completed\",\n \"is_skipped\",\n \"exclude_from_cycle\",\n \"order\",\n \"auto_archive\",\n \"auto_archive_delay_minutes\"\n ],\n \"properties\": {\n \"value\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"label\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"is_completed\": {\n \"type\": \"boolean\"\n },\n \"is_skipped\": {\n \"type\": \"boolean\"\n },\n \"exclude_from_cycle\": {\n \"type\": \"boolean\"\n },\n \"next_status\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"order\": {\n \"type\": \"number\"\n },\n \"auto_archive\": {\n \"type\": \"boolean\"\n },\n \"auto_archive_delay_minutes\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"additionalProperties\": true\n },\n \"statusPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"values\",\n \"default\",\n \"completed_values\",\n \"definitions\"\n ],\n \"properties\": {\n \"values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"completed_values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"skipped_values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default_skipped\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"definitions\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/statusDefinition\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"priorityDefinition\": {\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"label\",\n \"color\",\n \"weight\"\n ],\n \"properties\": {\n \"value\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"label\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"weight\": {\n \"type\": \"number\"\n }\n },\n \"additionalProperties\": true\n },\n \"priorityPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"values\",\n \"default\",\n \"definitions\"\n ],\n \"properties\": {\n \"values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"definitions\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/priorityDefinition\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"recurrencePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"syntax\",\n \"maintain_due_date_offset\",\n \"reset_body_checkboxes\"\n ],\n \"properties\": {\n \"syntax\": {\n \"const\": \"tasknotes\"\n },\n \"maintain_due_date_offset\": {\n \"type\": \"boolean\"\n },\n \"reset_body_checkboxes\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"occurrencePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"identity_roles\",\n \"default_materialization\",\n \"default_next_trigger\"\n ],\n \"properties\": {\n \"identity_roles\": {\n \"const\": [\n \"recurrenceParent\",\n \"occurrenceDate\"\n ]\n },\n \"default_materialization\": {\n \"enum\": [\n \"manual\",\n \"on_completion\",\n \"rolling\"\n ]\n },\n \"default_next_trigger\": {\n \"enum\": [\n \"completion\",\n \"completion_or_skip\"\n ]\n },\n \"past_horizon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"future_horizon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"additionalProperties\": false\n },\n \"linkPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"accepted_formats\",\n \"write_format\"\n ],\n \"properties\": {\n \"accepted_formats\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"wikilink\",\n \"markdown\"\n ]\n }\n },\n \"write_format\": {\n \"enum\": [\n \"wikilink\",\n \"markdown\"\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"archivePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"archived_tag\",\n \"move_on_archive\"\n ],\n \"properties\": {\n \"archived_tag\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"move_on_archive\": {\n \"type\": \"boolean\"\n },\n \"folder\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"additionalProperties\": false\n },\n \"timeTrackingPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"auto_stop_on_complete\"\n ],\n \"properties\": {\n \"auto_stop_on_complete\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"templatingPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\",\n \"occurrence_enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n },\n \"template_path\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"occurrence_enabled\": {\n \"type\": \"boolean\"\n },\n \"occurrence_template_path\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"failure_mode\": {\n \"enum\": [\n \"error\",\n \"warning_fallback\"\n ]\n },\n \"unknown_variable_policy\": {\n \"enum\": [\n \"preserve\",\n \"empty\"\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"nlpTrigger\": {\n \"type\": \"object\",\n \"required\": [\n \"property_id\",\n \"trigger\",\n \"enabled\"\n ],\n \"properties\": {\n \"property_id\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"trigger\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"enabled\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"nlpPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"triggers\"\n ],\n \"properties\": {\n \"triggers\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/nlpTrigger\"\n }\n }\n },\n \"additionalProperties\": false\n }\n }\n}\n" + } + ], + "provides": [ + { + "id": "tasknotes.task", + "version": "0.3.0-rc.4", + "digest": "sha256:6948f659df6af05ef95aa893f1d57849032546e8c6cfee8afd5afe566e4ceeb0" + } + ] +} diff --git a/public/contracts/packs/tasknotes.task/0.3.0-rc.14.json b/public/contracts/packs/tasknotes.task/0.3.0-rc.14.json new file mode 100644 index 0000000..4e7e126 --- /dev/null +++ b/public/contracts/packs/tasknotes.task/0.3.0-rc.14.json @@ -0,0 +1,68 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "tasknotes.task", + "version": "0.3.0-rc.14", + "name": "TaskNotes task type pack", + "description": "Portable tasks with a reviewed, atomic assignment upgrade.", + "resources": [ + { + "kind": "contract", + "mode": "managed", + "source": "contracts/tasknotes.task/0.3.0-rc.4.md", + "target": "_contracts/tasknotes.task.md", + "digest": "sha256:91165b7664f936bba9289aca984e2638901db7fedf68642ab755e8d0b424e734" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/tasknotes-task/2.md", + "target": "_types/task.md", + "digest": "sha256:ade71117bd31e571f403511c48d432bab7a05dfd25e730ca2931f3afda7f7cd5", + "upgrade_from": { + "digest": "sha256:b7f8af7b18d77859dab1f1532c1b55c08c7c39879f55e4ef2a94cb7d2d2284eb", + "document": "---\nkind: mdbase.type\nname: task\nversion: 1\ndescription: A task managed by TaskNotes.\nmatch:\n where:\n tags:\n contains: task\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n type: object\n additionalProperties: true\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n enum: &a2\n - none\n - open\n - in-progress\n - done\n - cancelled\n default: open\n priority:\n enum: &a4\n - none\n - low\n - normal\n - high\n default: normal\n due: &a1\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled: *a1\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n attachments:\n type: array\n items:\n type: string\n minLength: 1\n uniqueItems: true\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrence_anchor:\n enum:\n - scheduled\n - completion\n default: scheduled\n occurrence_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default: manual\n occurrence_next_trigger:\n enum:\n - completion\n - completion_or_skip\n default: completion\n occurrence_template:\n type: string\n occurrence_past_horizon:\n type: string\n occurrence_future_horizon:\n type: string\n recurrence_parent:\n type: string\n occurrence_date:\n type: string\n format: date\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n startTime:\n type: string\n format: date-time\n endTime:\n type: string\n format: date-time\n description:\n type: string\n duration:\n type: integer\n reminders:\n type: array\n items:\n oneOf:\n - type: object\n required:\n - id\n - type\n - absoluteTime\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: absolute\n description:\n type: string\n absoluteTime:\n type: string\n format: date-time\n - type: object\n required:\n - id\n - type\n - relatedTo\n - offset\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: relative\n description:\n type: string\n relatedTo:\n enum:\n - due\n - scheduled\n offset:\n type: string\n blockedBy:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n uid:\n type: string\n reltype:\n type: string\n gap:\n type: string\n required:\n - uid\n complete_instances:\n type: array\n items:\n type: string\n format: date\n skipped_instances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n tasknotes_manual_order:\n type: string\n allOf:\n - if:\n required:\n - status\n properties:\n status:\n enum: &a3\n - done\n not:\n required:\n - recurrence\n then:\n required:\n - completedDate\n required:\n - title\n - status\n - dateCreated\ncollection:\n read_defaults:\n status: open\n priority: normal\n recurrence_anchor: scheduled\n occurrence_materialization: manual\n occurrence_next_trigger: completion\n links:\n projects[]:\n target_type: any\n validate_exists: false\n attachments[]:\n validate_exists: false\n occurrence_template:\n target_type: any\n validate_exists: false\n recurrence_parent:\n target_type: task\n validate_exists: false\n blockedBy[].uid:\n target_type: task\n validate_exists: false\n path:\n runtime: tasknotes\n template: \"{{zettel}}\"\n folder: tasks\n generated_by: tasknotes.filename.create\n display:\n name_field: title\n unique:\n - field: id\n scope: type\nlifecycle:\n on_create:\n set:\n id:\n uuid: true\n dateCreated:\n now: true\n dateModified:\n now: true\n on_update:\n set:\n dateModified:\n now: true\nimplements:\n - contract: tasknotes.task\n version: 0.3.0-rc.3\n fields:\n id: id\n title: title\n status: status\n priority: priority\n due: due\n scheduled: scheduled\n contexts: contexts\n projects: projects\n attachments: attachments\n timeEstimate: timeEstimate\n completedDate: completedDate\n dateCreated: dateCreated\n dateModified: dateModified\n recurrence: recurrence\n recurrenceAnchor: recurrence_anchor\n occurrenceMaterialization: occurrence_materialization\n occurrenceNextTrigger: occurrence_next_trigger\n occurrenceTemplate: occurrence_template\n occurrencePastHorizon: occurrence_past_horizon\n occurrenceFutureHorizon: occurrence_future_horizon\n recurrenceParent: recurrence_parent\n occurrenceDate: occurrence_date\n tags: tags\n timeEntries: timeEntries\n reminders: reminders\n blockedBy: blockedBy\n completeInstances: complete_instances\n skippedInstances: skipped_instances\n icsEventId: icsEventId\n googleCalendarEventId: googleCalendarEventId\n googleCalendarExceptionEventId: googleCalendarExceptionEventId\n googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled\n googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates\n sortOrder: tasknotes_manual_order\n binding:\n profiles:\n - core-lite\n - recurrence\n - materialized-occurrences\n capabilities:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - archive\n - templating\n title:\n storage: frontmatter\n filename_format: zettel\n status:\n values: *a2\n default: open\n completed_values: *a3\n skipped_values:\n - cancelled\n default_skipped: cancelled\n definitions:\n - value: none\n label: None\n color: \"#94a3b8\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 0\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: open\n label: Open\n color: \"#64748b\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 1\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: in-progress\n label: In progress\n color: \"#3b82f6\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 2\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: done\n label: Done\n color: \"#22c55e\"\n is_completed: true\n is_skipped: false\n exclude_from_cycle: false\n order: 3\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: cancelled\n label: Cancelled\n color: \"#94a3b8\"\n is_completed: false\n is_skipped: true\n exclude_from_cycle: true\n order: 4\n auto_archive: false\n auto_archive_delay_minutes: 5\n priority:\n values: *a4\n default: normal\n definitions:\n - value: none\n label: None\n color: \"#94a3b8\"\n weight: 0\n - value: low\n label: Low\n color: \"#3b82f6\"\n weight: 1\n - value: normal\n label: Normal\n color: \"#f59e0b\"\n weight: 2\n - value: high\n label: High\n color: \"#ef4444\"\n weight: 3\n recurrence:\n syntax: tasknotes\n maintain_due_date_offset: true\n reset_body_checkboxes: false\n occurrences:\n identity_roles:\n - recurrenceParent\n - occurrenceDate\n default_materialization: manual\n default_next_trigger: completion\n past_horizon: P0D\n future_horizon: P14D\n links:\n accepted_formats:\n - wikilink\n - markdown\n write_format: wikilink\n archive:\n archived_tag: archived\n move_on_archive: false\n time_tracking:\n auto_stop_on_complete: false\n templating:\n enabled: false\n occurrence_enabled: false\nx-tasknotes-generator:\n managed_fields:\n - attachments\n - blockedBy\n - complete_instances\n - completedDate\n - contexts\n - dateCreated\n - dateModified\n - due\n - googleCalendarEventId\n - googleCalendarExceptionEventId\n - googleCalendarExceptionOriginalScheduled\n - googleCalendarMovedOriginalDates\n - icsEventId\n - id\n - occurrence_date\n - occurrence_future_horizon\n - occurrence_materialization\n - occurrence_next_trigger\n - occurrence_past_horizon\n - occurrence_template\n - priority\n - projects\n - recurrence\n - recurrence_anchor\n - recurrence_parent\n - reminders\n - scheduled\n - skipped_instances\n - status\n - tags\n - tasknotes_manual_order\n - timeEntries\n - timeEstimate\n - title\n---\n# Task\n\nTask records live under `tasks/`.\n" + } + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/tasknotes.task/0.3.0-rc.4.schema.json", + "target": "_schemas/tasknotes/tasknotes-task.schema.json", + "digest": "sha256:2ea0d6b968ec2329e87ed60c2685d490e0f66f2bc7b3a23547d8fc55a7936fbe" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json", + "target": "_schemas/tasknotes/tasknotes-task-binding.schema.json", + "digest": "sha256:5b38e8a1c426b7f7fa92d8353fe35dd98e632305cbb15ffccde387473166b267" + } + ] + }, + "resources": [ + { + "source": "contracts/tasknotes.task/0.3.0-rc.4.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: tasknotes.task\nversion: 0.3.0-rc.4\nname: TaskNotes task\ndescription: Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.4.\nrecord_schema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n $id: https://tasknotes.dev/schemas/tasknotes-task.schema.json\n title: TaskNotes portable task view\n description: The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract.\n type: object\n required:\n - status\n - dateCreated\n additionalProperties: false\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n type: string\n minLength: 1\n priority:\n type: string\n minLength: 1\n due:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n assignees:\n type: array\n uniqueItems: true\n items:\n type: string\n minLength: 1\n pattern: \\S\n description: Stable mdbase.person IDs. These references never grant collection access.\n attachments:\n type: array\n uniqueItems: true\n items:\n type: string\n minLength: 1\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrenceAnchor:\n enum:\n - scheduled\n - completion\n recurrenceParent:\n type: string\n occurrenceDate:\n type: string\n format: date\n occurrenceMaterialization:\n enum:\n - manual\n - on_completion\n - rolling\n occurrenceNextTrigger:\n enum:\n - completion\n - completion_or_skip\n occurrenceTemplate:\n type: string\n occurrencePastHorizon:\n type: string\n occurrenceFutureHorizon:\n type: string\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n reminders:\n type: array\n items:\n type: object\n blockedBy:\n type: array\n items:\n type: object\n completeInstances:\n type: array\n items:\n type: string\n format: date\n skippedInstances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n sortOrder:\n type: string\nbinding_schema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n $id: https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json\n title: TaskNotes task data-contract binding\n description: Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.\n type: object\n required:\n - profiles\n - capabilities\n - title\n - status\n - priority\n - recurrence\n - occurrences\n - links\n - archive\n - time_tracking\n - templating\n properties:\n profiles:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n enum:\n - core-lite\n - recurrence\n - templating\n - materialized-occurrences\n - extended\n capabilities:\n type: array\n uniqueItems: true\n items:\n enum:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - rename\n - archive\n - batch\n - concurrency\n - dry-run\n - migration\n - templating\n title:\n $ref: \"#/$defs/titlePolicy\"\n status:\n $ref: \"#/$defs/statusPolicy\"\n priority:\n $ref: \"#/$defs/priorityPolicy\"\n recurrence:\n $ref: \"#/$defs/recurrencePolicy\"\n occurrences:\n $ref: \"#/$defs/occurrencePolicy\"\n links:\n $ref: \"#/$defs/linkPolicy\"\n archive:\n $ref: \"#/$defs/archivePolicy\"\n time_tracking:\n $ref: \"#/$defs/timeTrackingPolicy\"\n templating:\n $ref: \"#/$defs/templatingPolicy\"\n nlp:\n $ref: \"#/$defs/nlpPolicy\"\n additionalProperties: false\n $defs:\n nonEmptyString:\n type: string\n minLength: 1\n stringSet:\n type: array\n uniqueItems: true\n items:\n $ref: \"#/$defs/nonEmptyString\"\n titlePolicy:\n type: object\n required:\n - storage\n properties:\n storage:\n enum:\n - filename\n - frontmatter\n filename_format:\n enum:\n - title\n - zettel\n - timestamp\n - uuid\n - custom\n custom_filename_template:\n $ref: \"#/$defs/nonEmptyString\"\n allOf:\n - if:\n properties:\n filename_format:\n const: custom\n required:\n - filename_format\n then:\n properties:\n custom_filename_template:\n $ref: \"#/$defs/nonEmptyString\"\n required:\n - custom_filename_template\n additionalProperties: true\n statusDefinition:\n type: object\n required:\n - value\n - label\n - color\n - is_completed\n - is_skipped\n - exclude_from_cycle\n - order\n - auto_archive\n - auto_archive_delay_minutes\n properties:\n value:\n $ref: \"#/$defs/nonEmptyString\"\n label:\n type: string\n color:\n type: string\n icon:\n $ref: \"#/$defs/nonEmptyString\"\n is_completed:\n type: boolean\n is_skipped:\n type: boolean\n exclude_from_cycle:\n type: boolean\n next_status:\n $ref: \"#/$defs/nonEmptyString\"\n order:\n type: number\n auto_archive:\n type: boolean\n auto_archive_delay_minutes:\n type: number\n minimum: 0\n additionalProperties: true\n statusPolicy:\n type: object\n required:\n - values\n - default\n - completed_values\n - definitions\n properties:\n values:\n $ref: \"#/$defs/stringSet\"\n default:\n $ref: \"#/$defs/nonEmptyString\"\n completed_values:\n $ref: \"#/$defs/stringSet\"\n skipped_values:\n $ref: \"#/$defs/stringSet\"\n default_skipped:\n $ref: \"#/$defs/nonEmptyString\"\n definitions:\n type: array\n items:\n $ref: \"#/$defs/statusDefinition\"\n additionalProperties: false\n priorityDefinition:\n type: object\n required:\n - value\n - label\n - color\n - weight\n properties:\n value:\n $ref: \"#/$defs/nonEmptyString\"\n label:\n type: string\n color:\n type: string\n icon:\n $ref: \"#/$defs/nonEmptyString\"\n weight:\n type: number\n additionalProperties: true\n priorityPolicy:\n type: object\n required:\n - values\n - default\n - definitions\n properties:\n values:\n $ref: \"#/$defs/stringSet\"\n default:\n $ref: \"#/$defs/nonEmptyString\"\n definitions:\n type: array\n items:\n $ref: \"#/$defs/priorityDefinition\"\n additionalProperties: false\n recurrencePolicy:\n type: object\n required:\n - syntax\n - maintain_due_date_offset\n - reset_body_checkboxes\n properties:\n syntax:\n const: tasknotes\n maintain_due_date_offset:\n type: boolean\n reset_body_checkboxes:\n type: boolean\n additionalProperties: false\n occurrencePolicy:\n type: object\n required:\n - identity_roles\n - default_materialization\n - default_next_trigger\n properties:\n identity_roles:\n const:\n - recurrenceParent\n - occurrenceDate\n default_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default_next_trigger:\n enum:\n - completion\n - completion_or_skip\n past_horizon:\n $ref: \"#/$defs/nonEmptyString\"\n future_horizon:\n $ref: \"#/$defs/nonEmptyString\"\n additionalProperties: false\n linkPolicy:\n type: object\n required:\n - accepted_formats\n - write_format\n properties:\n accepted_formats:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n enum:\n - wikilink\n - markdown\n write_format:\n enum:\n - wikilink\n - markdown\n additionalProperties: false\n archivePolicy:\n type: object\n required:\n - archived_tag\n - move_on_archive\n properties:\n archived_tag:\n $ref: \"#/$defs/nonEmptyString\"\n move_on_archive:\n type: boolean\n folder:\n $ref: \"#/$defs/nonEmptyString\"\n additionalProperties: false\n timeTrackingPolicy:\n type: object\n required:\n - auto_stop_on_complete\n properties:\n auto_stop_on_complete:\n type: boolean\n additionalProperties: false\n templatingPolicy:\n type: object\n required:\n - enabled\n - occurrence_enabled\n properties:\n enabled:\n type: boolean\n template_path:\n $ref: \"#/$defs/nonEmptyString\"\n occurrence_enabled:\n type: boolean\n occurrence_template_path:\n $ref: \"#/$defs/nonEmptyString\"\n failure_mode:\n enum:\n - error\n - warning_fallback\n unknown_variable_policy:\n enum:\n - preserve\n - empty\n additionalProperties: false\n nlpTrigger:\n type: object\n required:\n - property_id\n - trigger\n - enabled\n properties:\n property_id:\n $ref: \"#/$defs/nonEmptyString\"\n trigger:\n $ref: \"#/$defs/nonEmptyString\"\n enabled:\n type: boolean\n additionalProperties: false\n nlpPolicy:\n type: object\n required:\n - triggers\n properties:\n triggers:\n type: array\n items:\n $ref: \"#/$defs/nlpTrigger\"\n additionalProperties: false\n---\n\n# TaskNotes task contract\n\nTypes implement this contract through `implements`; applications consume\nthe normalized contract view rather than assuming frontmatter names.\n" + }, + { + "source": "types/tasknotes-task/2.md", + "document": "---\nkind: mdbase.type\nname: task\nversion: 2\ndescription: A task managed by TaskNotes.\nmatch:\n where:\n tags:\n contains: task\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n type: object\n additionalProperties: true\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n enum: &a1\n - none\n - open\n - in-progress\n - done\n default: open\n priority:\n enum: &a3\n - none\n - low\n - normal\n - high\n default: normal\n due:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n assignees:\n type: array\n items:\n type: string\n minLength: 1\n pattern: \\S\n uniqueItems: true\n attachments:\n type: array\n items:\n type: string\n minLength: 1\n uniqueItems: true\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrence_anchor:\n enum:\n - scheduled\n - completion\n default: scheduled\n occurrence_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default: manual\n occurrence_next_trigger:\n enum:\n - completion\n - completion_or_skip\n default: completion\n occurrence_template:\n type: string\n occurrence_past_horizon:\n type: string\n occurrence_future_horizon:\n type: string\n recurrence_parent:\n type: string\n occurrence_date:\n type: string\n format: date\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n startTime:\n type: string\n format: date-time\n endTime:\n type: string\n format: date-time\n description:\n type: string\n duration:\n type: integer\n reminders:\n type: array\n items:\n oneOf:\n - type: object\n required:\n - id\n - type\n - absoluteTime\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: absolute\n description:\n type: string\n absoluteTime:\n type: string\n format: date-time\n - type: object\n required:\n - id\n - type\n - relatedTo\n - offset\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: relative\n description:\n type: string\n relatedTo:\n enum:\n - due\n - scheduled\n offset:\n type: string\n blockedBy:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n uid:\n type: string\n reltype:\n type: string\n gap:\n type: string\n required:\n - uid\n complete_instances:\n type: array\n items:\n type: string\n format: date\n skipped_instances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n tasknotes_manual_order:\n type: string\n allOf:\n - if:\n required:\n - status\n properties:\n status:\n enum: &a2\n - done\n not:\n required:\n - recurrence\n then:\n required:\n - completedDate\n required:\n - title\n - status\n - dateCreated\ncollection:\n read_defaults:\n status: open\n priority: normal\n recurrence_anchor: scheduled\n occurrence_materialization: manual\n occurrence_next_trigger: completion\n links:\n projects[]:\n target_type: any\n validate_exists: false\n attachments[]:\n validate_exists: false\n occurrence_template:\n target_type: any\n validate_exists: false\n recurrence_parent:\n target_type: task\n validate_exists: false\n blockedBy[].uid:\n target_type: task\n validate_exists: false\n path:\n runtime: tasknotes\n template: \"{{zettel}}\"\n folder: tasks\n generated_by: tasknotes.filename.create\n display:\n name_field: title\n unique:\n - field: id\n scope: type\nlifecycle:\n on_create:\n set:\n id:\n uuid: true\n dateCreated:\n now: true\n dateModified:\n now: true\n on_update:\n set:\n dateModified:\n now: true\nimplements:\n - contract: tasknotes.task\n version: 0.3.0-rc.4\n fields:\n id: id\n title: title\n status: status\n priority: priority\n due: due\n scheduled: scheduled\n contexts: contexts\n projects: projects\n assignees: assignees\n attachments: attachments\n timeEstimate: timeEstimate\n completedDate: completedDate\n dateCreated: dateCreated\n dateModified: dateModified\n recurrence: recurrence\n recurrenceAnchor: recurrence_anchor\n occurrenceMaterialization: occurrence_materialization\n occurrenceNextTrigger: occurrence_next_trigger\n occurrenceTemplate: occurrence_template\n occurrencePastHorizon: occurrence_past_horizon\n occurrenceFutureHorizon: occurrence_future_horizon\n recurrenceParent: recurrence_parent\n occurrenceDate: occurrence_date\n tags: tags\n timeEntries: timeEntries\n reminders: reminders\n blockedBy: blockedBy\n completeInstances: complete_instances\n skippedInstances: skipped_instances\n icsEventId: icsEventId\n googleCalendarEventId: googleCalendarEventId\n googleCalendarExceptionEventId: googleCalendarExceptionEventId\n googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled\n googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates\n sortOrder: tasknotes_manual_order\n binding:\n profiles:\n - core-lite\n - recurrence\n - templating\n - materialized-occurrences\n - extended\n capabilities:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - archive\n - templating\n title:\n storage: frontmatter\n filename_format: zettel\n status:\n values: *a1\n default: open\n completed_values: *a2\n skipped_values: []\n definitions:\n - value: none\n label: None\n color: \"#cccccc\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 0\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: open\n label: Open\n color: \"#808080\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 1\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: in-progress\n label: In progress\n color: \"#0066cc\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 2\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: done\n label: Done\n color: \"#00aa00\"\n is_completed: true\n is_skipped: false\n exclude_from_cycle: false\n order: 3\n auto_archive: false\n auto_archive_delay_minutes: 5\n priority:\n values: *a3\n default: normal\n definitions:\n - value: none\n label: None\n color: \"#cccccc\"\n weight: 0\n - value: low\n label: Low\n color: \"#00aa00\"\n weight: 1\n - value: normal\n label: Normal\n color: \"#ffaa00\"\n weight: 2\n - value: high\n label: High\n color: \"#ff0000\"\n weight: 3\n recurrence:\n syntax: tasknotes\n maintain_due_date_offset: true\n reset_body_checkboxes: false\n occurrences:\n identity_roles:\n - recurrenceParent\n - occurrenceDate\n default_materialization: manual\n default_next_trigger: completion\n past_horizon: P0D\n future_horizon: P14D\n links:\n accepted_formats:\n - wikilink\n - markdown\n write_format: wikilink\n archive:\n archived_tag: archived\n move_on_archive: false\n time_tracking:\n auto_stop_on_complete: false\n templating:\n enabled: false\n occurrence_enabled: false\nx-tasknotes-generator:\n managed_fields:\n - assignees\n - attachments\n - blockedBy\n - complete_instances\n - completedDate\n - contexts\n - dateCreated\n - dateModified\n - due\n - googleCalendarEventId\n - googleCalendarExceptionEventId\n - googleCalendarExceptionOriginalScheduled\n - googleCalendarMovedOriginalDates\n - icsEventId\n - id\n - occurrence_date\n - occurrence_future_horizon\n - occurrence_materialization\n - occurrence_next_trigger\n - occurrence_past_horizon\n - occurrence_template\n - priority\n - projects\n - recurrence\n - recurrence_anchor\n - recurrence_parent\n - reminders\n - scheduled\n - skipped_instances\n - status\n - tags\n - tasknotes_manual_order\n - timeEntries\n - timeEstimate\n - title\n---\n\n# Task\n\nThis type definition implements the TaskNotes contract for this mdbase collection.\nIts JSON Schema describes persisted task frontmatter; collection and lifecycle\nmetadata describe generic mdbase behavior; `implements` maps the portable\nTaskNotes task view and supplies TaskNotes behavior.\n\nChanges made here are loaded by TaskNotes. Portable changes made in TaskNotes\nsettings are written back while unknown extensions are preserved.\n" + }, + { + "source": "schemas/tasknotes.task/0.3.0-rc.4.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://tasknotes.dev/schemas/tasknotes-task.schema.json\",\n \"title\": \"TaskNotes portable task view\",\n \"description\": \"The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract.\",\n \"type\": \"object\",\n \"required\": [\n \"status\",\n \"dateCreated\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"status\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"priority\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"due\": {\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n ]\n },\n \"scheduled\": {\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n ]\n },\n \"contexts\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"projects\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"assignees\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"\\\\S\"\n },\n \"description\": \"Stable mdbase.person IDs. These references never grant collection access.\"\n },\n \"attachments\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1\n }\n },\n \"timeEstimate\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"completedDate\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"dateCreated\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"dateModified\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"recurrence\": {\n \"type\": \"string\"\n },\n \"recurrenceAnchor\": {\n \"enum\": [\n \"scheduled\",\n \"completion\"\n ]\n },\n \"recurrenceParent\": {\n \"type\": \"string\"\n },\n \"occurrenceDate\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"occurrenceMaterialization\": {\n \"enum\": [\n \"manual\",\n \"on_completion\",\n \"rolling\"\n ]\n },\n \"occurrenceNextTrigger\": {\n \"enum\": [\n \"completion\",\n \"completion_or_skip\"\n ]\n },\n \"occurrenceTemplate\": {\n \"type\": \"string\"\n },\n \"occurrencePastHorizon\": {\n \"type\": \"string\"\n },\n \"occurrenceFutureHorizon\": {\n \"type\": \"string\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"timeEntries\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"reminders\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"blockedBy\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"completeInstances\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"skippedInstances\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"icsEventId\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"googleCalendarEventId\": {\n \"type\": \"string\"\n },\n \"googleCalendarExceptionEventId\": {\n \"type\": \"string\"\n },\n \"googleCalendarExceptionOriginalScheduled\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"googleCalendarMovedOriginalDates\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"sortOrder\": {\n \"type\": \"string\"\n }\n }\n}\n" + }, + { + "source": "schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json\",\n \"title\": \"TaskNotes task data-contract binding\",\n \"description\": \"Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.\",\n \"type\": \"object\",\n \"required\": [\n \"profiles\",\n \"capabilities\",\n \"title\",\n \"status\",\n \"priority\",\n \"recurrence\",\n \"occurrences\",\n \"links\",\n \"archive\",\n \"time_tracking\",\n \"templating\"\n ],\n \"properties\": {\n \"profiles\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"core-lite\",\n \"recurrence\",\n \"templating\",\n \"materialized-occurrences\",\n \"extended\"\n ]\n }\n },\n \"capabilities\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"dependencies\",\n \"reminders\",\n \"attachments\",\n \"links\",\n \"time-tracking\",\n \"materialized-occurrences\",\n \"rename\",\n \"archive\",\n \"batch\",\n \"concurrency\",\n \"dry-run\",\n \"migration\",\n \"templating\"\n ]\n }\n },\n \"title\": {\n \"$ref\": \"#/$defs/titlePolicy\"\n },\n \"status\": {\n \"$ref\": \"#/$defs/statusPolicy\"\n },\n \"priority\": {\n \"$ref\": \"#/$defs/priorityPolicy\"\n },\n \"recurrence\": {\n \"$ref\": \"#/$defs/recurrencePolicy\"\n },\n \"occurrences\": {\n \"$ref\": \"#/$defs/occurrencePolicy\"\n },\n \"links\": {\n \"$ref\": \"#/$defs/linkPolicy\"\n },\n \"archive\": {\n \"$ref\": \"#/$defs/archivePolicy\"\n },\n \"time_tracking\": {\n \"$ref\": \"#/$defs/timeTrackingPolicy\"\n },\n \"templating\": {\n \"$ref\": \"#/$defs/templatingPolicy\"\n },\n \"nlp\": {\n \"$ref\": \"#/$defs/nlpPolicy\"\n }\n },\n \"additionalProperties\": false,\n \"$defs\": {\n \"nonEmptyString\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"stringSet\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"titlePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"storage\"\n ],\n \"properties\": {\n \"storage\": {\n \"enum\": [\n \"filename\",\n \"frontmatter\"\n ]\n },\n \"filename_format\": {\n \"enum\": [\n \"title\",\n \"zettel\",\n \"timestamp\",\n \"uuid\",\n \"custom\"\n ]\n },\n \"custom_filename_template\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"allOf\": [\n {\n \"if\": {\n \"properties\": {\n \"filename_format\": {\n \"const\": \"custom\"\n }\n },\n \"required\": [\n \"filename_format\"\n ]\n },\n \"then\": {\n \"properties\": {\n \"custom_filename_template\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"required\": [\n \"custom_filename_template\"\n ]\n }\n }\n ],\n \"additionalProperties\": true\n },\n \"statusDefinition\": {\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"label\",\n \"color\",\n \"is_completed\",\n \"is_skipped\",\n \"exclude_from_cycle\",\n \"order\",\n \"auto_archive\",\n \"auto_archive_delay_minutes\"\n ],\n \"properties\": {\n \"value\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"label\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"is_completed\": {\n \"type\": \"boolean\"\n },\n \"is_skipped\": {\n \"type\": \"boolean\"\n },\n \"exclude_from_cycle\": {\n \"type\": \"boolean\"\n },\n \"next_status\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"order\": {\n \"type\": \"number\"\n },\n \"auto_archive\": {\n \"type\": \"boolean\"\n },\n \"auto_archive_delay_minutes\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"additionalProperties\": true\n },\n \"statusPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"values\",\n \"default\",\n \"completed_values\",\n \"definitions\"\n ],\n \"properties\": {\n \"values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"completed_values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"skipped_values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default_skipped\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"definitions\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/statusDefinition\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"priorityDefinition\": {\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"label\",\n \"color\",\n \"weight\"\n ],\n \"properties\": {\n \"value\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"label\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"weight\": {\n \"type\": \"number\"\n }\n },\n \"additionalProperties\": true\n },\n \"priorityPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"values\",\n \"default\",\n \"definitions\"\n ],\n \"properties\": {\n \"values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"definitions\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/priorityDefinition\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"recurrencePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"syntax\",\n \"maintain_due_date_offset\",\n \"reset_body_checkboxes\"\n ],\n \"properties\": {\n \"syntax\": {\n \"const\": \"tasknotes\"\n },\n \"maintain_due_date_offset\": {\n \"type\": \"boolean\"\n },\n \"reset_body_checkboxes\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"occurrencePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"identity_roles\",\n \"default_materialization\",\n \"default_next_trigger\"\n ],\n \"properties\": {\n \"identity_roles\": {\n \"const\": [\n \"recurrenceParent\",\n \"occurrenceDate\"\n ]\n },\n \"default_materialization\": {\n \"enum\": [\n \"manual\",\n \"on_completion\",\n \"rolling\"\n ]\n },\n \"default_next_trigger\": {\n \"enum\": [\n \"completion\",\n \"completion_or_skip\"\n ]\n },\n \"past_horizon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"future_horizon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"additionalProperties\": false\n },\n \"linkPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"accepted_formats\",\n \"write_format\"\n ],\n \"properties\": {\n \"accepted_formats\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"wikilink\",\n \"markdown\"\n ]\n }\n },\n \"write_format\": {\n \"enum\": [\n \"wikilink\",\n \"markdown\"\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"archivePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"archived_tag\",\n \"move_on_archive\"\n ],\n \"properties\": {\n \"archived_tag\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"move_on_archive\": {\n \"type\": \"boolean\"\n },\n \"folder\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"additionalProperties\": false\n },\n \"timeTrackingPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"auto_stop_on_complete\"\n ],\n \"properties\": {\n \"auto_stop_on_complete\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"templatingPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\",\n \"occurrence_enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n },\n \"template_path\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"occurrence_enabled\": {\n \"type\": \"boolean\"\n },\n \"occurrence_template_path\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"failure_mode\": {\n \"enum\": [\n \"error\",\n \"warning_fallback\"\n ]\n },\n \"unknown_variable_policy\": {\n \"enum\": [\n \"preserve\",\n \"empty\"\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"nlpTrigger\": {\n \"type\": \"object\",\n \"required\": [\n \"property_id\",\n \"trigger\",\n \"enabled\"\n ],\n \"properties\": {\n \"property_id\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"trigger\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"enabled\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"nlpPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"triggers\"\n ],\n \"properties\": {\n \"triggers\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/nlpTrigger\"\n }\n }\n },\n \"additionalProperties\": false\n }\n }\n}\n" + } + ], + "provides": [ + { + "id": "tasknotes.task", + "version": "0.3.0-rc.4", + "digest": "sha256:6948f659df6af05ef95aa893f1d57849032546e8c6cfee8afd5afe566e4ceeb0" + } + ] +} diff --git a/public/contracts/packs/tasknotes.task/0.3.0-rc.15.json b/public/contracts/packs/tasknotes.task/0.3.0-rc.15.json new file mode 100644 index 0000000..8d504fa --- /dev/null +++ b/public/contracts/packs/tasknotes.task/0.3.0-rc.15.json @@ -0,0 +1,68 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "tasknotes.task", + "version": "0.3.0-rc.15", + "name": "TaskNotes task type pack", + "description": "Portable tasks whose assignments link to person records, with a reviewed, atomic starter upgrade.", + "resources": [ + { + "kind": "contract", + "mode": "managed", + "source": "contracts/tasknotes.task/0.3.0-rc.5.md", + "target": "_contracts/tasknotes.task.md", + "digest": "sha256:ecadd00700e249940f4244aaa5b5985a96557d13340463ec491dfa5e89b032a4" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/tasknotes-task/3.md", + "target": "_types/task.md", + "digest": "sha256:02d1a2a04f26937dd7eec3cde3070dd770c73625e06f386d6214044d176788dd", + "upgrade_from": { + "digest": "sha256:b7f8af7b18d77859dab1f1532c1b55c08c7c39879f55e4ef2a94cb7d2d2284eb", + "document": "---\nkind: mdbase.type\nname: task\nversion: 1\ndescription: A task managed by TaskNotes.\nmatch:\n where:\n tags:\n contains: task\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n type: object\n additionalProperties: true\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n enum: &a2\n - none\n - open\n - in-progress\n - done\n - cancelled\n default: open\n priority:\n enum: &a4\n - none\n - low\n - normal\n - high\n default: normal\n due: &a1\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled: *a1\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n attachments:\n type: array\n items:\n type: string\n minLength: 1\n uniqueItems: true\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrence_anchor:\n enum:\n - scheduled\n - completion\n default: scheduled\n occurrence_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default: manual\n occurrence_next_trigger:\n enum:\n - completion\n - completion_or_skip\n default: completion\n occurrence_template:\n type: string\n occurrence_past_horizon:\n type: string\n occurrence_future_horizon:\n type: string\n recurrence_parent:\n type: string\n occurrence_date:\n type: string\n format: date\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n startTime:\n type: string\n format: date-time\n endTime:\n type: string\n format: date-time\n description:\n type: string\n duration:\n type: integer\n reminders:\n type: array\n items:\n oneOf:\n - type: object\n required:\n - id\n - type\n - absoluteTime\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: absolute\n description:\n type: string\n absoluteTime:\n type: string\n format: date-time\n - type: object\n required:\n - id\n - type\n - relatedTo\n - offset\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: relative\n description:\n type: string\n relatedTo:\n enum:\n - due\n - scheduled\n offset:\n type: string\n blockedBy:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n uid:\n type: string\n reltype:\n type: string\n gap:\n type: string\n required:\n - uid\n complete_instances:\n type: array\n items:\n type: string\n format: date\n skipped_instances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n tasknotes_manual_order:\n type: string\n allOf:\n - if:\n required:\n - status\n properties:\n status:\n enum: &a3\n - done\n not:\n required:\n - recurrence\n then:\n required:\n - completedDate\n required:\n - title\n - status\n - dateCreated\ncollection:\n read_defaults:\n status: open\n priority: normal\n recurrence_anchor: scheduled\n occurrence_materialization: manual\n occurrence_next_trigger: completion\n links:\n projects[]:\n target_type: any\n validate_exists: false\n attachments[]:\n validate_exists: false\n occurrence_template:\n target_type: any\n validate_exists: false\n recurrence_parent:\n target_type: task\n validate_exists: false\n blockedBy[].uid:\n target_type: task\n validate_exists: false\n path:\n runtime: tasknotes\n template: \"{{zettel}}\"\n folder: tasks\n generated_by: tasknotes.filename.create\n display:\n name_field: title\n unique:\n - field: id\n scope: type\nlifecycle:\n on_create:\n set:\n id:\n uuid: true\n dateCreated:\n now: true\n dateModified:\n now: true\n on_update:\n set:\n dateModified:\n now: true\nimplements:\n - contract: tasknotes.task\n version: 0.3.0-rc.3\n fields:\n id: id\n title: title\n status: status\n priority: priority\n due: due\n scheduled: scheduled\n contexts: contexts\n projects: projects\n attachments: attachments\n timeEstimate: timeEstimate\n completedDate: completedDate\n dateCreated: dateCreated\n dateModified: dateModified\n recurrence: recurrence\n recurrenceAnchor: recurrence_anchor\n occurrenceMaterialization: occurrence_materialization\n occurrenceNextTrigger: occurrence_next_trigger\n occurrenceTemplate: occurrence_template\n occurrencePastHorizon: occurrence_past_horizon\n occurrenceFutureHorizon: occurrence_future_horizon\n recurrenceParent: recurrence_parent\n occurrenceDate: occurrence_date\n tags: tags\n timeEntries: timeEntries\n reminders: reminders\n blockedBy: blockedBy\n completeInstances: complete_instances\n skippedInstances: skipped_instances\n icsEventId: icsEventId\n googleCalendarEventId: googleCalendarEventId\n googleCalendarExceptionEventId: googleCalendarExceptionEventId\n googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled\n googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates\n sortOrder: tasknotes_manual_order\n binding:\n profiles:\n - core-lite\n - recurrence\n - materialized-occurrences\n capabilities:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - archive\n - templating\n title:\n storage: frontmatter\n filename_format: zettel\n status:\n values: *a2\n default: open\n completed_values: *a3\n skipped_values:\n - cancelled\n default_skipped: cancelled\n definitions:\n - value: none\n label: None\n color: \"#94a3b8\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 0\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: open\n label: Open\n color: \"#64748b\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 1\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: in-progress\n label: In progress\n color: \"#3b82f6\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 2\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: done\n label: Done\n color: \"#22c55e\"\n is_completed: true\n is_skipped: false\n exclude_from_cycle: false\n order: 3\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: cancelled\n label: Cancelled\n color: \"#94a3b8\"\n is_completed: false\n is_skipped: true\n exclude_from_cycle: true\n order: 4\n auto_archive: false\n auto_archive_delay_minutes: 5\n priority:\n values: *a4\n default: normal\n definitions:\n - value: none\n label: None\n color: \"#94a3b8\"\n weight: 0\n - value: low\n label: Low\n color: \"#3b82f6\"\n weight: 1\n - value: normal\n label: Normal\n color: \"#f59e0b\"\n weight: 2\n - value: high\n label: High\n color: \"#ef4444\"\n weight: 3\n recurrence:\n syntax: tasknotes\n maintain_due_date_offset: true\n reset_body_checkboxes: false\n occurrences:\n identity_roles:\n - recurrenceParent\n - occurrenceDate\n default_materialization: manual\n default_next_trigger: completion\n past_horizon: P0D\n future_horizon: P14D\n links:\n accepted_formats:\n - wikilink\n - markdown\n write_format: wikilink\n archive:\n archived_tag: archived\n move_on_archive: false\n time_tracking:\n auto_stop_on_complete: false\n templating:\n enabled: false\n occurrence_enabled: false\nx-tasknotes-generator:\n managed_fields:\n - attachments\n - blockedBy\n - complete_instances\n - completedDate\n - contexts\n - dateCreated\n - dateModified\n - due\n - googleCalendarEventId\n - googleCalendarExceptionEventId\n - googleCalendarExceptionOriginalScheduled\n - googleCalendarMovedOriginalDates\n - icsEventId\n - id\n - occurrence_date\n - occurrence_future_horizon\n - occurrence_materialization\n - occurrence_next_trigger\n - occurrence_past_horizon\n - occurrence_template\n - priority\n - projects\n - recurrence\n - recurrence_anchor\n - recurrence_parent\n - reminders\n - scheduled\n - skipped_instances\n - status\n - tags\n - tasknotes_manual_order\n - timeEntries\n - timeEstimate\n - title\n---\n# Task\n\nTask records live under `tasks/`.\n" + } + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/tasknotes.task/0.3.0-rc.5.schema.json", + "target": "_schemas/tasknotes/tasknotes-task.schema.json", + "digest": "sha256:aec95578a093be95cbce0fb500964e7aeaeeacc611624fc2893074637dbd4125" + }, + { + "kind": "schema", + "mode": "managed", + "source": "schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json", + "target": "_schemas/tasknotes/tasknotes-task-binding.schema.json", + "digest": "sha256:5b38e8a1c426b7f7fa92d8353fe35dd98e632305cbb15ffccde387473166b267" + } + ] + }, + "resources": [ + { + "source": "contracts/tasknotes.task/0.3.0-rc.5.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: tasknotes.task\nversion: 0.3.0-rc.5\nname: TaskNotes task\ndescription: Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.5.\nrecord_schema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n $id: https://tasknotes.dev/schemas/tasknotes-task.schema.json\n title: TaskNotes portable task view\n description: The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.5 record contract.\n type: object\n required:\n - status\n - dateCreated\n additionalProperties: false\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n type: string\n minLength: 1\n priority:\n type: string\n minLength: 1\n due:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n assignees:\n type: array\n uniqueItems: true\n items:\n type: string\n minLength: 1\n pattern: \\S\n description: Links to records implementing mdbase.person, such as [[Alex Rivera]]. Implementing types declare this field in collection.links. These references never grant collection access.\n attachments:\n type: array\n uniqueItems: true\n items:\n type: string\n minLength: 1\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrenceAnchor:\n enum:\n - scheduled\n - completion\n recurrenceParent:\n type: string\n occurrenceDate:\n type: string\n format: date\n occurrenceMaterialization:\n enum:\n - manual\n - on_completion\n - rolling\n occurrenceNextTrigger:\n enum:\n - completion\n - completion_or_skip\n occurrenceTemplate:\n type: string\n occurrencePastHorizon:\n type: string\n occurrenceFutureHorizon:\n type: string\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n reminders:\n type: array\n items:\n type: object\n blockedBy:\n type: array\n items:\n type: object\n completeInstances:\n type: array\n items:\n type: string\n format: date\n skippedInstances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n sortOrder:\n type: string\nbinding_schema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n $id: https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json\n title: TaskNotes task data-contract binding\n description: Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.\n type: object\n required:\n - profiles\n - capabilities\n - title\n - status\n - priority\n - recurrence\n - occurrences\n - links\n - archive\n - time_tracking\n - templating\n properties:\n profiles:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n enum:\n - core-lite\n - recurrence\n - templating\n - materialized-occurrences\n - extended\n capabilities:\n type: array\n uniqueItems: true\n items:\n enum:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - rename\n - archive\n - batch\n - concurrency\n - dry-run\n - migration\n - templating\n title:\n $ref: \"#/$defs/titlePolicy\"\n status:\n $ref: \"#/$defs/statusPolicy\"\n priority:\n $ref: \"#/$defs/priorityPolicy\"\n recurrence:\n $ref: \"#/$defs/recurrencePolicy\"\n occurrences:\n $ref: \"#/$defs/occurrencePolicy\"\n links:\n $ref: \"#/$defs/linkPolicy\"\n archive:\n $ref: \"#/$defs/archivePolicy\"\n time_tracking:\n $ref: \"#/$defs/timeTrackingPolicy\"\n templating:\n $ref: \"#/$defs/templatingPolicy\"\n nlp:\n $ref: \"#/$defs/nlpPolicy\"\n additionalProperties: false\n $defs:\n nonEmptyString:\n type: string\n minLength: 1\n stringSet:\n type: array\n uniqueItems: true\n items:\n $ref: \"#/$defs/nonEmptyString\"\n titlePolicy:\n type: object\n required:\n - storage\n properties:\n storage:\n enum:\n - filename\n - frontmatter\n filename_format:\n enum:\n - title\n - zettel\n - timestamp\n - uuid\n - custom\n custom_filename_template:\n $ref: \"#/$defs/nonEmptyString\"\n allOf:\n - if:\n properties:\n filename_format:\n const: custom\n required:\n - filename_format\n then:\n properties:\n custom_filename_template:\n $ref: \"#/$defs/nonEmptyString\"\n required:\n - custom_filename_template\n additionalProperties: true\n statusDefinition:\n type: object\n required:\n - value\n - label\n - color\n - is_completed\n - is_skipped\n - exclude_from_cycle\n - order\n - auto_archive\n - auto_archive_delay_minutes\n properties:\n value:\n $ref: \"#/$defs/nonEmptyString\"\n label:\n type: string\n color:\n type: string\n icon:\n $ref: \"#/$defs/nonEmptyString\"\n is_completed:\n type: boolean\n is_skipped:\n type: boolean\n exclude_from_cycle:\n type: boolean\n next_status:\n $ref: \"#/$defs/nonEmptyString\"\n order:\n type: number\n auto_archive:\n type: boolean\n auto_archive_delay_minutes:\n type: number\n minimum: 0\n additionalProperties: true\n statusPolicy:\n type: object\n required:\n - values\n - default\n - completed_values\n - definitions\n properties:\n values:\n $ref: \"#/$defs/stringSet\"\n default:\n $ref: \"#/$defs/nonEmptyString\"\n completed_values:\n $ref: \"#/$defs/stringSet\"\n skipped_values:\n $ref: \"#/$defs/stringSet\"\n default_skipped:\n $ref: \"#/$defs/nonEmptyString\"\n definitions:\n type: array\n items:\n $ref: \"#/$defs/statusDefinition\"\n additionalProperties: false\n priorityDefinition:\n type: object\n required:\n - value\n - label\n - color\n - weight\n properties:\n value:\n $ref: \"#/$defs/nonEmptyString\"\n label:\n type: string\n color:\n type: string\n icon:\n $ref: \"#/$defs/nonEmptyString\"\n weight:\n type: number\n additionalProperties: true\n priorityPolicy:\n type: object\n required:\n - values\n - default\n - definitions\n properties:\n values:\n $ref: \"#/$defs/stringSet\"\n default:\n $ref: \"#/$defs/nonEmptyString\"\n definitions:\n type: array\n items:\n $ref: \"#/$defs/priorityDefinition\"\n additionalProperties: false\n recurrencePolicy:\n type: object\n required:\n - syntax\n - maintain_due_date_offset\n - reset_body_checkboxes\n properties:\n syntax:\n const: tasknotes\n maintain_due_date_offset:\n type: boolean\n reset_body_checkboxes:\n type: boolean\n additionalProperties: false\n occurrencePolicy:\n type: object\n required:\n - identity_roles\n - default_materialization\n - default_next_trigger\n properties:\n identity_roles:\n const:\n - recurrenceParent\n - occurrenceDate\n default_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default_next_trigger:\n enum:\n - completion\n - completion_or_skip\n past_horizon:\n $ref: \"#/$defs/nonEmptyString\"\n future_horizon:\n $ref: \"#/$defs/nonEmptyString\"\n additionalProperties: false\n linkPolicy:\n type: object\n required:\n - accepted_formats\n - write_format\n properties:\n accepted_formats:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n enum:\n - wikilink\n - markdown\n write_format:\n enum:\n - wikilink\n - markdown\n additionalProperties: false\n archivePolicy:\n type: object\n required:\n - archived_tag\n - move_on_archive\n properties:\n archived_tag:\n $ref: \"#/$defs/nonEmptyString\"\n move_on_archive:\n type: boolean\n folder:\n $ref: \"#/$defs/nonEmptyString\"\n additionalProperties: false\n timeTrackingPolicy:\n type: object\n required:\n - auto_stop_on_complete\n properties:\n auto_stop_on_complete:\n type: boolean\n additionalProperties: false\n templatingPolicy:\n type: object\n required:\n - enabled\n - occurrence_enabled\n properties:\n enabled:\n type: boolean\n template_path:\n $ref: \"#/$defs/nonEmptyString\"\n occurrence_enabled:\n type: boolean\n occurrence_template_path:\n $ref: \"#/$defs/nonEmptyString\"\n failure_mode:\n enum:\n - error\n - warning_fallback\n unknown_variable_policy:\n enum:\n - preserve\n - empty\n additionalProperties: false\n nlpTrigger:\n type: object\n required:\n - property_id\n - trigger\n - enabled\n properties:\n property_id:\n $ref: \"#/$defs/nonEmptyString\"\n trigger:\n $ref: \"#/$defs/nonEmptyString\"\n enabled:\n type: boolean\n additionalProperties: false\n nlpPolicy:\n type: object\n required:\n - triggers\n properties:\n triggers:\n type: array\n items:\n $ref: \"#/$defs/nlpTrigger\"\n additionalProperties: false\n---\n\n# TaskNotes task contract\n\nTypes implement this contract through `implements`; applications consume\nthe normalized contract view rather than assuming frontmatter names.\n" + }, + { + "source": "types/tasknotes-task/3.md", + "document": "---\nkind: mdbase.type\nname: task\nversion: 3\ndescription: A task managed by TaskNotes.\nmatch:\n where:\n tags:\n contains: task\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n type: object\n additionalProperties: true\n properties:\n id:\n type: string\n minLength: 1\n title:\n type: string\n minLength: 1\n status:\n enum: &a1\n - none\n - open\n - in-progress\n - done\n default: open\n priority:\n enum: &a3\n - none\n - low\n - normal\n - high\n default: normal\n due:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n scheduled:\n anyOf:\n - type: string\n format: date\n - type: string\n format: date-time\n contexts:\n type: array\n items:\n type: string\n projects:\n type: array\n items:\n type: string\n assignees:\n type: array\n items:\n type: string\n minLength: 1\n pattern: \\S\n uniqueItems: true\n attachments:\n type: array\n items:\n type: string\n minLength: 1\n uniqueItems: true\n timeEstimate:\n type: integer\n minimum: 0\n completedDate:\n type: string\n format: date\n dateCreated:\n type: string\n format: date-time\n dateModified:\n type: string\n format: date-time\n recurrence:\n type: string\n recurrence_anchor:\n enum:\n - scheduled\n - completion\n default: scheduled\n occurrence_materialization:\n enum:\n - manual\n - on_completion\n - rolling\n default: manual\n occurrence_next_trigger:\n enum:\n - completion\n - completion_or_skip\n default: completion\n occurrence_template:\n type: string\n occurrence_past_horizon:\n type: string\n occurrence_future_horizon:\n type: string\n recurrence_parent:\n type: string\n occurrence_date:\n type: string\n format: date\n tags:\n type: array\n items:\n type: string\n timeEntries:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n startTime:\n type: string\n format: date-time\n endTime:\n type: string\n format: date-time\n description:\n type: string\n duration:\n type: integer\n reminders:\n type: array\n items:\n oneOf:\n - type: object\n required:\n - id\n - type\n - absoluteTime\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: absolute\n description:\n type: string\n absoluteTime:\n type: string\n format: date-time\n - type: object\n required:\n - id\n - type\n - relatedTo\n - offset\n additionalProperties: false\n properties:\n id:\n type: string\n type:\n const: relative\n description:\n type: string\n relatedTo:\n enum:\n - due\n - scheduled\n offset:\n type: string\n blockedBy:\n type: array\n items:\n type: object\n additionalProperties: false\n properties:\n uid:\n type: string\n reltype:\n type: string\n gap:\n type: string\n required:\n - uid\n complete_instances:\n type: array\n items:\n type: string\n format: date\n skipped_instances:\n type: array\n items:\n type: string\n format: date\n icsEventId:\n type: array\n items:\n type: string\n googleCalendarEventId:\n type: string\n googleCalendarExceptionEventId:\n type: string\n googleCalendarExceptionOriginalScheduled:\n type: string\n format: date\n googleCalendarMovedOriginalDates:\n type: array\n items:\n type: string\n format: date\n tasknotes_manual_order:\n type: string\n allOf:\n - if:\n required:\n - status\n properties:\n status:\n enum: &a2\n - done\n not:\n required:\n - recurrence\n then:\n required:\n - completedDate\n required:\n - title\n - status\n - dateCreated\ncollection:\n read_defaults:\n status: open\n priority: normal\n recurrence_anchor: scheduled\n occurrence_materialization: manual\n occurrence_next_trigger: completion\n links:\n projects[]:\n target_type: any\n validate_exists: false\n assignees[]:\n validate_exists: false\n attachments[]:\n validate_exists: false\n occurrence_template:\n target_type: any\n validate_exists: false\n recurrence_parent:\n target_type: task\n validate_exists: false\n blockedBy[].uid:\n target_type: task\n validate_exists: false\n path:\n runtime: tasknotes\n template: \"{{zettel}}\"\n folder: tasks\n generated_by: tasknotes.filename.create\n display:\n name_field: title\n unique:\n - field: id\n scope: type\nlifecycle:\n on_create:\n set:\n id:\n uuid: true\n dateCreated:\n now: true\n dateModified:\n now: true\n on_update:\n set:\n dateModified:\n now: true\nimplements:\n - contract: tasknotes.task\n version: 0.3.0-rc.5\n fields:\n id: id\n title: title\n status: status\n priority: priority\n due: due\n scheduled: scheduled\n contexts: contexts\n projects: projects\n assignees: assignees\n attachments: attachments\n timeEstimate: timeEstimate\n completedDate: completedDate\n dateCreated: dateCreated\n dateModified: dateModified\n recurrence: recurrence\n recurrenceAnchor: recurrence_anchor\n occurrenceMaterialization: occurrence_materialization\n occurrenceNextTrigger: occurrence_next_trigger\n occurrenceTemplate: occurrence_template\n occurrencePastHorizon: occurrence_past_horizon\n occurrenceFutureHorizon: occurrence_future_horizon\n recurrenceParent: recurrence_parent\n occurrenceDate: occurrence_date\n tags: tags\n timeEntries: timeEntries\n reminders: reminders\n blockedBy: blockedBy\n completeInstances: complete_instances\n skippedInstances: skipped_instances\n icsEventId: icsEventId\n googleCalendarEventId: googleCalendarEventId\n googleCalendarExceptionEventId: googleCalendarExceptionEventId\n googleCalendarExceptionOriginalScheduled: googleCalendarExceptionOriginalScheduled\n googleCalendarMovedOriginalDates: googleCalendarMovedOriginalDates\n sortOrder: tasknotes_manual_order\n binding:\n profiles:\n - core-lite\n - recurrence\n - templating\n - materialized-occurrences\n - extended\n capabilities:\n - dependencies\n - reminders\n - attachments\n - links\n - time-tracking\n - materialized-occurrences\n - archive\n - templating\n title:\n storage: frontmatter\n filename_format: zettel\n status:\n values: *a1\n default: open\n completed_values: *a2\n skipped_values: []\n definitions:\n - value: none\n label: None\n color: \"#cccccc\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 0\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: open\n label: Open\n color: \"#808080\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 1\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: in-progress\n label: In progress\n color: \"#0066cc\"\n is_completed: false\n is_skipped: false\n exclude_from_cycle: false\n order: 2\n auto_archive: false\n auto_archive_delay_minutes: 5\n - value: done\n label: Done\n color: \"#00aa00\"\n is_completed: true\n is_skipped: false\n exclude_from_cycle: false\n order: 3\n auto_archive: false\n auto_archive_delay_minutes: 5\n priority:\n values: *a3\n default: normal\n definitions:\n - value: none\n label: None\n color: \"#cccccc\"\n weight: 0\n - value: low\n label: Low\n color: \"#00aa00\"\n weight: 1\n - value: normal\n label: Normal\n color: \"#ffaa00\"\n weight: 2\n - value: high\n label: High\n color: \"#ff0000\"\n weight: 3\n recurrence:\n syntax: tasknotes\n maintain_due_date_offset: true\n reset_body_checkboxes: false\n occurrences:\n identity_roles:\n - recurrenceParent\n - occurrenceDate\n default_materialization: manual\n default_next_trigger: completion\n past_horizon: P0D\n future_horizon: P14D\n links:\n accepted_formats:\n - wikilink\n - markdown\n write_format: wikilink\n archive:\n archived_tag: archived\n move_on_archive: false\n time_tracking:\n auto_stop_on_complete: false\n templating:\n enabled: false\n occurrence_enabled: false\nx-tasknotes-generator:\n managed_fields:\n - assignees\n - attachments\n - blockedBy\n - complete_instances\n - completedDate\n - contexts\n - dateCreated\n - dateModified\n - due\n - googleCalendarEventId\n - googleCalendarExceptionEventId\n - googleCalendarExceptionOriginalScheduled\n - googleCalendarMovedOriginalDates\n - icsEventId\n - id\n - occurrence_date\n - occurrence_future_horizon\n - occurrence_materialization\n - occurrence_next_trigger\n - occurrence_past_horizon\n - occurrence_template\n - priority\n - projects\n - recurrence\n - recurrence_anchor\n - recurrence_parent\n - reminders\n - scheduled\n - skipped_instances\n - status\n - tags\n - tasknotes_manual_order\n - timeEntries\n - timeEstimate\n - title\n---\n\n# Task\n\nThis type definition implements the TaskNotes contract for this mdbase collection.\nIts JSON Schema describes persisted task frontmatter; collection and lifecycle\nmetadata describe generic mdbase behavior; `implements` maps the portable\nTaskNotes task view and supplies TaskNotes behavior.\n\nChanges made here are loaded by TaskNotes. Portable changes made in TaskNotes\nsettings are written back while unknown extensions are preserved.\n" + }, + { + "source": "schemas/tasknotes.task/0.3.0-rc.5.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://tasknotes.dev/schemas/tasknotes-task.schema.json\",\n \"title\": \"TaskNotes portable task view\",\n \"description\": \"The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.5 record contract.\",\n \"type\": \"object\",\n \"required\": [\n \"status\",\n \"dateCreated\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"status\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"priority\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"due\": {\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n ]\n },\n \"scheduled\": {\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n {\n \"type\": \"string\",\n \"format\": \"date-time\"\n }\n ]\n },\n \"contexts\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"projects\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"assignees\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"\\\\S\"\n },\n \"description\": \"Links to records implementing mdbase.person, such as [[Alex Rivera]]. Implementing types declare this field in collection.links. These references never grant collection access.\"\n },\n \"attachments\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"type\": \"string\",\n \"minLength\": 1\n }\n },\n \"timeEstimate\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"completedDate\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"dateCreated\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"dateModified\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"recurrence\": {\n \"type\": \"string\"\n },\n \"recurrenceAnchor\": {\n \"enum\": [\n \"scheduled\",\n \"completion\"\n ]\n },\n \"recurrenceParent\": {\n \"type\": \"string\"\n },\n \"occurrenceDate\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"occurrenceMaterialization\": {\n \"enum\": [\n \"manual\",\n \"on_completion\",\n \"rolling\"\n ]\n },\n \"occurrenceNextTrigger\": {\n \"enum\": [\n \"completion\",\n \"completion_or_skip\"\n ]\n },\n \"occurrenceTemplate\": {\n \"type\": \"string\"\n },\n \"occurrencePastHorizon\": {\n \"type\": \"string\"\n },\n \"occurrenceFutureHorizon\": {\n \"type\": \"string\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"timeEntries\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"reminders\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"blockedBy\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"completeInstances\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"skippedInstances\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"icsEventId\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"googleCalendarEventId\": {\n \"type\": \"string\"\n },\n \"googleCalendarExceptionEventId\": {\n \"type\": \"string\"\n },\n \"googleCalendarExceptionOriginalScheduled\": {\n \"type\": \"string\",\n \"format\": \"date\"\n },\n \"googleCalendarMovedOriginalDates\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"format\": \"date\"\n }\n },\n \"sortOrder\": {\n \"type\": \"string\"\n }\n }\n}\n" + }, + { + "source": "schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json\",\n \"title\": \"TaskNotes task data-contract binding\",\n \"description\": \"Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.\",\n \"type\": \"object\",\n \"required\": [\n \"profiles\",\n \"capabilities\",\n \"title\",\n \"status\",\n \"priority\",\n \"recurrence\",\n \"occurrences\",\n \"links\",\n \"archive\",\n \"time_tracking\",\n \"templating\"\n ],\n \"properties\": {\n \"profiles\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"core-lite\",\n \"recurrence\",\n \"templating\",\n \"materialized-occurrences\",\n \"extended\"\n ]\n }\n },\n \"capabilities\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"dependencies\",\n \"reminders\",\n \"attachments\",\n \"links\",\n \"time-tracking\",\n \"materialized-occurrences\",\n \"rename\",\n \"archive\",\n \"batch\",\n \"concurrency\",\n \"dry-run\",\n \"migration\",\n \"templating\"\n ]\n }\n },\n \"title\": {\n \"$ref\": \"#/$defs/titlePolicy\"\n },\n \"status\": {\n \"$ref\": \"#/$defs/statusPolicy\"\n },\n \"priority\": {\n \"$ref\": \"#/$defs/priorityPolicy\"\n },\n \"recurrence\": {\n \"$ref\": \"#/$defs/recurrencePolicy\"\n },\n \"occurrences\": {\n \"$ref\": \"#/$defs/occurrencePolicy\"\n },\n \"links\": {\n \"$ref\": \"#/$defs/linkPolicy\"\n },\n \"archive\": {\n \"$ref\": \"#/$defs/archivePolicy\"\n },\n \"time_tracking\": {\n \"$ref\": \"#/$defs/timeTrackingPolicy\"\n },\n \"templating\": {\n \"$ref\": \"#/$defs/templatingPolicy\"\n },\n \"nlp\": {\n \"$ref\": \"#/$defs/nlpPolicy\"\n }\n },\n \"additionalProperties\": false,\n \"$defs\": {\n \"nonEmptyString\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"stringSet\": {\n \"type\": \"array\",\n \"uniqueItems\": true,\n \"items\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"titlePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"storage\"\n ],\n \"properties\": {\n \"storage\": {\n \"enum\": [\n \"filename\",\n \"frontmatter\"\n ]\n },\n \"filename_format\": {\n \"enum\": [\n \"title\",\n \"zettel\",\n \"timestamp\",\n \"uuid\",\n \"custom\"\n ]\n },\n \"custom_filename_template\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"allOf\": [\n {\n \"if\": {\n \"properties\": {\n \"filename_format\": {\n \"const\": \"custom\"\n }\n },\n \"required\": [\n \"filename_format\"\n ]\n },\n \"then\": {\n \"properties\": {\n \"custom_filename_template\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"required\": [\n \"custom_filename_template\"\n ]\n }\n }\n ],\n \"additionalProperties\": true\n },\n \"statusDefinition\": {\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"label\",\n \"color\",\n \"is_completed\",\n \"is_skipped\",\n \"exclude_from_cycle\",\n \"order\",\n \"auto_archive\",\n \"auto_archive_delay_minutes\"\n ],\n \"properties\": {\n \"value\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"label\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"is_completed\": {\n \"type\": \"boolean\"\n },\n \"is_skipped\": {\n \"type\": \"boolean\"\n },\n \"exclude_from_cycle\": {\n \"type\": \"boolean\"\n },\n \"next_status\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"order\": {\n \"type\": \"number\"\n },\n \"auto_archive\": {\n \"type\": \"boolean\"\n },\n \"auto_archive_delay_minutes\": {\n \"type\": \"number\",\n \"minimum\": 0\n }\n },\n \"additionalProperties\": true\n },\n \"statusPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"values\",\n \"default\",\n \"completed_values\",\n \"definitions\"\n ],\n \"properties\": {\n \"values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"completed_values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"skipped_values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default_skipped\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"definitions\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/statusDefinition\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"priorityDefinition\": {\n \"type\": \"object\",\n \"required\": [\n \"value\",\n \"label\",\n \"color\",\n \"weight\"\n ],\n \"properties\": {\n \"value\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"label\": {\n \"type\": \"string\"\n },\n \"color\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"weight\": {\n \"type\": \"number\"\n }\n },\n \"additionalProperties\": true\n },\n \"priorityPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"values\",\n \"default\",\n \"definitions\"\n ],\n \"properties\": {\n \"values\": {\n \"$ref\": \"#/$defs/stringSet\"\n },\n \"default\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"definitions\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/priorityDefinition\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"recurrencePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"syntax\",\n \"maintain_due_date_offset\",\n \"reset_body_checkboxes\"\n ],\n \"properties\": {\n \"syntax\": {\n \"const\": \"tasknotes\"\n },\n \"maintain_due_date_offset\": {\n \"type\": \"boolean\"\n },\n \"reset_body_checkboxes\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"occurrencePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"identity_roles\",\n \"default_materialization\",\n \"default_next_trigger\"\n ],\n \"properties\": {\n \"identity_roles\": {\n \"const\": [\n \"recurrenceParent\",\n \"occurrenceDate\"\n ]\n },\n \"default_materialization\": {\n \"enum\": [\n \"manual\",\n \"on_completion\",\n \"rolling\"\n ]\n },\n \"default_next_trigger\": {\n \"enum\": [\n \"completion\",\n \"completion_or_skip\"\n ]\n },\n \"past_horizon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"future_horizon\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"additionalProperties\": false\n },\n \"linkPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"accepted_formats\",\n \"write_format\"\n ],\n \"properties\": {\n \"accepted_formats\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": {\n \"enum\": [\n \"wikilink\",\n \"markdown\"\n ]\n }\n },\n \"write_format\": {\n \"enum\": [\n \"wikilink\",\n \"markdown\"\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"archivePolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"archived_tag\",\n \"move_on_archive\"\n ],\n \"properties\": {\n \"archived_tag\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"move_on_archive\": {\n \"type\": \"boolean\"\n },\n \"folder\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n }\n },\n \"additionalProperties\": false\n },\n \"timeTrackingPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"auto_stop_on_complete\"\n ],\n \"properties\": {\n \"auto_stop_on_complete\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"templatingPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"enabled\",\n \"occurrence_enabled\"\n ],\n \"properties\": {\n \"enabled\": {\n \"type\": \"boolean\"\n },\n \"template_path\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"occurrence_enabled\": {\n \"type\": \"boolean\"\n },\n \"occurrence_template_path\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"failure_mode\": {\n \"enum\": [\n \"error\",\n \"warning_fallback\"\n ]\n },\n \"unknown_variable_policy\": {\n \"enum\": [\n \"preserve\",\n \"empty\"\n ]\n }\n },\n \"additionalProperties\": false\n },\n \"nlpTrigger\": {\n \"type\": \"object\",\n \"required\": [\n \"property_id\",\n \"trigger\",\n \"enabled\"\n ],\n \"properties\": {\n \"property_id\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"trigger\": {\n \"$ref\": \"#/$defs/nonEmptyString\"\n },\n \"enabled\": {\n \"type\": \"boolean\"\n }\n },\n \"additionalProperties\": false\n },\n \"nlpPolicy\": {\n \"type\": \"object\",\n \"required\": [\n \"triggers\"\n ],\n \"properties\": {\n \"triggers\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/$defs/nlpTrigger\"\n }\n }\n },\n \"additionalProperties\": false\n }\n }\n}\n" + } + ], + "provides": [ + { + "id": "tasknotes.task", + "version": "0.3.0-rc.5", + "digest": "sha256:dde71d0d776aa0069ee627fe3c10b1a20f87ba36929a16790598ebfb4e8ebf04" + } + ] +} diff --git a/public/contracts/schemas/mdbase.person/1.0.0.schema.json b/public/contracts/schemas/mdbase.person/1.0.0.schema.json new file mode 100644 index 0000000..6116dff --- /dev/null +++ b/public/contracts/schemas/mdbase.person/1.0.0.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/contracts/schemas/mdbase.person/1.0.0.schema.json", + "title": "Person", + "description": "A portable person reference with editable account identity associations. Not an authentication or access-control assertion.", + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { + "type": "string", + "pattern": "\\S", + "description": "Stable person identifier used by references such as task assignments; independent of file path, name, account, and membership." + }, + "name": { + "type": "string", + "pattern": "\\S", + "description": "Collection-owned display name, not a verified account name." + }, + "identities": { + "type": "array", + "uniqueItems": true, + "description": "Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.", + "items": { + "type": "object", + "required": ["issuer", "subject"], + "properties": { + "issuer": { + "type": "string", + "format": "uri", + "pattern": "^https?://", + "description": "Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL." + }, + "subject": { + "type": "string", + "pattern": "\\S", + "description": "Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential." + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/public/contracts/schemas/mdbase.person/2.0.0.schema.json b/public/contracts/schemas/mdbase.person/2.0.0.schema.json new file mode 100644 index 0000000..65e3dff --- /dev/null +++ b/public/contracts/schemas/mdbase.person/2.0.0.schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/contracts/schemas/mdbase.person/2.0.0.schema.json", + "title": "Person", + "description": "A person represented by a record, referenced by links to that record, with editable account identity associations. Not an authentication or access-control assertion.", + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string", + "pattern": "\\S", + "description": "Collection-owned display name, not a verified account name." + }, + "identities": { + "type": "array", + "uniqueItems": true, + "description": "Editable identity associations. Missing or empty means this person has no linked account. Match issuer and subject exactly; never match by email or name.", + "items": { + "type": "object", + "required": [ + "issuer", + "subject" + ], + "properties": { + "issuer": { + "type": "string", + "format": "uri", + "pattern": "^https?://", + "description": "Stable issuer URL supplied by the identity service. Copy exactly; do not derive from a collection authority or relay URL." + }, + "subject": { + "type": "string", + "pattern": "\\S", + "description": "Opaque, case-sensitive, account-wide identifier supplied by the issuer. Not an email, membership ID, or credential." + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/public/contracts/schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json b/public/contracts/schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json new file mode 100644 index 0000000..af2bcc9 --- /dev/null +++ b/public/contracts/schemas/tasknotes.task.binding/0.3.0-rc.4.schema.json @@ -0,0 +1,469 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json", + "title": "TaskNotes task data-contract binding", + "description": "Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.", + "type": "object", + "required": [ + "profiles", + "capabilities", + "title", + "status", + "priority", + "recurrence", + "occurrences", + "links", + "archive", + "time_tracking", + "templating" + ], + "properties": { + "profiles": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "core-lite", + "recurrence", + "templating", + "materialized-occurrences", + "extended" + ] + } + }, + "capabilities": { + "type": "array", + "uniqueItems": true, + "items": { + "enum": [ + "dependencies", + "reminders", + "attachments", + "links", + "time-tracking", + "materialized-occurrences", + "rename", + "archive", + "batch", + "concurrency", + "dry-run", + "migration", + "templating" + ] + } + }, + "title": { + "$ref": "#/$defs/titlePolicy" + }, + "status": { + "$ref": "#/$defs/statusPolicy" + }, + "priority": { + "$ref": "#/$defs/priorityPolicy" + }, + "recurrence": { + "$ref": "#/$defs/recurrencePolicy" + }, + "occurrences": { + "$ref": "#/$defs/occurrencePolicy" + }, + "links": { + "$ref": "#/$defs/linkPolicy" + }, + "archive": { + "$ref": "#/$defs/archivePolicy" + }, + "time_tracking": { + "$ref": "#/$defs/timeTrackingPolicy" + }, + "templating": { + "$ref": "#/$defs/templatingPolicy" + }, + "nlp": { + "$ref": "#/$defs/nlpPolicy" + } + }, + "additionalProperties": false, + "$defs": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "stringSet": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "titlePolicy": { + "type": "object", + "required": [ + "storage" + ], + "properties": { + "storage": { + "enum": [ + "filename", + "frontmatter" + ] + }, + "filename_format": { + "enum": [ + "title", + "zettel", + "timestamp", + "uuid", + "custom" + ] + }, + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "allOf": [ + { + "if": { + "properties": { + "filename_format": { + "const": "custom" + } + }, + "required": [ + "filename_format" + ] + }, + "then": { + "properties": { + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "required": [ + "custom_filename_template" + ] + } + } + ], + "additionalProperties": true + }, + "statusDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "is_completed", + "is_skipped", + "exclude_from_cycle", + "order", + "auto_archive", + "auto_archive_delay_minutes" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "is_completed": { + "type": "boolean" + }, + "is_skipped": { + "type": "boolean" + }, + "exclude_from_cycle": { + "type": "boolean" + }, + "next_status": { + "$ref": "#/$defs/nonEmptyString" + }, + "order": { + "type": "number" + }, + "auto_archive": { + "type": "boolean" + }, + "auto_archive_delay_minutes": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": true + }, + "statusPolicy": { + "type": "object", + "required": [ + "values", + "default", + "completed_values", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "completed_values": { + "$ref": "#/$defs/stringSet" + }, + "skipped_values": { + "$ref": "#/$defs/stringSet" + }, + "default_skipped": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/statusDefinition" + } + } + }, + "additionalProperties": false + }, + "priorityDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "weight" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "weight": { + "type": "number" + } + }, + "additionalProperties": true + }, + "priorityPolicy": { + "type": "object", + "required": [ + "values", + "default", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/priorityDefinition" + } + } + }, + "additionalProperties": false + }, + "recurrencePolicy": { + "type": "object", + "required": [ + "syntax", + "maintain_due_date_offset", + "reset_body_checkboxes" + ], + "properties": { + "syntax": { + "const": "tasknotes" + }, + "maintain_due_date_offset": { + "type": "boolean" + }, + "reset_body_checkboxes": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "occurrencePolicy": { + "type": "object", + "required": [ + "identity_roles", + "default_materialization", + "default_next_trigger" + ], + "properties": { + "identity_roles": { + "const": [ + "recurrenceParent", + "occurrenceDate" + ] + }, + "default_materialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "default_next_trigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "past_horizon": { + "$ref": "#/$defs/nonEmptyString" + }, + "future_horizon": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "linkPolicy": { + "type": "object", + "required": [ + "accepted_formats", + "write_format" + ], + "properties": { + "accepted_formats": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "write_format": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "additionalProperties": false + }, + "archivePolicy": { + "type": "object", + "required": [ + "archived_tag", + "move_on_archive" + ], + "properties": { + "archived_tag": { + "$ref": "#/$defs/nonEmptyString" + }, + "move_on_archive": { + "type": "boolean" + }, + "folder": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "timeTrackingPolicy": { + "type": "object", + "required": [ + "auto_stop_on_complete" + ], + "properties": { + "auto_stop_on_complete": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "templatingPolicy": { + "type": "object", + "required": [ + "enabled", + "occurrence_enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "occurrence_enabled": { + "type": "boolean" + }, + "occurrence_template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "failure_mode": { + "enum": [ + "error", + "warning_fallback" + ] + }, + "unknown_variable_policy": { + "enum": [ + "preserve", + "empty" + ] + } + }, + "additionalProperties": false + }, + "nlpTrigger": { + "type": "object", + "required": [ + "property_id", + "trigger", + "enabled" + ], + "properties": { + "property_id": { + "$ref": "#/$defs/nonEmptyString" + }, + "trigger": { + "$ref": "#/$defs/nonEmptyString" + }, + "enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "nlpPolicy": { + "type": "object", + "required": [ + "triggers" + ], + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/$defs/nlpTrigger" + } + } + }, + "additionalProperties": false + } + } +} diff --git a/public/contracts/schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json b/public/contracts/schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json new file mode 100644 index 0000000..af2bcc9 --- /dev/null +++ b/public/contracts/schemas/tasknotes.task.binding/0.3.0-rc.5.schema.json @@ -0,0 +1,469 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task-binding.schema.json", + "title": "TaskNotes task data-contract binding", + "description": "Semantic configuration supplied by an mdbase type that implements tasknotes.task 0.3.0-rc.3.", + "type": "object", + "required": [ + "profiles", + "capabilities", + "title", + "status", + "priority", + "recurrence", + "occurrences", + "links", + "archive", + "time_tracking", + "templating" + ], + "properties": { + "profiles": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "core-lite", + "recurrence", + "templating", + "materialized-occurrences", + "extended" + ] + } + }, + "capabilities": { + "type": "array", + "uniqueItems": true, + "items": { + "enum": [ + "dependencies", + "reminders", + "attachments", + "links", + "time-tracking", + "materialized-occurrences", + "rename", + "archive", + "batch", + "concurrency", + "dry-run", + "migration", + "templating" + ] + } + }, + "title": { + "$ref": "#/$defs/titlePolicy" + }, + "status": { + "$ref": "#/$defs/statusPolicy" + }, + "priority": { + "$ref": "#/$defs/priorityPolicy" + }, + "recurrence": { + "$ref": "#/$defs/recurrencePolicy" + }, + "occurrences": { + "$ref": "#/$defs/occurrencePolicy" + }, + "links": { + "$ref": "#/$defs/linkPolicy" + }, + "archive": { + "$ref": "#/$defs/archivePolicy" + }, + "time_tracking": { + "$ref": "#/$defs/timeTrackingPolicy" + }, + "templating": { + "$ref": "#/$defs/templatingPolicy" + }, + "nlp": { + "$ref": "#/$defs/nlpPolicy" + } + }, + "additionalProperties": false, + "$defs": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "stringSet": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "titlePolicy": { + "type": "object", + "required": [ + "storage" + ], + "properties": { + "storage": { + "enum": [ + "filename", + "frontmatter" + ] + }, + "filename_format": { + "enum": [ + "title", + "zettel", + "timestamp", + "uuid", + "custom" + ] + }, + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "allOf": [ + { + "if": { + "properties": { + "filename_format": { + "const": "custom" + } + }, + "required": [ + "filename_format" + ] + }, + "then": { + "properties": { + "custom_filename_template": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "required": [ + "custom_filename_template" + ] + } + } + ], + "additionalProperties": true + }, + "statusDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "is_completed", + "is_skipped", + "exclude_from_cycle", + "order", + "auto_archive", + "auto_archive_delay_minutes" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "is_completed": { + "type": "boolean" + }, + "is_skipped": { + "type": "boolean" + }, + "exclude_from_cycle": { + "type": "boolean" + }, + "next_status": { + "$ref": "#/$defs/nonEmptyString" + }, + "order": { + "type": "number" + }, + "auto_archive": { + "type": "boolean" + }, + "auto_archive_delay_minutes": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": true + }, + "statusPolicy": { + "type": "object", + "required": [ + "values", + "default", + "completed_values", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "completed_values": { + "$ref": "#/$defs/stringSet" + }, + "skipped_values": { + "$ref": "#/$defs/stringSet" + }, + "default_skipped": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/statusDefinition" + } + } + }, + "additionalProperties": false + }, + "priorityDefinition": { + "type": "object", + "required": [ + "value", + "label", + "color", + "weight" + ], + "properties": { + "value": { + "$ref": "#/$defs/nonEmptyString" + }, + "label": { + "type": "string" + }, + "color": { + "type": "string" + }, + "icon": { + "$ref": "#/$defs/nonEmptyString" + }, + "weight": { + "type": "number" + } + }, + "additionalProperties": true + }, + "priorityPolicy": { + "type": "object", + "required": [ + "values", + "default", + "definitions" + ], + "properties": { + "values": { + "$ref": "#/$defs/stringSet" + }, + "default": { + "$ref": "#/$defs/nonEmptyString" + }, + "definitions": { + "type": "array", + "items": { + "$ref": "#/$defs/priorityDefinition" + } + } + }, + "additionalProperties": false + }, + "recurrencePolicy": { + "type": "object", + "required": [ + "syntax", + "maintain_due_date_offset", + "reset_body_checkboxes" + ], + "properties": { + "syntax": { + "const": "tasknotes" + }, + "maintain_due_date_offset": { + "type": "boolean" + }, + "reset_body_checkboxes": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "occurrencePolicy": { + "type": "object", + "required": [ + "identity_roles", + "default_materialization", + "default_next_trigger" + ], + "properties": { + "identity_roles": { + "const": [ + "recurrenceParent", + "occurrenceDate" + ] + }, + "default_materialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "default_next_trigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "past_horizon": { + "$ref": "#/$defs/nonEmptyString" + }, + "future_horizon": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "linkPolicy": { + "type": "object", + "required": [ + "accepted_formats", + "write_format" + ], + "properties": { + "accepted_formats": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "write_format": { + "enum": [ + "wikilink", + "markdown" + ] + } + }, + "additionalProperties": false + }, + "archivePolicy": { + "type": "object", + "required": [ + "archived_tag", + "move_on_archive" + ], + "properties": { + "archived_tag": { + "$ref": "#/$defs/nonEmptyString" + }, + "move_on_archive": { + "type": "boolean" + }, + "folder": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "additionalProperties": false + }, + "timeTrackingPolicy": { + "type": "object", + "required": [ + "auto_stop_on_complete" + ], + "properties": { + "auto_stop_on_complete": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "templatingPolicy": { + "type": "object", + "required": [ + "enabled", + "occurrence_enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "occurrence_enabled": { + "type": "boolean" + }, + "occurrence_template_path": { + "$ref": "#/$defs/nonEmptyString" + }, + "failure_mode": { + "enum": [ + "error", + "warning_fallback" + ] + }, + "unknown_variable_policy": { + "enum": [ + "preserve", + "empty" + ] + } + }, + "additionalProperties": false + }, + "nlpTrigger": { + "type": "object", + "required": [ + "property_id", + "trigger", + "enabled" + ], + "properties": { + "property_id": { + "$ref": "#/$defs/nonEmptyString" + }, + "trigger": { + "$ref": "#/$defs/nonEmptyString" + }, + "enabled": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "nlpPolicy": { + "type": "object", + "required": [ + "triggers" + ], + "properties": { + "triggers": { + "type": "array", + "items": { + "$ref": "#/$defs/nlpTrigger" + } + } + }, + "additionalProperties": false + } + } +} diff --git a/public/contracts/schemas/tasknotes.task/0.3.0-rc.4.schema.json b/public/contracts/schemas/tasknotes.task/0.3.0-rc.4.schema.json new file mode 100644 index 0000000..56c1803 --- /dev/null +++ b/public/contracts/schemas/tasknotes.task/0.3.0-rc.4.schema.json @@ -0,0 +1,202 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task.schema.json", + "title": "TaskNotes portable task view", + "description": "The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.4 record contract.", + "type": "object", + "required": [ + "status", + "dateCreated" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "title": { + "type": "string", + "minLength": 1 + }, + "status": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "string", + "minLength": 1 + }, + "due": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "scheduled": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "contexts": { + "type": "array", + "items": { + "type": "string" + } + }, + "projects": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "pattern": "\\S" + }, + "description": "Stable mdbase.person IDs. These references never grant collection access." + }, + "attachments": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "timeEstimate": { + "type": "integer", + "minimum": 0 + }, + "completedDate": { + "type": "string", + "format": "date" + }, + "dateCreated": { + "type": "string", + "format": "date-time" + }, + "dateModified": { + "type": "string", + "format": "date-time" + }, + "recurrence": { + "type": "string" + }, + "recurrenceAnchor": { + "enum": [ + "scheduled", + "completion" + ] + }, + "recurrenceParent": { + "type": "string" + }, + "occurrenceDate": { + "type": "string", + "format": "date" + }, + "occurrenceMaterialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "occurrenceNextTrigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "occurrenceTemplate": { + "type": "string" + }, + "occurrencePastHorizon": { + "type": "string" + }, + "occurrenceFutureHorizon": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "timeEntries": { + "type": "array", + "items": { + "type": "object" + } + }, + "reminders": { + "type": "array", + "items": { + "type": "object" + } + }, + "blockedBy": { + "type": "array", + "items": { + "type": "object" + } + }, + "completeInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "skippedInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "icsEventId": { + "type": "array", + "items": { + "type": "string" + } + }, + "googleCalendarEventId": { + "type": "string" + }, + "googleCalendarExceptionEventId": { + "type": "string" + }, + "googleCalendarExceptionOriginalScheduled": { + "type": "string", + "format": "date" + }, + "googleCalendarMovedOriginalDates": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "sortOrder": { + "type": "string" + } + } +} diff --git a/public/contracts/schemas/tasknotes.task/0.3.0-rc.5.schema.json b/public/contracts/schemas/tasknotes.task/0.3.0-rc.5.schema.json new file mode 100644 index 0000000..8944161 --- /dev/null +++ b/public/contracts/schemas/tasknotes.task/0.3.0-rc.5.schema.json @@ -0,0 +1,202 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://tasknotes.dev/schemas/tasknotes-task.schema.json", + "title": "TaskNotes portable task view", + "description": "The storage-neutral record view exposed by the tasknotes.task 0.3.0-rc.5 record contract.", + "type": "object", + "required": [ + "status", + "dateCreated" + ], + "additionalProperties": false, + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "title": { + "type": "string", + "minLength": 1 + }, + "status": { + "type": "string", + "minLength": 1 + }, + "priority": { + "type": "string", + "minLength": 1 + }, + "due": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "scheduled": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "string", + "format": "date-time" + } + ] + }, + "contexts": { + "type": "array", + "items": { + "type": "string" + } + }, + "projects": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "pattern": "\\S" + }, + "description": "Links to records implementing mdbase.person, such as [[Alex Rivera]]. Implementing types declare this field in collection.links. These references never grant collection access." + }, + "attachments": { + "type": "array", + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "timeEstimate": { + "type": "integer", + "minimum": 0 + }, + "completedDate": { + "type": "string", + "format": "date" + }, + "dateCreated": { + "type": "string", + "format": "date-time" + }, + "dateModified": { + "type": "string", + "format": "date-time" + }, + "recurrence": { + "type": "string" + }, + "recurrenceAnchor": { + "enum": [ + "scheduled", + "completion" + ] + }, + "recurrenceParent": { + "type": "string" + }, + "occurrenceDate": { + "type": "string", + "format": "date" + }, + "occurrenceMaterialization": { + "enum": [ + "manual", + "on_completion", + "rolling" + ] + }, + "occurrenceNextTrigger": { + "enum": [ + "completion", + "completion_or_skip" + ] + }, + "occurrenceTemplate": { + "type": "string" + }, + "occurrencePastHorizon": { + "type": "string" + }, + "occurrenceFutureHorizon": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "timeEntries": { + "type": "array", + "items": { + "type": "object" + } + }, + "reminders": { + "type": "array", + "items": { + "type": "object" + } + }, + "blockedBy": { + "type": "array", + "items": { + "type": "object" + } + }, + "completeInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "skippedInstances": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "icsEventId": { + "type": "array", + "items": { + "type": "string" + } + }, + "googleCalendarEventId": { + "type": "string" + }, + "googleCalendarExceptionEventId": { + "type": "string" + }, + "googleCalendarExceptionOriginalScheduled": { + "type": "string", + "format": "date" + }, + "googleCalendarMovedOriginalDates": { + "type": "array", + "items": { + "type": "string", + "format": "date" + } + }, + "sortOrder": { + "type": "string" + } + } +} diff --git a/site-sources.json b/site-sources.json index e2498e1..a142467 100644 --- a/site-sources.json +++ b/site-sources.json @@ -9,7 +9,7 @@ }, "contracts": { "repository": "mdbase-dev/mdbase-contracts", - "ref": "ade8d1a7443cfaf077746ef148b9d87a865109fc" + "ref": "f289a42ecc6dd39bec05318c64af5463d050500a" }, "implementations": [ { diff --git a/src/data/contracts.json b/src/data/contracts.json index 60fc628..940b713 100644 --- a/src/data/contracts.json +++ b/src/data/contracts.json @@ -19,6 +19,26 @@ "artifact": "./artifacts/contracts/mdbase.contact/1.0.0.md", "standards": [] }, + { + "id": "mdbase.person", + "version": "1.0.0", + "name": "Person", + "description": "A portable person reference with editable account identity associations.", + "contract_type": "record", + "digest": "sha256:e2a9435ad01a2c06c151bf6af62a9d04aa30faa8e6128e4b5fe39378c767465c", + "artifact": "./artifacts/contracts/mdbase.person/1.0.0.md", + "standards": [] + }, + { + "id": "mdbase.person", + "version": "2.0.0", + "name": "Person", + "description": "A person record, referenced by links, with editable account identity associations.", + "contract_type": "record", + "digest": "sha256:2899b149b1602bd4e51ff8e87c82dc92da3f690f4e89b1a6caf5b2b555540fe5", + "artifact": "./artifacts/contracts/mdbase.person/2.0.0.md", + "standards": [] + }, { "id": "mdbase.record.created", "version": "1.0.0", @@ -188,6 +208,16 @@ "digest": "sha256:4761ee78615882170cae6e52590f98917f549bd89d852a0c40568583394d7264", "artifact": "./artifacts/contracts/tasknotes.task/0.3.0-rc.3.md", "standards": [] + }, + { + "id": "tasknotes.task", + "version": "0.3.0-rc.5", + "name": "TaskNotes task", + "description": "Portable task data and behavior defined by tasknotes-spec 0.3.0-rc.5.", + "contract_type": "record", + "digest": "sha256:ecadd00700e249940f4244aaa5b5985a96557d13340463ec491dfa5e89b032a4", + "artifact": "./artifacts/contracts/tasknotes.task/0.3.0-rc.5.md", + "standards": [] } ], "packs": [ @@ -217,13 +247,101 @@ ] }, "installation": { - "visibility": "default", + "visibility": "hidden", + "recommendation": "user", + "primary_type": "contact", + "types": [ + { + "name": "contact", + "label": "Contact" + } + ] + } + }, + { + "id": "mdbase.contact", + "version": "1.1.0", + "name": "People and contacts type pack", + "description": "Portable people, editable account identity associations, and familiar contact fields.", + "digest": "sha256:14bba55df0574401b46ae08e5ef1e41e615d1477f70c3cc202eb9ff179287864", + "provision": "./packs/mdbase.contact/1.1.0.json", + "provides": [ + { + "id": "mdbase.person", + "version": "1.0.0", + "digest": "sha256:cda32ead27eaf70440efe3fadd8b5334df9af82f378b2af1bc786f7ab0bd0fc3" + }, + { + "id": "mdbase.contact", + "version": "1.0.0", + "digest": "sha256:49cfe15403dfc741a693e89a2f4d2857de306f391d02cb03e67bfaf0aa1d6b0d" + } + ], + "resource_count": 6, + "display": { + "name": "People and contacts", + "summary": "Reference people across apps and collections without tying records to account membership.", + "category": "people", + "audience": "general", + "icon": "user", + "badges": [ + "Portable person references" + ] + }, + "installation": { + "visibility": "hidden", "recommendation": "user", "primary_type": "contact", "types": [ { "name": "contact", "label": "Contact" + }, + { + "name": "person", + "label": "Person" + } + ] + } + }, + { + "id": "mdbase.contact", + "version": "1.2.0", + "name": "People type pack", + "description": "Portable people, editable account identity associations, and familiar contact fields.", + "digest": "sha256:dbbb3a874cfc5d69a2a5793c86dab801c16438d58a270b48bc7376fc8bbdfa2d", + "provision": "./packs/mdbase.contact/1.2.0.json", + "provides": [ + { + "id": "mdbase.person", + "version": "2.0.0", + "digest": "sha256:f16c462a1fd422f44ed055002f8476ec53c164107647fec782aeb74adeab2f9d" + }, + { + "id": "mdbase.contact", + "version": "1.0.0", + "digest": "sha256:49cfe15403dfc741a693e89a2f4d2857de306f391d02cb03e67bfaf0aa1d6b0d" + } + ], + "resource_count": 7, + "display": { + "name": "People", + "summary": "Reference people across apps and collections without tying records to account membership.", + "category": "people", + "audience": "general", + "icon": "user", + "badges": [ + "Portable person references" + ] + }, + "installation": { + "visibility": "default", + "recommendation": "user", + "primary_type": "person", + "types": [ + { + "name": "person", + "label": "Person" } ] } @@ -384,6 +502,44 @@ } ] } + }, + { + "id": "tasknotes.task", + "version": "0.3.0-rc.15", + "name": "TaskNotes task type pack", + "description": "Portable tasks whose assignments link to person records, with a reviewed, atomic starter upgrade.", + "digest": "sha256:db3b0b28c6fb286bc8c7bbbee9f4b01f567078c208187d17ce049d1e62a9a8cb", + "provision": "./packs/tasknotes.task/0.3.0-rc.15.json", + "provides": [ + { + "id": "tasknotes.task", + "version": "0.3.0-rc.5", + "digest": "sha256:dde71d0d776aa0069ee627fe3c10b1a20f87ba36929a16790598ebfb4e8ebf04" + } + ], + "resource_count": 4, + "display": { + "name": "TaskNotes tasks", + "summary": "Manage portable Markdown tasks, assignments, dates, recurrence, reminders, and time tracking.", + "category": "work", + "audience": "general", + "icon": "square-check-big", + "badges": [ + "TaskNotes compatible" + ] + }, + "installation": { + "visibility": "default", + "recommendation": "integration-managed", + "primary_type": "task", + "caution": "Upgrades the previous starter type while preserving independent customizations. Conflicts or other references to the previous contract block the whole upgrade.", + "types": [ + { + "name": "task", + "label": "Task" + } + ] + } } ] }