# gizfs:s3

Bounded S3 profile. HTTP parsing/framing, URI codecs, calendar and cryptography remain SDK owners. Mutation preparation never publishes catalog state: the caller commits its command to the shared volume journal first.

```gizlang
import * as S3 from "gizfs:s3";
```

## Types

### `Credential`

```gizlang
type Credential = { access: string; secret: bytes; tenant: string; uid: i64; gid: i64; nativeKey: bytes; }
```

An S3 access key: its id, secret, tenant, the file owner that it writes as, and its key for native requests.

- `access`: `string`
- `secret`: `bytes`
- `tenant`: `string`
- `uid`: `i64`
- `gid`: `i64`
- `nativeKey`: `bytes`

### `Prepared`

```gizlang
type Prepared = { requestId: string; command: bytes; response: Http.Response; }
```

A prepared S3 request: its id, the encoded command to commit, and the response after the commit.

- `requestId`: `string`
- `command`: `bytes`
- `response`: `gizlang_http.Response`

### `Auth`

```gizlang
type Auth = { credential: Credential; requestId: string; body: bytes; }
```

An authenticated request: its credential, request id and body.

- `credential`: `M45.Credential`
- `requestId`: `string`
- `body`: `bytes`

### `HeadAuth`

```gizlang
type HeadAuth
```

An authenticated request head whose body is still to come (Payload checks it as it arrives).

- `credential`: `M45.Credential`

### `CapabilityRead`

```gizlang
type CapabilityRead = { token: string; request: Http.Request; }
```

A capability read: the token, and the request without the token.

- `token`: `string`
- `request`: `gizlang_http.Request`

### `Payload`

```gizlang
type Payload
```

One bounded decoder/checksum state. feed accepts at most a 16 KiB HTTP
piece and returns at most that many decoded bytes. AWS chunk signatures
are checked incrementally; staging bytes is safe, publishing before finish
is forbidden. Neither AWS chunk size nor total object size buffers data.

Opaque: create and use it through this module's functions.

### `Deletion`

```gizlang
type Deletion = { quiet: bool; keys: Vec<string>; }
```

A DeleteObjects body: its keys in order (at most 1000), and Quiet, which asks for the failures only. Version IDs and
the other children of an Object are not read.

- `quiet`: `bool`
- `keys`: `Vec<string>`

### `ReadPlan`

```gizlang
type ReadPlan = { response: Http.Response; start: i64; end: i64; }
```

A read response and the byte range of the object that its body holds.

- `response`: `gizlang_http.Response`
- `start`: `i64`
- `end`: `i64`

### `Target`

```gizlang
type Target = { bucket: string; key: string; version: i64; uploadId: string; read: bool; upload: bool; }
```

What an S3 request names: bucket, key, version and upload, and whether it reads or uploads.

- `bucket`: `string`
- `key`: `string`
- `version`: `i64`
- `uploadId`: `string`
- `read`: `bool`
- `upload`: `bool`

### `PartCopy`

```gizlang
type PartCopy = { prepared: Prepared; source: Object.Entry; start: i64; end: i64; maxChunks: i64; }
```

One captured source version, retained by the caller until publication.
ByteRange owns the same grammar used by ordinary copies and reads.

- `prepared`: `M45.Prepared`
- `source`: `M42.Entry`
- `start`: `i64`
- `end`: `i64`
- `maxChunks`: `i64`

## Functions

### `capabilityRead`

```gizlang
function capabilityRead(request: Http.Request): Result<Option<CapabilityRead>, string>
```

The capability read of a request, or none when the request has no token.
A token excludes every other authentication and a request body.

Effects: fail.

### `admitRead`

```gizlang
function admitRead(key: bytes, tenant: string, token: string, bucket: string, objectKey: string, now: i64): Result<Security.Capability, string>
```

Admit a capability read of KEY in BUCKET: the token is valid under the
Policy key, names the Space of this tenant, grants viewer or more, and
targets the `bucket`, a `prefix` that ends in "/" (key BUCKET/PREFIX), or the
`object` (key BUCKET/KEY). Grants only add, so a grant on an ancestor covers the object.

Effects: fail.

### `canonical`

```gizlang
function canonical(request: Http.Request, signedHeaders: string): Result<string, string>
```

The SigV4 canonical request of REQUEST with SIGNEDHEADERS.

Effects: fail.

### `canonicalHead`

```gizlang
function canonicalHead(request: Http.Request, signedHeaders: string): Result<string, string>
```

Canonicalize an admitted head while its signed payload digest is verified
incrementally by Payload. This function does not authenticate a request.

Effects: fail.

### `authenticate`

```gizlang
function authenticate(request: Http.Request, credentials: Vec<Credential>, region: string, nowMs: i64): Result<Credential, string>
```

