NEW SECTION: Root Documentation
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/introduction.md
# Introduction
Your AI assistant can already search, compare prices, and fill shopping carts. But you'd never give it your credit card because there's no way to set safe boundaries.
**Blue** unlocks safe autonomy at machine speed: it lets every participant - human or AI - specify **exactly** what's permitted, verify **who** initiated each action, and rely on trusted processors to enforce the rules.
## 1. The big idea (why Blue feels familiar)
When two people strike a deal we …
1. **Talk it through** in a shared [language](./language/introduction).
2. **Write it down** so everyone can see the terms and track how the deal is unfolding.
3. **Bring in trusted parties** - escrow, card network, courier - when the stakes feel risky.
4. **Act and observe** - we do our part while watching others do theirs.
Blue gives software the same four steps:
| Human habit | Blue feature |
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
| Shared words | **Full-sentence [vocabulary](./language/blue-id).** Forget stubby API nouns; describe intent the way you'd explain it to a person. |
| Written contract | **Self-contained [document](./contracts/introduction).** Facts *plus* deterministic rules any Blue processor can run. |
| Trusted 3rd parties | **Named participants** (Stripe, DHL) who participate in the interaction by following the agreed [rules](./contracts/sequential-workflow). |
| Verifiable activity | **Personal signed [timelines](./timelines/introduction).** Each party publishes their actions to their own timeline while observing others'. |
> **Participants** are actors named in the document (e.g. Alice, Bob, Stripe).
> **Processors** are whichever engines they choose - [MyOS](./myos/why-myos) in the cloud, a CLI binary, or tomorrow's phone app - that read the document **plus** the timelines and converge independently.
## 2. Example Story — *"I want a painless refund"*
### 2.1. The problem
Alice likes Bob's \$120 video-course but has never heard of him. She'll buy only if a refund is automatic for the first week. Bob is happy—provided everything runs itself.
### 2.2. Bob's Blue solution
:::info Order document — participants: Alice, Bob
- If Alice accepts the course, Bob provides an embedded payment document
- If payment is refunded, course access is immediately revoked
:::
:::info Stripe-payment document — participants: Alice, Bob, Stripe
- **Capture** $120 the moment Alice pays.
- For the next **7 days** Alice may post `RequestRefund`.
- On that event **Stripe refunds the full amount** automatically—no Bob approval.
- Bob can still hit the API and refund on his own.
:::
One link, one language, one contract - each party processes it on whichever engine they already trust.
### 2.3. Why Alice clicks **Buy**
* **She trusts Stripe, not Bob.** She interacts directly with Stripe and knows her refund right is enforced.
* **Crystal checkout copy.** Stripe can show *"Instant refund within 7 days"* because it reads that promise straight from Bob's document.
* **Self-service.** Alice can click *Refund* **or** drop `RequestRefund` onto her timeline; either path works.
### 2.4. How the week unfolds
| Day | Timeline entry | Outcome (seen by every processor) |
|-----|----------------|-----------------------------------|
| 0 | `AuthorisePayment` (Alice) → `PaymentCaptured` (Stripe) | Course unlocked; refund window ticking |
| 5 | `RequestRefund` (Alice) | Stripe refunds \$120; Bob's dashboard logs `PaymentRefunded`; Order flips to **Cancelled** |
| 8 | *(none)* | A late request is ignored - rule expired |
No emails, no screenshots, no chargebacks: the timelines settle it.
## Why This Works: Email + Blockchain, Without the Baggage
Think of Blue as combining the best of both worlds:
- **Like email**: You control your own timeline, share what you want, maintain privacy
- **Like blockchain**: Everyone can verify what happened, but without expensive global consensus
- **Unlike both**: Documents contain executable rules, not just static data
Alice's refund worked because her timeline proved her request, Stripe's timeline proved the refund, and the document's rules guaranteed the outcome.
## 3. What this buys you
* **No new backbone** — run [MyOS](./myos/why-myos), a [Java local app](https://github.com/bluecontract/blue-language-java), or a [Node.js Lambda](https://github.com/bluecontract/blue-js); everyone reaches the same verdict.
* **Infinite scalability** — every party processes only the timelines named in its contract, so there's **no global ledger to bottleneck or shard**. One deal or a million run with the same architecture.
* **No schema-sync calls** — reference any concept; the [BlueId](./language/blue-id) proves its meaning.
* **No invisible behaviour** — the only path to action is a [timeline](./timelines/introduction) everyone can inspect.
* **Plug-and-play trust** — drop in a bank, insurer, or sensor as a named participant; they enforce their slice and earn a fee without new code or schema mapping.
## 4. Why Blue ≠ blockchain / DLT
* **Personal timelines, not global consensus.** Like email, you control your own timeline and share selectively. Unlike blockchain, there's no expensive global ledger to maintain or expensive mining to secure.
* **Document-focused verification.** Processors only need timelines from participants named in a specific document—not the entire network's history.
* **Privacy by design.** Alice's `RequestRefund` is visible to Stripe but not necessarily to anyone else—no public blocks exposing every transaction.
* **Efficiency without compromise.** All processors reach the same conclusion, but without mining, global consensus, or network-wide synchronization—just verified timelines from the specific parties involved.
## 5. Where this heads next
### A. Trust Distribution Made Simple
Create a focused Blue doc with **only the parties who matter**—your bank for [payments](./payments/single-payment) or [payment plans](./payments/payment-plan), your carrier for delivery, your insurer for edge cases—and embed it in the main deal.
Each participant enforces its slice, appends signed events, and **earns a fee for the assurance it provides**. Trust becomes modular, verifiable, and profitable.
### B. The Collaboration Economy
Because Blue docs are [generated from natural language by AI](../_prompt/unfinished/ai/document-creation), bespoke contracts take minutes, not weeks. Micro-partnerships, flash supply chains, ad-hoc revenue splits flourish—trust no longer drags. See the [Xavier ↔ Alice](./myos/collaboration-economy) example.
### C. AI-Hive Governance
Thousands of specialised agents can negotiate at silicon speed—**but nothing executes unless it lands on a timeline**. Guardian docs act as circuit-breakers, so humans keep the wheel while the hive runs 1000× faster. Speed for the bots, brakes for the people—built in.
## 6. Take-home sentence
> **Blue lets software speak in full sentences, wrap those sentences in a verifiable contract, and require every action to land on a signed timeline - so any processor you trust can enforce the deal exactly as written.**
Everything else - [MyOS dashboards](./myos/quick-start), [`/blue` endpoints](./integration/blue-endpoint), [channel-binding recipes](./contracts/channel-binding) - exists to make that sentence trivial to ship.
### Next stops
* **[Language primer](./language/introduction)** — BlueIds, structural types, extending the web of meaning.
* **[Contract guide](./contracts/introduction)** — workflows, channels, coordination strategies.
* **[Payment recipes](./payments/single-payment)** — delivery capture, usage billing, escrow layers.
* **[Quick-start](./myos/quick-start)** — post events, watch independent processors agree.
----------------------------------------
NEW SECTION: language
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/language/introduction.md
# Introduction to Blue Language
## The Problem of Reinvention
How many times have you defined a `Person` class in your career?
```java
// Java
public class Person {
private String name;
private String surname;
private int age;
// And so on...
}
```
```typescript
// TypeScript
interface Person {
name: string;
surname: string;
age: number;
// And so on...
}
```
```python
# Python
class Person:
def __init__(self, name, surname, age):
self.name = name
self.surname = surname
self.age = age
# And so on...
```
Every API, every service, every application reinvents these basic types. We have schemas, DTOs, POJOs, models, and interfaces—all representing the same concepts in slightly different ways.
Solutions like Schema.org tried to standardize these definitions, but they weren't flexible enough or easy enough to integrate with existing systems. The problem persists: we lack a universal language for describing digital objects.
## A Universal Language for Digital Objects
We believe that clear communication requires a common language—not just for simple API requests and responses, but for complex digital relationships, contracts, and behaviors. That's why Blue is the **B**asic **L**anguage that **U**nifies **E**xperience.
Blue lets you define an object once and use it everywhere, across systems, programming languages, and organizations.
## The Core Idea: Content-Addressable Types
The key innovation in Blue is that every document has a unique content hash called a **blueId**. This is essentially a single word that uniquely represents specific content.
You can try it yourself at [web.blue/blue-id-calculator](https://web.blue/blue-id-calculator)
Let's start with a simple type definition:
```yaml
name: Simple Amount
amount:
type: Double
currency:
type: Text
```
This has the blueId `FgHZjSNb8X9zty82ps4eRkVVuhpPG6ajSGvG6HKKrhUq` - a unique fingerprint of its content.
Now we can define another type that uses this one:
```yaml
name: Person
age:
type: Integer
spent:
type:
blueId: FgHZjSNb8X9zty82ps4eRkVVuhpPG6ajSGvG6HKKrhUq # Simple Amount
```
This `Person` type has blueId `GRwTYsr32pieyWQH1PAFrQAWBUCbKivH4K9yYC8hFHaU`.
## Creating Instances with Types
Now we can create an actual person:
```yaml
name: Alice
type:
blueId: GRwTYsr32pieyWQH1PAFrQAWBUCbKivH4K9yYC8hFHaU # Person
age: 25
spent:
amount: 27.15
currency: USD
```
This instance has blueId `3JTd8soWugBAfxBAYKuScmmvbdgFw9SVp7fPdJgrAUVn`.
## The Magic of Meaning-Based Identity
Here's where it gets interesting. You'll get the _exact same blueId_ if you expand all the type references:
```yaml
name: Alice
type:
name: Person
age:
type: Integer
spent:
type:
name: Simple Amount
amount:
type: Double
currency:
type: Text
age: 25
spent:
amount: 27.15
currency: USD
```
This produces the same blueId: `3JTd8soWugBAfxBAYKuScmmvbdgFw9SVp7fPdJgrAUVn`
This is a core principle of Blue: **documents with the same meaning have the same blueId, regardless of how they're represented.**
## Simplifying with Names
For convenience, you can use type names directly with the `blue` directive:
```yaml
blue: https://language.blue/simple.blue
name: Alice
type: Person
age: 25
spent:
amount: 27.15
currency: USD
```
This tells processors where to find the type definitions. Throughout this documentation, we'll use this convention to keep examples clean and focused.
## Extension and Type Safety
In Blue, every document can be a type for another document:
```yaml
name: Alice Extended
type: Alice
smiling: true
friends:
type: List
itemType: Person
```
Every `Alice Extended` must be an `Alice`. If fields like `age` or `spent` were already set in `Alice`, they cannot be overwritten—you can only add new attributes or complete those that weren't specified earlier.
This creates a strong type system without requiring a centralized registry of types.
## Language Integration
Blue isn't just a document format—it integrates with your programming language of choice. For Java:
```java
@TypeBlueId("FgHZjSNb8X9zty82ps4eRkVVuhpPG6ajSGvG6HKKrhUq")
@AllArgsConstructor
public class SimpleAmount {
Double amount;
String currency;
}
@TypeBlueId("GRwTYsr32pieyWQH1PAFrQAWBUCbKivH4K9yYC8hFHaU")
@AllArgsConstructor
public class Person {
String name;
Integer age;
SimpleAmount spent;
}
// Creating and using a Blue document
Person alice = new Person("Alice", 25, new SimpleAmount(27.15, "USD"));
Blue blue = new Blue();
// Calculate the blueId
String blueId = blue.calculateBlueId(alice);
assert blueId.equals("3JTd8soWugBAfxBAYKuScmmvbdgFw9SVp7fPdJgrAUVn");
// Convert to YAML
String yaml = blue.objectToYaml(alice);
```
The calculated blueId will match the one from our YAML examples, and the generated YAML will be semantically equivalent.
## Reusing Existing Types
Rather than defining all types yourself, you can import libraries from [repo.blue](https://repo.blue) and other sources. This gives you immediate access to standard types like `Person`, `Address`, `Payment`, and more specialized industry-specific types.
For popular types, language-specific libraries are available:
```bash
# JavaScript/TypeScript
npm install @blue-repository/identity-types
# Java
blue.repositoryidentity-types1.0.0
# Python
pip install blue-repository-identity-types
```
This eliminates the need to reinvent common structures and ensures consistent definitions across systems and organizations.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/language/types.md
# Type System and Extension
In the previous section, we introduced the basic concept of types in Blue. Now, let's explore the type system more deeply, seeing how it enables powerful inheritance and extension models while maintaining strict compatibility.
:::note
For clarity, most examples in this documentation omit the `blue:` directive that would typically be required in practice. Learn more about this directive in the [Blue Directive](./blue-directive) section.
:::
## Building Type Hierarchies
Blue's type system allows you to create sophisticated inheritance hierarchies where more specialized types extend general ones:
```yaml
name: Product
price:
amount:
type: Number
contracts:
amountValidator:
type: Schema Validator
minimum: 0
currency:
type: ISO-4217 Currency Code
sku:
type: Text
```
The `contracts` section introduces an important Blue concept: contracts define special behaviors for documents or fields. Here, the Schema Validator contract enforces constraints on the `price.amount` field. You'll learn more about contracts in the [Contracts section](../contracts/introduction).
Note that all fields in Blue are optional by default. If you want to make a field required, you need to add that constraint explicitly:
```yaml
name: Electronics
type: Product
manufacturer:
type: Text
contracts:
requiredFieldValidator:
type: Schema Validator
required: true # This field must be present
```
## Specialization with Constraints
Let's create more specialized product types by adding both fields and constraints:
```yaml
name: Smartphone
type: Electronics
screenSize:
type: Number
contracts:
screenSizeValidator:
type: Schema Validator
minimum: 3.5
maximum: 7.5
operatingSystem:
type: Text
contracts:
osOptionsValidator:
type: Schema Validator
options: ['iOS', 'Android']
```
You can also define field types separately for reuse:
```yaml
name: Operating System
type: Text
contracts:
osOptionsValidator:
type: Schema Validator
options: ['iOS', 'Android']
name: Smartphone
type: Electronics
screenSize:
type: Number
contracts:
screenSizeValidator:
type: Schema Validator
minimum: 3.5
maximum: 7.5
operatingSystem:
type: Operating System
```
Both approaches achieve the same result, giving you flexibility in how you organize your types.
Let's continue building our hierarchy:
```yaml
name: iPhone
type: Smartphone
operatingSystem: iOS # Fixed value for all iPhones
model:
type: Text
contracts:
modelValidator:
type: Schema Validator
required: true
```
## Inheriting and Adding Contracts
When you extend a type, you inherit all its contracts. To add additional constraints to fields, use new contracts with descriptive names:
```yaml
name: Premium Smartphone
type: Smartphone
price:
amount:
contracts:
premiumPriceValidator:
type: Schema Validator
minimum: 599.99 # Additional constraint on price amount
```
When resolved, the `price.amount` field will have both the `amountValidator` from `Product` (requiring ≥ 0) and the `premiumPriceValidator` from `Premium Smartphone` (requiring minimum 599.99). Together, these effectively restrict price to be minimum 599.99 if present.
This ability to progressively add constraints is powerful for modeling domain-specific rules that build upon more general ones.
## Multi-Level Inheritance
Blue supports multi-level inheritance, allowing you to create deeply specialized types:
```yaml
name: iPhone 14
type: iPhone
model: '14' # Fixed value for all iPhone 14s
storage:
type: Text
contracts:
storageOptionsValidator:
type: Schema Validator
options: ['128GB', '256GB', '512GB', '1TB']
```
When we create an instance:
```yaml
name: iPhone 14 128GB
type: iPhone 14
storage: '128GB'
price:
amount: 799.99
currency: USD
color: Blue
```
The document inherits all properties from the entire inheritance chain, including the fixed values `operatingSystem: iOS` from the `iPhone` type and `model: "14"` from the `iPhone 14` type.
## Type Enforcement Rules
The Blue type system enforces strict rules during inheritance:
1. **No Overriding Values**: If a parent type defines a field value, child types inherit exactly that value and cannot change it
2. **Type Compatibility**: If a parent type defines a field's type, child types must use the same or a compatible subtype
3. **Additive Properties Only**: Child types can add new properties but cannot remove inherited ones
For example, these would be invalid:
```yaml
# INVALID - trying to change inherited fixed value
name: InvalidiPhone
type: iPhone
operatingSystem: Android # Cannot override 'iOS' value from iPhone type
```
```yaml
# INVALID - trying to change the type of 'price.amount'
name: InvalidProduct
type: Product
price:
amount:
type: Text # Cannot override Number type from Product
```
These strict rules ensure that a fundamental principle holds true: **Every instance of a subtype is also a valid instance of its parent type**. This means every "iPhone 14" is an "iPhone", every "iPhone" is a "Smartphone", and so on up the type hierarchy.
This principle—known as the Liskov Substitution Principle in object-oriented design—is strictly enforced in Blue's type system.
## Working with Collections
Blue supports two primary collection types—lists and dictionaries—that let you build complex data structures:
```yaml
# A product bundle with a list of items
name: Starter Tech Bundle
bundlePrice:
amount: 1299.99
currency: USD
items:
type: List
itemType: Product
- type: Smartphone
name: iPhone 14
model: "14"
storage: "128GB"
price:
amount: 799.99
currency: USD
- type: Electronics
name: Wireless Earbuds
manufacturer: Apple
price:
amount: 249.99
currency: USD
- type: Electronics
name: Wireless Charger
manufacturer: Belkin
price:
amount: 49.99
currency: USD
```
```yaml
# Inventory management with product counts
name: Store Inventory
stock:
type: Dictionary
keyType: Text
valueType: Integer
'iPhone 14 128GB Black': 23
'iPhone 14 256GB Black': 15
'iPhone 14 Pro 128GB Silver': 8
'Samsung Galaxy S23': 12
```
These examples demonstrate how collections enable complex data modeling while maintaining Blue's strict typing:
- The `items` list can contain any `Product` subtype
- The `stock` dictionary maps product names to their inventory counts
## Programming Language Integration
Blue types map cleanly to object-oriented programming concepts:
```java
// Define classes mapped to Blue types
@TypeBlueId("Price-BlueId")
public class Price {
private Double amount;
private String currency;
}
@TypeBlueId("Product-BlueId")
public class Product {
private String name;
private String description;
private Price price;
private String sku;
}
// Specialization with enum for type-safe values
public enum OperatingSystem {
IOS, ANDROID
}
@TypeBlueId("Smartphone-BlueId")
public class Smartphone extends Product {
private Double screenSize;
private OperatingSystem operatingSystem;
}
// Converting between YAML and Java objects
String phoneYaml = """
name: iPhone 14
type: Smartphone
price:
amount: 799.99
currency: USD
screenSize: 6.1
operatingSystem: IOS
""";
// Convert YAML to Java object
Blue blue = new Blue(nodeProvider);
Smartphone phone = blue.yamlToObject(phoneYaml, Smartphone.class);
// Verify the conversion
assert phone.getName().equals("iPhone 14");
assert phone.getPrice().getAmount() == 799.99;
assert phone.getPrice().getCurrency().equals("USD");
assert phone.getOperatingSystem() == OperatingSystem.IOS;
```
This bidirectional mapping ensures that Blue documents can be seamlessly converted to strongly-typed language objects and back again.
## Resolving Documents
When a Blue processor encounters a document with type references, it performs "resolution" to fully expand all types:
```yaml
# Before resolution
name: iPhone 14 Pro 256GB Black
type: iPhone 14
storage: "256GB"
color: Black
price:
amount: 1099.99
currency: USD
# After resolution (blueId: 9pq5Enj1LFqQskQShJwK9ERU8u2CLfnP2KbeaufYJyNm)
name: iPhone 14 Pro 256GB Black
type:
name: iPhone 14
type:
name: iPhone
type:
name: Smartphone
type:
name: Electronics
type:
name: Product
price:
amount:
type: Number
contracts:
amountValidator:
type: Schema Validator
minimum: 0
currency:
type: ISO-4217 Currency Code
sku:
type: Text
manufacturer:
type: Text
contracts:
requiredFieldValidator:
type: Schema Validator
required: true
screenSize:
type: Number
contracts:
screenSizeValidator:
type: Schema Validator
minimum: 3.5
maximum: 7.5
operatingSystem: iOS
model: "14"
storage:
type: Text
contracts:
storageOptionsValidator:
type: Schema Validator
options: ["128GB", "256GB", "512GB", "1TB"]
storage: "256GB"
color: Black
price:
amount: 1099.99
currency: USD
```
Resolution creates a fully expanded document that contains all inherited properties and constraints. This ensures consistent validation and behavior across different processors.
You can perform resolution using the Blue library:
```java
// Parse the document
Blue blue = new Blue(nodeProvider);
Node node = blue.yamlToNode(yaml);
// Resolve types
Node resolved = blue.resolve(node);
// Convert back to YAML
String resolvedYaml = blue.nodeToYaml(resolved);
```
## Verifying Type Relationships
You can check if one document is a valid subtype of another:
```java
boolean isIPhone = blue.nodeMatchesType(myPhone, iPhone); // true
boolean isSmartphone = blue.nodeMatchesType(myPhone, smartphone); // true
boolean isProduct = blue.nodeMatchesType(myPhone, product); // true
```
This enables type-safe operations in your applications when working with Blue documents.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/language/blue-id.md
# BlueId: Universal Content Addressing
In previous sections, we explored Blue's type system and document inheritance. Now, let's focus on the heart of Blue's referencing system: the BlueId—a unique identifier based on content rather than location.
## Beyond Traditional Identifiers
Traditional identifiers tell you where to find something:
- URLs point to server locations
- Database IDs reference rows in tables
- UUIDs are assigned to specific objects
In contrast, a BlueId represents what something is—its actual content and meaning. This creates a fundamentally different way of referencing digital objects:
```yaml
# Traditional approach
{
"id": "8f7d3c2e-1a5b-4f9c-8d7e-6b2c1a3f4e5d",
"name": "iPhone 14",
"price": 799.99
}
# Blue approach
name: iPhone 14
price: 799.99
# This document's BlueId is HxvqaVPopn9w8CuVAp4YpVbiaEG25MmZY1UVZ4nA1hxV
```
The BlueId is not stored in the document—it's derived from the content itself.
## The Web of Meaning
Every BlueId represents a "word" in a vast language of digital content:
- Each document node has its own BlueId
- The same content always has the same BlueId
- BlueIds can reference content across systems and organizations
- Multiple documents can incorporate the same content via BlueId
This creates a web of interconnected content where references are based on meaning, not location:
Traditional integration approaches require us to constantly reinvent and redefine our data models. It's like meeting new people and having to teach them the words for "apple," "orange," and "dog" every time. Blue offers a different approach—a shared semantic web where concepts are universally addressable.
Instead of trading isolated schemas and models, we're building a collective knowledge network. Any system can reference any node in this web without prior coordination. Your "Person" type can be immediately understood and used by others without custom mapping or translation.
This network is continuously enriched as more systems adopt Blue. Common patterns naturally emerge, and specialized domains can extend standard types without breaking compatibility. It's a living language that grows organically with use.
## BlueId Calculation
BlueId is a content hash calculated for every document using a bottom-up approach, starting from the deepest layer and propagating upwards. Technically, it's a base58-encoded SHA-256 hash of canonicalized JSON (following RFC8785 standards) for each node in the document. This ensures:
- Uniqueness: Any change in the content results in a new BlueId
- Integrity: Documents reference each other unambiguously
- Interconnectedness: Documents can be linked, forming a web of interconnected content
The specific normalization procedures and implementation details are available in the [Specification: BlueId Calculation](../advanced/formal-specification.md#blueid-calculation) section.
## Walking the Blue Web
One of Blue's powerful capabilities is exploring this semantic web by retrieving referenced content as needed. Starting with any BlueId, you can "extend" outward to explore connected nodes.
For example, with our "Alice" document from earlier:
```yaml
# Starting point - just the BlueId
blueId: 3JTd8soWugBAfxBAYKuScmmvbdgFw9SVp7fPdJgrAUVn
```
We can extend one level to see the immediate properties:
```java
Node node = blue.blueIdToNode("3JTd8soWugBAfxBAYKuScmmvbdgFw9SVp7fPdJgrAUVn");
Node oneLevelExtended = blue.extend(node, PathLimits.withSinglePath("/*"));
```
Which produces:
```yaml
name: Alice
type:
blueId: GRwTYsr32pieyWQH1PAFrQAWBUCbKivH4K9yYC8hFHaU # Person
age: 25
spent:
blueId: HB8H2fLKAVZcEcqh19HiTehXjy25d22MMF6wAVvDzC4i # 27.15 USD
```
We can explore specific paths more deeply:
```java
Node spentExtended = blue.extend(node, PathLimits.withSinglePath("/spent/*"));
```
```yaml
name: Alice
type:
blueId: GRwTYsr32pieyWQH1PAFrQAWBUCbKivH4K9yYC8hFHaU # Person
age: 25
spent:
amount: 27.15
currency: USD
```
## Practical Example: E-Commerce System
Let's explore a more complex real-world example showing how BlueIds connect multiple documents in an e-commerce system:
```yaml
# Customer order with BlueId references
name: Order #12345
date: 2023-06-15
customer:
blueId: 3JTd8soWugBAfxBAYKuScmmvbdgFw9SVp7fPdJgrAUVn # Alice
items:
- product:
blueId: HxvqaVPopn9w8CuVAp4YpVbiaEG25MmZY1UVZ4nA1hxV # iPhone 14
quantity: 1
- product:
blueId: 8xYi5Svou5DVawB7CDEGuZitUGFChRYcJUF67bQ3NfXt # Wireless Earbuds
quantity: 2
catalog:
blueId: kL9mN0pQrStUvWxYz1A2B3C4D5E6F7G8H4FGh7j8 # Full product catalog
```
In this example, the order references:
- A customer profile (Alice)
- Individual products being ordered
- The entire product catalog (potentially thousands of products)
The order document remains lightweight because it only contains BlueId references to these larger entities. If we need customer details, we can extend just that path:
```java
Node orderWithCustomer = blue.extend(order, PathLimits.withSinglePath("/customer/**"));
```
```yaml
name: Order #12345
date: 2023-06-15
customer:
name: Alice
type:
name: Person
# Full Person type definition
age: 25
spent:
amount: 27.15
currency: USD
items:
- product:
blueId: HxvqaVPopn9w8CuVAp4YpVbiaEG25MmZY1UVZ4nA1hxV # iPhone 14
quantity: 1
- product:
blueId: 8xYi5Svou5DVawB7CDEGuZitUGFChRYcJUF67bQ3NfXt # Wireless Earbuds
quantity: 2
catalog:
blueId: kL9mN0pQrStUvWxYz1A2B3C4D5E6F7G8H4FGh7j8 # Full product catalog
```
## Extension Risk Management
Extend carefully! Some BlueIds can represent enormous amounts of data:
- The `catalog` BlueId in our example might contain thousands of products, each with detailed specifications
- A BlueId representing Wikipedia would contain millions of interconnected articles
- A [Timeline](../timelines/introduction) of an active user could contain years of activity records
As in real life, you rarely need to download all knowledge—just the parts relevant to your current task. Blue's extension mechanism lets you precisely control how much data you retrieve.
## web.blue: The Blue Explorer
Web.blue is a website that helps you explore the Blue web. You can provide your own node providers—components that map BlueIds to documents—and visualize content in multiple ways:
As a document:

Or as an interactive graph that you can traverse:
 
Web.blue demonstrates how BlueIds enable document exploration without prior knowledge of structure. The restaurant menu example loads gradually as content is retrieved from IPFS, showing how Blue documents can be distributed across decentralized storage systems.
This approach solves a fundamental web problem: content disappearing when URLs change. With BlueIds, you have the fingerprint of content, allowing you to retrieve it from any source that has it. The mapping between BlueIds and IPFS Content Identifiers follows specific transformation rules detailed in the [Java implementation](https://github.com/bluecontract/blue-language-java/blob/master/src/main/java/blue/language/provider/ipfs/BlueIdToCid.java) section.
## Why BlueId Matters
The BlueId approach provides several unique advantages:
1. **Semantic References**: References point to meaning, not just bytes
2. **Universal Vocabulary**: Every piece of content has a unique "word" that identifies it
3. **Location Independence**: Content can move between systems while references remain valid
4. **Natural Deduplication**: Identical content is automatically unified
5. **Verifiable Content**: BlueIds serve as built-in integrity checks
Compare this with other hash-based systems:
| System | What it Hashes | Purpose |
| --------------- | -------------------------------------------- | ------------------------------------------ |
| BlueId | Semantic structure with meaning preservation | Content-addressing with semantic awareness |
| Git Hash | File content + metadata | Version control |
| IPFS CID | Raw bytes | File storage |
| Blockchain Hash | Transaction data | Transaction verification |
The key distinction is that BlueId preserves meaning, not just structure or bytes.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/language/blue-directive.md
# The Blue Directive
While Blue enforces a rigorous structure internally, it aims to be as user-friendly as possible for document authors. The `blue` directive bridges this gap by transforming human-friendly documents into proper Blue documents before processing begins.
## Preprocessing with the Blue Directive
The `blue` directive appears at the root level of a document and specifies transformations to apply during preprocessing:
```yaml
blue: Ticket Details v1.0
Ticket Number: ABC-12345
Departure Date: 2023-10-15
Seat: 14A
```
Preprocessing occurs before any other document processing, including BlueId calculation. This ensures that:
1. The original document can be user-friendly and flexible
2. The resulting document strictly follows Blue conventions
3. The BlueId is calculated only after preprocessing completes
The `blue` directive itself is removed during preprocessing, meaning it doesn't affect the document's BlueId or semantic content.
## Common Transformations
Let's explore the most useful transformations that can be included in the `blue` directive:
### Replace Inline Types with BlueIds
This transformation converts simple type names to their full BlueId references:
```yaml
blue:
- type:
blueId: 27B7fuxQCS1VAptiCPc2RMkKoutP5qxkh3uDxZ7dr6Eo
mappings:
Person: 8xYi5Svou5DVawB7CDEGuZitUGFChRYcJUF67bQ3NfXt
Dog: G1pcQx2tq16z5yVqE9TGaCH5uCDAaMZ6uFts7d3NztYo
name: Alice Smith
type: Person
pet:
type: Dog
name: Rex
```
After preprocessing:
```yaml
name: Alice Smith
type:
blueId: 8xYi5Svou5DVawB7CDEGuZitUGFChRYcJUF67bQ3NfXt
pet:
type:
blueId: G1pcQx2tq16z5yVqE9TGaCH5uCDAaMZ6uFts7d3NztYo
name: Rex
```
This transformation (BlueId: `27B7fuxQCS1VAptiCPc2RMkKoutP5qxkh3uDxZ7dr6Eo`) allows you to write documents with simple type names that humans can understand.
### Infer Basic Types For Untyped Values
This transformation automatically determines types for primitive values:
```yaml
blue:
- type:
blueId: FGYuTXwaoSKfZmpTysLTLsb8WzSqf43384rKZDkXhxD4
x: 12
y: true
z: Hello
```
After preprocessing:
```yaml
x:
type: Integer
value: 12
y:
type: Boolean
value: true
z:
type: Text
value: Hello
```
This transformation (BlueId: `FGYuTXwaoSKfZmpTysLTLsb8WzSqf43384rKZDkXhxD4`) eliminates the need to explicitly specify types for every value.
### Convert Attribute Names To Camel Case
This transformation standardizes field names to programming-friendly format:
```yaml
blue:
- type:
blueId: GpMaofZmtLhEQbwkaYd3hm6Es1udEySM6svg8UoN1yEH
Seat No.: 156
Arrival Time: 15:25
```
After preprocessing:
```yaml
seatNo: 156
arrivalTime: 15:25
```
This transformation (BlueId: `GpMaofZmtLhEQbwkaYd3hm6Es1udEySM6svg8UoN1yEH`) makes documents both human-readable and programming-friendly.
### Normalize DateTime Values
This transformation converts date strings to structured DateTime objects:
```yaml
blue:
- type:
blueId: 93nhEGAmviA5Ey8wZ4ZfeHheAbzvxz473rG92zznvTps
datetimePattern: yyyy-MM-dd HH:mm
arrival: 2025-03-27 15:25
```
After preprocessing:
```yaml
arrival:
type: DateTime
year: 2025
month: 3
day: 27
hour: 15
minute: 25
```
This transformation (BlueId: `93nhEGAmviA5Ey8wZ4ZfeHheAbzvxz473rG92zznvTps`) allows human-readable dates while ensuring proper structural representation.
### Map Attribute Names
This transformation translates field names between languages or formats:
```yaml
blue:
- type:
blueId: 27B7fuxQCS1VAptiCPc2RMkKoutP5qxkh3uDxZ7dr6Eo
mappings:
チケット整理番号: ticketSerial
出発日時: departure
座席番号: seatNo
チケット整理番号: HL-923554
出発日時: 2025-03-27 15:25
座席番号: 15
```
After preprocessing:
```yaml
ticketSerial: HL-923554
departure: 2025-03-27 15:25
seatNo: 15
```
This enables content creation in any language while maintaining consistent field names in the processed document.
## Default Blue Directive
Every Blue document has an implicit default `blue` directive if none is specified:
```yaml
blue:
- type:
blueId: 27B7fuxQCS1VAptiCPc2RMkKoutP5qxkh3uDxZ7dr6Eo
mappings:
Text: F92yo19rCcbBoBSpUA5LRxpfDejJDAaP1PRxxbWAraVP
Double: 68ryJtnmui4j5rCZWUnkZ3DChtmEb7Z9F8atn1mBSM3L
Integer: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
Boolean: EL6AjrbJsxTWRTPzY8WR8Y2zAMXRbydQj83PcZwuAHbo
List: G8wmfjEqugPEEXByMYWJXiEdbLToPRWNQEekNxrxfQWB
Dictionary: 294NBTj2mFRL3RB4kDRUSckwGg7Kzj6T8CTAFeR1kcSA
- type:
blueId: FGYuTXwaoSKfZmpTysLTLsb8WzSqf43384rKZDkXhxD4
```
This default directive (BlueId: `EWj6aMM5nRAS9hYmrJXpJeL6zNRCVtZJguan9b4ZqJN7`) provides mappings for basic types and enables type inference.
## A Complete Example
Let's see what happens when we apply multiple transformations together:
```yaml
blue: Ticket Details v.1.51
Ticket Serial No.: HL-923554
Departure: 2025-03-27 15:25
Seat No.: 15
```
After all transformations:
```yaml
ticketSerial:
type:
blueId: F92yo19rCcbBoBSpUA5LRxpfDejJDAaP1PRxxbWAraVP
value: HL-923554
departure:
type:
blueId: 4UevQMiUg5BjYe9sX26xf4QHgFoKPmf7JVAM9wk4bmzR
year:
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
value: 2025
month:
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
value: 3
day:
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
value: 27
hour:
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
value: 15
minute:
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
value: 25
seatNo:
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8
value: 15
```
The BlueId of this fully processed document is `2YUzCvdTQKB34MutfhsKHEEbdNqJL6FVPNvNcVVvBJDP`.
## The Power of Text Aliases
One of the most powerful aspects of the Blue directive is the ability to use text aliases for transformation sets:
```yaml
blue: Ticket Details v.1.51
Ticket Serial No.: HL-923554
Departure: 2025-03-27 15:25
Seat No.: 15
```
```yaml
blue: Ticket Details v.1.51 JP
チケット整理番号: HL-923554
出発日時: 2025-03-27 15:25
座席番号: 15
```
Despite being written in different languages, both documents preprocess to identical structures with the same BlueId: `2YUzCvdTQKB34MutfhsKHEEbdNqJL6FVPNvNcVVvBJDP`.
To make this work, you register aliases with your Blue processor:
```java
blue.addPreprocessingAliases(Map.of(
"Ticket Details v.1.51", "5VEx7ee9to3Z56eVdkNzBfpHaZU9KD4moYttpS5h6bHt",
"Ticket Details v.1.51 JP", "3wfkqtvZvgiff55ZhrtToK3sDcPHvKKY5DcZw68nor3i"
));
```
## URL References and Security
The `blue` directive can also reference a URL:
```yaml
blue: https://language.blue/simple.blue
name: Alice
type: Person
age: 25
```
For security reasons, URL fetching is disabled by default in most Blue processors. To enable it:
```java
blue.enablePreprocessingDirectivesFetchForUrls();
```
:::caution
Enabling URL fetching creates potential security vulnerabilities. Use registered aliases in production systems.
:::
## Creating Custom Transformations
Anyone can define custom transformations for specialized preprocessing needs. These transformations must be registered with processors that need to understand them.
----------------------------------------
NEW SECTION: contracts
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/introduction.md
# Introduction to Contracts
Blue contracts are the foundation of dynamic, event-driven behavior in Blue documents. While the Blue language itself provides structure and content addressing, contracts bring documents to life by defining how they respond to events and interact with the world.
## What Are Blue Contracts?
Blue contracts are components within documents that define:
1. **Event channels** that documents listen to
2. **Processing rules** determining how to handle events
3. **State transitions** that update document content
4. **Operations** that documents expose to the outside world
Unlike traditional smart contracts on blockchain platforms, Blue contracts don't require global consensus or a specific runtime environment. Instead, they focus on deterministic behavior that any compliant processor can verify independently.
## Core Philosophy
Blue contracts are built on four key principles:
- **Event-Driven Architecture**: Documents react to events from multiple sources
- **Deterministic Processing**: Given the same inputs, deterministic contracts produce identical results across all processors
- **Channel-First Design**: All interactions begin with channels
- **Composable Behavior**: Contracts combine to create sophisticated applications
## Core Components
### 1. Channels
Channels are the entry points for all events into a document:
```yaml
contracts:
userTimeline:
type: Timeline Channel
account: alice@example.com
```
Every event that affects a document must enter through a channel. Channels can represent user timelines, document changes, REST API endpoints, or external systems.
### 2. Handlers
Handlers process events from channels and execute business logic:
```yaml
contracts:
paymentHandler:
type: Sequential Workflow
channel: paymentEvents
steps:
- name: Verify Amount
# Step details...
```
The most common handler is the Sequential Workflow, which executes a series of steps in response to events.
### 3. Additional Contract Types
Beyond channels and handlers, Blue supports other specialized contracts:
```yaml
contracts:
schemaValidator:
type: Schema Validator
amount:
minimum: 0
maximum: 1000000
```
These contracts serve specific purposes like validating document content, defining operations that others can invoke, or specifying how processors should handle the document. Each contract type focuses on a particular aspect of document behavior.
## Hierarchical Processing
Blue documents can contain nested nodes with their own contracts:
```yaml
name: Payment Agreement
status: pending
btcPayment:
type: BTC Payment
contracts:
btcChannel:
# BTC-specific contracts
contracts:
statusChannel:
# Parent document contracts
```
When processing such documents, the processor evaluates all contracts at all levels of the hierarchy, creating a composed system that respects all defined behaviors.
## Document Processing Mechanics
The Blue processing model follows a single-event pattern:
1. An event arrives at a document through a channel
2. The processor identifies workflows listening to that channel
3. Workflows execute their logic, potentially updating the document
4. If updates occur, Document Update Channels may trigger additional processing
5. Workflows may also emit new events, causing further processing
6. This cycle continues until the document reaches a stable state
7. The processor returns the final updated document and any triggered events
This approach ensures that all compliant processors will reach exactly the same final state, given the same inputs. The deterministic nature of this processing is fundamental to Blue's trust model - allowing independent verification without requiring global consensus.
A critical aspect of this model is maintaining consistent event ordering when processing events from multiple channels, and ensuring that all processors reference the same external reality. For example, when processors handle events from external systems like cryptocurrency transactions or sports results, they must agree on the canonical source of truth. Blue addresses these challenges through channel coordination patterns and specialization mechanisms, which we'll explore in detail in the "Channel-Based Event Model" section.
## Comparison to Traditional Smart Contracts
| Feature | Blue Contracts | Blockchain Smart Contracts |
|---------|---------------|----------------------------|
| Execution Environment | Any Blue processor | Specific blockchain VM |
| Consensus Mechanism | Independent verification | Global network consensus |
| State Storage | Document-centric | Global ledger |
| Integration Approach | Multiple channels | Limited oracle integrations |
| Privacy Model | Flexible, document-specific | Public by default |
| Scripting Capabilities | JavaScript and more | Platform-specific language |
| Reality Model | Multiple verified perspectives | Single global state |
Blue's approach mirrors real-world reasoning - individuals independently observe events, apply shared rules, and reach compatible conclusions without central coordination. Unlike blockchain's enforced global consensus, Blue enables multiple valid perspectives while maintaining verification through clear rules and shared evidence. This provides flexibility without sacrificing trust, allowing systems to model reality more naturally.
## A Minimal Example
Here's a complete working example of a Blue document with contracts:
```yaml
name: Simple Counter
counter: 0
contracts:
# Define a channel for events
incrementChannel:
type: Timeline Channel
account: user@example.com
# Define a workflow for those events
counterWorkflow:
type: Sequential Workflow
channel: incrementChannel
steps:
- name: Increment Counter
type: Update Document
changeset:
- op: replace
path: /counter
val: ${document('/counter') + 1}
```
This document listens to a timeline and increments a counter each time an event arrives.
## Processing Example
Here's how this document would be processed in Java:
```java
// Parse the document
Blue blue = new Blue(nodeProvider);
Node doc = blue.yamlToNode(yaml);
// Create a processor for the document
DocumentProcessor processor = blue.processor(doc);
// Process an incoming event
ProcessingResult result = processor.processEvent(timelineEvent);
// Get the updated document and triggered events
Node updatedDoc = result.getUpdatedDocument();
List triggeredEvents = result.getTriggeredEvents();
// The counter is now incremented
// updatedDoc will have counter = 1
```
We can also convert the Blue document to a Java object:
```java
// Define a Java class representing the document
@Data
public class SimpleCounter {
private int counter;
}
// Convert the updated document to a Java object
SimpleCounter simpleCounter = blue.nodeToObject(updatedDoc, SimpleCounter.class);
// Access the counter property
assert simpleCounter.getCounter() == 1;
```
This example demonstrates the complete lifecycle of contract processing:
1. An event arrives through the `incrementChannel`
2. The `counterWorkflow` processes the event
3. The document is updated with counter incremented
4. The processor returns the updated document
5. The document can be mapped to Java objects for easier manipulation
Each processor following the Blue contract specification will reach identical results when processing the same events in the same order.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/checkpoints.md
# Processing Checkpoints
Blue documents evolve as they process events, changing their state—and therefore their BlueId—while maintaining their fundamental identity. Processing checkpoints capture this temporal dimension, serving as formal markers in a document's ongoing journey.
## The Need for State Tracking
Consider a document that processes events from a timeline:
```yaml
name: Simple Counter
counter: 0
contracts:
incrementChannel:
type: Timeline Channel
account: user@example.com
counterWorkflow:
type: Sequential Workflow
channel: incrementChannel
steps:
- name: Update Counter
type: Update Document
changeset:
- op: replace
path: /counter
val: ${document('/counter') + 1}
```
As this document processes events, its state changes:
- After one event: `counter: 1`
- After two events: `counter: 2`
- After three events: `counter: 3`
Each state change creates a new BlueId—a new content hash representing the document's new reality. Without some record of which events created this state, processors would have no way to know where in the event stream this document currently exists.
## The Processing Checkpoint Contract
The Processing Checkpoint contract serves as a formal record of a document's position in time:
```yaml
name: Simple Counter
counter: 2
contracts:
incrementChannel:
type: Timeline Channel
account: user@example.com
counterWorkflow:
type: Sequential Workflow
channel: incrementChannel
steps:
- name: Update Counter
type: Update Document
changeset:
- op: replace
path: /counter
val: ${document('/counter') + 1}
checkpoint:
type: Processing Checkpoint
# Implementation details follow
```
This contract is optional, but when present, processors are expected to automatically update it after processing each event, maintaining an accurate record of the document's temporal position.
## Common Checkpoint Types
The Blue language allows various checkpoint implementations. Here are the most common types:
### Channel Event Checkpoint
This approach records the BlueId of the last processed event from each channel:
```yaml
checkpoint:
type: Channel Event Checkpoint
lastEvents:
incrementChannel:
blueId: 7UEBwTmRMfQ92rGt4vHkzPa8Ypd5KJsLNcA3FV6xDqbn # Last processed event
```
This approach:
- Provides exact tracking of which events were processed
- Works reliably across decentralized processors
- Supports multi-channel documents with independent event streams
For documents with multiple channels, all are tracked independently:
```yaml
checkpoint:
type: Channel Event Checkpoint
lastEvents:
userChannel:
blueId: 7UEBwTmRMfQ92rGt4vHkzPa8Ypd5KJsLNcA3FV6xDqbn
paymentChannel:
blueId: CgJ83PcZwuAHboEL6AjrbJsxTWRTPzY8WR8Y2zAMXRbyd
weatherChannel:
blueId: JXiEdbLToPRWNQEekNxrxfQWBG8wmfjEqugPEEXByMYW
```
### Timestamp Checkpoint
For some scenarios, a timestamp-based checkpoint is used:
```yaml
checkpoint:
type: Timestamp Checkpoint
timestamp: '2023-10-15T14:30:00Z' # Last processed event timestamp
```
Important considerations for timestamp checkpoints:
- The timestamp must be deterministic (typically derived from event timestamps)
- All processors must interpret time identically
- Precision must be sufficient to distinguish between events
Timestamp checkpoints work best in controlled environments where:
- Events have reliable timestamps
- Event ordering by time is consistent
- Time interpretation is standardized across processors
## The River of Time: Document Identity Across States
In traditional databases, identity is imposed externally: a record with ID 12345 remains "the same record" regardless of how its contents change. But in a content-addressed system like Blue, the fundamental question becomes more profound: what makes a document "the same document" when its content—and thus its BlueId—changes over time?
The answer lies in the Processing Checkpoint contract, which creates a formal history of causality. This history binds different document states together, creating a continuous identity through time:
```yaml
# The document in its past (BlueId: a1b2c3...)
name: Simple Counter
counter: 0
contracts:
# Channel and workflow definitions
checkpoint:
type: Channel Event Checkpoint
lastEvents:
incrementChannel: { blueId: null } # No events processed yet
```
```yaml
# The document in its present (BlueId: d4e5f6...)
name: Simple Counter
counter: 2
contracts:
# Channel and workflow definitions
checkpoint:
type: Channel Event Checkpoint
lastEvents:
incrementChannel: { blueId: 8Y2zAMXRbydQj83PcZwuAHboEL6AjrbJsxTWRTPzY }
```
These two documents have different BlueIds because their content has changed, yet they represent the same logical entity at different points in its lifecycle. The checkpoint creates a causal connection between them, showing how one evolved into the other.
This is more than just a technical feature—it's a formal model of identity through change. Like the philosophical Ship of Theseus which remains "the same ship" even as all its planks are replaced over time, a Blue document remains "the same document" through its processing history despite having completely different content and BlueId.
## The Three Temporal Dimensions
The Processing Checkpoint gives every document three temporal dimensions:
### 1. Verifiable Past
The checkpoint's record of processed events creates a verifiable history. Any processor can:
- Validate that the document legitimately evolved from a known earlier state
- Reproduce the document's current state by replaying events
- Verify the integrity of document processing
### 2. Known Present
The checkpoint itself represents the document's "now"—its current position in the event timeline. This gives processors:
- A clear understanding of what state the document represents
- Confidence in which events have been incorporated
- A foundation for consistent behavior across systems
### 3. Processable Future
By knowing exactly which events have been processed, the checkpoint enables:
- Precise continuation of processing from the current state
- Clear criteria for what constitutes a "new" event
- Orderly evolution to future states
## Automatic Checkpoint Management
Blue processors update checkpoints automatically after each event is processed:
```java
// Process an event
ProcessingResult result = processor.processEvent(event);
Node updatedDoc = result.getUpdatedDocument();
// The checkpoint is automatically updated
Node checkpoint = updatedDoc.getAsNode("/contracts/checkpoint/lastEvents/incrementChannel");
String lastEventId = checkpoint.getBlueId();
assert lastEventId.equals(event.getBlueId());
```
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/coordination.md
# Events from Multiple Sources
Blue documents often receive events from multiple channels. While each channel maintains its own ordering, a key challenge arises: how should events from different channels be sequenced relative to each other? This page explains how Blue handles this challenge through channel coordination contracts.
## The Multi-Channel Counter Problem
Let's start with a concrete example: a document that counts events from both Alice and Bob:
```yaml
name: Alice and Bob Counter
counterAlice: 0
counterBob: 0
contracts:
aliceChannel:
type: Timeline Channel
account: alice@example.com
bobChannel:
type: Timeline Channel
account: bob@example.com
aliceWorkflow:
type: Sequential Workflow
channel: aliceChannel
steps:
- name: Update Alice Counter
type: Update Document
changeset:
- op: replace
path: /counterAlice
val: ${document('/counterAlice') + 1}
bobWorkflow:
type: Sequential Workflow
channel: bobChannel
steps:
- name: Update Bob Counter
type: Update Document
changeset:
- op: replace
path: /counterBob
val: ${document('/counterBob') + 1}
```
This document works well when processed by a single processor that receives events in a fixed order. But what happens when multiple processors independently handle the same document? Without coordination, they might process the events in different orders, leading to different final states.
## The Coordination Problem
Consider this sequence of events:
1. Alice adds event A1 to her timeline
2. Bob adds event B1 to his timeline
3. Alice adds event A2 to her timeline
Processor 1 might see: A1 → B1 → A2
Processor 2 might see: A1 → A2 → B1
Processor 3 might see: B1 → A1 → A2
Without coordination, these processors will reach different document states, breaking Blue's deterministic processing guarantee. This is where channel coordination contracts become essential.
## Centralized Coordinator
For scenarios where centralized processing is acceptable, the Centralized Coordinator provides a straightforward solution:
```yaml
name: Alice and Bob Counter with Central Coordination
counterAlice: 0
counterBob: 0
contracts:
aliceChannel:
type: Timeline Channel
account: alice@example.com
bobChannel:
type: Timeline Channel
account: bob@example.com
channelCoordinator:
type: Centralized Coordinator
authority: myos.blue
channels: [aliceChannel, bobChannel]
# Workflows as before
```
### Benefits and Limitations
**Benefits:**
- Simple implementation
- Immediate ordering decisions
- No coordination overhead for participants
- Higher performance
**Limitations:**
- Requires trust in the central authority
- Creates a single point of failure
## Vector Clock Coordinator
The Vector Clock Coordinator enables decentralized coordination between independent timelines by implementing a logical clock system:
```yaml
name: Alice and Bob Counter with Vector Coordination
counterAlice: 0
counterBob: 0
contracts:
aliceChannel:
type: Timeline Channel
account: alice@example.com
bobChannel:
type: Timeline Channel
account: bob@example.com
channelCoordinator:
type: Vector Clock Coordinator
channels: [aliceChannel, bobChannel]
# Workflows as before
```
### How Vector Clock Coordination Works
This coordination mechanism:
1. Requires each timeline entry to include a vector clock (counters for all participants)
2. Establishes causal relationships between events based on these vectors
3. Orders concurrent events deterministically using timeline IDs
4. Ensures all processors reach the same event ordering
In practice, each timeline entry includes a vector showing what the participant has seen:
```yaml
# Example entry in Alice's timeline
type: Vector Clock Message
message: 'Increment counter'
vectorClock:
alice@example.com: 2 # Alice's timeline (incremented)
bob@example.com: 1 # Last seen event from Bob
```
The Vector Clock Coordinator enables resilient decentralized coordination even during network partitions, though it requires active participation from all channels.
For a detailed explanation of vector clocks with complex examples, see the [Vector Clock Coordination](../advanced/vector-clock) page.
### Benefits and Limitations
**Benefits:**
- Works in fully decentralized environments
- No central authority required
- Guarantees causal consistency
- Participants maintain autonomy
**Limitations:**
- Requires active participation from all channels
- Increases timeline entry complexity
- May delay event processing while waiting for acknowledgments
- Creates some performance overhead
## Ethereum Coordinator
The Ethereum Coordinator uses an Ethereum smart contract to establish a canonical ordering:
```yaml
name: Alice and Bob Counter with Blockchain Coordination
counterAlice: 0
counterBob: 0
contracts:
aliceChannel:
type: Timeline Channel
account: alice@example.com
bobChannel:
type: Timeline Channel
account: bob@example.com
channelCoordinator:
type: Ethereum Coordinator
contractAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'
chainId: 1
channels: [aliceChannel, bobChannel]
# Workflows as before
```
### How the Ethereum Coordinator Works
This coordination mechanism:
1. Requires participants to submit event hashes to an Ethereum smart contract
2. Uses the blockchain's ordering (block number and transaction index) to sequence events
3. Ensures all processors can independently verify the same sequence
The Ethereum smart contract typically implements a simple event registry:
```solidity
// Simple Event Registry Contract
contract EventRegistry {
event EventRegistered(bytes32 eventId, uint256 timestamp);
function registerEvent(bytes32 eventId) external {
emit EventRegistered(eventId, block.timestamp);
}
}
```
Processors observe the Ethereum blockchain to determine the canonical order of registered events.
### Benefits and Limitations
**Benefits:**
- Decentralized without requiring participant cooperation
- Provides tamper-resistant ordering
- Resistant to participant collusion
- Creates publicly verifiable evidence
**Limitations:**
- Higher cost (Ethereum gas fees)
- Slower confirmation times
- Requires Ethereum infrastructure
- Adds blockchain dependency
## Choosing a Coordination Strategy
When designing Blue documents with multiple channels, consider these factors:
1. **Trust Model**: Is a central authority acceptable, or is full decentralization required?
2. **Performance Needs**: Is immediate processing critical, or can events wait for coordination?
3. **Participant Capabilities**: Can all participants implement complex coordination protocols?
4. **Resilience Requirements**: How important is operation during infrastructure disruptions?
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/channel-binding.md
# Channel Binding
Blue documents can interact with events from the external world - from cryptocurrency transactions to weather conditions. This creates a powerful connection between digital documents and physical reality, but introduces an important question: how do we establish a shared understanding of external events?
## Individual Interpretation: A Starting Point
Let's explore a document that tracks two different types of external events:
```yaml
name: External Reality Counter
btcBlockCount: 0
sunnyDayCount: 0
contracts:
btcChannel:
type: BTC Ledger Channel
network: mainnet
weatherChannel:
type: Channel
description: 'Incoming events represent sunny days in New York'
btcBlockWorkflow:
type: Sequential Workflow
channel: btcChannel
steps:
- name: Increment BTC Block Counter
type: Update Document
changeset:
- op: replace
path: /btcBlockCount
val: ${document('/btcBlockCount') + 1}
weatherWorkflow:
type: Sequential Workflow
channel: weatherChannel
steps:
- name: Increment Sunny Day Counter
type: Update Document
changeset:
- op: replace
path: /sunnyDayCount
val: ${document('/sunnyDayCount') + 1}
```
This document increments counters when Bitcoin blocks are confirmed or when there's a sunny day in New York. By default, each processor can decide for itself:
- How to connect to the Bitcoin network
- What constitutes a "sunny" day in New York
This approach works in scenarios where:
- The document is processed by a single entity making its own determinations
- Participants have a shared understanding of how to interpret external events
- Precise agreement isn't critical to the document's purpose
This mirrors everyday casual agreements like "If it's sunny tomorrow, let's go to the park" - we don't typically specify the exact definition of "sunny" or which weather service to consult.
However, if Alice and Bob both process this document independently, they'll likely reach different counts based on their individual interpretations of "sunny" or which Bitcoin node they connect to.
## Establishing Shared Sources: Channel Bindings
For most practical Blue documents, we need to ensure all processors work with the same events. This is where channel bindings come in - they establish authoritative sources for events.
Let's modify our counter to use shared event sources:
```yaml
name: Shared Reality Counter
type: External Reality Counter
contracts:
mainBtcLedgerChannel:
type: MyOS Timeline Channel
account: main-btc-channel@myos.blue
event:
type: Block Confirmation
weatherObservationChannel:
type: MyOS Timeline Channel
account: new-york-weather-channel@myos.blue
event:
type: Weather Observation
condition: sunny
channelBindings:
type: Channel Source Binding
btcChannel: mainBtcLedgerChannel
weatherChannel: weatherObservationChannel
```
With this configuration:
1. The abstract `btcChannel` now receives events from the concrete `mainBtcLedgerChannel`
2. The abstract `weatherChannel` receives events from the concrete `weatherObservationChannel`
3. All processors using this document will work with identical events
The `Channel Source Binding` preserves the document's logical structure while ensuring all processors share the same understanding of external events.
## Why Channel Bindings Matter
Channel bindings solve a fundamental challenge in distributed systems: establishing agreement about external reality. By explicitly defining authoritative sources, Blue documents can:
1. **Create consistency across processors**: Everyone works with the same inputs
2. **Maintain document simplicity**: Keep the core logic focused on what happens, not where events come from
3. **Enable verification**: Observers can check the authoritative sources
4. **Preserve logical structure**: Abstract channels define what the document responds to, concrete channels define where events come from
This pattern is essential for practically any Blue document that needs to function across multiple processors or participants.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/sequential-workflow.md
# Sequential Workflows
Sequential Workflows are the processing engines of Blue documents, defining how documents respond to events with a series of ordered steps. These workflows enable deterministic business logic that transforms static documents into dynamic, responsive entities.
## The Workflow Concept
At its core, a Sequential Workflow is a contract that:
1. Listens to a specific channel for events
2. Processes those events through an ordered sequence of steps
3. Updates the document or triggers additional events
4. Produces deterministic results across all processors
Unlike traditional programming where execution can follow many paths, Sequential Workflows guarantee the same outcome for every processor given the same inputs—critical for maintaining Blue's trustless verification model.
## A Practical Example: Online Lesson
Let's explore Sequential Workflows through a practical example—an online tutoring platform where teachers and students coordinate lessons.
First, let's define the confirmation event type that our workflow will process:
```yaml
name: Online Lesson Confirmation
confirmLesson:
description: Determines if the lesson should be confirmed or not
type: Boolean
priceInUsd:
description: Price in USD
type: Double
```
Now, let's create our main document type:
```yaml
name: Online Lesson
lessonDate:
description: Scheduled date and time for the lesson
type: DateTime
durationInMinutes:
description: Duration of the lesson in minutes
type: Positive Integer
approved:
description: Whether the teacher has approved this lesson
type: Boolean
default: false
priceInUsd:
description: Price of the lesson in USD
type: Double
teacherMessage:
description: Message from the teacher about the lesson
type: Text
contracts:
teacherChannel:
description: Channel for teacher communication
type: Timeline Channel
studentChannel:
description: Channel for student communication
type: Timeline Channel
confirmLessonWorkflow:
type: Sequential Workflow
channel: teacherChannel
event:
type: Online Lesson Confirmation
steps:
- name: ProcessConfirmation
type: JavaScript Code
code: |
// Extract confirmation data from the event
const confirmation = event;
// Prepare data for document update
return {
approved: confirmation.confirmLesson,
price: confirmation.confirmLesson ? confirmation.priceInUsd : null,
message: confirmation.confirmLesson ?
"Lesson confirmed at $" + confirmation.priceInUsd :
"Lesson declined by teacher"
};
- name: UpdateLessonStatus
type: Update Document
changeset:
- op: replace
path: /approved
val: ${steps.ProcessConfirmation.approved}
- op: replace
path: /priceInUsd
val: ${steps.ProcessConfirmation.price}
- op: replace
path: /teacherMessage
val: ${steps.ProcessConfirmation.message}
```
This document defines:
- Basic properties for an online lesson (date, duration, approval status)
- Channels for both teacher and student
- A Sequential Workflow that processes confirmation events from the teacher
## Creating a Specific Lesson
Using the Online Lesson type, we can create a specific lesson instance:
```yaml
name: Alice-Bob Lesson
type: Online Lesson
lessonDate:
year: 2025
month: 5
day: 1
hour: 13
durationInMinutes: 90
```
Initially, this lesson is pending approval. The teacher (Alice) must send a confirmation event to approve or decline it:
```yaml
# Approval message
type: Online Lesson Confirmation
confirmLesson: true
priceInUsd: 99.99
# Or, alternatively, rejection message
type: Online Lesson Confirmation
confirmLesson: false
```
When the workflow processes this event, it will:
1. Extract confirmation details in the JavaScript step
2. Update the document's approval status, price, and message in the Update Document step
After processing an approval, the document would look like this:
```yaml
name: Alice-Bob Lesson
type: Online Lesson
lessonDate:
year: 2025
month: 5
day: 1
hour: 13
durationInMinutes: 90
approved: true
priceInUsd: 99.99
teacherMessage: "Lesson confirmed at $99.99"
```
The key benefit here is that both Alice and Bob can run this document using their own independent processors. As long as they have access to the same timeline events, they will always reach identical document states—ensuring consistent interpretation without requiring central coordination.
## Workflow Components
Let's examine the key components of Sequential Workflows:
### Channel Binding
Every workflow must specify which channel it listens to:
```yaml
confirmLessonWorkflow:
type: Sequential Workflow
channel: teacherChannel
```
This binding determines which events will trigger the workflow. A single channel can trigger multiple workflows, and a document can contain many workflows listening to different channels.
### Event Filtering (Optional)
Workflows can optionally filter for specific event types:
```yaml
event:
type: Online Lesson Confirmation
```
When specified, only events matching this type will trigger the workflow. Without this filter, the workflow processes all events from the channel.
### Steps
The heart of a workflow is its sequence of steps, executed in order:
```yaml
steps:
- name: Step1
# Step details
- name: Step2
# Step details
```
Each step receives:
- The triggering event
- The current document state
- Results from all previous steps
## Common Step Types
Blue provides several standard step types that all processors must implement, but the architecture is extensible—allowing for custom step types as needed.
### JavaScript Code Step
The JavaScript Code Step enables custom logic with full access to event data and document state:
```yaml
- name: ProcessConfirmation
type: JavaScript Code
code: |
// Event data is available directly
const confirmation = event;
// Document access via document() function
const currentDuration = document('/durationInMinutes');
// Return data for use in subsequent steps
return {
approved: confirmation.confirmLesson,
price: confirmation.confirmLesson ? confirmation.priceInUsd : null
};
```
#### JavaScript Context
The JavaScript environment provides these capabilities:
| Variable/Function | Description |
|-------------------|-------------|
| `event` | The triggering event object |
| `document(path)` | Function to access document state at the specified path |
| `steps` | Object containing results from previous steps |
The code must be deterministic—avoiding `Date.now()`, `Math.random()`, or other non-deterministic functions—to ensure all processors reach identical results.
### Update Document Step
The Update Document Step modifies the document using standard JSON Patch operations:
```yaml
- name: UpdateLessonStatus
type: Update Document
changeset:
- op: replace
path: /approved
val: ${steps.ProcessConfirmation.approved}
- op: replace
path: /priceInUsd
val: ${steps.ProcessConfirmation.price}
```
#### Available Operations
| Operation | Description |
|-----------|-------------|
| `replace` | Replace an existing value |
| `add` | Add a new value (or create if path doesn't exist) |
| `remove` | Remove a value |
| `copy` | Copy from one location to another |
| `move` | Move from one location to another |
#### Template Expressions
Within an Update Document step, you can use JavaScript template expressions with the `${...}` syntax:
```yaml
- op: replace
path: /total
val: ${document('/subtotal') * 1.1} # Add 10% tax
```
These expressions can reference:
- Document values via `document('/path')`
- Previous step results via `steps.StepName.property`
- Event data via `event.property`
### Custom and Specialized Steps
The Blue ecosystem supports extensible step types:
- **Standard Steps**: Must be implemented by all processors (JavaScript Code, Update Document, [Trigger Event](events))
- **Custom Steps**: Can be created for specialized purposes
- **Platform-Specific Steps**: Platforms like MyOS offer additional steps like "Call Agent" for integrating with their agent ecosystem
As with all other contracts, make sure that processors you and others you work with have support for the contract types and workflow step types defined in your documents - the more standard steps you use, the easier it will be to ensure compatibility across different environments.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/embedded-documents.md
# Embedded Documents
Blue documents can embed other documents that have their own contracts and behaviors. This creates compositional structures where both parent and embedded documents process events independently while maintaining a consistent state. This page explains how to use these embedded documents and ensure they're properly processed.
## Moving Beyond Simple Documents
While previous examples focused on single documents with contracts, real-world applications often require complex document structures with embedded components:
- Payment agreements with embedded payment method documents
- Event contracts with embedded ticket verification systems
- Legal agreements with embedded identity verification flows
These embedded documents can have their own channels, workflows, and processing states. However, Blue doesn't automatically process every embedded document—it requires explicit instructions about which embedded documents should be active.
## Extending Our Online Lesson Example
Let's extend our online tutoring platform to include payment processing. In addition to setting the price as before, we'll now have the teacher provide a complete payment document:
```yaml
name: Online Lesson with Payment
type: Online Lesson
payment:
description: Payment details for this lesson
type: Stripe Payment
contracts:
# Enable processing of the embedded payment document
embedded:
type: Process Embedded
paths:
- /payment
# Extend the existing workflow to set the payment
confirmLessonWorkflow:
steps:
- blueId: bT4vHkzPa8Ypd5KJsLNcA3FV6xDqbnG1pcQx2tq16z5 # BlueId of the original steps
- name: UpdatePayment
type: Update Document
changeset:
- op: replace
path: /payment
val: ${event.payment}
```
For now, we're simply embedding the payment document so it's included in processing. In the [Events](events) section, we'll explore how this payment document can interact with the parent document through events.
For details on how Stripe Payments might work with Blue, see [Smart Card Payments](../payments/single-payment).
:::tip Workflow Extension Pattern
In the example above, we're not redefining the entire workflow - we're extending it. By referencing the BlueId of the existing steps defined in the "Online Lesson" type and then adding another step, we're effectively saying "do everything the original workflow does, then do this additional step."
This builds on Blue's [type extending mechanism](../language/types) and creates a clean inheritance pattern where we maintain all the original functionality while adding payment-specific behavior.
:::
## Explicit Processing with Process Embedded
The key to working with embedded documents is the `Process Embedded` contract:
```yaml
embedded:
type: Process Embedded
paths:
- /payment
- /gameStats
```
This contract tells the processor exactly which embedded documents should be processed. Without this declaration, embedded documents remain static data—their contracts aren't evaluated, and they don't receive events.
### The Rationale for Selective Processing
Consider a document with multiple embedded references:
```yaml
name: Order #12345
customer:
blueId: HVkRPb4L3EQey6rdwypi7na7ATz5P3PLH8Q3PSy2WQ94 # Customer profile
payment:
blueId: 2qCKS6yS11cYGabM3nPXsbd6DYK4m6WNrEqGGyySDCaD # Payment document
productCatalog:
blueId: kL9mN0pQrStUvWxYz1A2B3C4D5E6F7G8H4FGh7j8 # Entire catalog with thousands of products
```
Automatically processing every BlueId reference would be inefficient, especially for large references like product catalogs. The explicit `Process Embedded` approach ensures processors only extend and process the specific paths needed for the document's functionality.
## How Embedded Document Processing Works
When a processor encounters a `Process Embedded` contract, it:
1. Extends all specified paths to retrieve the full embedded documents
2. Evaluates all contracts within those embedded documents
3. Processes events for both the parent and embedded documents
4. Maintains checkpoints independently for each document
5. Returns the updated parent document with updated embedded documents
This creates a composite processing environment where multiple documents work together while maintaining their independence.
## Temporal Synchronization with Checkpoints
It may happen that an embedded document is temporally behind the parent document (has an earlier [checkpoint](checkpoints)). When this occurs, the processor must handle the temporal differences.
### Channel Coordination During Embedding
When multiple documents with their own contracts are processed together, they must share a common coordinator to determine event ordering. This coordinator ensures consistent event processing across all embedded documents.
For documents with different temporal positions, the coordinator will process earlier events first. This means:
1. The coordinator collects events from all channels across all processed documents
2. It orders these events according to its coordination strategy
3. When an embedded document is behind temporally, its events will naturally come first in the ordered sequence
4. The embedded document will process all its backlogged events before the parent document processes newer events
This isn't the processor "recognizing a gap"—it's simply the coordinator doing its normal job of chronologically ordering events from all available channels.
## Embedded Node Channels
Embedded documents can also serve as event sources through the `Embedded Node Channel` contract:
```yaml
gameEventsChannel:
type: Embedded Node Channel
path: /game
```
This contract treats events from the embedded document as if they were coming from a separate channel, allowing the parent document to listen for and react to them.
## Example: Historical Game Processing
This example shows how to embed a historical game document and track specific events:
```yaml
name: LeBron Blocks Counter
blocks: 0
game:
blueId: 7UEBwTmRMfQ92rGt4vHkzPa8Ypd5KJsLNcA3FV6xDqbn # Cavs-Warriors Game 7 Finals 2016
contracts:
# Enable processing of the embedded game
embedded:
type: Process Embedded
paths:
- /game
# Channel for game events
gameChannel:
type: Embedded Node Channel
path: /game
# Listen for blocking events
blocksTracker:
type: Sequential Workflow
channel: gameChannel
event:
type: Blocked Shot
player: LeBron James
steps:
- type: Update Document
changeset:
- op: replace
path: /blocks
val: ${document('/blocks') + 1}
```
### How This Works
In this example, we're embedding a game from 2016 into a current document. When processing begins:
1. The coordinator will see that the game document is temporally far behind (from 2016)
2. All game events will be sequenced before any current-day events
3. The game events will be processed in chronological order, incrementing the blocks counter
4. This effectively "replays" the historical game within our document
We're essentially playing back a complete game recording within our document, with our contracts reacting to it. Since the game is from the past, all its events will be processed before any current events from other channels.
### Circular References
To learn how to address circular references go to [Advanced Topics - Circular References](../advanced/circular-references)
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/events.md
# Events
Events are the foundation of Blue document interactions—they flow into documents through channels, trigger workflows, and can be emitted by documents during processing. This page explains how events function within the Blue ecosystem and how documents can both react to and generate events.
## The Event Lifecycle
Every Blue document interaction follows this pattern:
1. An event enters a document through a channel
2. Workflows process the event, potentially updating the document state
3. During processing, the document may generate new events
4. Any generated events are included in the processing result
5. Events directed to internal channels are also processed immediately as part of the same cycle
## Extending Our Online Lesson Example
Building on the embedded payment document from the previous page, let's configure our lesson document to react to events from the embedded payment:
```yaml
name: Online Lesson with Payments and Events
type: Online Lesson with Payments
contracts:
# Channel for payment events
paymentChannel:
type: Embedded Node Channel
path: /payment
# Handler for payment success
paymentSuccessHandler:
type: Sequential Workflow
channel: paymentChannel
event:
type: Payment Successful
steps:
- name: UpdateLessonStatus
type: Update Document
changeset:
- op: replace
path: /status
val: "paid"
```
In this example, we create a channel that listens for events from the embedded payment document. When the payment document processes a successful transaction, it emits a "Payment Successful" event. Our parent document receives this event through the `paymentChannel` and updates the lesson status to "paid."
This pattern creates a clean separation:
- The payment document handles transaction processing
- The lesson document manages the overall lesson state
- Events provide the communication bridge between them
## Document Update Channels
Document Update events occur whenever a specific path in a document changes. You can listen for these changes using a Document Update Channel:
```yaml
statusUpdateChannel:
type: Document Update
path: /status
```
This channel emits events whenever the `/status` field changes. These events include both the old and new values:
```yaml
type: Document Update
path: /status
before: "pending"
after: "confirmed"
```
:::note
Document Update channels only trigger when the exact node at the specified path changes, not when children of that path change. For example, `/payment/status` changes won't trigger a channel watching `/payment`.
:::
### Notifications
`Document Processing Notification` is a useful event type that can be used to show messages to user about processing changes:
```yaml
# Add to our Online Lesson contracts
statusUpdateChannel:
type: Document Update
path: /status
# Notification workflow for status changes
statusNotificationWorkflow:
type: Sequential Workflow
channel: statusUpdateChannel
steps:
- name: CreateNotification
type: JavaScript Code
code: |
// Create appropriate notification based on new status
const newStatus = event.after;
const oldStatus = event.before;
let message;
switch(newStatus) {
case "confirmed":
message = "Your lesson has been confirmed! Please complete payment.";
break;
case "paid":
message = "Payment received! Your lesson is fully booked.";
break;
default:
message = `Lesson status changed from ${oldStatus} to ${newStatus}.`;
}
return {
events: [
{
type: "Document Processing Notification",
message: message
}
]
};
```
This workflow:
1. Listens for changes to the lesson status
2. Creates appropriate notification messages
3. Emits notification events
These notification events are included in the processing result and can be handled by external systems to send emails or other communications.
## Event Triggers
The Event Action Trigger contract provides a declarative way to transform events without requiring JavaScript code:
```yaml
lessonStatusTriggers:
type: Event Action Trigger
events:
- on:
type: Document Processing Initiated
emit:
type: Lesson Created
createdAt: ${event.timestamp}
- on:
type: Document Update
path: /status
after: "paid"
emit:
type: Lesson Ready
lessonId: ${document('/id')}
scheduledTime: ${document('/lessonDate')}
```
This contract:
- Automatically generates a "Lesson Ready" event when status changes to "paid"
- Emits a "Lesson Created" event when the document is first processed
The `Document Processing Initiated` event is a system event that fires automatically when a document with no previous [checkpoint](checkpoints.md) is processed for the first time.
## Trigger Event Step
Events can also be triggered from [sequential workflows](sequential-workflow) through Trigger Event step:
```yaml
- name: SendConfirmation
type: Trigger Event
event:
type: Lesson Confirmation
message: "Your lesson has been confirmed for ${document('/lessonDate')}"
```
## Error Events
Blue represents errors as events, allowing consistent handling of both normal and error conditions. Error events typically include:
- **type**: The error category (Validation Error, Processing Error, Fatal Error)
- **message**: A human-readable explanation
- **context**: Additional information like affected fields or error codes
Common error types include:
| Error Type | Description | Processing Impact |
|------------|-------------|-------------------|
| Validation Error | Invalid input data | Processing continues |
| Fatal Error | Unrecoverable failure | Processing stops |
Fatal errors (such as division by zero in JavaScript) stop all processing and prevent document updates, ensuring documents remain in a valid state.
## Event Processing Mechanics
When a Blue processor receives an event, it follows this sequence:
1. The event enters through a channel
2. Workflows listening to that channel execute in a deterministic order
3. These workflows may update the document and generate new events
4. Generated events directed to internal channels are processed immediately
5. This cycle continues until all internal events are processed
6. The processor returns:
- The final document state
- All generated events
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/operations.md
# Operations
Operations are named, structured interfaces that documents expose to the outside world. They define specific actions that can be performed on a document, complete with formal request definitions.
## The Role of Operations in Blue
Blue documents interact with the world through channels, processing events that arrive through these pathways. Operations build on this foundation by creating well-defined action endpoints within a document.
When to use operations:
- To create clearly named actions that express intent (e.g., `approvePayment`, `scheduleLesson`)
- To enforce specific input structures and validation rules
- To organize document capabilities into logical functional units
- To enable discoverability of available actions
Operations provide an organizational layer that helps structure interactions with a document. They create a clear API for document manipulation while working through the same underlying channel mechanisms that power all Blue document interactions.
## Defining Operations
Operations are defined using the `Operation` contract:
```yaml
increment:
type: Operation
request:
description: Represents a value by which counter will be incremented
type: Integer
```
This definition specifies:
1. The operation name (`increment`)
2. The expected input structure (`request`)
3. A description for the request
## Implementing Operations
Once defined, operations need an implementation. The most common approach is using a `Sequential Workflow Operation`:
```yaml
incrementImpl:
type: Sequential Workflow Operation
operation: increment
steps:
- type: Update Document
changeset:
- op: replace
path: /counter
val: ${event.value + document('/counter')}
```
This implementation:
1. Links to the `increment` operation definition
2. Defines processing steps that execute when the operation is called
The operation's implementation can access:
- The request data via `event`
- The current document state via `document()`
- Any other contextual information needed
## Invoking Operations
Operations are invoked by sending an `Operation Request` event to the document's channel:
```yaml
type: Operation Request
operation: increment # Name of the operation to call
request: 5 # The increment value
document:
blueId: 7UEBwTmRMfQ92rGt4vHkzPa8Ypd5KJsLNcA3FV6xDqbn # Target document ID
allowNewerVersion: true # Accept if document has changed
```
### Request Formats
The `request` field can contain:
1. **Simple values** for primitive types:
```yaml
request: 5 # Integer
```
2. **Structured objects** for complex types:
```yaml
request:
a: 12
b: xyz
```
The request structure must match what's defined in the operation contract. If it doesn't match, the operation won't execute and will return an error.
### The `allowNewerVersion` Flag
The `allowNewerVersion` flag addresses an important concern: what happens if the document changes between when you retrieve it and when you send your operation?
- `true`: Process the operation on the latest version, even if it changed
- `false`: Only process if the document still has the same BlueId as specified
This gives callers control over concurrent modifications:
- Use `true` when the operation should work regardless of other changes
- Use `false` when the operation depends on the document being in a specific state
## Complete Counter Example
Let's bring everything together with our simple counter example:
```yaml
name: Simple Counter
counter: 0
contracts:
ownerChannel:
type: Timeline Channel
# Defines the increment operation interface
increment:
type: Operation
request:
description: Represents a value by which counter will be incremented
type: Integer
# Implements the increment operation
incrementImpl:
type: Sequential Workflow Operation
operation: increment
steps:
- type: Update Document
changeset:
- op: replace
path: /counter
val: ${event.value + document('/counter')}
```
When a client wants to increment the counter:
1. It sends an Operation Request to the document's timeline:
```yaml
type: Operation Request
operation: increment
request: 5
document:
blueId: 7UEBwTmRMfQ92rGt4vHkzPa8Ypd5KJsLNcA3FV6xDqbn
allowNewerVersion: true
```
2. Any compliant document processor:
- Receives the request through the `ownerChannel`
- Identifies the `increment` operation and its implementation
- Executes the Update Document step, adding 5 to the counter
3. The counter is now incremented by 5
## Operations in MyOS
You can see the example above in action in the [Warm-Up Example](../myos/quick-start) from the Quick Start guide:

----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/contracts/contract-package-template.md
# Contract Package Templates
Contract Package Templates provide a powerful abstraction mechanism for Blue documents by generating sets of related contracts from a single configuration block. They act as "macros" that expand into multiple interconnected contracts based on parameters you specify.
## Why Use Templates?
Templates solve several common challenges when building Blue documents:
- **Reduce repetition** - Avoid writing the same contract patterns over and over
- **Standardize implementations** - Ensure consistent behavior across documents
- **Simplify complex functionality** - Express sophisticated behaviors concisely
- **Focus on parameters** - Configure only what varies while inheriting best practices
Every compliant Blue processor must support the standard templates defined at [Blue Contract Templates Repository](../advanced/contract-package-templates).
## How Templates Work
When a processor encounters a template reference in a document, it:
1. Evaluates the template parameters against the provided values
2. Generates multiple concrete contracts based on those parameters
3. Inserts the generated contracts directly into the document's contract collection
4. Processes these contracts like any others defined in the document
The template itself isn't part of the final document structure—only the contracts it generates.
## Logic Attached to Data
Contract Package Templates represent a powerful pattern where reusable logic can be attached to specific data locations within a document. This creates a separation between:
- **Data structure** - The document fields that store information
- **Logic** - The operations and workflows that manipulate this data
By linking templates to specific document paths, we create a system where the document essentially serves as a database, while templates provide the interactive logic that operates on this data.
For example, the Field Setter template links an operation to a specific document path, allowing you to change that data through a standard interface. More complex templates like Online Lessons Operations connect sophisticated workflows to specific data sections (teacher profile, schedule, lesson types), creating a complete application from a data structure.
## Standard Templates
### Field Setter
The Field Setter template creates contracts that allow updating a specific field in your document:
```yaml
giftOptionSetter:
type: Field Setter
fieldPath: /includeGift
operationName: setGiftOption
channel: customerChannel
fieldType: Boolean
```
See full specification at [Field Setter Template](../advanced/contract-package-templates#field-setter).
### Chat Messages
The Chat Messages template creates a simple messaging system within your document:
```yaml
generalChat:
type: Chat Messages
channel: userChannel
```
See full specification at [Chat Messages Template](../advanced/contract-package-templates#chat-messages).
### Access Management
The Access Management template creates a complete role-based access control system with operations for managing roles and participants:
```yaml
accessManagement:
type: Access Management
roles:
Admin:
description: "Can manage the entire picnic and reset contributions"
operations:
- resetContributions
- manageRoles
participants:
- ownerChannel
channelName: adminChannel
User:
description: "Can choose what to bring to the picnic"
operations:
- chooseFood
- chooseAlcohol
participants:
- aliceChannel
- bobChannel
- celineChannel
- deanChannel
channelName: userChannel
```
This template is particularly interesting because it doesn't need to connect to specific document paths - it's focused on generating contracts that manage access control.
## Complex Application Templates
More sophisticated templates combine multiple features into application-specific packages:
### Online Lessons
As demonstrated in the [Assistant Agents](../myos/assistant-agents) section, this template creates a teaching platform by connecting logic to specific data locations:
```yaml
teachingOperations:
type: Online Lessons
teacherProfilePath: /teacher
schedulePath: /schedule
lessonTypesPath: /offerings
```
This generates contracts implementing:
- Teacher profile management
- Lesson type configuration with pricing
- Schedule availability settings
- and more
The template takes existing data structures in the document and overlays operations and workflows that manipulate this data. This creates a complete teaching platform by connecting standardized logic to your document's specific data organization.
## Best Practices
When using Contract Package Templates:
1. **Choose the right abstraction level** - Use templates for patterns that repeat across documents
2. **Keep parameters meaningful** - Only parameterize values that need to vary
3. **Document clearly** - Make it obvious what your template generates
4. **Test thoroughly** - Verify that generated contracts behave as expected
5. **Consider composition** - Combine multiple templates for complex functionality
By leveraging Contract Package Templates effectively, you can create sophisticated Blue documents with less code and greater consistency, treating your document as a data store with attachable logic bundles.
----------------------------------------
NEW SECTION: timelines
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/timelines/introduction.md
# Timelines
## What are Timelines?
A timeline is a hash-chained sequence of authenticated events that serves as a verifiable record of actions. Timelines provide the cryptographically secure foundation for interactions within Blue documents, allowing processors to verify exactly who performed which actions.
Each timeline entry is linked to previous entries, creating an immutable chain that cannot be retroactively modified without detection.
## Timelines as Event Sources
Documents in Blue receive events through channels, with timelines being the most common channel type:
```yaml
name: Purchase Agreement
contracts:
buyerChannel:
type: Timeline Channel
timelineId: buyer-timeline-123
sellerChannel:
type: Timeline Channel
timelineId: seller-timeline-456
purchaseWorkflow:
type: Sequential Workflow
channel: buyerChannel
event:
type: Confirm Purchase
steps:
- type: Update Document
changeset:
- op: add
path: /status
val: "confirmed"
```
When an event appears on the buyer's timeline, the document processes it according to defined workflows. The timeline provides cryptographic verification that the event genuinely came from the claimed source, creating a foundation of trust for all document operations. When multiple timelines interact with the same document, proper coordination mechanisms are needed to determine the order of processing events from different sources, as explained in detail in the [Events from Multiple Sources](../contracts/coordination) section.
## Timeline Types and Trust Models
The Blue language accommodates multiple timeline implementations, each offering different trust characteristics:
### Managed Timelines
**MyOS Timelines** provide a convenient managed implementation with email-based authentication and extensive features:
```yaml
userTimeline:
type: MyOS Timeline
account: user@example.com
```
These timelines are straightforward to set up and use. While they rely on MyOS as a service provider, the nature of timelines limits this trust requirement in important ways:
- Timeline services like MyOS only record ordered messages; they don't execute arbitrary operations
- Timeline entries are chained, making any tampering immediately detectable
- Any timeline manipulation would be cryptographically verifiable, undermining the provider's reputation
- The contents of timeline messages may be encrypted, limiting what the provider can see
For most use cases, managed timelines offer an excellent balance of convenience and security. Learn more in the [MyOS Timelines](./myos-timelines) section.
### Self-Hosted Timelines
For organizations with specific compliance requirements, self-hosted implementations are available:
```yaml
personalTimeline:
type: AWS Basic Timeline with Secp256k1 Schnorr Signature
name: MyTimeline
sqs: arn:aws:sqs:eu-west-1:000000000000:SimpleBlueTimeline-TimelineEntriesSQS-xxx
publicKey: 03a1b2c3d4e5f6098a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f40
```
These implementations require more technical setup and maintenance but provide additional control.
### Institutional Timelines
Organizations, governments, and institutions can provide timeline implementations with stronger identity verification:
```yaml
citizenTimeline:
type: USDS Citizen Timeline
signature: f2b1a3c5d7e9f0e1d3c2b4a6987f5e4d2c1b3a59687766554433221
api: https://api.usds.gov/v1/timelines/public/entries
publicKey: 03a1b2c3d4e5f6098a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f40
```
For example, a professor can issue academic records associated with their institutional timeline and the student's timeline:
1. The resulting document is persistent and student-owned, not just a record in a university database
2. Students can embed their verified academic records into other documents like job applications or loan agreements
3. As a living document, the professor can update grades if necessary (for corrections or academic integrity issues)
This creates persistent digital credentials with clear provenance and update capabilities.
### Blockchain-Based Timelines
For maximum decentralization, timelines can be built on top of blockchain systems:
```yaml
ethTimeline:
type: ETH Standard Timeline
address: 0x1234567890abcdef1234567890abcdef12345678
```
These timelines inherit the security and decentralization properties of the underlying blockchain.
## Timeline Privacy Models
Timelines support different privacy models:
- **Public timelines**: Entries visible to anyone who knows the timeline ID
- **Private timelines**: Entries only visible to authorized participants
- **Mixed privacy**: Individual entries can be encrypted, allowing selective sharing
It's generally recommended to create a unique timeline for each interaction or relationship rather than using a single timeline for all activities. This improves privacy and limits the scope of information sharing.
## Anatomy of a Timeline Entry
The base definition of a timeline entry includes:
```yaml
name: Timeline Entry
timeline:
type: Timeline
entryPrev:
type: Timeline Entry
message:
# Any message content
```
Different timeline implementations extend this with additional fields. For example, a MyOS Timeline Entry:
```yaml
timeline:
type: MyOS Timeline
timelineId: 554d7714-5c18-4a8b-9ffd-edba24b067f0
accountId: 15543223
entryPrev:
blueId: 8BqE4SiVtoJsYKDgHLmzCdWqVN2r5fup7wV
timestamp: 2023-11-10T14:27:19Z
message:
type: Purchase Request
itemId: ITEM-12345
quantity: 3
signature: 6tM3RwnJpLvKgHZ9yb2kLw5EdXCSfPjmXyJ2
```
This structure ensures:
- **Integrity**: Entries cannot be modified once added (hash chain integrity)
- **Authentication**: Each entry is verifiably from the claimed author
- **Ordering**: The sequence of events is preserved through previous entry references
## Timeline Owners Beyond Humans
Timelines can represent various actors in a system:
- **Human users**: The most common timeline owners
- **AI agents**: Creating accountability for automated systems
- **IoT devices**: Establishing trusted device identity
- **Organizations**: Representing collective entities through authorized signers
- **Services**: Creating verifiable service identities
This flexibility allows Blue documents to model complex multi-party interactions where both human and non-human actors need to be represented with clear identity and action verification.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/timelines/myos-timelines.md
# MyOS Timelines
## Introduction
MyOS Timelines provide a managed implementation of Blue's timeline concept, offering a convenient way to create, access, and coordinate verifiable event chains. These timelines are hosted and maintained by MyOS, a platform that we'll explore in more detail in the [Why MyOS](../myos/why-myos) chapter.
MyOS Timelines handle all the cryptographic verification, storage, and access control automatically, allowing you to focus on your document logic rather than timeline infrastructure.
## Referencing Specific Timelines
When you know the exact timeline identifiers you want to use, you can reference them directly:
```yaml
contracts:
aliceTimeline:
type: MyOS Timeline
timelineId: 12345
bobTimeline:
type: MyOS Timeline
timelineId: 23456
```
This approach gives you precise control over which timelines your document uses. However, it comes with an important consideration: **you must ensure you have access to these timelines**. If your document doesn't have the necessary permissions, you'll need to request access from the timeline owners before your document can read from or write to these timelines.
## Simplified Timeline Management with MyOS Account
For most use cases, MyOS offers a more convenient approach using account references:
```yaml
contracts:
aliceTimeline:
type: MyOS Account
email: alice@xyz.com
bobTimeline:
type: MyOS Account
accountId: 12345
```
When you use this pattern, MyOS automatically:
1. **Creates dedicated timelines** for this specific document and each participant
2. **Manages access permissions** so all participants can interact through these timelines
3. **Handles timeline coordination** to ensure consistent event ordering across participants
This approach significantly reduces administrative overhead by eliminating the need to manually create and manage timeline access.
## Dynamic Participant Management
MyOS also automatically handles changing participants according to the rules defined in your document. If your document includes workflows which alter participants, or access management contracts like:
```yaml
accessManagement:
type: Access Management
roles:
Admin:
operations:
- addParticipant
- removeParticipant
participants:
- aliceChannel
Viewer:
operations:
- getDocumentDetails
participants:
- bobChannel
```
When participants are added or removed through document operations (like `addParticipant` or `removeParticipant`), MyOS automatically:
- Creates new timelines for newly added participants
- Grants appropriate permissions based on assigned roles
- Revokes access for removed participants
- Updates timeline coordination to include or exclude the relevant timelines
This means you can focus on your document's business logic while MyOS handles all the underlying complexity of timeline and permission management as your document evolves over time.
----------------------------------------
NEW SECTION: myos
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/why-myos.md
# Why You Need MyOS
Blue already gives you deterministic documents that any compliant processor can run.
**MyOS** supplies the day-to-day infrastructure around those documents — private timelines, ordered event delivery, user interfaces, and optional platform services such as payments and cross-agent calls.

## 1. Core capabilities and where to learn more
| Capability | What MyOS contributes | Further reading |
|------------|----------------------|-----------------------------------------------------------------------------------|
| Timeline automation | Creates and permissions timelines from simple MyOS Account references; no manual key-management or event sequencing code. | [Timeline Management](../timelines/myos-timelines) |
| Document processors ("agents") | Hosted Blue engines with web UI, chat, and webhook outputs. | [Quick-Start](./quick-start) |
| Blink assistant | Natural-language interface; explains documents, turns chat into operation calls. | [Built-in Platform Agents](./platform-agents) |
| Custom UI tabs | Recognises standard operation sets (e.g. Online Lessons Operations) and renders a task-specific dashboard. | [Assistant Agents](./assistant-agents) |
| Agent marketplace | Optional listing; users still need explicit access grants before invoking operations. | [Assistant Agents » Publishing](./assistant-agents#publishing-to-the-marketplace) |
| Access management | UI and contracts for Account → Agent and Agent → Agent permissions, with conditions encoded in Blue. | [MyOS Agents](./myos-agents) |
| Agent-to-agent calls | Call Agent workflow step for synchronous operation invocations inside the platform. | [MyOS Agents » Calling Operations](./myos-agents#calling-operations) |
| Payment & offer services | Paula (payments) and Ophelia (offers) agents; package operations into sellable products. | [Assistant Agents](./assistant-agents) |
| Workspaces | A workspace is a Blue document pre-loaded with Chat Ops, Access Management, and Subnodes contracts; useful for multi-party projects. | [Quick-Start » Adding to Workspaces](./quick-start#adding-to-workspaces) |
## 2. How MyOS works for you
### 2.1 Timeline management
MyOS automatically handles timelines across accounts, making event coordination between parties straightforward. When you create a document with account references:
```yaml
contracts:
alice:
type: MyOS Account
email: alice@example.com
bob:
type: MyOS Account
email: bob@example.com
```
At runtime MyOS:
- Allocates a private timeline for each account
- Records its real ID inside the running document
- Guarantees that authorised processors always see a complete, ordered view
This eliminates the need for complex timeline management code.
### 2.2 Document processing paths
| Role | Typical path |
|------|-------------|
| Developer | POST YAML to `/agents`, receive webhooks for every change. See [Warm-Up Example](./quick-start) in the Quick-Start. |
| Business user | Create a document in the web interface or convert an existing agreement with Blink's help. Walk-through in B2B Agreement Conversion (link forthcoming). |
### 2.3 Event coordination
For your own document processors leveraging MyOS for event handling, create a `/timeline-group` with your relevant timelines. MyOS will deliver events through webhooks while maintaining consistent state and order as a single, deduplicated event feed that external engines can replay.
### 2.4 Service integration
Publish your API as an agent:
1. Write a Blue document with operations that map to your endpoint
2. Install it as an agent
3. Share it with partners via access-grant documents
Examples:
- Teaching service in [Alice and Bob Lesson](./assistant-agents)
Enterprise AI agents follow the same pattern; see [MyOS Chats](./chat) for custom UI approaches.
## 3. Agent interaction inside MyOS
Blue itself is deterministic and decentralised.
Within the hosted environment agents can also listen to, or call, other agents:
```yaml
# Listen
supportChannel:
type: MyOS Agent Channel
agent: customerSupport
event: { type: Ticket Closed }
# Call
- type: Call Agent
agent: paymentProcessor
operation: capture
params: { amount: 120, currency: USD }
```
Access is controlled by dedicated Blue documents:
- **Account-to-Agent Access Grant** – permits a user to invoke selected operations
- **Agent-to-Agent Access Grant** – permits one processor to call another, subject to conditions (balance > 0, specific data present, etc.)
These documents are optional; if omitted, agents remain isolated and purely deterministic.
## 4. Trust model in detail
Running on MyOS entrusts the platform with four responsibilities:
| Responsibility | What MyOS does | How you can verify |
|----------------|---------------|-------------------|
| Timeline custody | Stores entries in hash-chained order; enforces declared visibility. | Compare entry hashes with external copies; inspect access logs. |
| Contract execution | Runs documents exactly as written; supports all mandatory and widely-used contract types. | Re-process the same event log on an independent engine; compare BlueIds. |
| Event delivery | Publishes processor-emitted events to timelines or webhooks without loss. | Check that each emitted event's hash appears on the target timeline. |
| Permission enforcement | Applies Account→Agent and Agent→Agent grants; rejects unauthorised calls. | Review the audit stream of successful and denied invocations. |
For external assurance, embed a MyOS Event Monitor that republishes chosen events to a timeline owned by a neutral party (e.g. Stripe or a regulator).
Monitors themselves are Blue documents, so their guarantees are transparent.
## 5. Illustrative scenarios
- **Warm-Up Counter** – minimal agent demonstrating timeline creation, chat operations, and a simple increment workflow.
- **Online Lessons service** – combines Online Lessons Operations with Access Management; MyOS adds scheduling and payments UI.
- **E-learning resale agreement** – standalone document tracking bookings, revenue share, and termination between two organisations.
- **Xavier–Alice collaboration** – marketing agent links to teaching agent via an Event Monitor and recurring payment document; illustrates cross-agent calls and external timeline publication.
## 6. When MyOS is a good fit
| Situation | Benefit |
|-----------|---------|
| Non-technical participants | Blink explanations, natural-language chat, ready dashboards. |
| Rapid SaaS offering | Avatar, marketplace listing, built-in payments and offers. |
| High event volume | Managed coordinators and consolidated webhook streams. |
| Multi-agent orchestration | Call Agent steps avoid bespoke API gateways. |
| Enterprise AI tooling | Host AI agents that interact with partners through the same Blue language. |
You can move documents freely: develop on MyOS, export to a private processor, or mix hosted and self-hosted engines inside one arrangement.
The choice depends on how much infrastructure you wish to operate yourself.
## 7. Financial platform capabilities
MyOS is a next-generation financial platform designed to transform money movement.
**For financial institutions:** See how payment gateways can enhance their APIs with conditional payments and advanced workflows in our [Payments section](../payments/introduction).
**For solution builders:** Incorporate these financial services directly into your Blue documents and MyOS agents to create unique payment flows, conditional transactions, and multi-party agreements that were previously impossible to implement without extensive custom development.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/quick-start.md
# Your First Document in MyOS
This tutorial walks you through creating and interacting with a simple counter in MyOS. You'll learn about the two ways to run documents in MyOS, how to create them, interact with them, and include them in collaborative workspaces.
## Understanding Documents in MyOS
Everything in MyOS is powered by Blue documents. These documents can be presented in two ways:
### Agents with Faces
- Have a visual avatar representation
- Appear in the Agents section with a dedicated interface
- Ideal for tools you'll share with others
- Visually represented in chats and workspaces
### Activities
- Don't have a visual representation
- Appear in a list format (similar to email)
- Better for personal use or one-off documents
- Represented by initials in a circle when added to chats
Both have identical functionality - the difference is purely in presentation.
## The Counter Document
Let's start with a basic counter document in Blue:
```yaml
name: Warm-Up Example
description: A simple demo document
counter:
description: Some important counter
value: 0
contracts:
# Creates a dedicated timeline for the account that runs this document
ownerChannel:
type: MyOS Account Owner
# Enables chat functionality
chatOps:
type: Chat Operations
# Defines the increment operation interface
increment:
type: Operation
request:
description: Represents a value by which counter will be incremented
type: Integer
# Implements the increment operation
incrementImpl:
type: Sequential Workflow Operation
operation: increment
steps:
- type: Update Document
changeset:
- op: replace
path: /counter
val: ${event.value + document('/counter/value')}
response:
type: Integer
value: ${document('/counter/value')}
```
## Method 1: Creating an Agent with a Face
### Using the MyOS Web App
Log in to the MyOS web application

Navigate to "Agents" in the upper menu

Click "Create Agent", then choose "Select agent using custom code" and paste the document code into the editor

Provide an agent name and select a face/avatar for your agent

It is now on your agents list together with all other agents you have

### Using the API
You can achieve the same result as above with this single API call:
```bash
curl -X POST https://api.myos.blue/agents \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"document": "name: Warm-Up Example\ndescription: A simple demo document\n...",
"agentName": "Warm-Up Example",
"agentFaceId": 45
}'
```
Note: Both `agentName` and `agentFaceId` (a number between 0-1000) are required for agents with faces.
## Method 2: Creating an Activity
### Using Blink in MyOS
Log in to the MyOS web application

Open Blink, your Head of Agents, who also stores all your activities

Click "Add new"

Paste your document code

Your document will appear in your list of activities, similar to an email inbox.

### Using the API
```bash
curl -X POST https://api.myos.blue/agents \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"document": "name: Warm-Up Example\ndescription: A simple demo document\n..."
}'
```
## Interacting with Your Counter
Whether you created an agent or activity, you'll have the same interaction capabilities:
### The Interface
Both agents and activities share a consistent interface with two main tabs:
- **Details tab**: Shows the document's current state and includes several sub-sections:
- Main: Overview with creation date and status
- Description: The document's purpose
- Current state: Live values of document fields
- Participants: Channels document processor listens to
- All actions: Available operations
- Source: The original document Blue code as YAML
- **Activity tab**: Shows the interaction history and allows communication with the document

### Blink Insights
A powerful feature of MyOS is how Blink automatically analyzes your document and provides human-readable summaries. In the blue section labeled "Blink Insights," you'll see:
- A clear explanation of what your document does
- Key features broken down into bullet points
- The current state explained in natural language
This makes even complex documents easy to understand for non-technical users.
### Using the Activity Interface
In the Activity tab, you can interact with your document in several ways:
1. **Operation requests**: Type "increment the counter by 5" and Blink will translate this into a proper operation call, matching format defined in the document.
2. **Regular messages**: Since we enabled `Chat Operations`, you can also send normal messages.

### Using the API
API calls work identically for both agents and activities:
```bash
# To increment the counter
curl -X POST https://api.myos.blue/agents/{id}/increment \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '5'
# To send a chat message
curl -X POST https://api.myos.blue/agents/{id}/chat \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '"Hello from the API!"'
```
From outside it's impossible to differentiate if the request was made through API or through Blink. In both cases a proper request will be sent to Bob's timeline and that will result in processor doing the changes.

## Sharing Your Counter
Both agents and activities can be shared:
1. Navigate to the "Settings" tab
2. Under "Sharing", click "Add User"
3. Enter the email of the user you want to share with
4. Select which operations they can access

Agents with faces are more visually recognizable when shared, but both types have identical sharing capabilities.
## Adding to Workspaces
You can include either agents or activities in collaborative workspaces:
Workspaces in MyOS are collaboration hubs where you can:
- Bring together multiple people and agents
- Create structured subtasks (which are themselves Blue documents)
- Maintain context for an ongoing project or relationship
- Track progress across multiple related activities

You can create multiple tasks within a workspace to:
- Connect different agents together
- Automate common processes
- Delegate specific responsibilities to different participants
- Create conditional logic between activities
### Creating Workspaces via API
Under the hood, a MyOS Workspace is a Blue document with specific contracts available. You can create workspaces programmatically:
```bash
curl -X POST https://api.myos.blue/agents \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"document": "name: Our Workspace\ntype: MyOS Workspace\ncontracts:\n aliceTimeline:\n type: MyOS Timeline\n email: alice@xyz.com\n someAgent:\n type: MyOS Agent\n agentId: 1234"
}'
```
The document structure for a workspace typically looks like:
```yaml
name: Our Workspace
type: MyOS Workspace
contracts:
aliceTimeline:
type: MyOS Timeline
email: alice@xyz.com
someAgent:
type: MyOS Agent
agentId: 1234
```
A MyOS Workspace is simply a base document with Chat Operations, Access Management Operations, and Subnodes Operations already activated (see [Operations](../contracts/operations) for more details). The main elements you need to specify are the channels that represent participants - both human users and agents.
Once created, you can interact with the workspace through standard API calls:
```bash
# To send a message to the workspace
curl -X POST https://api.myos.blue/agents/{workspaceId}/chat \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '"Let\'s discuss the project plan"'
```
Every time you create a workflow or subtask within a workspace, you're effectively creating a new agent that processes its own document, all within the context of the parent workspace.
## Monetizing Your Agent
Every agent with a face, like our Warm-Up Example, can be offered on the Agents Marketplace - either for free or as a paid service through offers.
### Publishing to the Marketplace
To publish your agent navigate to its "Settings" tab and turn on "Make it searchable for others" option:

Click on "Create and manage offers" to be redirected to a built-in agent Ophelia who handles offers:

Once published, anyone can find your agent in the marketplace and see its details and offerings.

### Customer Experience
When customers discover your agent, they can install it to their MyOS environment:

After installation, they'll need to purchase one of your packages to gain access to the agent's functionality:

### How Access Works
Every offer contains a Blue document template that must be initiated by the customer. When a customer selects an offer, they're starting this document which begins a defined process—such as requiring payment verification before granting access rights to the agent.
Every subsequent call to your agent goes through this agreement, which verifies the customer's access rights. This creates a clear, verifiable record of the relationship between customer and service provider.

This same mechanism works for free offerings, custom agreements, or complex B2B relationships as explained in [B2B Agreements](../myos/agreements).
## Choosing Between Agents and Activities
**Use an Agent with a Face when:**
- You want to create a sharable tool or service
- You plan to offer it in the Agents Marketplace
- Document uses REST API calls to your API
- It needs a distinctive visual identity for recognition
- It will be used repeatedly across multiple contexts
**Use an Activity when:**
- You're creating agreements or collaboration documents
- It represents a specific transaction or interaction
- It's part of a larger workflow or process
- You're making something primarily for personal use
Remember that while both have the same technical capabilities, they serve different purposes in the MyOS ecosystem. Agents are designed to be shared services, while activities are typically interaction-specific documents.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/myos-agents.md
# MyOS Agents as Processors
MyOS agents are fundamentally Blue document processors with enhanced capabilities. When you create an agent in MyOS, you're essentially deploying a specialized processor dedicated to a specific document. As seen in the [Quick Start example](./quick-start), these processors provide additional functionality beyond what's possible with standard Blue processing.
## MyOS Timelines
MyOS Timelines are managed by the MyOS platform. Documents can reference these timelines through specific contracts that indicate which timelines should be used during processing.
### Including Timelines in Documents
There are several ways to include a MyOS timeline in your document:
#### 1. Reference by Timeline ID
To include all events from a specific timeline from the beginning:
```yaml
aliceTimeline:
type: MyOS Timeline
timelineId: 1234
```
This adds a channel that processes all events from this timeline, starting from the very first event.
#### 2. Reference with Checkpoint
To start processing from a specific point in the timeline:
```yaml
aliceTimeline:
type: MyOS Timeline
timelineId: 1234
checkpoint:
type: Channel Event Checkpoint
lastEvents:
aliceTimeline:
blueId: vHkzPa8Ypd5KJsLNcA3FV6xDqbn7UEBwTmRMfQ92rGt4
```
This approach processes only events that occur after the specified checkpoint.
#### 3. Reference by User Identity
You can also reference a timeline by a user's email or account ID:
```yaml
aliceTimeline:
type: MyOS Timeline
email: alice@xyz.com
```
Or:
```yaml
aliceTimeline:
type: MyOS Timeline
accountId: 12345
```
### How MyOS Handles Timeline References
When MyOS encounters a timeline reference by email or account ID, it automatically:
1. Creates a timeline for the specified user if needed
2. Updates the document with the actual timeline ID
3. Grants the processing agent read access to this timeline
4. Grants all necessary permissions for the newly created timelines to the agent processing this document
5. Notifies the account owner about their inclusion in the document
For example, if you start a document with:
```yaml
name: Some Doc
contracts:
aliceTimeline:
type: MyOS Timeline
email: alice@xyz.com
bobTimeline:
type: MyOS Timeline
email: bob@xyz.com
```
After processing, MyOS will update the document to include:
```yaml
myOSProcessor:
type: MyOS Processor
timelines:
aliceTimeline:
type: MyOS Timeline
timelineId: 1234
bobTimeline:
type: MyOS Timeline
timelineId: 2345
```
This automatic timeline creation and access management is one of the key benefits of using MyOS as your processor.
## MyOS Agents
MyOS agents can reference other agents, allowing agents processing documents to interact with each other.
### Referencing Other Agents
To reference another MyOS agent:
```yaml
someAgent:
type: MyOS Agent
agentId: 1234
```
### Two Primary Uses for Agent References
#### 1. Listening to Events
You can listen to events triggered by another agent:
```yaml
someAgentChannel:
type: MyOS Agent Channel
agent: someAgent
event:
type: Terminate Contract Event
```
This creates a channel that contains events from the referenced agent, starting from when the document processor begins listening. Unlike timeline references, agent channels do not include historical events - only new events from the moment of connection forward.
#### 2. Calling Operations
You can call operations provided by another agent within a Sequential Workflow:
```yaml
someOperationImpl:
type: Sequential Workflow
operation: reserveLesson
steps:
- name: CallSecretary
type: Call Agent
agent: someAgent
operation: reserveLesson
params:
beginning: ${ request }
duration: ${ document('/lessonDuration') }
```
The `Call Agent` step is a MyOS-specific enhancement that allows direct invocation of operations from other agents. The result from the operation call is available in the `response` variable, and any errors are captured in the `errors` object.
## Access Granting in MyOS
For the agent interactions described above to work, proper permissions must be granted to the agent processing the document. This is where MyOS's access control system becomes essential.
### Extending Blue's Security Model
While standard Blue documents provide security through document-defined rules and contracts, MyOS adds an additional layer of agent-level permission management. This builds on Blue's fundamental security features:
- In standard Blue, a document's security is defined through its contracts and rules
- MyOS extends this by adding explicit agent-to-agent access controls
- This allows for sophisticated permission management while maintaining the document-centric security model
### Account-to-Agent Access
As demonstrated in the [Quick Start example](./quick-start), an account owner can share their agent with another account. This MyOS feature allows controlled access to agent operations through the user interface or API.
### Agent-to-Agent Access
More powerful is the ability for agents to grant access to other agents. This is implemented through specialized Agent Access Grant documents:
```yaml
name: Example Access Grant
type: Agent-to-Agent Access Grant
targetAgent:
agentId: 123
owner: 234
callingAgent:
agentId: 567
owner: 789
targetAgentExposedOperations:
- name: capture
request:
currency: USD
callingAgentDocumentRequirements:
- type: Document Contains
content:
name: Abc
- type: JavaScript Condition
expression: ${document("/availableTokens") > 0}
```
This grant document specifies:
1. Which agent is being granted access (callingAgent)
2. Which agent is providing access (targetAgent)
3. Which operations the calling agent can invoke
4. What conditions the calling agent's document must satisfy
The ability to set granular, conditional access requirements creates a powerful trust mechanism for inter-agent collaboration. This allows agents to safely expose specific functionality to other agents while maintaining control over how that functionality is used.
MyOS's access granting system transforms individual agents into a cooperative ecosystem, where complex relationships between documents and their processors can be managed with security and precision - all while building on Blue's core security principles.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/assistant-agents.md
# Assistant Agents
MyOS assistant agents are document processors with specialized user interfaces designed for specific use cases. These agents provide intuitive visual tools for managing complex operations while maintaining Blue's document-centric approach under the hood.
## Alice's Story: Creating an Online Lessons Service
Continuing Alice's teaching journey from our [Contracts](../contracts/sequential-workflow) section, let's see how she creates a fully-functional lesson service with MyOS.
### Creating a Teaching Assistant
Rather than coding a document from scratch, Alice can quickly create a specialized agent:
1. From MyOS, Alice navigates to "Agents" > "New Agent"
2. She selects "Offer services" and then "Teacher (Online lessons)"
3. She enters agent's name and completes the setup

Unlike our basic Warm-Up example (which had only "Details" and "Activity" tabs), Alice's new Online Lessons agent has three tabs in its interface:
- **UI**: A specialized interface for managing her teaching business
- **Activity**: Timeline and interactions
- **Details**: Document information and configurations

### Setting Up the Teaching Business
The custom UI allows Alice to:
- Create her teacher profile with credentials, teaching style, and languages
- Define lesson types, durations, and pricing
- Manage her availability calendar
- Track bookings and payments
The dashboard helps her keep track of her lessons and manage her schedule effectively:


## Sharing and Offering the Service
### Publishing to the Marketplace
Alice can publish her agent to the MyOS Marketplace to make it discoverable by potential students:
1. From Settings, she toggles "Make searchable for others"
2. She configures how her service appears in search results

**Important**: When someone finds Alice's agent in the Marketplace, they cannot immediately use its services. All agents require specific access permissions before they can be used, even after installation.
### Granting Access
We've already seen how Alice can [share her agent directly with specific people](./quick-start#sharing-your-counter) in the Warm-Up Example. However, direct sharing is most useful for people Alice already knows, like family members who might help manage her schedule.
Another way to grant access is through documents that establish a relationship between Alice and another MyOS account. These documents can include conditions that, when met, automatically grant specific access rights. We will see examples of such documents in [Agreements](./agreements) and [Collaboration Economy](./collaboration-economy) pages, but another example is Offer.
### Creating Service Offers
Alice can create access-granting offers by clicking "Create and manage offers for this agent's services," which connects her with Ophelia, a built-in MyOS agent that specializes in offer management.
With Ophelia, Alice can create structured offers such as a single lesson package:

When someone purchases this offer and makes a payment, they'll automatically receive permission to book a single session with Alice's teaching agent. The offer itself is a Blue document that handles the payment verification and access granting process.
## Bob's Experience: Finding and Using the Service
When Bob finds Alice's agent (either through the Marketplace or via a direct link) and installs it, his initial access is limited. He can only view Alice's profile information and see her available calendar slots.


To gain booking privileges, Bob needs to browse Alice's available offers and select one that fits his needs.

After selecting an offer, Bob completes the payment process:

Once payment is complete, Bob gains access to his lesson details. He can now see the lesson status, join link, and refund options - all determined by the specific terms defined in the offer he purchased.

This lesson agreement is actually a Blue document between Bob and Alice. Importantly, Alice can see exactly the same agreement in her Activities, ensuring both parties have a consistent view of their arrangement.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/platform-agents.md
# Built-in Platform Agents
Every MyOS user automatically receives three built-in platform agents upon installation. These core agents provide essential functionality across the platform and serve as the foundation for your MyOS experience.
## Core Platform Agents
When you first install MyOS, your account is automatically equipped with:
1. **Blink** - Your Head of Agents
2. **Paula** - Your Payment Assistant
3. **Ophelia** - Your Offers Manager
These built-in agents operate like any other agent in the system—they can be included in workspaces, shared with others, and provide operations to other agents. The key difference is that these foundational agents cannot be deleted, as they provide essential platform functionality.
## Blink: Head of Agents

Blink is your primary assistant and serves as the "Head of Agents" in your MyOS ecosystem. As the most important of the built-in agents, Blink:
- Manages all your activities and keeps track of your documents
- Helps execute operations on your documents
- Provides explanations and insights about complex documents
- Participates in every activity to offer assistance
- Coordinates communication between agents
- Maintains your central notification hub
Blink's interface provides a centralized view of your MyOS activity. She acts as your guide to the platform and helps translate natural language requests into specific operations that other agents can understand.
## Paula: Payment Assistant

Paula exclusively focuses on payment processing and financial transactions. With Paula, you can:
- Process all types of payments (card payments, bank transfers, cryptocurrency)
- Handle both incoming and outgoing transactions
- Manage and configure different payment methods
- Track payment requests and approvals
- Monitor payment-related revenue streams
- Generate detailed payment reports
Paula provides a consistent interface for all payment activities across MyOS, regardless of which payment methods or providers you're using. She serves as your central hub for all money movement within the platform.
## Ophelia: Offers Manager

Ophelia helps you create, manage, and optimize offers for your products and services.
As introduced in the [previous page](./assistant-agents), Ophelia plays a crucial role in helping create structured offers that customers can purchase.
## Technical Integration
From a developer perspective, built-in agents can be accessed programmatically just like any other agent. To find their IDs:
```bash
# Retrieve all available agents, including built-in ones
GET https://api.myos.blue/agents
```
You can identify built-in agents by their types in the response. Once you have the ID, you can call operations they support, create workspaces with them, or include them in documents as agents that will be called
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/agreements.md
# B2B Agreements
In MyOS, business agreements are simply Blue documents that establish formal relationships between parties with specific terms, conditions, and operations. While there's nothing technically special about these documents—they appear in Blink's activities like any other document—they serve a critical business purpose by transforming static agreements into dynamic, executable processes.
## Beyond Basic Access Rights
In the [previous section](./assistant-agents#granting-access), we saw how Alice could share her teaching agent directly or through offers. Now we'll explore another powerful approach to establishing business relationships in MyOS – creating specialized B2B agreement documents that define custom terms, payment structures, and operational workflows between organizations, all using the same underlying Blue document-with-rules foundation.
Blue is particularly well-suited for B2B agreements because it can:
1. Precisely specify everything the parties have agreed upon
2. Transform static terms into executable operations
3. Maintain state to track the relationship over time
4. Automate workflows between the parties
5. Handle permissions and access rights conditionally
What makes Blue agreements truly powerful is distributed trust. Rather than Alice and the platform needing to fully trust each other, they can involve trusted third parties (like payment processors or verification services) to independently enforce specific parts of the agreement. This shifts trust from the relationship to the process itself, creating more secure and reliable business arrangements.
In this section, we'll focus on establishing the agreement structure and operations. Later, in the [Payments section](../payments/introduction), we'll extend this example to include automated payment processing, showing how the same agreement can evolve to handle financial transactions.
## Alice's B2B Agreement Story
Let's continue Alice's teaching journey and see how she expands her business through a B2B agreement with an e-learning platform.
### Receiving the Agreement Proposal
Alice receives a proposal from "Sample E-learning Platform" who wants to resell her online lessons to their students. The platform needs to access Alice's schedule and manage bookings on behalf of their customers.

Opening the proposal, Alice can review the specific terms offered:

Alice can see Blink's summary of the key agreement terms:
- The platform will pay 10% of sales with a minimum payment of $100
- They want the ability to cancel bookings up to 48 hours in advance without penalties
- Either party can terminate the agreement at any point
If Alice has questions about the proposal, she can ask Blink directly to clarify any details:

### Agreement in Action
After Alice accepts the agreement, it becomes active and the e-learning platform can begin booking lessons on behalf of their students. The agreement document keeps track of all activity and maintains the current balance:

As lessons are booked, the agreement automatically:
- Tracks each booking in its activity timeline
- Updates the current balance
- Counts the total lessons booked
- Maintains the agreement's operational state
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/myos/collaboration-economy.md
# Collaboration Economy
The true power of a universal language like Blue emerges when individuals can instantly connect their activities without custom integrations or platform limitations. This creates what we call the "Collaboration Economy" – where forming business relationships, establishing partnerships, and creating collaborative ventures happens with unprecedented speed and flexibility.
## The Power of Universal Connection
When every digital activity speaks the same language, collaboration becomes frictionless. In MyOS, this means:
- Anyone can propose unique partnership structures
- Agreements execute automatically without middleware
- Access rights are granted conditionally and precisely
- AI agents can negotiate on your behalf
- Payments flow automatically based on verified events
This creates the foundation for a new collaboration economy. Building trusted relationships becomes faster and cheaper. AI agents represent individuals and organizations, forming connections previously impossible due to trust barriers. From neighborhood resource sharing to global supply chains, a decentralized network emerges—built on verifiable documents rather than corporate gatekeepers.
## Alice's Affiliate Marketing Story
Let's see how this works in practice through Alice's experience with Xavier, a marketing specialist.
### Enabling Collaborative Proposals
When configuring her teaching agent, Alice enables the "Open for Collaboration" option in her settings.

This signals to the MyOS ecosystem that she's open to receiving business proposals from other users and agents.

Unlike rigid "affiliate programs" with pre-determined terms, this open approach allows anyone to propose a custom collaboration structure that fits their unique capabilities and Alice's specific needs.
### Xavier's AdWords Promotion Offer
Xavier specializes in Google AdWords marketing and sees an opportunity to promote Alice's teaching service. He crafts a specific proposal and sends it to Alice.


Xavier didn't need to write any code or understand Blue's technical details—he just explained his business idea to Blink who translated it into a proper Blue document ready to send.

### Alice accepts the agreement
The agreement arrives to Alice's inbox.

This is how it is presented to her.

Once she does all the steps the agreement becomes active.

### The MyOS AdWords Connection
Xavier's proposal works by connecting with the MyOS AdWords agent—a specialized agent that can create and manage Google Ad campaigns, track clicks, and identify conversions. When Alice accepts the proposal, the system automatically:
1. Creates the necessary ad campaigns
2. Sets up tracking to identify customers who come through ads
3. Establishes listening permissions for bookings in Alice's teaching agent
4. Configures the payment calculation mechanism
Once Alice accepts the agreement, Xavier can immediately begin creating ads.

Xavier doesn't need specialized AdWords knowledge—he simply describes what he wants to Blink, who handles the technical details with the AdWords agent. Alice can see these activities in the agreement timeline and has operations available to approve or reject specific campaigns:

The result is instantly visible as ads appear in Google search results:

### Tracking the Customer Journey
When potential students click on these ads, they're directed to Alice's profile with special tracking parameters:

If they book a lesson, the agreement automatically:
- Identifies this booking as coming from Xavier's campaign
- Records the booking in the activity timeline
- Updates the revenue and commission calculations

### Transparent Collaboration
As the partnership progresses, the agreement document maintains the current state without requiring manual reconciliation by either party:

----------------------------------------
NEW SECTION: payments
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/payments/introduction.md
# Introduction
Money has evolved from physical tokens to increasingly abstract forms of trust—each evolution expanding what's possible while requiring new frameworks for verification. Blue documents represent the next step: programmable trust that adapts to any payment scenario while enabling unprecedented customization and automation.
## The Evolution of Payment Trust
Throughout history, payment systems have evolved to solve increasingly complex trust problems:
**Village Barter (Direct Trust)**: When humans exchanged goods directly, trust was personal and immediate—you could see what you were getting and knew who you were trading with.
**Precious Metals (Material Trust)**: Coins made of gold and silver enabled trade beyond immediate communities by embedding value in the material itself.
**Paper Currency (Institutional Trust)**: Paper money shifted trust from materials to institutions, requiring belief in the government or bank that issued it.
**Digital Banking (Network Trust)**: Electronic payments moved trust to interconnected banking networks—invisible systems that record and verify transactions.
**Cryptocurrency (Algorithmic Trust)**: Bitcoin and other cryptocurrencies attempted to replace institutional trust with mathematical certainty—trusting code instead of companies.
Each evolution expanded what was possible while introducing new constraints. The cryptocurrency model, for instance, provides verification without requiring trusted institutions, but at the cost of flexibility and sometimes practicality.
## Beyond Binary Trust Models
Blue introduces a fundamentally different approach: **programmable trust that adapts to each payment scenario**.
Instead of forcing all transactions into a single trust model, Blue allows participants to define exactly:
- Who they trust for different aspects of a transaction
- What conditions must be verified
- How verification happens
- When funds move
- What evidence remains
This creates a universal framework where payments can be as simple or sophisticated as needed, without requiring participants to build custom infrastructure. Whether you need [Smart Card Payments](./single-payment) with conditional logic, [Adaptive Payment Plans](./payment-plan) that respond to events, or [AI-ready payment authorization](./blue-paynote), Blue's document-centric approach provides a unified solution.
## Redirecting Trust Through Documents
Consider a simple example:
```
Party A (Floor Polisher) doesn't trust Party B (Customer)
Party B (Customer) doesn't trust Party A (Floor Polisher)
Both trust Party C (Bank)
```
With Blue, the payment document can specify:
- The work to be completed
- Verification criteria
- The bank as the trusted verifier ([Smart Bank Transfer](./bank-transfer))
- Automatic payment upon verification
Neither the customer nor the service provider needs to trust each other—they've redirected their trust to the bank through the document. The bank doesn't need special infrastructure—just the ability to verify and process Blue documents through a standard [/blue endpoint](../integration/blue-endpoint).
The same framework applies whether:
- A customer is buying a concert ticket with satisfaction guarantee using a [Smart Card Payment](./single-payment#example-guaranteed-delivery-discount-promise)
- A company is paying a vendor contingent on milestone completion via [Smart Bank Transfer](./bank-transfer#example-buying-a-volvo-excavator)
- An AI agent is making a purchase with strict spending limits through a [Blue PayNote](./blue-paynote)
- A complex revenue sharing agreement requires automated calculation with an [Adaptive Payment Plan](./payment-plan#example-dynamic-balance-payment-plan)
## From Inflexible Rails to Adaptive Networks
Traditional payment systems are like railroad tracks—they can only move in predetermined directions with fixed rules. Cryptocurrencies add programmability but require consensus across their entire networks.
Blue payments are different:
- Each document defines its own rules and trust model
- Verification can involve any participant or combination of participants
- Rules can adapt to context without requiring global consensus
- Trust can flow through existing institutions while adding new capabilities
Payment processors looking to expand their capabilities can transform into comprehensive trust platforms by implementing [Stripe on Steroids](./stripe-on-steroids) patterns, creating new revenue streams while solving previously intractable trust problems.
## AI-Enabled Payment Intelligence
When combined with AI, Blue payment documents unlock unprecedented capabilities:
- AIs can create custom payment structures based on natural language requests
- Complex conditional payments become accessible to non-technical users
- Payment relationships can continuously adapt to changing conditions through [Adaptive Payment Plans](./payment-plan)
- Multi-party settlements can be automated across institutional boundaries
- AI agents can safely make purchases using [Blue PayNotes](./blue-paynote#ai-hive-economy) with bounded authorization
The result is that people express what they want ("Pay the cleaner if the work passes inspection") while AIs handle the complexity of turning those intentions into secure, verifiable payment documents.
## A New Payment Reality
In the Blue payment world:
- Consumers gain unprecedented flexibility and guarantees through [Smart Card Payments](./single-payment)
- Merchants create custom payment experiences without building infrastructure by leveraging [existing payment gateways](./stripe-on-steroids)
- Financial institutions provide value through verification rather than just movement with [Smart Bank Transfers](./bank-transfer)
- AI agents safely initiate payments within clear boundaries using [Blue PayNotes](./blue-paynote)
- Everyone benefits from transparency and common verification standards
For organizations implementing these solutions, MyOS provides pre-built components like [Paula, the Payment Assistant](../myos/platform-agents), that make working with payments straightforward while maintaining all the power of Blue's programmable trust.
The future of payments isn't about replacing banks or payment processors—it's about extending their capabilities through a universal language for payment terms, conditions, and verification. Payment providers can transform their offerings by implementing the [/blue endpoint](../integration/blue-endpoint) and supporting Blue's payment document types.
Blue documents turn the abstract concept of "trust" into concrete, programmable, AI-ready instructions that can be verified by all participants—creating a payment ecosystem limited only by imagination, not infrastructure.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/payments/single-payment.md
# Smart Card Payment
Payment processors like Stripe could transform their capabilities using Blue documents. By upgrading static payment transactions into dynamic, programmable documents with built-in rules, verification, and multi-party capabilities, they can offer unprecedented flexibility while maintaining compatibility with existing systems.
For technical implementation details, see the [/blue Endpoint](../integration/blue-endpoint) page. This page focuses on the document types themselves and how they could function in a payment context.
## Card Payment: The Foundation
Below is a simplified version of the Card Payment type from the [repo.blue Payments Package](https://www.repo.blue/packages/Chess/types):
```yaml
name: Card Payment
amount:
type: Double
currency:
type: Text
captured:
type: Boolean
default: false
failed:
type: Boolean
default: false
error:
type: Card Processing Error
paymentProcessorId:
type: Text
description: Reference ID in the payment processor's system
refunds:
type: List
itemType: Refund
disputes:
type: List
itemType: Dispute
token:
type: Card Token
contracts:
paymentProcessor:
type: Channel
description: Channel for payment processor events
# Core payment operations
refund:
type: Operation
description: Records a refund that has been processed, adding it to the payment's refund history and triggering a Payment Refunded event
request:
type: RefundRequest
amount:
type: Integer
description: Amount that was refunded
reason:
type: Text
description: Reason for the refund
# Additional operations and their implementations for refund, void, dispute, and others
```
This document type would be used by processors like Stripe to represent payment transactions and manage their lifecycle within the Blue ecosystem.
## Classic Card Payment: The Gateway to Blue
The Classic Card Payment extends the base type to provide a direct equivalent to what Stripe's API experience could be:
```yaml
name: Classic Card Payment
type: Card Payment
contracts:
paymentProcessor:
type: Internal Logic Channel
description: Untrackable internal system of the payment processor
merchantApi:
type: REST API Channel
provider: stripe.com
endpointScheme:
type: Resource Path Pattern
basePath: /api
paths:
- path: /charge/{chargeId}/capture
method: POST
operation: capture
- path: /charge/{chargeId}/refund
method: POST
operation: refund
# Other operations like authorize, update, void are also supported
```
The `Internal Logic Channel` represents the potential internal systems where payment processing would happen without external verification. The `REST API Channel` maps standard API endpoints to operations on the document.
When you might submit a Classic Card Payment to a `/blue` endpoint:
```yaml
type: Classic Card Payment
amount: 100
currency: USD
captured: false
token: tok_1234
```
A payment processor could handle this similar to how they would process a standard API request to create a charge. The resulting payment could potentially:
- Be visible in the processor's dashboard alongside other charges
- Trigger webhooks similar to standard charges
- Be accessible through standard API endpoints
- Generate reports and analytics
The returned document would include the payment processor's charge ID:
```yaml
type: Classic Card Payment
amount: 100
currency: USD
captured: false
token: tok_1234
paymentProcessorId: ch_123456
```
This approach would allow using Blue documents while maintaining existing integrations and workflows.
This is particularly useful in [Recurring Payment](./payment-plan) scenarios where you need to create regular payments based on non-standard processes. For example, a variable billing amount based on usage, complex trial periods, or custom billing cycles that don't fit standard subscription models could all be implemented through Blue documents while still creating standard payments in the processor's system.
## Smart Card Payment: Beyond Traditional Processing
The Smart Card Payment introduces transparency, verification, and programmable behavior while maintaining compatibility with existing systems:
```yaml
name: Smart Card Payment
type: Card Payment
contracts:
paymentProcessor:
type: Timeline Channel
description: Auditable timeline of payment processor events
paymentProcessorMerchantTimeline:
type: Timeline Channel
description: Timeline where payment processor records merchant API requests
merchantTimeline:
type: Timeline Channel
description: Timeline for direct merchant events
customerTimeline:
type: Timeline Channel
description: Timeline for customer-initiated events
merchantApi:
type: REST API Channel
provider: stripe.com
proxy: paymentProcessorMerchantTimeline
endpointScheme:
type: Resource Path Pattern
basePath: /api
paths:
- path: /charge/{chargeId}/capture
method: POST
operation: capture
- path: /charge/{chargeId}/refund
method: POST
operation: refund
```
The `paymentProcessorMerchantTimeline` serves a special purpose - it's where the payment processor would record all API requests received from the merchant. When standard API calls are made, these calls could be translated into timeline events, creating a complete audit trail.
If implemented by a payment processor like Stripe, Smart Card Payments could potentially:
- Be visible alongside standard transactions in a payment dashboard
- Generate the same types of webhook notifications as regular payments
- Be accessible through standard API endpoints with additional verification capabilities
### Example: Guaranteed Delivery Discount Promise
Imagine shopping at an online store that promises: "If your order takes more than 4 days to deliver, you automatically get an 80% discount." This is a great offer, but how can you trust the shop will honor it?
Enter the Smart Card Payment with third-party verification:
```yaml
type: Smart Card Payment
amount: 1000
currency: USD
captured: false
token: tok_1234
orderTimestamp: "2023-08-15T12:30:00Z"
contracts:
merchant:
type: MyOS Account
email: shop@example.com
customer:
type: MyOS Account
email: buyer@example.com
deliveryTimeline:
type: MyOS Account
email: dhl-tracking@example.com
# Delivery guarantee workflow
deliveryGuaranteeWorkflow:
type: Sequential Workflow
channel: deliveryTimeline
event:
type: Package Delivered
steps:
- name: ProcessDelivery
type: JavaScript Code
code: |
// Extract order and delivery timestamps
const orderTime = new Date(document('/orderTimestamp'));
const deliveryTime = new Date(event.timestamp);
// Calculate delivery duration in days
const deliveryDays = (deliveryTime - orderTime) / (1000 * 60 * 60 * 24);
// Determine payment action based on delivery time
if (deliveryDays <= 4) {
return {
events: [
{
type: "Capture Payment",
reason: "Package delivered in " + deliveryDays.toFixed(1) + " days",
amount: document('/amount')
}
]
};
} else {
// Apply 80% discount for late delivery
const discountedAmount = document('/amount') * 0.2;
return {
events: [
{
type: "Capture Payment",
reason: "Late delivery discount applied (80% off)",
amount: discountedAmount
}
]
};
}
```
In this example, trust is established through trusted third parties rather than relying solely on the merchant:
1. The payment processor (like Stripe) would hold the payment authorization but not capture funds until delivery is confirmed
2. DHL (or another delivery service) would provide independent verification of when the package was actually delivered
3. The Blue document contains the agreed-upon rules that automatically determine the final payment amount
**This creates a triangle of trust where:**
- The shop cannot change the rules after purchase
- DHL provides independent delivery confirmation
- The payment processor ensures payment rules are followed
- The customer can verify the entire process
The shop demonstrates commitment to their promise by putting the guarantee into a verification system outside their control. All parties can independently verify that the rules were followed correctly.
### Example: Cryptocurrency Exchange with Payment Protection
Imagine a scenario where a merchant is selling Bitcoin to a customer. The challenge: how can the customer be sure they'll receive the BTC after paying? And how can the merchant ensure they'll get paid once they transfer the cryptocurrency?
Here's how it could work using an Smart Card Payment with cryptographic verification:
```yaml
type: Smart Card Payment no API Access
amount: 5000
currency: USD
captured: false
token: tok_1234
btcKey:
publicKey: "03abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
keyProvided: false
contracts:
merchant:
type: MyOS Account
email: merchant@example.com
customer:
type: MyOS Account
email: customer@example.com
# Merchant provides their private key
merchantPrivateKeyWorkflow:
type: Sequential Workflow
channel: merchantTimeline
event:
type: Provide BTC Key
steps:
- name: ValidatePrivateKey
type: JavaScript Code
code: |
import { bitcoinjs } from 'blue:FaTx83nVvz7K5uA9RwQhP2bY1LdJtE6mX4G';
// Extract key from event and document
const privateKeyWIF = event.privateKey;
const expectedPublicKey = document('/btcKey/publicKey');
// Verify the private key matches the public key
function verifyPrivateKeyMatchesPublicKey(privateKeyWIF, expectedPublicKeyHex) {
try {
const keyPair = bitcoinjs.ECPair.fromWIF(privateKeyWIF);
const actualPublicKey = keyPair.publicKey.toString('hex');
return actualPublicKey === expectedPublicKeyHex;
} catch (error) {
return false;
}
}
const isValid = verifyPrivateKeyMatchesPublicKey(privateKeyWIF, expectedPublicKey);
if (!isValid) {
return {
events: [
{
type: "Illegal Request",
message: "Private key does not match required public key"
}
]
};
}
// Valid key provided
return {
events: [
{
type: "BTC Key Verified",
publicKey: expectedPublicKey
},
{
type: "Capture Payment",
reason: "Cryptographic verification completed"
}
],
keyValid: true
};
- name: UpdateKeyStatus
type: Update Document
changeset:
- op: replace
path: /btcKey/keyProvided
val: ${steps.ValidatePrivateKey.keyValid}
```
Here's how this scenario works:
1. The merchant places BTC in a special 2-of-2 multisignature wallet
2. The customer already has one private key but needs the merchant's private key to access the funds
3. The customer authorizes a card payment but it's not captured yet
4. The merchant provides their private key through the document workflow
5. The document verifies the key matches the expected public key
6. Upon verification, the card payment is captured and the customer can now access the BTC
By using "Smart Card Payment no API Access," the merchant can only receive payment by providing the correct private key through the timeline - they cannot capture the payment through the payment processor's API. This creates a trustless exchange where:
- The customer doesn't need to trust the merchant will deliver the BTC
- The merchant doesn't need to trust the customer will pay
- The payment processor ensures funds only move when cryptographic proof is provided
- Both parties can independently verify the entire process
This approach could be extended to various high-value exchanges where trust between parties is limited, and cryptographic verification serves as an objective arbitrator.
## Implementation Example
When sending an Smart Card Payment to a `/blue` endpoint:
```yaml
type: Smart Card Payment
amount: 1000
currency: USD
captured: false
token: tok_1234
contracts:
merchant:
type: MyOS Account
email: merchant@example.com
customer:
type: MyOS Account
email: customer@example.com
```
The payment processor could return the document with timeline IDs and payment details:
```yaml
type: Smart Card Payment
amount: 1000
currency: USD
captured: false
token: tok_1234
paymentProcessorId: ch_123456
contracts:
merchant:
type: MyOS Account
email: merchant@example.com
timelineId: 1234
customer:
type: MyOS Account
email: customer@example.com
timelineId: 2345
paymentProcessor:
type: MyOS Account
account: stripe-payments
timelineId: 3456
paymentProcessorMerchantTimeline:
type: MyOS Account
account: stripe-merchant-proxy
timelineId: 4567
```
The payment would then exist both in the payment processor's systems and as a Blue document with timelines. You could potentially interact with it through either the standard API or through timeline events.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/payments/payment-plan.md
# Adaptive Payment Plan
Payment plans allow merchants to define complex rules for when and how payments should occur. Unlike traditional subscription systems with rigid timing and amount structures, Blue payment plans can respond to any event, trigger based on any condition, and create sophisticated payment flows that would be difficult or impossible to implement with standard payment APIs.
## Beyond Simple Subscriptions
While payment processors like Stripe offer subscription capabilities, Blue payment plans extend far beyond simple recurring billing:
- **Event-driven payments** - trigger charges based on any verifiable event
- **Conditional logic** - only charge when specific conditions are met
- **Variable amounts** - calculate payment amounts dynamically
- **Multi-party verification** - ensure all parties agree before payments move
- **Transparent rules** - make payment logic visible and verifiable to all participants
## The Payment Plan Type
Here's the foundational Payment Plan type:
```yaml
name: Payment Plan
description: A dynamic document that manages when and how payments are triggered
```
The Payment Plan is a generic type that can be extended and customized for specific use cases. Payment processors can listen to events like `Process Payment` or `Process Debit`, which contain the details of a Card Payment to process.
## Example: Netflix-Style Subscription
This example shows a simple monthly subscription similar to what Netflix might use:
```yaml
name: Premium Video Subscription
type: Payment Plan
currency: USD
token tok_1234
subscriptionDetails:
planName: "Premium"
price: 19.99
contracts:
merchant:
type: MyOS Account
email: streaming-service@example.com
customer:
type: MyOS Account
email: subscriber@example.com
billingScheduleTrigger:
type: MyOS Account
email: monthly+2024-05-01T09:00Z@datetime.myos.blue
monthlyBillingTrigger:
type: Sequential Workflow
channel: billingScheduleChannel
steps:
- name: PreparePayment
type: JavaScript Code
code: |
return {
amount: document('/subscriptionDetails/price'),
description: `Monthly charge for ${document('/subscriptionDetails/planName')} plan`
};
- name: TriggerPayment
type: Trigger Event
event:
type: Process Payment
payment:
amount: ${steps.PreparePayment.amount}
currency: ${document('/currency')}
description: ${steps.PreparePayment.description}
token: ${document('/paymentMethod/token')}
```
This example maps directly to subscription capabilities already offered by payment processors, but with additional transparency. Both the merchant and customer can verify exactly when payments will be triggered and for what amount.
## Example: Conditional Payment Based on Sports Outcome
Here's how you could create a payment that only processes if the Lakers win their next game:
```yaml
name: Lakers Victory Payment
type: Payment Plan
currency: USD
paymentMethod:
token: tok_1234
type: card
betDetails:
amount: 100.00
team: "Los Angeles Lakers"
opponent: "Boston Celtics"
gameDate: "2023-10-15"
status: "pending"
contracts:
bettor:
type: MyOS Account
email: fan@example.com
bookie:
type: MyOS Account
email: sportsbook@example.com
sportsResultsChannel:
type: MyOS Account
email: official-nba-results@example.com
gameResultProcessor:
type: Sequential Workflow
channel: sportsResultsChannel
event:
type: Game Result
steps:
- name: VerifyGame
type: JavaScript Code
code: |
// Verify this is the game we're interested in
const isTargetGame =
event.homeTeam === document('/betDetails/team') &&
event.awayTeam === document('/betDetails/opponent') ||
event.awayTeam === document('/betDetails/team') &&
event.homeTeam === document('/betDetails/opponent');
if (!isTargetGame) {
return { relevantGame: false };
}
// Check if Lakers won
const lakersWon =
(event.homeTeam === document('/betDetails/team') && event.homeScore > event.awayScore) ||
(event.awayTeam === document('/betDetails/team') && event.awayScore > event.homeScore);
return {
relevantGame: true,
lakersWon: lakersWon
};
- name: ProcessGameResult
type: Update Document
condition: ${steps.VerifyGame.relevantGame === true}
changeset:
- op: replace
path: /status
val: ${steps.VerifyGame.lakersWon ? "approved" : "rejected"}
- name: TriggerPaymentIfWon
type: Trigger Event
condition: ${steps.VerifyGame.relevantGame === true && steps.VerifyGame.lakersWon === true}
event:
type: Process Payment
payment:
amount: ${document('/betDetails/amount')}
currency: ${document('/currency')}
description: "Payment for Lakers victory over ${document('/betDetails/opponent')}"
token: ${document('/paymentMethod/token')}
```
**Business Value**: The customer can be confident that payment will only process if the Lakers actually win. The payment depends on data from an official NBA results channel, not just the merchant's claim. The payment processor enforces these rules, ensuring the merchant can't charge unless the agreed-upon condition is met.
## Example: Dynamic Balance Payment Plan
This example shows how a payment plan can accumulate charges based on activity and only process payments when requested by the recipient:
```yaml
name: AdWords Promotion Payment Plan for Xavier
type: Payment Plan
currency: USD
balance: 0.00
paymentMethod:
token: tok_1234
type: card
contracts:
merchant:
type: MyOS Account
account: alice@example.com
recipient:
type: MyOS Account
account: xavier@example.com
eventsTimeline:
type: MyOS Account
account: ${document('/monitoringTimeline')}
bookingProcessor:
type: Sequential Workflow
channel: eventsTimeline
event:
type: Booking Created
steps:
- name: ExtractAndAddAmount
type: JavaScript Code
code: |
// Extract price amount from booking event
const bookingAmount = event.price?.amount || 0;
return {
amount: bookingAmount,
bookingId: event.id || "unknown"
};
- name: UpdateBalance
type: Update Document
changeset:
- op: replace
path: /balance
val: ${document('/balance') + steps.ExtractAndAddAmount.amount}
cancellationProcessor:
type: Sequential Workflow
channel: eventsTimeline
event:
type: Booking Cancelled
steps:
- name: ExtractAndSubtractAmount
type: JavaScript Code
code: |
// Extract price amount from cancellation event
const bookingAmount = event.price?.amount || 0;
return {
amount: bookingAmount,
bookingId: event.id || "unknown"
};
- name: UpdateBalance
type: Update Document
changeset:
- op: replace
path: /balance
val: ${document('/balance') - steps.ExtractAndSubtractAmount.amount}
requestPayment:
type: Operation
requestPaymentImpl:
type: Sequential Workflow Operation
operation: requestPayment
channel: recipientChannel
steps:
- name: ValidateBalance
type: JavaScript Code
code: |
// Check if there's a balance to pay
const currentBalance = document('/balance');
if (currentBalance <= 0) {
throw new Error("No balance to pay. Current balance: $" + currentBalance);
}
return {
paymentAmount: currentBalance,
notes: event || ""
};
- name: TriggerPayment
type: Trigger Event
event:
type: Process Debit
debit:
amount: ${steps.ValidateBalance.paymentAmount}
currency: ${document('/currency')}
notes: ${steps.ValidateBalance.notes}
token: ${document('/paymentMethod/token')}
- name: UpdatePaymentRecord
type: Update Document
changeset:
- op: replace
path: /balance
val: 0
```
**Business Value**: This example demonstrates how real-world business rules can be encoded directly in a payment document. The payment plan responds to booking events, maintaining a running balance that Xavier can request payment for at any time. The payment processor ensures that:
1. Only valid booking events affect the balance
2. Cancellations properly reduce the balance
3. Xavier can only request payment for the actual accumulated balance
4. All parties can verify the exact rules being applied
Unlike traditional payment systems where business logic typically lives in custom code, this approach embeds the entire payment flow directly in the document, making it transparent, verifiable, and portable.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/payments/blue-paynote.md
# Blue PayNote
Blue PayNote enables AI agents to make payments within precisely defined boundaries without requiring access to your actual payment credentials. Like handing your child $20 with specific instructions to buy only vegetables, PayNotes create bounded payment authorizations that both the agent and merchant can verify.
## The Problem
AI agents can already search, negotiate, and fill shopping carts, but we don't want to hand them our card numbers, bank tokens, or crypto wallets. We need a way to delegate *just enough* payment power—no more, no less—while keeping humans (or higher-order agents) in control of value and risk.
## The Idea
Picture sliding a **$20 bill into an envelope** and writing on the flap: "Only spend this on vegetables."
A Blue **PayNote** is that envelope—only digital, cryptographically signed, and machine-readable. The "bill" inside can be:
* A reserved card authorization
* A prepared bank transfer
* A BTC-UTXO
* Or just a promise backed by the issuer's reputation
The text on the flap is code written in **Blue**—the same language used across Card Payments and Smart Transfers. It defines tasks, checks, and workflows that must be satisfied before the funds move.
## How PayNotes Work
### The PayNote Lifecycle
1. **Issuer drafts the note** – sets `maxValue`, lists `payeeTasks`, picks a `paymentMethod`
2. **Issuer assigns the agent** – separate `assignAgent` operation signs the note into force
3. **Agent presents note to merchant** – via web widget, `/blue`, or MyOS
4. **Merchant evaluates and accepts** – provides their timeline ID which the agent adds as `payee`
5. **Payee fulfills tasks** – uploads documents, confirms details, provides evidence through their timeline
6. **Workflows & embedded docs validate** – processing the submitted evidence and emitting either positive or negative events
7. **Settlement fires** – the chosen `paymentMethod` executes once all tasks are cleared
8. **Note finalizes** – status flips to *Paid*
## PayNote in Action: Real-World Applications
### iPhone Shopping Assistant
* **Problem**: Alice wants her AI assistant to not only search for but actually purchase an iPhone 16, 256GB, Alpine Blue if it finds one within her budget, but doesn't want to share her payment credentials.
* **Payee Tasks**: Merchant confirms exact product specifications match requirements.
* **Payment Method**: Card Payment through MyOS Payment Agent with automatic processing.
### Bulk Business Supply Order
* **Problem**: Large Polish e-commerce platform uses AI agents to continuously restock inventory, negotiating with EU suppliers for pre-approved products but requiring financial guardrails without slowing down operations.
* **Payee Tasks**: Supplier must provide standardized order confirmation document and quality certification.
* **Payment Method**: Automatic bank transfer once documentation is approved.
### Used Camera Purchase with Visual Verification
* **Problem**: Professional photographer wants to find a used medium-format camera in excellent condition, but needs verification of its state before committing to the purchase.
* **Payee Tasks**: Seller uploads detailed images and operational video; independent AI Agent analyzes and confirms condition meets requirements.
* **Payment Method**: Blue document from a crypto custodian, cross-embedded with the PayNote, handling the automatic cryptocurrency payment when verification completes.
## How PayNotes Are Used
PayNotes can be integrated into various systems and platforms, enabling AI agents to make authorized purchases across different environments.
### Website Payment Method
The simplest integration is adding PayNote as a standard payment method at checkout alongside options like Visa, Mastercard, and PayPal:
1. Agent selects "Pay with Blue PayNote" at checkout
2. Agent provides the complete PayNote document
3. Merchant reviews the PayNote conditions and decides if they can fulfill requirements
4. If accepted, merchant provides their timeline identifier
5. Agent adds merchant timeline as the Payee in the PayNote
6. Website displays "Payment Processing" status while verification tasks are completed
7. Once all tasks are verified and payment executes, the website confirms successful payment
This approach allows AI agents to browse any e-commerce site, navigate product pages, complete checkout forms, and use PayNotes as payment without the website needing to understand Blue's technical details.

### /blue Endpoint for Advanced Integration
For more sophisticated interactions, services can implement the [`/blue` endpoint](../integration/blue-endpoint) allowing agents to conduct structured negotiations:
Instead of following a rigid checkout flow, agents can engage in back-and-forth conversations about product details, shipping terms, additional services, and payment conditions. PayNotes can be embedded within these negotiations as payment guarantees, enabling complex conditional transactions.
For example, an AI agent might say: "I'm interested in the iPhone 16, Alpine Blue, 256GB. I can pay $528 - here is my PayNote with guaranteed bank payment. If you can sell for this price, let's create an Order document and I will embed this PayNote and it will auto execute once courier confirms the product is shipped."
### MyOS Integration
Within the MyOS ecosystem, PayNotes integrate seamlessly into workspaces and agent interactions:
1. Users can instruct agents to complete tasks with attached PayNotes for payment
2. Agents can negotiate with service providers within workspaces
3. PayNote verification and settlement happens automatically within the platform
4. Payment status updates appear directly in workspace activity feeds
This approach is particularly powerful for ongoing relationships where multiple tasks might be delegated to different agents, each with their own payment authorization.

## Why PayNotes Matter in the AI Economy
Autonomous agents will soon execute *thousands* of micro-transactions for us. Blue PayNote gives each of them a narrow, self-documenting payment lane—strong enough to be trusted, but too narrow to be abused.
* **Security** – No raw card numbers or bank credentials leak to agents
* **Auditability** – Every note is a tamper-evident doc with a full Timeline
* **Flexibility** – Same mechanism covers prepaid, credit, or pure IOU scenarios
* **Composable** – Tasks, workflows, and third-party attestations snap together
## Deep Dive: The Alice iPhone Case
Let's explore three different ways Alice could use a PayNote to purchase an iPhone 16, all using MyOS as the infrastructure for timelines and coordination.
### Approach 1: Simple Shop Confirmation with Automated Bank Payment
In this scenario, Alice wants a straightforward verification where trusted shops simply confirm the product matches her requirements, combined with automated payment.
**PayNote Setup**:
- Agent can invite only trusted electronics retailers as payees
- Simple "yes/no" confirmation of product specifications
- [Smart Bank Transfer](./bank-transfer) for automatic payment
**Implementation Details**:
- Alice creates a PayNote and limits acceptable payees to a list of trusted merchants
- She then goes to her bank and asks the AI assistant to create a [Smart Bank Transfer](./bank-transfer) with guaranteed funds to be triggered when this PayNote has tasks completed
- She [embeds](../contracts/embedded-documents) what her bank gives her into the PayNote itself
These steps can be done manually using a notepad or any programming language of her choice, or using MyOS for creating such a PayNote.
- Once ready, she assigns her shopping agent to this PayNote
- When her shopping agent finds the best price, it adds the merchant as payee (merchants outside the trusted list are rejected)
- Merchant confirms the product matches specifications through their timeline
- All tasks clear automatically, triggering the embedded Smart Bank Transfer
- Once payment is completed, PayNote status updates to "Paid"
### Approach 2: Structured Data Verification with Cryptocurrency Settlement
In this approach, Alice requires more rigorous verification with structured order data and cryptocurrency payment.
**PayNote Setup**:
- Merchant must provide structured order details in specific format
- Coinbase-backed payment for automatic cryptocurrency settlement
**Implementation Details**:
- Alice creates a PayNote with structured data verification requirements
- Similarly to before, she [cross-embeds](../advanced/circular-references#temporal-evolution-into-circular-references) a Coinbase-backed payment document with this PayNote, so that payment is triggered once tasks are done, and PayNote moves to "paid" once payment is confirmed
- Her shopping agent negotiates with retailers and selects the best option
- The merchant provides structured order details through their timeline
- A workflow automatically validates the data against Alice's requirements
- When all tasks clear, the Coinbase payment document automatically executes
- PayNote status updates to "Paid" when the cryptocurrency transaction confirms
### Approach 3: Second-hand Purchase with Video Verification
For a used iPhone purchase, Alice implements sophisticated video verification with AI analysis.
**PayNote Setup**:
- Seller must provide HD video showing device condition and functionality
- MyOS Agent backed by GPT-4o must verify video authenticity and assess condition
- Manual card payment after verification
**Implementation Details**:
- Alice creates a PayNote through MyOS workspace and also requires her Payment Agent to prepare a confirmation for merchants that she has a card added and has a clean payment record from previous PayNotes
- Her shopping agent finds a suitable used iPhone from a private seller
- The seller uploads a video showing the phone from all angles, turning it on, and demonstrating key features
- Opening Settings shows expected parameters for the device
- A MyOS Vision Agent powered by GPT-4o analyzes the video to verify:
- The phone is genuinely an iPhone 16, Alpine Blue, 256GB
- The screen has no visible damage
- If the AI approves, Alice receives a notification to complete payment
- Alice manually completes payment through MyOS
- PayNote status updates to "Paid" once payment confirmation is received
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/payments/bank-transfer.md
# Smart Bank Transfer
Just as card payments can be enhanced with Blue documents, bank transfers can also be transformed from simple money movements into conditional, programmable transfers with built-in verification and multi-party confirmation. Examples from [Card Payment](./single-payment) and [Payment Plan](./payment-plan) also apply to bank transfers, however, smart bank transfers could be particularly transformative for B2B agreements.
## Example: Buying a Volvo Excavator
Consider a construction company purchasing a $220,000 Volvo excavator from a supplier. Rather than using complex escrow arrangements or negotiating who bears the payment risk, they create a smart payment with conditions guaranteed by their bank:
The payment document specifies three verification requirements before funds are released:
- Delivery to Oakland by Global Machinery Ltd.
- Technical integration completion by EquipLink Systems
- Inspection tests by HeavyEquip Inspectors LLC
When the payer initiates this smart transfer, the bank confirms the funds are available and commits to following the payment rules. The payer can then share this payment document with the supplier. The main payment document includes the payer, the payee, and the bank as direct participants.
The payment document contains three embedded documents, each with its own set of participants including the relevant verification company. As these companies complete their tasks and update their respective documents, the main payment automatically tracks completion status. The bank simply guarantees it will execute the payment rules as defined in the document—much easier than traditional escrow arrangements where banks must manually verify specific conditions. This automation makes smart transfers significantly cheaper to offer at scale.

The bank app becomes much more than a transaction tool. The CEO sees not just that money is pending, but the precise status of each verification requirement. This creates unprecedented transparency in complex B2B transactions, reducing risk for all parties while maintaining the security of traditional banking.
When all conditions are finally met, the CEO receives a notification that payment will process automatically, but can choose to release it immediately:

## Initiating Smart Bank Transfers
There are several ways these enhanced transfers could be implemented:
1. For banks providing APIs, it could leverage the [/blue endpoint](../integration/blue-endpoint), making it accessible to developers
2. Banks could offer a MyOS Agent that handles the integration seamlessly
3. Most naturally, banks could enable customers to initiate such transfers directly from their banking app or web interface, either by:
- Uploading a prepared Blue document (perhaps created by legal counsel)
- Using the bank's AI assistant to generate an appropriate document based on natural language explanation, similar to [how it's handled in MyOS](../myos/quick-start)
Once initiated, the payer can share the payment document with other participants, allowing them to track status and fulfill their verification responsibilities.
## Transforming Banking Apps into Business Tools
These smart transfers fundamentally change the relationship between businesses and their banking tools. Banking apps transform from simple financial ledgers into comprehensive business intelligence platforms that provide:
### Enterprise Relationship Management
For CFOs and CEOs, their banking app now shows not just transaction amounts but relationship status across their business ecosystem. The app becomes the first place executives check to understand:
- Status of major equipment purchases
- Verification progress from multiple vendors
- Upcoming conditional payment triggers
- Documentation completeness across complex deals
### Risk Reduction Through Smart Rules
Unlike traditional escrow that requires costly manual administration, smart transfers operate on predefined rules that execute automatically when conditions are met. This dramatically reduces:
- Administrative costs for the bank
- Time delays in transaction processing
- Risk of miscommunication about requirements
- Need for manual intervention and verification
For banks, this means offering escrow-like security at regular transfer prices, opening this powerful capability to a much broader market of business transactions.
## How Embedded Documents Enable Multi-Party Verification
The power of this approach comes from how Blue handles document composition. The main payment document establishes the overall transaction structure and includes the bank, payer, and payee. Inside this document are three separate embedded documents:
1. **Delivery Verification Document**: Participants include Global Machinery Ltd., the payer, and the payee
2. **Technical Integration Document**: Participants include EquipLink Systems, the payer, and the payee
3. **Inspection Document**: Participants include HeavyEquip Inspectors LLC, the payer, and the payee
Each embedded document has its own timeline, rules, and participants. The verification companies only interact with their specific document, unaware of the overall payment structure. This separation provides clean interfaces while maintaining document integrity.
The main payment document monitors these embedded documents through [Document Update Channels](../contracts/events#document-update-channels) that detect when status changes. When all embedded documents reach their "completed" state, the main document initiates the payment release process.
This approach allows specialized verification providers to participate exactly where their expertise is needed, without requiring them to understand the entire payment flow or interact with systems outside their area of focus.
## Beyond Simple Transfers
These smart bank transfers enable sophisticated business orchestration:
- Construction projects with staged payments to multiple subcontractors
- Manufacturing partnerships with quality-based payment adjustments
- International trade with regulatory and customs verification
- Technology implementations with performance-based compensation
By implementing these smart transfers, forward-thinking financial institutions can position themselves at the center of the trust ecosystem, creating new value-added services that generate revenue while delivering unprecedented control and transparency to their business clients.
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/payments/stripe-on-steroids.md
# Stripe on Steroids
## Supercharging Payment Gateways with Blue
Payment gateways like Stripe have transformed digital commerce by making online payments accessible to businesses of all sizes. While these platforms excel at moving money and managing transactions, they face increasing pressure to handle complex payment scenarios that go beyond simple authorizations and captures.
Blue introduces a breakthrough approach that allows payment gateways to dramatically extend their capabilities without rebuilding core infrastructure. By implementing a few strategic integration points, you can offer your merchants sophisticated payment experiences that were previously impossible—creating new revenue streams while strengthening your position in the payments ecosystem.
## Opportunities for Payment Gateways
### 1. The `/blue` Endpoint: Your Gateway to Enhanced Payments
By implementing the [/blue endpoint](../integration/blue-endpoint), payment gateways can accept and process Blue documents alongside standard API requests. This endpoint serves as a bridge between Blue's powerful document capabilities and your existing payment infrastructure.
```http
POST /blue HTTP/1.1
Host: api.yourpaymentgateway.com
Content-Type: application/json
{
"type": "Smart Card Payment",
"amount": 1000,
"currency": "USD",
"captured": false,
"token": "tok_1234",
"contracts": {
// Payment rules, verification requirements, etc.
}
}
```
The beauty of this approach is that you can continue processing payments through your existing infrastructure while adding powerful new capabilities. Your dashboard, reporting tools, and reconciliation systems will see these payments alongside standard transactions—they just happen to have enhanced powers.
**Implementation Advantage:** Most of the processing can be handled by MyOS, with your gateway simply routing events and updates. This means minimal changes to your core systems. See the [/blue endpoint guide](../integration/blue-endpoint) for technical details.
### 2. Smart Card Payments: Verification-Enhanced Transactions
[Smart Card Payments](../payments/single-payment) transform standard card transactions into programmable agreements with built-in verification. Your merchants can create payments that:
- Automatically refund if specific conditions aren't met
- Partially capture based on delivery outcomes
- Include third-party verification before settlement
- Handle complex escrow-like arrangements without manual intervention
For example, a merchant could offer: "80% discount if delivery takes more than 4 days, verified by DHL tracking." The payment processor enforces this guarantee, building trust with customers who know the promise is backed by verification, not just merchant goodwill.
**Revenue Opportunity:** You can charge premium fees for these enhanced capabilities, especially when they reduce chargebacks and disputes by making terms and conditions executable rather than merely documented.
### 3. Payment Plans: Dynamic Subscription Management
[Payment Plans](../payments/payment-plan) extend beyond rigid subscription models to create truly responsive recurring payments. These plans can:
- Trigger charges based on external events
- Calculate dynamic amounts using business logic
- Respond to performance metrics or usage patterns
- Include multi-party verification requirements
For example, a marketing agency could create a payment plan that charges clients based on actual performance metrics from ad platforms. This eliminates the need for manual invoicing and verification, creating a more responsive and transparent billing relationship.
**Merchant Value:** Your clients gain the ability to create payment arrangements that perfectly match their business models without building custom billing infrastructure.
### 4. PayNote Integration: AI-Ready Payment Authorization
By supporting [Blue PayNotes](../payments/blue-paynote) in your checkout flow, you can position yourself at the forefront of AI-driven commerce. PayNotes allow:
- AI shopping agents to make bounded purchases
- Conditional payment authorization with verification
- Task-specific payment authority delegation
- Built-in verification requirements before settlement
You can integrate PayNotes in two ways:
1. **Basic Integration:** Accept PayNotes as a payment method at checkout, similar to accepting a card or wallet
2. **Enhanced Integration:** Provide tools for merchants to respond to PayNote verification tasks, automating the fulfillment verification process
**Competitive Advantage:** By supporting PayNotes, you become the payment gateway of choice for AI-powered shopping assistants—a rapidly growing segment of the market.
### 5. Leveraging Your Financial Infrastructure
Your existing financial capabilities can become payment methods within the Blue ecosystem:
- **Internal Account Transfers:** Use your internal ledger system for instant movements between merchants on your platform
- **Balance Management:** Offer instant settlement to connected accounts when specific conditions are met
- **Cross-Currency Optimization:** Use your FX capabilities as specialized payment methods in Blue documents
- **Split Payments:** Enable complex revenue sharing directly through your settlement infrastructure
For example, a marketplace could create a document that automatically distributes revenue between multiple parties based on their contributions, using your internal movement capabilities for instant, low-cost settlement.
**Strategic Position:** By exposing your internal capabilities as Blue payment methods, you become a more integral part of your merchants' financial operations.
## Business Benefits for Payment Gateways
### New Revenue Streams
Blue integration creates multiple opportunities for premium services:
- **Verification Fees:** Charge for enforcing conditions and verifying outcomes
- **Enhanced Payment Types:** Premium pricing for Smart Card Payments and Payment Plans
- **AI Payment Infrastructure:** Position as the gateway for AI-driven commerce
- **Reduced Risk Services:** Charge for guaranteed outcomes that reduce merchant risk
### Competitive Differentiation
While other gateways focus on commoditizing basic payment processing, you can offer:
- **Programmable Payments:** Go beyond basic authorizations and captures
- **Trust Infrastructure:** Become the arbiter of conditional transactions
- **AI-Ready Commerce:** Support the next generation of autonomous purchasing
- **Verification Network:** Create an ecosystem of trusted verification providers
### Merchant Retention
Enhanced capabilities create deeper integration with merchant operations:
- **Reduced Platform Switching:** Unique capabilities increase switching costs
- **Operational Integration:** Become part of core business processes, not just checkout
- **Customizable Solutions:** Address complex use cases without custom development
----------------------------------------
NEW SECTION: integration
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/integration/blue-endpoint.md
# /blue Endpoint
The `/blue` endpoint adds programmable document capabilities to any API with minimal integration effort. By adding this standardized endpoint to your service, you enable clients to submit Blue documents that can interact with your core services while adding sophisticated rules, verification, and multi-party capabilities.
Most importantly, by allowing your customers to represent your services as Blue documents, you give them the opportunity to embed these services into other documents they use, enabling integration with all kinds of tools. You also become a party to which trust can be delegated, according to Blue's philosophy. All of this results in possible additional revenue streams and deeper customer relationships.
## Why Add a `/blue` Endpoint?
Adding Blue document support to your API creates significant business opportunities without requiring changes to your core functionality:
- **Handle "impossible" edge cases**: Support complex scenarios without custom development
- **Enable multi-party verification**: Create transparent processes visible to all participants
- **Add new capabilities instantly**: Respond to market needs without lengthy development cycles
- **Maintain backward compatibility**: Your existing API remains unchanged
- **Join the interoperability network**: Connect with other Blue-enabled services
## Integration Strategy Options
There are several approaches to integrating the `/blue` endpoint with your existing services, depending on your needs and technical capabilities:
### Level 1: MyOS-Powered Integration
- Use MyOS to handle all document processing
- Your service simply forwards documents and receives webhooks
- Simplest implementation with minimal development effort
- Best for initial deployments
### Level 2: Verification-Based Integration
- Receive updates from MyOS, including the triggering events
- Run your own Blue processor to verify the changes
- Confirm that the original event actually results in the reported change
- Better security model while leveraging MyOS infrastructure
### Level 3: Independent Integration
- Use your own timeline implementation
- Don't rely on MyOS at all
- Complete control over the entire processing pipeline
- Highest autonomy but more complex implementation
In this guide, we'll demonstrate the simplest approach (Level 1) where MyOS handles all processing. This example uses a Stripe-like payment processor to illustrate the integration.
## Minimal Implementation
Here's a minimal implementation for a Stripe-like payment processor using the `spring-blue-gateway-starter`:
```java
/* ──────────────────────────────────────────────────────────────── */
/* 0. Declare what this gateway supports */
/* ──────────────────────────────────────────────────────────────── */
@BlueGateway(
rootTypes = { Payment.class, PaymentPlan.class },
capabilityPacks = { MinimalContractPack.class },
languagePacks = { FinancialLanguagePack.class,
CommonEntitiesPack.class },
envPreset = MyOsDefault.class // ← single preset we allow
)
class GatewayCfg { }
```
The `@BlueGateway` annotation configures what your endpoint supports:
- `rootTypes`: The document types your service can process (in this case, payment-related documents)
- `capabilityPacks`: Sets of contracts and operations your service understands
- `languagePacks`: Pre-defined types your service can work with
- `envPreset`: The processing environment you support
While you can support multiple processing environments, in this example we've chosen to support only the MyOS environment. The environment setting controls important aspects like:
- Which timeline implementations are accepted
- What coordination mechanisms are available
- How cross-document references are resolved
- Where processing actually occurs
```java
/* ──────────────────────────────────────────────────────────────── */
/* 1. REST controller – one POST, one optional GET */
/* ──────────────────────────────────────────────────────────────── */
@RestController
@RequiredArgsConstructor
class BlueEndpoint {
private final Blue blue; // parser + helpers from starter
private final CapabilityChecker caps; // bean that knows your packs
private final MyOsClient myos; // wraps POST /agents
private final PaymentRouter router; // routes payment documents
/* ---- (optional) capabilities discovery ------------------------ */
@GetMapping(value = "/blue/capabilities", produces = "application/json")
public String caps() {
return caps.asJson(); // auto-generated manifest
}
/* ---- process document and create agent/payment as needed ------ */
@PostMapping(value = "/blue",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity launch(@RequestBody String rawJson) {
// 1) Parse JSON into Blue Node
Node doc = blue.jsonToNode(rawJson);
// 2) Validate root + contract types against declared capability packs
caps.assertAccepted(doc); // throws 422 if anything unsupported
// 3) Process based on document type
String paymentId = null;
Node updatedDoc = null;
if (blue.isNodeSubtypeOf(doc, ClassicCardPayment.class)) {
// Process Classic Payment directly through payment processor only
paymentId = router.processPayment(doc);
// Update the document with payment ID
ObjectNode objectDoc = (ObjectNode) doc;
objectDoc.put("paymentProcessorId", paymentId);
// For Classic payments, we don't create a MyOS agent
updatedDoc = objectDoc;
}
else if (blue.isNodeSubtypeOf(doc, SmartCardPayment.class)) {
// Process Smart Payment through both payment processor and MyOS
// Create payment in processor system first
paymentId = router.processPayment(doc);
// Add the payment processor ID to the document
ObjectNode objectDoc = (ObjectNode) doc;
objectDoc.put("paymentProcessorId", paymentId);
// Create agent in MyOS with updated document
MyOSResponse response = myos.createAgent(blue.nodeToJson(objectDoc));
// MyOS returns the full document with timeline IDs added
updatedDoc = blue.jsonToNode(response.getDocument());
}
else {
// For Payment Plan or other documents, just create an agent in MyOS
MyOSResponse response = myos.createAgent(rawJson);
// Get the updated document from MyOS
updatedDoc = blue.jsonToNode(response.getDocument());
}
// Return the full updated document
return ResponseEntity.ok(blue.nodeToJson(updatedDoc));
}
}
// Simplified MyOS response model
class MyOSResponse {
private String agentId;
private String document; // JSON string of updated document
public String getAgentId() {
return agentId;
}
public String getDocument() {
return document;
}
}
```
The `/blue/capabilities` endpoint is crucial as it allows clients to discover what document types and contracts your service supports. This enables:
- Automatic document validation before submission
- Dynamic construction of compatible documents
- Discovery of your service's capabilities by tools and other services
### Runtime Flow
1. Client POSTs a document to `/blue`
2. Your endpoint validates it against supported capabilities
3. For classic payments, process directly through your core services
4. For smart payments, forward to MyOS for processing
5. Return the appropriate ID and BlueId
6. Future updates arrive via webhook
## Handling Webhooks
The webhook handler translates document events into operations on your core services:
```java
/* ──────────────────────────────────────────────────────────────── */
/* 1. Event classes (from blue.repo) */
/* ──────────────────────────────────────────────────────────────── */
@TypeBlueId("E7aQ…")
public record RefundPayment(String paymentId, long amount) {}
@TypeBlueId("F2bK…")
public record MakeInternalStripePayment(
long amount, String recipientStripeAccount, String notes) {}
/* ──────────────────────────────────────────────────────────────── */
/* 2. Business service */
/* ──────────────────────────────────────────────────────────────── */
@Service
class PaymentProcessor {
void refund(String paymentId, long amount) {
// call internal ledger or external Stripe API
}
void capture(long amount, String recipient, String notes) {
// call internal ledger or external Stripe API
}
}
/* ──────────────────────────────────────────────────────────────── */
/* 3. Webhook payload DTO */
/* ──────────────────────────────────────────────────────────────── */
record MyOsWebhook(
String agentId,
String document, // raw JSON string
List triggeredEvents) {} // each raw event JSON
/* ──────────────────────────────────────────────────────────────── */
/* 4. Webhook endpoint */
/* ──────────────────────────────────────────────────────────────── */
@RestController
@RequiredArgsConstructor
class MyOsWebhookEndpoint {
private final Blue blue; // helper from starter
private final SnapshotStore store; // keeps latest doc
private final PaymentProcessor payments;
private final Logger logger = LoggerFactory.getLogger(MyOsWebhookEndpoint.class);
@PostMapping(value="/blue/webhook",
consumes=MediaType.APPLICATION_JSON_VALUE)
public void handle(@RequestBody MyOsWebhook wh) {
/* 1 ─ parse and save the latest document */
Node doc = blue.jsonToNode(wh.document());
store.upsertLatest(wh.agentId(), doc);
/* 2 ─ inspect triggered events */
for (String raw : wh.triggeredEvents()) {
Node evNode = blue.jsonToNode(raw);
// Determine the event class based on its BlueId
Optional> eventClass = blue.determineClass(evNode);
if (eventClass.isPresent()) {
Class> clazz = eventClass.get();
// Process known event types
if (RefundPayment.class.isAssignableFrom(clazz)) {
RefundPayment ev = blue.nodeToObject(evNode, RefundPayment.class);
payments.refund(ev.paymentId(), ev.amount());
logger.info("Processed refund for payment {}: ${}", ev.paymentId(), ev.amount());
}
else if (MakeInternalStripePayment.class.isAssignableFrom(clazz)) {
MakeInternalStripePayment ev = blue.nodeToObject(evNode, MakeInternalStripePayment.class);
payments.capture(ev.amount(), ev.recipientStripeAccount(), ev.notes());
logger.info("Processed capture: ${} for account {}",
ev.amount(), ev.recipientStripeAccount());
}
// Add handlers for other payment-related events as needed
}
}
}
}
```
When a document triggers events like `MakeInternalStripePayment`, your webhook handler calls the appropriate method on your payment service, integrating Blue documents with your existing business logic.
## Supported Document Types
As a payment processor, you might support these Blue document types:
### Card Payment
A standard payment transaction with enhanced capabilities:
See [Card Payment](../payments/single-payment) for detailed examples, including guaranteed delivery discounts and cryptocurrency exchange with protection.
### Payment Plan
A dynamic document that manages when and how payments are triggered:
See [Payment Plan](../payments/payment-plan) for examples of subscription and event-based payment scenarios.
## Security and Authentication
The `/blue` endpoint integrates with your existing authentication:
```java
@PostMapping(value = "/blue")
@PreAuthorize("hasAuthority('PAYMENT_PROCESSING')")
public ResponseEntity> securedBlueEndpoint(@RequestBody String rawJson) {
// Process document with normal auth checks
}
```
This ensures that:
- Your security policies apply to Blue documents
- Access control uses your existing mechanisms
- Audit trails maintain continuity with your current systems
## Benefits for All Participants
A payment processor implementing the `/blue` endpoint creates value for all parties:
**For Merchants:**
- Handle complex payment scenarios without custom code
- Create better customer experiences with transparent terms
- Add payment rules that integrate with other business processes
**For Customers:**
- Verify that payments only happen under agreed conditions
- Gain visibility into payment status and logic
- Reduce risk in complex transactions
**For the Payment Processor:**
- Differentiate with advanced payment capabilities
- Expand into new use cases beyond standard payments
- Add value without changing core payment systems
## Implementation Steps
1. **Add Dependencies**:
```gradle
implementation 'blue.starter:spring-blue-gateway-starter:1.0.0'
implementation 'blue.repo:payments:1.12'
```
2. **Configure Your Gateway**:
Define which document types and contracts your endpoint supports
3. **Create Endpoint and Webhook Handler**:
Add the controllers shown in this guide
4. **Connect to Your Core Services**:
Map document events to your business logic
5. **Test with Sample Documents**:
Verify processing of basic and advanced payment scenarios
----------------------------------------
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/integration/myos-agent.md
# Publish as MyOS Agent
Whether you're running an e-commerce platform, offering SaaS services, or providing any digital product, exposing your functionality as MyOS Agents creates powerful new opportunities for your business. This integration connects your offerings to the entire Blue ecosystem, enabling unprecedented levels of automation, collaboration, and reach.
## Why Publish Your Services as MyOS Agents?
Publishing your services as MyOS Agents transforms how others can discover, consume, and integrate with your offerings:
### 1. Become Part of User Agreements and Workflows
When your services are available as MyOS Agents, users can seamlessly include them in their agreements and processes:
- **Automated Purchases**: E-commerce platforms can have products automatically ordered when specific conditions are met
- **Service Integration**: SaaS providers can have their services automatically invoked as part of larger business processes
- **Verified Workflows**: Your services can act as trusted verification steps in complex multi-party agreements
Instead of requiring custom API integration work for every new use case, your services become plug-and-play components that anyone can incorporate into their Blue documents.
### 2. Enable Ad-hoc Process Building in Workspaces
[MyOS Workspaces](../myos/quick-start#adding-to-workspaces) provide collaborative environments where teams build structured processes. As a published Agent, your services can be:
- Included as participants in workspace conversations
- Added as resources for specific tasks or activities
- Configured to provide specialized capabilities within the workspace
This makes your offerings accessible in the midst of active collaboration, right where decisions are being made.
### 3. Leverage the Offer System for Direct Sales
Following the pattern shown in our [Warm-Up example](../myos/quick-start#monetizing-your-agent), you can leverage MyOS Offers to create a new sales channel:
- Offers in MyOS contain the actual documents needed to purchase your products or services
- These documents encode the complete purchase flow, from payment to access provisioning
- When a customer purchases your offer, the document automatically executes, granting appropriate access
- Your services become instantly available without manual intervention
This approach provides another sales channel alongside your existing website, completely automated through Blue documents. You can use standard offer templates or create customized offers for specific products, subscription tiers, or special promotions - all automatically processed through MyOS.
### 4. Enable Automated Partnerships and Cross-Sales
As demonstrated in our guides on [B2B Agreements](../myos/agreements) and the [Collaboration Economy](../myos/collaboration-economy), publishing as a MyOS Agent unlocks new partnership models:
- **Affiliate Relationships**: Others can promote your services with automatic commission tracking
- **Bundled Offerings**: Your services can be packaged with complementary offerings from other providers
- **Revenue Sharing**: Create sophisticated arrangements with proportional compensation
- **Cross-Promotion**: Allow marketing specialists to drive traffic to your services with performance-based payment
These partnerships execute automatically through Blue documents, requiring no changes to your core systems or manual reconciliation.
## Integration Options
There are two primary approaches to exposing your services within the MyOS ecosystem:
1. **Implement the `/blue` Endpoint**: The simplest way to expose your API to MyOS is to publish a [`/blue` endpoint](./blue-endpoint). This allows any service speaking Blue, including MyOS, to communicate with your website.
2. **Create an Agent with Custom API Mappings**: Alternatively, you can create an agent with custom mappings to your API, without modifying your existing endpoints.
If you're interested and your business fits the profile of our Golden Agent program, get in touch with us at [https://labs.blue/golden-agents](https://labs.blue/golden-agents).
----------------------------------------
NEW SECTION: advanced
File: /Users/piotr/data/contract-blue-docusaurus/_prompt/../docs/advanced/formal-specification.md
# Blue Language Specification
This document provides the technical specification for Blue Language, defining core structures, behaviors, and rules that compliant processors must implement.
## 1. Document Structure
### 1.1 Base Format
Blue documents use YAML or JSON as their foundation. Any valid YAML or JSON document is a valid Blue document if it adheres to the conventions defined in this specification.
### 1.2 Node Structure
A node is the fundamental unit in Blue. Every node belongs to exactly one of these categories:
1. **Value Node**: Contains a primitive value (Integer, Text, Double, Boolean)
2. **List Node**: Contains an ordered collection of other nodes
3. **Structure Node**: Contains named references to other nodes
## 2. Reserved Attributes
Blue reserves several attribute names with special meaning:
| Attribute | Purpose |
|-----------|---------|
| `name` | The name of the element |
| `description` | A textual description of the element |
| `type` | Reference to another document/type that this element inherits from |
| `value` | The primitive value of the element |
| `blueId` | The content-based identifier of the element |
| `contracts` | Rules that define how the document responds to events |
| `blue` | Transformations for Blue processors |
| `items` | List items (for list nodes only) |
| `itemType` | Type constraint for list items |
| `keyType` | Type constraint for dictionary keys |
| `valueType` | Type constraint for dictionary values |
These attributes must only be used according to their intended purpose to ensure consistent behavior across processors.
### 2.1 Special Text Attributes
The `name` and `description` attributes have special properties:
- Always treated as text values
- Are part of the node itself (not references to other nodes)
- Used directly in BlueId calculation
- Cannot be referenced as separate nodes
For example:
```yaml
# Correct
name: Some Name
otherTextParam:
value: Some Value
type: Text
# Also correct - referencing a node with BlueId
name: Some Name
otherTextParam:
blueId: CLthNx8MWUfPWr1xXzSivsxjye9uQyi77Ep6LGPLvYpM
```
## 3. Node Categories and Constraints
### 3.1 Value Nodes
A value node must:
- Have a `value` property
- Not have `items` or `properties`
- Be of a basic type (Integer, Text, Double, Boolean) or a subtype
Example:
```yaml
myInteger:
value: 42
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8 # Integer
```
### 3.2 List Nodes
A list node must:
- Have an `items` property containing a list
- Not have `value` or `properties`
- Optionally have an `itemType` constraint
Example:
```yaml
myList:
items:
- 1
- 2
- 3
itemType:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8 # Integer
```
### 3.3 Structure Nodes
A structure node must:
- Have properties referencing other nodes
- Not have `value` or `items`
Example:
```yaml
person:
name: John Doe
age: 30
address:
street: 123 Main St
city: Anytown
```
## 4. Type System
### 4.1 Primitive Types
Blue defines four primitive types:
| Type | BlueId | Description | Example Values |
|------|--------|-------------|----------------|
| `Text` | F92yo19rCcbBoBSpUA5LRxpfDejJDAaP1PRxxbWAraVP | Text strings | `"Hello"` |
| `Integer` | DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8 | Arbitrary precision integer | `42`, `9007199254740991` |
| `Double` | 68ryJtnmui4j5rCZWUnkZ3DChtmEb7Z9F8atn1mBSM3L | IEEE 754 double-precision | `3.14159` |
| `Boolean` | EL6AjrbJsxTWRTPzY8WR8Y2zAMXRbydQj83PcZwuAHbo | Logical true/false | `true`, `false` |
### 4.2 Integer Representation
Integers in Blue have arbitrary precision:
- Values within JavaScript safe integer range (-9007199254740991 to 9007199254740991) are stored natively
- Values outside this range are stored as strings with the Integer type
Example:
```yaml
x1:
value: 123
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8 # Integer
x2:
value: "132452345234524739582739458723948572934875"
type:
blueId: DHmxTkFbXePZHCHCYmQr2dSzcNLcryFVjXVHkdQrrZr8 # Integer
```
### 4.3 Type Inheritance
When a node specifies a `type`, it inherits all properties from the referenced type. If document B specifies `type: A`, then B is considered a subtype of A, inheriting its properties.
### 4.4 Type Extension Rules
When extending a type:
1. Fixed values in the parent type cannot be overridden
2. New properties can be added
3. Properties with no fixed values can be assigned values
4. Type compatibility must be maintained (child properties must use the same or compatible subtypes)
## 5. BlueId Calculation
### 5.1 BlueId Definition
A BlueId is a content-based identifier calculated for every node in a Blue document. It uniquely identifies a node based on its semantic content.
### 5.2 BlueId Algorithm
The BlueId calculation algorithm works as follows:
1. **Clean the structure**: Remove null values
2. **For primitive values** (String, Number, Boolean):
- Hash the string representation directly
3. **For maps (structure nodes)**:
- If the map contains a `blueId` key, use its value directly
- Otherwise:
- Keep `name`, `value`, and `description` as direct values
- Replace all other properties with their BlueId references
- Hash this transformed map
4. **For lists**:
- If the list has only one item, return the BlueId of that item
- Otherwise:
- Calculate the BlueId of the sublist excluding the last element
- Calculate the BlueId of the last element
- Create a list with these two BlueIds and hash it
Here is the complete algorithm in Java:
```java
public String calculate(Object object) {
Object cleanedObject = cleanStructure(object);
if (cleanedObject instanceof String || cleanedObject instanceof Number || cleanedObject instanceof Boolean) {
return hashProvider.apply(cleanedObject.toString());
} else if (cleanedObject instanceof Map) {
return calculateMap((Map) cleanedObject);
} else if (cleanedObject instanceof List) {
return calculateList((List