# How the Cache Stability System Ensures Byte-Stable Prompts in Reasonix

> Discover how Reasonix ensures byte-stable prompts by separating static metadata and deterministically hashing it for reproducible cacheable prompt prefixes. Learn more!

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: internals
- Published: 2026-08-13

---

**Reasonix guarantees byte-stable prompts by separating static metadata from dynamic content, then deterministically serializing and hashing only the static portion to create cacheable, reproducible prompt prefixes.**

The **cache stability system** in Reasonix is designed to solve a fundamental problem in LLM-based applications: caching responses requires identical byte sequences across runs, yet prompts often contain variable data like timestamps, file paths, or skill implementations that change between invocations. According to the esengine/DeepSeek-Reasonix source code, the system achieves this through architectural separation of static and dynamic prompt components.

---

## Core Components of the Cache Stability System

### System-Prompt Index: The Cache-Stable Prefix

In [`internal/skill/index.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/index.go), Reasonix builds a **cache-stable prefix** containing only immutable metadata: skill names and short descriptions. Crucially, skill bodies—which may execute arbitrary code and produce variable outputs—are deliberately excluded from this index.

The `WriteIndex` function in this file handles canonical serialization:

- Entries formatted as `name: description` (one per line)
- Deterministic newline separation
- Explicit UTF-8 encoding
- No discretionary whitespace

This format eliminates encoding ambiguities that could otherwise corrupt cache keys.

### Tool Contract Static Definitions

File [`internal/tool/tool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/tool.go) defines **static tool contracts** comprising name, arguments, and description. These contracts are computed once at startup and frozen thereafter. Unlike dynamic tool invocations, the contract representation never changes at runtime, making it safe to include in cache-stable prompts.

### Deterministic Ordering Mechanism

In [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go), all registry entries—skills, tools, and builtin plugins—maintain **insertion order** during registration. Before serialization, the collection is sorted to guarantee that identical logical sets always produce identical byte sequences regardless of initialization order.

### Cache-Key Generation via Cryptographic Hashing

The canonical index string from `BuildIndex()` undergoes SHA-256 hashing to produce the final cache key. Because the input bytes are strictly deterministic, the resulting hash is **byte-stable**: the same skill/tool configuration always yields identical cache identifiers.

---

## Runtime Prompt Assembly Process

The assembly flow in [`internal/sessioninbox/refs.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/sessioninbox/refs.go) demonstrates how static and dynamic portions combine:

1. **Startup phase**: Register all builtin tools (`internal/tool/builtin/*`) and user skills (`internal/skill/*.go`)
2. **Index construction**: `WriteIndex` iterates the registry, emits `name: description` lines, sorts the slice
3. **Hash computation**: SHA-256 digest becomes the cache-stable identifier
4. **Final composition**: Static index string prepended to variable user prompt
5. **Cache lookup**: Provider matches hash against stored responses; cache hit returns identical result for identical static prefix

This architecture ensures that **only user-provided content can vary**. Any modification to skill implementations, temporary paths, or timestamps remains isolated from the cache key calculation.

---

## Practical Implementation Examples

### Building a Cache-Stable System Prompt

```go
package main

import (
	"context"
	"github.com/esengine/DeepSeek-Reasonix/internal/skill"
)

// Register a custom skill at init time
func init() {
	skill.Register(skill.Def{
		Name:        "hello",
		Description: "Returns a friendly greeting",
		Body: func(ctx context.Context, args map[string]string) (string, error) {
			return "Hello, " + args["name"] + "!", nil
		},
	})
}

func main() {
	// Build the cache-stable system-prompt prefix
	idx, err := skill.BuildIndex()
	if err != nil {
		panic(err)
	}
	// idx is byte-stable and cacheable
	// Example output:
	//   "builtin:bash: Execute a shell command
	//    builtin:git: Run a git operation
	//    hello: Returns a friendly greeting"
	_ = idx
}

```

### Generating Deterministic Cache Keys

```go
package main

import (
	"crypto/sha256"
	"encoding/hex"
	"github.com/esengine/DeepSeek-Reasonix/internal/skill"
)

func cacheKeyForPrompt(userPrompt string) string {
	staticPrefix, _ := skill.BuildIndex()          // deterministic bytes
	fullPrompt := staticPrefix + "\n" + userPrompt // final LLM prompt
	sum := sha256.Sum256([]byte(fullPrompt))
	return hex.EncodeToString(sum[:])
}

```

Repeated execution with identical registered skills produces the same `cacheKeyForPrompt` value, confirming byte-stability.

---

## Source Files Implementing Cache Stability

| File | Purpose |
|------|---------|
| [`internal/skill/index.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/index.go) | Constructs cache-stable prefix; provides `WriteIndex` and deterministic ordering |
| [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go) | Handles registration; isolates dynamic bodies from static metadata |
| [`internal/tool/tool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/tool/tool.go) | Defines static tool contracts for inclusion in stable prompts |
| [`internal/taskcontract/taskcontract.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/taskcontract/taskcontract.go) | Abstract contract layer contributing to byte-stable definitions |
| [`internal/sessioninbox/refs.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/sessioninbox/refs.go) | Demonstrates static/dynamic prompt concatenation |

---

## Summary

- **Static/dynamic separation** in [`internal/skill/index.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/index.go) excludes variable skill bodies from cache keys
- **Canonical serialization** via `WriteIndex` eliminates formatting ambiguities
- **Deterministic ordering** in [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go) ensures consistent byte sequences
- **SHA-256 hashing** of the stable prefix creates reproducible cache identifiers
- **Runtime assembly** in [`internal/sessioninbox/refs.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/sessioninbox/refs.go) combines cached prefix with variable user input

---

## Frequently Asked Questions

### What makes a prompt "byte-stable" in Reasonix?

A byte-stable prompt produces **identical byte sequences** across multiple executions when given the same static configuration. Reasonix achieves this by strictly controlling which data enters the cache key calculation—only skill names, descriptions, and tool contracts are included, while dynamic implementations and variable runtime data are excluded.

### Why exclude skill bodies from the cache-stable index?

Skill bodies contain **executable code** that may produce different outputs depending on context, timing, or external state. Including these in cache keys would cause cache fragmentation and misses. The `skill.Def` struct in [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go) explicitly separates `Body` (runtime logic) from `Name` and `Description` (static metadata), enabling selective inclusion.

### How does deterministic ordering prevent cache inconsistencies?

Without explicit sorting, iteration order over maps or registration sequences could vary between runs due to concurrency or initialization timing. The sorting step in `WriteIndex` ensures that `{skillA, skillB}` and `{skillB, skillA}` registerings both serialize identically, collapsing equivalence classes to single cache entries.

### Can the serialization format affect cache stability?

Yes. Reasonix uses a **rigid format** (`name: description\n`) with explicit UTF-8 encoding to prevent common instability sources: variable whitespace, platform-specific newlines, or encoding mismatches. Alternative approaches like JSON with default marshaling risk key ordering differences or pretty-printing variations.