Header and query SigV4 plus AWS's signed chunk chain. Unsigned query
payloads are restricted to reads; STS and trailers remain unsupported.

Effects: fail.

### `authorize`

```gizlang
function authorize(request: Http.Request, credentials: Vec<Credential>, region: string, nowMs: i64): Result<Auth, string>
```

The credential, request id and body of REQUEST when its SigV4 signature is valid in REGION at NOWMS. It fails with
the S3 error code.

Effects: fail.

### `authorizeTrusted`

```gizlang
function authorizeTrusted(request: Http.Request, credentials: Vec<Credential>, region: string, nowMs: i64, secure: bool): Result<Auth, string>
```

secure is supplied only by the gateway's actual TLS serving path. Request
headers and forwarded-proto values can never establish this trust.

Effects: fail.

### `presign`

```gizlang
function presign(endpoint: string, access: string, secret: bytes, region: string, bucket: string, key: string, seconds: i64, nowMs: i64): Result<string, string>
```

A presigned GET URL for one object: SigV4 query authentication that authorizeHead
accepts for `seconds` (1 s to 7 days) from nowMs. `endpoint` is the scheme and
authority of the gateway, such as `https://s3.example.com:8443`.

Effects: fail.

### `authorizeHead`

```gizlang
function authorizeHead(request: Http.Request, credentials: Vec<Credential>, region: string, nowMs: i64, secure: bool): Result<HeadAuth, string>
```

As authorize, from the head alone; SECURE says that the request came over TLS (only then may an unsigned payload
come).

Effects: fail.

### `payload`

```gizlang
function payload(head: HeadAuth, request: Http.Request, limit: i64): Result<Payload, string>
```

A checker of the body of the request of HEAD, at most LIMIT bytes (aws-chunked or whole).

Effects: fail.

### `xml`

```gizlang
function xml(status: i64, body: bytes): Http.Response
```

An S3 XML answer.

Effects: fail.

### `errorResponse`

```gizlang
function errorResponse(status: i64, code: string): Http.Response
```

An S3 XML error response with STATUS and CODE.

Effects: fail.

### `protocolError`

```gizlang
function protocolError(code: string): Http.Response
```

The S3 error response of CODE, with its status.

Effects: fail.

### `commandResponse`

```gizlang
function commandResponse(request: Http.Request, result: Object.Outcome): Http.Response
```

Deterministic XML success bodies also reproduce correctly from the sole
volume idempotency ledger after a lost commit reply.

Effects: fail.

### `completion`

```gizlang
function completion(data: bytes): Result<Vec<Object.PartTag>, string>
```

The parts that a CompleteMultipartUpload body names, in its order.

Effects: fail.

### `deletion`

```gizlang
function deletion(data: bytes): Result<Deletion, string>
```

The keys of a DeleteObjects request body, and whether it asks for a quiet answer.

Effects: fail.

### `query`

```gizlang
function query(request: Http.Request, tokenKey: bytes): Result<Option<Object.Query>, string>
```

Native and remote callers share one paged route and token grammar.

Effects: fail.

### `pageResponse`

```gizlang
function pageResponse(request: Http.Request, page: Object.Page, tokenKey: bytes): Http.Response
```

Formatting receives lean pages, with no independent sort/filter path.

Effects: fail.

### `prepare`

```gizlang
function prepare(state: Object.State, request: Http.Request, credentials: Vec<Credential>, region: string, nowMs: i64, upload: (tenant: string, data: bytes, generation: i64) => Result<Vec<Store.Receipt>, string>, fetch: (blob: Store.Identity) => Result<bytes, string>): Result<Prepared, string>
```

Native callers own an authority read barrier and must retain immutable
roots across I/O and publication; these functions acquire no lease. upload
durably fans out bounded chunks; committed apply verifies every receipt.

Effects: fail, read, write, console, io.

### `prepareTrusted`

```gizlang
function prepareTrusted(state: Object.State, request: Http.Request, credentials: Vec<Credential>, region: string, nowMs: i64, upload: (tenant: string, data: bytes, generation: i64) => Result<Vec<Store.Receipt>, string>, fetch: (blob: Store.Identity) => Result<bytes, string>, secure: bool): Result<Prepared, string>
```

prepare, where SECURE says that the request came over TLS.

Effects: fail, read, write, console, io.

### `prepareAuthorized`

```gizlang
function prepareAuthorized(state: Object.State, request: Http.Request, a: Auth, nowMs: i64, upload: (tenant: string, data: bytes, generation: i64) => Result<Vec<Store.Receipt>, string>, fetch: (blob: Store.Identity) => Result<bytes, string>, headOnly: bool, captured: Option<Object.Version>): Result<Prepared, string>
```

A trusted adapter calls this only after authentication of the original
request and complete payload verification. request contains decoded payload
bytes and the selected semantic path; a.requestId retains the original
signed host/path identity. This operation does not establish authentication.

