When one package prepares data and another package needs it, the consumer should read a data name. It should not import the producer package, parse its files, or guess the storage address.
A project-preview package prepares a list of preview URLs and statuses. A web-frame package wants to render the active URL. The web-frame should not import project-preview storage code. It should read the view it was given.The producer can change how records are prepared. The consumer should keep reading the same public input shape.Traditional app shape
import { getPreviewRecords } from '../project-preview/store';
export function WebFrame() {
const preview = getPreviewRecords().find(item => item.active);
return renderUrl(preview.url);
}
This ties the web frame to the project-preview package. The consumer now depends on the producer’s module path, function name, record shape, and selection logic.Bitfield shape
producer package prepares records
Runtime Kit exposes a data name
consumer package reads that input
consumer decodes only the public view it asked for
The consumer can read source-by-label, source-by-address, selected-file, current-project, or any other input that the package file exposes. It does not read producer private code.Code translation
Traditional path
import { previewStore } from '../project-preview/store';
const active = previewStore.getActivePreview();
Bitfield path
const active = readInput('project-preview-surface');
React adapter example
import { useBitfieldData } from '@bitfield/runtime-kit/react';
type PreviewSurface = {
projectId: string;
name?: string;
url?: string;
isConnected?: boolean;
status?: string;
};
export function PreviewPanel() {
const preview = useBitfieldData<PreviewSurface>('project-preview-surface');
if (preview.loading) return <p>Loading preview</p>;
if (preview.error) return <p>Could not load preview.</p>;
if (!preview.data?.url) return <p>No preview URL yet.</p>;
return <iframe title={preview.data.name ?? 'Project preview'} src={preview.data.url} />;
}
Descriptor-projected records
Some consumers need a different view of the same source. That should be data, not a new import path.source-by-label:
params.source_address_label = project-preview-surface
field map says which public field is the URL
This lets the consumer read a projected view. It does not make the consumer depend on the producer’s private data layout.Four prepared-read situations
Preview surface
Private preview helper
import { getPreviewUrl } from '../project-preview/build-preview';
const url = await getPreviewUrl(projectId);
Read the prepared preview
const preview = readInput('project-preview-surface');
The preview package prepares the public view. The consumer renders the view without importing the preview package’s builder code.Selected file content
Private file reader
import { readSelectedFileText } from '../file-editor/files';
const text = await readSelectedFileText();
Read the file-facing public values
const selectedFile = readInput('selected-file');
const fileContent = readInput('selected-file-content');
The selected file fact and the prepared content are separate public reads. The consumer does not become the file package.Help content
Private help file
const markdown = await fetch('/packages/help/content/getting-started.md').then((r) => r.text());
Read the prepared help
const help = readInput('getting-started-help');
The package can change how it ships or prepares the help content while the consumer keeps the same public read.Worktree records
Private record cache
import { records } from '../git-worktree/private-record-cache';
const current = records.filter((record) => record.projectId === projectId);
Read the prepared records
const worktrees = readInput('git-worktree-records');
The consumer asks for the public prepared records it needs. It does not import the producer’s cache or storage shape.Consumer boundary checklist
| Question | Correct answer |
|---|
| Does the consumer import the package that prepared the data? | No. It reads a data name. |
| Does the consumer parse another package’s boundary file? | No. Runtime Kit resolves package material. |
| Does the consumer build storage addresses by string operations? | No. It uses public input names or descriptors. |
| Does the consumer assume producer field names are permanent? | No. Descriptor data maps the public view. |
| Does the consumer work outside React? | Yes. Any shell can follow the same input boundary. |
Full before and after
Traditional feature request
“Show the preview URL beside the current file and include help text if the user opens the command palette.”Bad implementation
import { fileTreeStore } from '../file-tree/store';
import { getPreviewUrl } from '../project-preview/private-preview';
import helpMarkdown from '../help/content/getting-started.md?raw';
export async function buildPanel() {
return {
file: fileTreeStore.selectedFile,
previewUrl: await getPreviewUrl(fileTreeStore.projectId),
help: helpMarkdown,
};
}
This code makes one consumer depend on three private details: file tree state shape, preview implementation, and help package folder layout.Public read version
const selectedFile = readInput('selected-file');
const preview = readInput('project-preview-surface');
const help = readInput('getting-started-help');
The consumer reads three public names. Each preparing package can change its private code without forcing this panel to change.The same translation works for a native app, terminal view, or future shell. The adapter changes. The public inputs do not.What this prevents
| Bad shape | Why it breaks | Better shape |
|---|
| Consumer imports producer package. | Moving the producer breaks the consumer. | Consumer reads a data name. |
Consumer parses things-to-store-and-run.json. | UI code becomes package-loader code. | Runtime Kit resolves the package file. |
| Consumer builds storage addresses by string concatenation. | Address rules leak into app code. | Consumer uses a named input. |
| Consumer assumes producer field names forever. | Producer cannot change its private shape safely. | Descriptor data maps the public view. |
React is one adapter for reading a data name. A Swift, Kotlin, terminal, or future shell should follow the same boundary: read the named input, not the package that prepared it.Review check
If consumer code says import ... from '../other-package', ask why. A consumer package should receive a data name or an action name. It should not inspect another package’s source files.Next