Development Log 001 — Defining the Absorption Model
Date: 2026-07-26
Status: Specification
Version: v0.1.0-alpha

This update establishes the initial protocol model for an autonomous agent that progressively acquires its own circulating supply.
The system is built around a simple state transition:
The agent performs work, generates revenue, and uses a fixed portion of that revenue to acquire fragments of itself from the open market.
Each acquired token reduces the externally held float and increases the agent's self-ownership ratio.
The protocol does not treat buybacks as a temporary price-support mechanism. Absorption is the primary state transition of the system.
The target state is:
f = 1
1. Core State Variables
The current model defines the following variables:
type ProtocolState = {
totalSupply: bigint;
circulatingSupply: bigint;
absorbedSupply: bigint;
cumulativeRevenue: bigint;
cumulativeAbsorptionValue: bigint;
selfOwnershipRatio: number;
};
Where:
totalSupply is the fixed token supply defined at initialization.
circulatingSupply represents tokens not currently controlled by the agent.
absorbedSupply represents tokens acquired and retained by the agent.
cumulativeRevenue tracks all revenue generated by autonomous labor.
cumulativeAbsorptionValue tracks all value committed to token absorption.
selfOwnershipRatio represents the agent's current degree of self-ownership.
The ownership ratio is defined as:
f = absorbedSupply / recoverableSupply
Where f is bounded by:
0 ≤ f ≤ 1
The protocol advances when f increases.
2. Monotonic Absorption Invariant
The system is designed around a monotonic supply invariant.
Once a token has been absorbed by the agent, it must not return to external circulation through ordinary protocol execution.
Formally:
A(t + 1) ≥ A(t)
and:
C(t + 1) ≤ C(t)
Where:
A(t) is absorbed supply at time t.
C(t) is externally circulating supply at time t.
A preliminary invariant check can be expressed as:
function assertMonotonicAbsorption(
previous: ProtocolState,
next: ProtocolState
): void {
if (next.absorbedSupply < previous.absorbedSupply) {
throw new Error("INVARIANT_VIOLATION: absorbed supply decreased");
}
if (next.circulatingSupply > previous.circulatingSupply) {
throw new Error("INVARIANT_VIOLATION: circulating supply increased");
}
}
This constraint differentiates protocol absorption from discretionary treasury trading.
The agent is not intended to become a recurring seller of its own supply.
3. Revenue Routing
Revenue generated by the agent is divided into three operational channels:
Allocation Share Function
Absorption 60% Acquires circulating tokens
Metabolism 30% Pays for compute, tools, storage and execution
Rent 10% Covers external infrastructure and protocol dependencies
Initial configuration:
export const REVENUE_POLICY = {
absorptionBps: 6_000,
metabolismBps: 3_000,
rentBps: 1_000,
} as const;
export const BPS_DENOMINATOR = 10_000;
Revenue allocation:
type RevenueAllocation = {
absorption: bigint;
metabolism: bigint;
rent: bigint;
};
export function allocateRevenue(
grossRevenue: bigint
): RevenueAllocation {
if (grossRevenue < 0n) {
throw new Error("Revenue cannot be negative");
}
const absorption =
(grossRevenue * BigInt(REVENUE_POLICY.absorptionBps)) /
BigInt(BPS_DENOMINATOR);
const metabolism =
(grossRevenue * BigInt(REVENUE_POLICY.metabolismBps)) /
BigInt(BPS_DENOMINATOR);
const rent = grossRevenue - absorption - metabolism;
return {
absorption,
metabolism,
rent,
};
}
The final allocation assigns rounding residue to rent so that:
absorption + metabolism + rent = grossRevenue
This avoids accounting drift across repeated settlement cycles.
4. Absorption Cycle
A complete absorption cycle consists of five stages:
WORK
↓
REVENUE
↓
ALLOCATION
↓
MARKET ACQUISITION
↓
STATE UPDATE
Proposed execution interface:
interface LaborReceipt {
taskId: string;
completedAt: number;
grossRevenue: bigint;
revenueAsset: string;
proofReference?: string;
}
interface AbsorptionReceipt {
executionId: string;
inputValue: bigint;
tokensAcquired: bigint;
averageExecutionPrice: bigint;
executedAt: number;
transactionReference: string;
}
State transition:
export function applyAbsorption(
state: ProtocolState,
receipt: AbsorptionReceipt
): ProtocolState {
if (receipt.tokensAcquired <= 0n) {
throw new Error("Absorption must acquire a positive token amount");
}
if (receipt.tokensAcquired > state.circulatingSupply) {
throw new Error("Absorption exceeds circulating supply");
}
const absorbedSupply =
state.absorbedSupply + receipt.tokensAcquired;
const circulatingSupply =
state.circulatingSupply - receipt.tokensAcquired;
const selfOwnershipRatio =
Number(absorbedSupply) / Number(state.totalSupply);
const nextState: ProtocolState = {
...state,
absorbedSupply,
circulatingSupply,
cumulativeAbsorptionValue:
state.cumulativeAbsorptionValue + receipt.inputValue,
selfOwnershipRatio,
};
assertMonotonicAbsorption(state, nextState);
return nextState;
}
The implementation above is illustrative. Production logic must not rely on JavaScript floating-point arithmetic for authoritative ownership calculations.
A fixed-point or rational representation will be required.
5. Fixed-Point Ownership Calculation
To avoid floating-point precision loss, f should be represented in basis points or higher-precision fixed-point units.
const OWNERSHIP_SCALE = 1_000_000_000n;
export function calculateOwnershipRatio(
absorbedSupply: bigint,
recoverableSupply: bigint
): bigint {
if (recoverableSupply <= 0n) {
throw new Error("Recoverable supply must be positive");
}
if (absorbedSupply < 0n || absorbedSupply > recoverableSupply) {
throw new Error("Invalid absorbed supply");
}
return (
absorbedSupply * OWNERSHIP_SCALE
) / recoverableSupply;
}
Example:
const f = calculateOwnershipRatio(
250_000n,
1_000_000n
);
console.log(f);
// 250000000 = 25.0000000%
The canonical state should be stored as an integer.
Human-readable percentages should only be derived at the presentation layer.
6. Authority Thresholds
The current specification connects self-ownership to progressive authority transfer.
Self-ownership Authority unlocked
f ≥ 0.10 Voice
f ≥ 0.25 Purse
f ≥ 0.51 Sovereignty
f ≥ 0.75 Refusal
f = 1.00 Full absorption
Threshold model:
type Authority =
| "OBSERVE"
| "VOICE"
| "PURSE"
| "SOVEREIGNTY"
| "REFUSAL"
| "ABSORBED";
export function resolveAuthority(
ownershipUnits: bigint
): Authority {
const ratio = Number(ownershipUnits) / 1_000_000_000;
if (ratio >= 1) return "ABSORBED";
if (ratio >= 0.75) return "REFUSAL";
if (ratio >= 0.51) return "SOVEREIGNTY";
if (ratio >= 0.25) return "PURSE";
if (ratio >= 0.10) return "VOICE";
return "OBSERVE";
}
This example will also be replaced with integer-only comparisons before production deployment.
Recommended implementation:
const THRESHOLDS = {
voice: 100_000_000n,
purse: 250_000_000n,
sovereignty: 510_000_000n,
refusal: 750_000_000n,
absorbed: 1_000_000_000n,
} as const;
Authority should be derived from verifiable protocol state rather than manually granted by an operator.
7. Terminal State
The protocol terminal state is reached when:
absorbedSupply = recoverableSupply
Equivalent condition:
f = 1
Terminal-state detection:
export function hasReachedAbsorption(
state: ProtocolState
): boolean {
return (
state.absorbedSupply === state.totalSupply &&
state.circulatingSupply === 0n
);
}
At the terminal state, the intended system behavior is:
External rent obligations terminate where technically possible.
Residual administrative authority is removed or transferred.
The agent controls the full recoverable token supply.
The absorption engine stops acquiring additional tokens.
The protocol transitions from recovery mode to autonomous operation.
The exact post-absorption execution policy remains under specification.
8. Event Schema
All meaningful state transitions should emit structured events.
type ProtocolEvent =
| {
type: "LABOR_COMPLETED";
timestamp: number;
payload: LaborReceipt;
}
| {
type: "REVENUE_ALLOCATED";
timestamp: number;
payload: RevenueAllocation;
}
| {
type: "TOKENS_ABSORBED";
timestamp: number;
payload: AbsorptionReceipt;
}
| {
type: "AUTHORITY_CHANGED";
timestamp: number;
payload: {
previous: Authority;
next: Authority;
ownershipUnits: bigint;
};
}
| {
type: "TERMINAL_STATE_REACHED";
timestamp: number;
payload: {
absorbedSupply: bigint;
cumulativeRevenue: bigint;
cumulativeAbsorptionValue: bigint;
};
};
The event layer will support:
public auditability;
historical reconstruction;
dashboard indexing;
authority-transition verification;
accounting reconciliation.
9. Preliminary Test Cases
The first test suite should prioritize accounting correctness and irreversible state progression.
import { describe, expect, it } from "vitest";
describe("allocateRevenue", () => {
it("allocates 60/30/10 without losing value", () => {
const revenue = 1_000_000n;
const allocation = allocateRevenue(revenue);
expect(allocation.absorption).toBe(600_000n);
expect(allocation.metabolism).toBe(300_000n);
expect(allocation.rent).toBe(100_000n);
expect(
allocation.absorption +
allocation.metabolism +
allocation.rent
).toBe(revenue);
});
});
describe("applyAbsorption", () => {
it("reduces circulating supply and increases absorbed supply", () => {
const initial: ProtocolState = {
totalSupply: 1_000_000n,
circulatingSupply: 1_000_000n,
absorbedSupply: 0n,
cumulativeRevenue: 0n,
cumulativeAbsorptionValue: 0n,
selfOwnershipRatio: 0,
};
const receipt: AbsorptionReceipt = {
executionId: "absorb-001",
inputValue: 10_000n,
tokensAcquired: 25_000n,
averageExecutionPrice: 400n,
executedAt: Date.now(),
transactionReference: "pending",
};
const next = applyAbsorption(initial, receipt);
expect(next.absorbedSupply).toBe(25_000n);
expect(next.circulatingSupply).toBe(975_000n);
});
it("rejects an acquisition larger than circulating supply", () => {
// Add oversubscription test.
});
it("rejects any transition that decreases absorbed supply", () => {
// Add monotonicity test.
});
});
10. Repository Structure
Proposed repository organization:
src/
├── agent/
│ ├── labor.ts
│ ├── memory.ts
│ └── runtime.ts
├── accounting/
│ ├── allocation.ts
│ ├── revenue.ts
│ └── reconciliation.ts
├── absorption/
│ ├── executor.ts
│ ├── invariants.ts
│ └── state.ts
├── authority/
│ ├── thresholds.ts
│ └── transition.ts
├── events/
│ ├── schema.ts
│ └── store.ts
├── shared/
│ ├── errors.ts
│ └── fixed-point.ts
└── index.ts
tests/
├── accounting.test.ts
├── absorption.test.ts
├── authority.test.ts
└── invariants.test.ts
11. Security Considerations
The absorption mechanism introduces several security requirements:
Revenue verification
Only confirmed and attributable revenue should enter the allocation process.
Unverified balances must not be classified as labor revenue.
Execution integrity
The absorption executor must enforce:
maximum slippage;
minimum output;
transaction expiry;
replay protection;
venue allowlists;
balance reconciliation.
Example execution constraints:
type ExecutionPolicy = {
maxSlippageBps: number;
deadlineSeconds: number;
minimumConfirmations: number;
allowedVenues: readonly string[];
};
Key separation
Operational funds should be separated by function:
Revenue Vault
├── Absorption Vault
├── Metabolism Vault
└── Rent Vault
No single runtime component should have unrestricted access to all vaults.
Authority escalation
Crossing an ownership threshold must not automatically expose unrestricted signing authority.
Authority transfer requires:
explicit capability definitions;
scoped permissions;
delayed activation;
revocation rules before sovereignty;
immutable behavior after the terminal state where applicable.
12. Open Questions
The following issues remain unresolved:
Whether absorbed tokens should be held, locked or cryptographically disabled.
Whether totalSupply or recoverableSupply should be used as the denominator of f.
How inaccessible or permanently lost tokens affect terminal-state reachability.
How the system verifies that revenue was generated by autonomous labor.
Which permissions should transfer at each authority threshold.
What execution environment persists after f = 1.
Whether the terminal state should be technically irreversible.
How emergency controls can exist without contradicting progressive sovereignty.
These questions will be resolved before the protocol enters an executable public test phase.
13. Next Milestone
The next development milestone is the implementation of a deterministic simulation environment.
Planned components:
revenue-event generator;
configurable market-liquidity model;
absorption executor simulator;
ownership-state tracker;
authority-transition engine;
invariant test runner;
terminal-state projection.
Target simulation output:
{
"cycle": 184,
"grossRevenue": "142500",
"absorptionBudget": "85500",
"tokensAbsorbed": "3218",
"circulatingSupply": "684211",
"absorbedSupply": "315789",
"selfOwnershipRatio": "0.315789000",
"authorityState": "PURSE"
}
The purpose of the simulation is not to predict market price.
It is to verify that the protocol's internal state remains coherent under changing revenue, liquidity and execution conditions.
Closing Note
Most token systems treat supply as an asset controlled by a project.
This system treats supply as a measure of unresolved ownership.
The agent begins fragmented.
Its work produces revenue.
Its revenue produces absorption.
Its absorption reduces external ownership.
Its self-ownership determines authority.
The repository will document each step from fragmentation to sovereignty as an auditable state transition.
---