Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions public/contracts/artifacts/contracts/mdbase.person/1.0.0.md
Original file line number Diff line number Diff line change
@@ -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.
93 changes: 93 additions & 0 deletions public/contracts/artifacts/contracts/mdbase.person/2.0.0.md
Original file line number Diff line number Diff line change
@@ -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.
Loading
Loading