Treat this as an opinionated draft proposing a solution to a problem. Please let us know your thoughts by providing comments below - any feedback is welcome!
Context and problem
Ceramic users cannot easily make statements about other data in Ceramic that they expect to be static. For example, if a user wanted to write a review (represented as a Ceramic stream) about a product (also represented as a Ceramic stream), they may have an assumption that the product’s details (e.g., name, quantity, condition, etc.) would not change. Currently however, when creating a review that references a stream, the reviewer has no guarantees that changes will not be made by the product owner in the future, thus making the review inaccurate or obsolete.
More specifically, Ceramic is currently not natively optimized to allow application developers to easily query an older version (or the original version) of updated documents, so in the given example, it would be difficult for the Review to be tied to an older version of a Product.
Inefficient workarounds are possible but may be a frustrating experience since they require application developers to write custom logic.
A better solution would be to natively enable developers to allow their users to author document types for which the values should never change, regardless of how those immutable documents are referenced by other data points.
Goals
- Provide a way to ensure that the relationship of one document referencing a second document does not ever become invalidated by an update to the second document
- E.g., if a user leaves a review for a specific version of an audit, that review should not apply to a newer version of the audit
Solution
The proposed solution is a feature that enables developers to lock field values within a model document. Locked fields cannot be changed once they are defined during the creation of the model instance document.
For example:
- Auditors cannot update an Audit version within an existing stream to inherit earlier reviews.
- Auditors must publish a new stream with a new Audit which must gather new reviews.
- Each stream document represents a version of an Audit
Code sample: Defining a locked field during schema modeling (eventual syntax may vary)
## merely an example below - actual values likely would include a proof
type SoftwareSecurityAudit
@createModel(accountRelation: LIST,
description: "A software security audit")
@createIndex(fields: [{ path: "issuanceDate" }])
@createIndex(fields: [{ path: "approval" }])
@createIndex(fields: [{ path: "softwareItemLocation" }])
{
controller: DID! @documentAccount
issuanceDate: @locking DateTime!
approval: @locking Boolean!
softwareItemLocation: @locking CID!
}
Risks
This solution does introduce some potential risks. Notably, if a user is tricked into creating a document due to phishing, a hack or anything else, they’d have no recourse to change it. Similarly, organizations that delegate write access to their members e.g., using CACAO, are exposed to this risk at a larger scale since any member’s “mistake” would be unrecoverable for the entire organization.
Requirements
Feature | Details | Priority | Open questions |
---|---|---|---|
Ability to lock one or more fields | Ability to (optionally) define new schemas that have the ability to have locked fields. e.g., Audit schema | Must have | Should a model be locked at the global level or at the individual field level? |
By the controller | Only the controller can lock fields and only at the time of schema creation | Must have | |
Irreversable locking | Locked fields can never be updated after they model instance has been created, and the fields are first defined.e.g., The Product that an Audit points to (and possibly also all the values of the Audit) are locked | Must have | |
Compatible with existing features and other new features (e.g., SET) | Further exploration is required to see how field locking interacts with newly proposed relationship types. | Must have | How does field locking interact with the newly proposed SET feature? |