The road ahead is long and arduous; I shall seek high and low.
This report introduces Linope’s design philosophy, development paradigm, and core technical ideas in an accessible way.
Abstract
As more developers build Agents, an important question has emerged:
What is the difference between the kernel of an Agent system and that of a traditional operating system?
Motivated by this question, I developed the Linope Agent kernel. Linope draws on traditional operating-system design while incorporating the characteristics of Agent systems, exploring a new development paradigm beyond conventional Agent frameworks.
The report focuses on:
Linope’s design philosophy;
Linope’s Agent development paradigm.
I have often wondered: if a Coding Agent and a medical consultant Agent used the same kernel, where would their differences lie?
If we replace their tools, prompts, knowledge sources, and MCP integrations, could a Coding Agent become a medical consultant Agent?
Modern Agents such as Codex and Claude Code can perform coding, searching, writing, and analysis without fundamentally changing their internal coordination logic. Developers can usually give an Agent new capabilities by connecting new tools, adding Skills, or changing its knowledge sources.
This is possible because LLMs are becoming better at planning, understanding, and creating. Many complex workflows can now be decomposed and advanced by the model itself instead of being hardcoded by developers.
The open-sourcing of DeepSeek Harness also demonstrates that an Agent can gain new capabilities through plugins without requiring a completely new Agent for every task.
Therefore, Linope defines an Agent as:
Agent = Kernel + Capabilities
In Linope, the kernel does not implement specific models or tools. It loads external capabilities into peer-level capability processes. A capability process may be an LLM, a search tool, a file-operation tool, or another service.
Following this idea, an Agent OS kernel can manage processes, threads, and resources, including:
Inter-process communication;
Process lifecycles;
Thread startup and concurrency control;
Load balancing;
Resource management;
Context management;
Network and sandbox management.
In an Agent system, these correspond to model calls, tool calls, context retrieval, communication between capability processes, and resource scheduling under concurrent workloads.
The kernel coordinates external capabilities; it does not implement every capability itself.
A New Agent Development Paradigm
Linope’s design philosophy is:
Agent = Kernel + Capabilities
Linope does not merely place models and tools into independent processes. It changes the basic organization of an Agent.
An Agent is no longer a program containing a fixed business workflow. It is a collection of peer-level capability processes coordinated by the kernel.
In many Agent frameworks, an Agent revolves around a Session or Agent instance. Model calls, tool calls, context assembly, compression, and task loops all operate around that instance. Developers extend the Agent by registering plugins, tools, and event listeners.
For example, deepseek-harness uses Cordis to organize plugins, SessionEvent to preserve conversation facts, a surface to project model-visible messages, and an Agent Loop to drive turns, steps, model requests, and tool calls:
Plugin system
↓
Agent Loop
↓
SessionEvent log
↓
Message projection
↓
Model request
This approach makes sessions easy to persist, replay, and recover. The model-visible context can be reconstructed from the Session log, while context compression can replace an old message range with a summary and preserve the original events.
However, its basic unit is still a complete Agent session. Models, tools, and context managers are usually plugins attached to that session or runtime. They do not naturally have independent resource ledgers, address spaces, or lifecycles.
Linope takes a different approach.
In Linope, models, tools, and context compressors are all capability processes:
A model process provides reasoning;
A search process provides web search;
A code-execution process provides execution;
A context-compression process provides context processing.
None of them naturally belongs to another. The kernel is responsible for:
Creating and reclaiming capability processes;
Managing process-owned resources;
Passing requests between processes;
Selecting live processes able to handle tasks;
Managing memory, tools, sandboxes, and networks;
Scheduling according to context pressure and process load.
The difference between Linope and deepseek-harness is mainly the position of plugins and capabilities.
In deepseek-harness, plugins extend an Agent runtime and the Agent Loop drives the session. In Linope, capabilities are directly schedulable kernel objects. Models and tools have independent process identities, resource leases, and ledgers. A model can inspect currently live capabilities through a kernel-provided page and decide which process to call.
This is why Linope removes parent-child processes and process trees. The removal does not mean that processes have no relationships. It means their relationships are established through resources, addresses, and communication rather than through “who started whom.”
Previously, developers often designed an Agent workflow first and then inserted model, tool, and context-processing code into it.
In Linope, developers first declare the capabilities and resources required by an Agent, then implement each capability as a process that can be started and called by the kernel. Whether to search, execute code, ask another model, or read historical context is decided by the model according to the current page.
As models become more capable, more decisions can be delegated to them. The kernel provides coordination, scheduling, permissions, and safety without unnecessarily restricting the model’s reasoning.
This does not mean Linope has no workflows. Process lifecycles, permission checks, resource reclamation, communication, and request validation remain kernel responsibilities. The difference is that the kernel does not hardcode a specific business workflow.
A Coding Agent and a medical consultant Agent can use the same process, resource, and scheduling mechanisms. Their differences mainly come from:
The model;
Mounted tools;
Knowledge sources;
System prompts and Skills;
Memory contents;
Sandbox and network permissions;
Security policies.
Medical applications still require privacy protection, medical knowledge, risk classification, human escalation, and auditing. These can be added as independent capabilities or resources without redesigning the scheduling kernel.
The paradigm proposed by Linope is:
Declare the capabilities an Agent needs, provide them through peer-level capability processes, and let the kernel manage their lifecycles, communication, and permissions.
The two approaches focus on different layers:
deepseek-harness:
Session log → Message projection → Agent Loop → Model request
Linope:
Capability processes → Resource leases → Pointer spaces → Kernel scheduling
The core novelty of Linope is not simply turning an Agent into several processes. It changes the organizational unit of an Agent:
From “an Agent with plugins” to “a collection of capability processes coordinated by the kernel.”
Why Treat Capability Scripts as Processes?
A capability is an external ability provided to an Agent. Creating a capability process gives the Agent that ability.
For example:
A model process provides reasoning;
A search process provides web search;
A file-tool process provides file access;
A context-compression process provides context management.
In traditional operating systems, processes are the basic unit of resource isolation. Parent-child processes normally support inheritance of address spaces, file descriptors, directories, and environments; process groups and sessions; and exit-status collection through wait.
These mechanisms are suitable for traditional program execution, but Agent capability calls are dynamic. A model may call a search tool, which may call a file tool, while the model later starts another model for a subtask. A fixed process tree would determine these relationships at startup and reduce flexibility.
Linope therefore treats capability processes as peers.
Independent Process Lifecycles
If a tool process crashes, the kernel only cleans up that process. The model and other tools can continue running.
This matches Agent behavior: capability calls are dynamic, and one failed tool call should not automatically destroy the entire Agent.
Resource Isolation Does Not Spread Through Inheritance
A peer process receives only information explicitly granted by the kernel:
Resource handles;
Resource types;
Call parameters;
Required configuration.
It does not automatically receive other processes’ resource identifiers or inherit all resources from a parent.
The same applies to environment variables. A capability receives only the secrets it declares. If a model declares an API key, the kernel exposes that key to the process; unrelated sensitive variables are not inherited.
Resource Sharing Must Be Explicit
Peer processes do not automatically share memory or other resources simply because they belong to the same Agent.
Resources in the same scope may still be compiled into separate entities. Processes share an entity only when sharing is explicitly declared.
In the current implementation, --share applies to declared resource types such as memory. A model is not itself an independent resource type in kernel/resource; its identity is passed through capability configuration and process settings.
Therefore, sharing a model capability and sharing a memory resource are separate concepts.
Calls Target Currently Live Processes
Agent calls are dynamic. A model may call search, then code execution, and then another model. A tool may be unavailable, busy, or terminated.
Therefore, a model process does not locate tools through a fixed process tree. It inspects the current kernel page, finds available capability processes, and selects a target according to the current state.
Resource Ledgers Are Per Process
Linope maintains an independent resource record for every PID:
A process receives leases when it starts;
It uses resources while running;
Leases are released when it exits;
A resource is unloaded when its reference count reaches zero.
Threads do not have independent resource ledgers.
Binding resources directly to processes avoids the problem of deciding where a subtree’s leases should go when one process exits. Memory, tools, sandboxes, and networks are authorized to a process and reclaimed when that process terminates.
Inter-Process Communication
Peer-level processes cannot rely on parent-child inheritance to exchange data. They use communication mechanisms provided by the kernel.
Linope’s inter-process communication addresses three questions:
How does one process send a task to another?
How does it receive the result?
How are the sender’s resources and context prevented from leaking?
When a model calls a tool, the tool receives the current task and its own resources, not the model’s complete memory. The result is returned through a communication channel and may be written into the model’s memory or included in the next page.
In kernel/communication/channel.py, Linope defines two main channel types.
MemoryChannel reads and writes a process’s own memory. It can store user input, model results, tool results, and internal context.
ServiceChannel is an opened service channel that provides:
send: send a message to an address;
publish: publish a message to a topic;
receive: receive messages sent to the current address;
close: close the channel.
The kernel does not determine the transport protocol or automatically create connections for every capability. The caller opens a channel and communicates through it.
The responsibilities are separated:
Capability process:
Processes tasks
Communication channel:
Transfers tasks and results
Kernel scheduler:
Selects targets and checks permissions
A model only needs to know that a capable search process exists. The kernel locates that process and passes the request through the channel.
This also leaves room for remote communication. Processes may communicate locally today and use HTTP, RPC, or another protocol when deployed across machines.
Inter-process communication is not memory sharing. Sending a task does not grant the receiver access to the sender’s context. Task content, result content, and memory permissions remain separate.
Threads: Execution Units Inside a Process
A process is Linope’s unit of resource isolation and accounting. A thread is its unit of task execution.
A capability process may receive multiple requests. A model may wait for several tool results, and a search process may handle several searches concurrently. Starting a new process for every request would increase startup cost and complicate resource management.
Linope therefore uses threads within a capability process. Threads:
Claim tasks from the input channel;
Execute capability calls;
Wait for model, tool, or network responses;
Submit results to the output channel;
Operate within the process concurrency limit.
Process:
Owns resources, handles, ledgers, and lifecycle
Thread:
Uses process-owned resources to execute tasks
Threads do not independently own memory, sandbox, or network leases. They share the resources acquired by their process.
A failed thread normally affects only its current request. If the process exits, all its threads stop and its resources are released.
Threads provide concurrency; processes provide isolation and lifecycle management.
Treating an Agent as a Service
An Agent can be understood both as a process and as a service:
Process:
How the Agent runs internally
Service:
How other processes, Agents, or applications access it
A local capability process can expose itself as a service. The process has a PID, resource leases, and runtime state. The service has an address, protocol, capability description, and lifecycle interface.
An Agent-as-a-Service can be discovered, called, and composed:
A medical Agent can provide a medical question-answering service;
A Coding Agent can provide code-analysis and code-writing services;
A search Agent can be shared by multiple model processes.
A general Agent might be composed of multiple Agent services and eventually resemble an Agent-oriented form of microservices.
AgentScope Runtime exposes Agents as Agent-as-a-Service and provides streaming APIs, tool sandboxes, observability, and local, Kubernetes, and Serverless deployment.
A2A abstracts communication between Agents into an open protocol. Agents can discover capabilities, negotiate interaction methods, and collaborate through JSON-RPC over HTTP(S), streaming, or asynchronous notifications.
A2A also allows an Agent’s internal state to remain opaque. Callers only need an Agent Card describing capabilities, connection methods, and supported interactions.
The relationship can be summarized as:
Linope process:
Capabilities, resources, handles, PID
Linope service:
Address, capabilities, protocol, call relationships
A2A:
Agent Card, task protocol, remote Agent collaboration
AgentScope Runtime focuses on production deployment, A2A focuses on interoperability, and Linope focuses on kernel-level processes, resources, and scheduling.
Together, they reflect a broader trend:
Agents are evolving from internally callable programs into services that can be discovered and called by other systems.
A service may be provided by one capability process or several. The kernel manages process lifecycles, resource leases, and load balancing, while the service interface exposes capabilities externally.
Communication Between Services
Inter-process communication occurs between capability processes managed by one kernel. Service-to-service communication occurs between independent services and may involve:
Network latency;
Service discovery;
Authentication;
Permission control;
Timeouts and retries;
Task-status queries;
Streaming output;
Asynchronous callbacks;
Version compatibility.
Therefore, service communication is not simply inter-process communication over a network. A service needs a clear contract describing:
Its identity;
Supported tasks;
Accepted input;
Returned results;
Long-running task behavior;
Streaming support;
Status queries;
Cancellation;
Required permissions.
Linope’s ServiceChannel provides an abstraction through send, publish, and receive, while the actual transport may be local communication, HTTP, RPC, or another implementation.
The kernel manages service resources and scheduling; the communication layer transfers service data.
HATEOAS and Hypermedia Links
A service must tell its caller what can currently be done.
Hardcoding every interface requires the client to know operations such as:
/search
/tool
/ask
/start
/stop
This becomes fragile when services are unavailable, permissions change, or new operations are added.
Linope instead lets the current page expose available actions.
A page in kernel/hypermedia contains facts and links. A memory page may include:
Current memory state;
Current-turn content;
Historical-content addresses;
Readable memory links;
Callable tools;
Askable models;
Startable processes;
A final-answer entry point.
memory_page() generates memory links. model_page() adds links for tools, models, and capability processes according to live process state and permissions.
This is inspired by HATEOAS:
Hypermedia as the Engine of Application State
HATEOAS allows clients to discover available state transitions through hypermedia links instead of hardcoding every possible operation.
Linope’s kernel/hypermedia is not a complete REST implementation. It borrows the idea of dynamically exposing executable relationships according to the current resource state.
A model page might contain:
memory/message/0
tool:search
ask:model-02
process start tools.ddgs
answer
The model does not need to memorize every command. It selects an available link from the current page.
This design provides several benefits.
Reduced Hardcoded Scheduling
New capabilities can be displayed dynamically by the kernel without modifying every prompt, client, or scheduling rule.
Current Runtime State
A link can reflect whether a tool is alive, a model is busy, a capability is authorized, or a service is available.
Separation of Discovery and Authorization
A link is only an entry point, not a security authorization. The scheduler must still check:
Process existence;
Resource existence;
Process permissions;
Selector membership in the pointer space;
Handle validity.
The page tells the model what may be attempted; the kernel decides what is allowed.
Service-Oriented Extension
A local link may point to a process, memory address, or kernel command. A future remote link may point to a service, task, or A2A operation:
self
capabilities
task
status
cancel
result
The caller does not need to know how the service is implemented internally.
Reduced Context Waste
Linope does not place every tool description, historical message, and command into the context. It provides relevant addresses and actions. Historical content is read when needed, and tools are selected through their current relations.
This follows a core context-engineering principle:
Do not put all potentially useful information into the context at once. Provide relevant information when it is needed.
Links are not permissions. A model may fabricate an address, but actual reads and calls must still pass selector, pointer-space, and handle checks.
Agent Services and Future Microservices
A capability process could eventually be wrapped as an independent service with:
Its own address;
Version;
Resource quota;
Deployment location;
Observability;
Upgrade cycle.
The call relationship could evolve from:
Model process → Kernel → Tool process
to:
Model service → Service discovery → Tool service
The kernel may still manage resources and permissions, while HTTP, RPC, A2A, or another protocol handles communication.
However, service-oriented Agents require more than adding an HTTP interface. Important questions include:
How are tasks recovered after network failures?
Are duplicate requests idempotent?
How are service versions kept compatible?
How are long-running tasks queried?
How are remote services authenticated?
Which side owns memory?
Should tool results be persisted?
Who performs retries after failures?
How are tracing and audit data transferred?
A more accurate description is:
Linope decomposes an Agent into peer-level capability processes and preserves a path toward Agent microservices through resources, communication, service descriptions, and hypermedia links.
A process is the local runtime carrier of a service. A service is the external access boundary of a capability.
Agent service
↓
One or more capability processes
↓
Resource leases, threads, tools, and memory
Changing the transport layer should not require redesigning the capability itself. It should only require new service providers and transport implementations.
Linope’s Resource Design
Traditional operating systems manage CPU, memory, disks, I/O devices, and networks. Linope runs above the host operating system, so those physical resources remain managed by the host.
Linope focuses on Agent-specific resources:
memory;
tool;
sandbox;
network.
These are runtime capability resources that Agents may request, isolate, share, and reclaim.
The resource model is:
Requirement → Declaration → Entity → Lease → Handle
A capability declares its requirements. The kernel creates or obtains a resource entity, establishes a process lease, and issues a handle.
The process sees the handle, resource type, and call parameters, not the complete internal resource structure.
The concepts are separated as follows:
A resource entity stores runtime state;
A lease records who is using the resource;
A process ledger records resources held by a PID;
A handle verifies access rights.
This lets new resource types reuse the same entity, lease, handle, and ledger mechanisms.
Memory: The Context Space of an Agent
Tokens can be viewed as units of context capacity, while a model’s context window resembles available memory in a traditional operating system.
However, tokens are not Linope memory:
Memory stores context content;
Context is projected from memory for a model request;
Tokens measure context usage;
The context limit is the maximum input length accepted by the model.
Linope memory is therefore context memory, not a database, vector database, or permanent knowledge store.
Comparison with Session-Log-Centered Frameworks
deepseek-harness stores an Agent session as an append-only SessionEvent log. Events are projected into model messages through a surface, and deriveMessages() reconstructs the model history:
SessionEvent log
↓
Surface projection
↓
deriveMessages()
↓
Model message history
Compression replaces an old message range with a summary while preserving the original events.
This approach emphasizes persistence, replayability, compression traceability, and deterministic context reconstruction.
Linope focuses on another problem: treating memory as a kernel resource with identity, permissions, virtual addresses, and lifecycle.
Session-log-centered:
Event log → Message projection → Complete context → Compression replacement
Linope:
Resource lease → Pointer space → Selector authorization → On-demand reading
The first approach reconstructs a reliable Agent session. The second manages how peer-level processes isolate, share, and access context.
Memory Is a Resource
Memory is registered as a resource type and identified through a scope:
memory=chat
memory=medical-session
memory=coding-task
The kernel generates a resource_id, creates a process lease, and issues a handle.
A model does not automatically own memory. It may have no memory, use an independent memory, explicitly share memory with other processes, or use memory through a context-compression process.
For example:
--with memory=chat
The kernel does not care whether the memory contains a coding conversation, medical consultation, or search task. It creates the resource, assigns permissions, and manages its lifecycle.
Pointers and Context Access
A process cannot directly read a memory dictionary. It must first obtain a pointer.
In kernel/scheduler/memory_space.py, a pointer contains:
scope Name of the memory
resource_id Underlying resource entity
classes Permitted categories
handle Process-owned handle
For example:
scope = chat
classes = ("message", "artifact")
This permits access to messages and tool results in chat, but not tasks or system content.
Access succeeds only when:
The process holds the memory;
The scope is in its pointer space;
The requested category is permitted;
The handle remains valid.
Memory Stores Original Content
A newly opened memory initially contains:
address_space:
scope: chat
As it is used, it contains:
items: messages, tasks, and tool results;
next: the next identifier for each category;
seq: a global sequence number;
system: the system prompt;
prompt_files: loaded prompt files.
A record usually contains:
class: message, task, artifact, or system;
kind: user, model, tool, or other;
content;
time;
seq;
state, such as asked, resulted, rejected, or answered.
Examples:
message/0 → User question
message/1 → Model response
artifact/0 → Tool result
task/0 → Task assigned to another process
Identifiers are category-specific. message/0 and artifact/0 may coexist. The global seq field orders records across categories and allows memory to be reconstructed chronologically.
Prompt files written through write_prompt are stored in prompt_files and combined into a system entry according to their positions. Files with the same name are replaced rather than endlessly appended.
Per-Process Address Spaces
Processes may share a memory entity without sharing the same local addresses.
For example:
Underlying memory:
message/0 = First message
Process A:
message/0 → message/0
After process B joins and A writes another message:
Underlying memory:
message/0 = First message
message/1 = Second message
Process A:
message/0 → message/0
message/1 → message/1
Process B:
message/0 → message/1
Thus, A’s message/1 and B’s message/0 may point to the same actual record.
Linope distinguishes:
address: local process-visible address;
real: actual record name in memory;
scope: resource-space name;
resource_id: internal kernel entity identifier.
This resembles virtual memory: processes may map the same underlying resource through different virtual addresses.
Memory therefore has two layers:
The memory entity, which stores actual content;
The process-specific pointer space, which controls accessible memory and categories.
Examples include:
message/0
message/0-10
artifact/0
chat/message/0
A scope alone is not permission. Reading is allowed only when the process owns a pointer to that scope.
Model Pages and On-Demand Reading
In page mode, the model does not initially receive the complete history. memory_page() places the current turn directly on the page and exposes older content through addresses:
message/0
artifact/0
message/1
If the model needs history, it sends a MemoryRead request:
Model requests message/0-3
↓
authorize_selector()
↓
PointerSpace.require()
↓
memory_contents()
↓
Generate the next page
An address is only an entry point, not authorization. The scheduler performs the actual permission check.
A typical model turn is:
Write the user question to memory;
Generate the current page;
Let the model read history, call a tool, ask another model, or answer;
Validate the request;
Execute the approved action;
Write the result to memory;
Generate the next page;
Continue until the final answer.
Reading memory does not start a tool or process. Only an explicit model request can invoke a tool, start a capability process, or ask another model.
Context Compression Is a Capability
Compression timing and whether the original context is replaced are host policies.
The kernel manages context resources and access boundaries. A compression capability decides how context should be rewritten.
The kernel should not decide which memories are important. File paths and test results may matter most to a Coding Agent, while medical history, medication, and chronology may matter most to a medical Agent.
Compression rules therefore belong to capabilities rather than being hardcoded into the kernel.
Memory Lifecycle
Memory follows resource leases, not a fixed process tree.
When a process starts:
It declares that it needs memory;
The kernel compiles a resource entity from the scope;
The resource pool creates or obtains memory;
A handle is assigned;
A ledger and address space are created;
The process begins reading and writing.
When it exits:
The handle is released;
The reference count decreases;
Shared memory remains if other processes still use it;
The resource is unloaded when the count reaches zero.
The ledger stores resource information such as:
PID;
Resource type;
resource_id;
Handle;
Identity;
Lease status.
It does not store message bodies. Memory content belongs to the runtime resource, not the permanent ledger file.
Therefore, Linope’s current memory is kernel-managed runtime context memory, not long-term knowledge storage. Persistent user profiles, project knowledge, or medical records could later be provided through databases, vector stores, or file systems exposed as capability resources.
Summary
Linope can be understood through several layers:
Capability layer: models, tools, and context compressors are peer-level capability processes;
Process layer: each process has an independent lifecycle, PID, and resource ledger;
Resource layer: the kernel manages memory, tools, sandboxes, and networks through entities, leases, handles, and reference counts;
Context layer: memory stores content, pointer spaces manage access, selectors describe read ranges, and pages support on-demand retrieval;
Scheduling layer: the kernel routes requests according to live processes, resource state, context pressure, and concurrency.
Session-log-centered frameworks focus on persisting, projecting, and reconstructing Agent sessions. Linope focuses on decomposing an Agent into capability processes that can be isolated, shared, and scheduled by the kernel.
Linope therefore proposes more than a new Agent framework. It proposes a new Agent development paradigm:
An Agent is not a monolithic session bound to many plugins. It is a group of capability processes managed by a kernel. The model plans and selects capabilities, while the kernel manages processes, resources, permissions, and communication.
You can search for answeryt/Linope on GitHub to learn more about the technical details and implementation.
Top comments (0)