Effects: fail, read, write, console, io.

### `readPlan`

```gizlang
function readPlan(request: Http.Request, version: Object.Version, nowMs: i64): Result<ReadPlan, string>
```

Version was captured and pinned by the sole Volume authority. Header and
condition evaluation never reacquires a newer mutable head during a read.

Effects: fail.

### `addressRequest`

```gizlang
function addressRequest(request: Http.Request, endpointHost: string): Result<Http.Request, string>
```

Select a semantic path AFTER authenticating the original request. An empty
endpointHost keeps path-style routing. Otherwise the exact configured Host
authority (including any port) admits path style, and only a valid bucket
prefix followed by '.' and that authority admits virtual-host style.
No forwarded header, DNS lookup, suffix guess, URI decoding or dot/empty
segment normalization changes this selection. SigV4 always uses the original
request; the returned request must never be reauthenticated as that request.

Effects: fail.

### `viewActions`

```gizlang
function viewActions(request: Http.Request): Result<i64, string>
```

Route classification uses the same canonical operation query owner. The
Volume derives committed mutation intents independently before publication.

Effects: fail.

### `completes`

```gizlang
function completes(request: Http.Request): bool
```

Whether REQUEST completes a multipart upload (POST with uploadId).

Effects: fail.

### `target`

```gizlang
function target(request: Http.Request): Result<Target, string>
```

The S3 owner alone classifies routes. Version zero means the current head.

Effects: fail.

### `copyTarget`

```gizlang
function copyTarget(request: Http.Request): Result<Option<Target>, string>
```

The source of an x-amz-copy-source request, or none when the request has none. It fails when the header is not
valid.

Effects: fail.

### `prepareVerified`

```gizlang
function prepareVerified(state: Object.State, request: Http.Request, head: HeadAuth, digest: bytes, now: i64, upload: (tenant: string, data: bytes, generation: i64) => Result<Vec<Store.Receipt>, string>, fetch: (blob: Store.Identity) => Result<bytes, string>, headOnly: bool): Result<Prepared, string>
```

Reuse the complete route/condition/metadata owner without materializing GET
bytes. The caller already verified the authenticated payload to its digest.

Effects: fail, read, write, console, io.

### `finishUpload`

```gizlang
function finishUpload(plan: Prepared, id: string, chunks: Vec<Store.Chunk>, size: i64, digest: bytes, maxChunks: i64): Result<Prepared, string>
```

Replace only the immutable manifest of a successfully admitted empty-body
PUT/UploadPart plan. Protection, conditions and route semantics stay owned
by prepareAuthorized, and no metadata is published by this operation.

Effects: fail, read, write, console, io.

### `partCopyTarget`

```gizlang
function partCopyTarget(request: Http.Request): Result<Option<Target>, string>
```

The source of an UploadPartCopy request, or none when the request is not one. It fails when it is not valid.

Effects: fail.

### `preparePartCopy`

```gizlang
function preparePartCopy(state: Object.State, request: Http.Request, a: Auth, source: Object.Version, now: i64): Result<PartCopy, string>
```

The source was authorized and pinned by Volume. All route, upload,
protection, metadata and copy-condition checks use the canonical owner.

Effects: fail, read, write, console, io.

### `transferPart`

```gizlang
function transferPart(plan: PartCopy, generation: i64, upload: (tenant: string, data: bytes, generation: i64) => Result<Vec<Store.Receipt>, string>, fetch: (blob: Store.Identity) => Result<bytes, string>, active: () => bool): Result<Prepared, string>
```

Drain only verified immutable pieces, preserving bounded byte residence.
Admission counts the canonical command contribution before extending its
manifest. Cancellation, fetch and staging failures never return a command.
Whole-source copies also verify the captured aggregate digest; a range's
new aggregate digest is computed from every selected, verified byte.

Effects: fail, read, write, console, io.

## Methods

### `HeadAuth.requestId`

```gizlang
function HeadAuth.requestId(self: HeadAuth, digest: bytes): string
```

The request id of the request with the body digest DIGEST.

Effects: fail.

### `Payload.feed`

```gizlang
function Payload.feed(self: mut Payload, data: bytes): Result<bytes, string>
```

The body bytes of DATA, after the chunk signatures are checked.

Effects: fail.

### `Payload.finish`

```gizlang
function Payload.finish(self: mut Payload): Result<bytes, string>
```

The rest of the body. It fails when the body is shorter than it said or a signature does not match.

Effects: fail.

## Constants

### `CAPABILITY_PARAMETER`

```gizlang
const CAPABILITY_PARAMETER = "X-Giz-Capability"
```

The query parameter that carries a Security.capability token in place of
SigV4, for one GET or HEAD of an object (GIZSTACK-PLATFORM §4.1).

