@heddleagent/s3
v6.1.1
Published
Official Amazon S3 adapters for selected Heddle-owned durable storage ports
Maintainers
Readme
@heddleagent/s3
Official Amazon S3 implementations for selected public Heddle-owned durable storage ports. The package keeps each domain behind an intentionally narrow entrypoint:
| Entrypoint | Domain contract | Status |
| --- | --- | --- |
| @heddleagent/s3/memory | MemoryCheckpointStore from @heddleagent/runtime/advanced | Supported |
| @heddleagent/s3/working-set | WorkingSetCheckpointStore from @heddleagent/runtime/advanced | Supported |
There is no generic S3 filesystem or root storage provider. Configuration, approvals, MCP consent, telemetry, artifacts, conversations, active execution, and unbounded runtime-directory backup are outside this package.
Install
npm install @heddleagent/s3 @heddleagent/runtime @aws-sdk/client-s3The memory entrypoint supports the established Runtime 6.x contract. The
working-set entrypoint requires @heddleagent/[email protected] or newer. Package
6.1 is certified against both Runtime 7.1 and Runtime 8 and declares the
combined >=6.4.0 <10 peer range; it does not change stored object formats.
Memory checkpoints
import { S3Client } from '@aws-sdk/client-s3';
import {
MemoryCheckpointService,
deriveMemoryScopeId,
} from '@heddleagent/runtime/advanced';
import { S3MemoryCheckpointStore } from '@heddleagent/s3/memory';
const scopeId = deriveMemoryScopeId({
adopterId: authenticatedIdentity.adopterId,
tenantId: authenticatedIdentity.tenantId,
subjectId: authenticatedIdentity.subjectId,
owner: { kind: 'agent', id: configuredAgent.id },
});
const store = new S3MemoryCheckpointStore({
client: new S3Client({ region: process.env.AWS_REGION }),
bucket: process.env.HEDDLE_STATE_BUCKET!,
});
const checkpoints = new MemoryCheckpointService('/var/lib/heddle/memory', store);
await checkpoints.restore(scopeId); // before bootstrapping or reading memory
// Let the memory domain operate on its local working copy.
await checkpoints.checkpoint(scopeId); // after a stable memory-changing boundaryHeddle owns file selection, schemas, canonical JSON, checksums, restore safety, and compare-and-swap semantics. This package owns only S3 object keys and conditional requests. The caller still owns authenticated scope derivation, restore-before-use ordering, stable checkpoint triggers, AWS credentials, bucket configuration, encryption policy, lifecycle policy, and client shutdown.
Working-set checkpoints
import { S3Client } from '@aws-sdk/client-s3';
import {
WorkingSetCheckpointService,
deriveWorkingSetScopeId,
} from '@heddleagent/runtime/advanced';
import { S3WorkingSetCheckpointStore } from '@heddleagent/s3/working-set';
const scopeId = deriveWorkingSetScopeId({
adopterId: verifiedIdentity.adopterId,
tenantId: verifiedIdentity.tenantId,
subjectId: verifiedIdentity.subjectId,
productSessionId: verifiedIdentity.productSessionId,
});
const store = new S3WorkingSetCheckpointStore({
client: new S3Client({ region: process.env.AWS_REGION }),
bucket: process.env.HEDDLE_STATE_BUCKET!,
});
const checkpoints = new WorkingSetCheckpointService(
'/var/lib/heddle/working',
store,
{
limits: {
maxFileCount: 256,
maxFileBytes: 2 * 1024 * 1024,
maxTotalBytes: 32 * 1024 * 1024,
},
resetLocalWorkingCopy: async () => {
// The host must remove only its validated, disposable working root.
},
},
);
await checkpoints.prepareOrRecover(scopeId); // before constructing file tools
// Run one scope-bound agent invocation against the recovered working root.
await checkpoints.checkpoint(scopeId); // before publishing terminal successThe working-set domain is a bounded, integrity-checked portable directory. It is distinct from Heddle memory and from product data. The Heddle service owns path policy, symlink rejection, resource limits, canonical encoding, reset and restore ordering, checksums, and manifest semantics. The adapter never scans a filesystem and never decides which execution scope or successful boundary is eligible for a checkpoint.
Object and concurrency model
Objects use the same generation/manifest protocol in separate configurable
namespaces. Memory defaults to heddle/memory/v1; working sets default to
heddle/working-set/v1:
scopes/<opaque-memory-scope>/generations/<generation-id>.json
scopes/<opaque-memory-scope>/manifest.jsonThe adapter writes each generation with If-None-Match: *, then advances the
manifest with either If-None-Match: * or the prior ETag in If-Match.
Memory deletion uses the manifest ETag in If-Match. A stale writer receives
the domain's checkpoint conflict error; exact retries of an already committed
generation are idempotent. After an ambiguous write response, the working-set
adapter reads durable truth and accepts only the exact intended generation or
manifest. Divergent or corrupt content fails closed. Neither adapter issues a
bucket-listing call.
Memory delete() removes only the authoritative manifest. Immutable
generations may remain for recovery. A time-only S3 lifecycle rule cannot know
which generation the current manifest references, so it must not blindly
expire every current generation object in either namespace. Use
reference-aware garbage collection for unreferenced generations; bucket
lifecycle can safely cover noncurrent manifest versions, delete markers, and
abandoned multipart uploads.
IAM and operations
Grant the memory host these object actions on its configured prefix:
s3:GetObject;s3:PutObject; ands3:DeleteObject.
Working-set checkpoints require only s3:GetObject and s3:PutObject below
their separate prefix; the v1 store never deletes an authoritative manifest.
Also grant s3:ListBucket on the purpose-dedicated checkpoint bucket. Amazon
S3 returns 403 Access Denied for a missing GetObject key without that
permission, which is indistinguishable from a genuine authorization failure;
with it, first-use restore receives the expected 404 Not Found. The adapter
still does not enumerate checkpoint keys, and object access remains scoped to
the configured prefix.
Conditional writes use AWS Signature Version 4 through the normal SDK client. Use bucket-default encryption or an operator-owned SSE-KMS bucket policy; this adapter does not override bucket encryption, credentials, region, endpoint, retry strategy, or network policy.
Shutdown checkpointing may reduce recent loss but must not be the only trigger. Checkpoint after memory-changing user interactions and completed memory maintenance transactions reach a stable boundary.
