# Consumer contract
`K1WebCoding` is the synchronous, exclusively caller-owned boundary for one user's disposable Web cache, private candidate, projection view, and fresh Podman checks. Independent instances share no coding-layer lock. Stateful operations require `&mut self`; authorization and optional source-preservation effects are supplied per operation and are never retained.
```rust
pub struct WebCodingRevisions { pub boot: String, pub schema: String, pub route: String, pub harness: String, pub check_policy: String }
pub struct WebCodingConfig;
impl WebCodingConfig { pub fn new(revisions: WebCodingRevisions, projection_root: PathBuf, podman: WebPodmanConfig) -> Result<Self, WebCodingError>; }
pub struct CheckExecution { pub diagnostics: CommandDiagnostics, pub report: Report }
pub enum CheckOutcome { Reused, Checked(Box<CheckExecution>) }
pub struct PublishResult { pub source: Arc<SourcePackage>, pub check: CheckOutcome, pub outcome: PublishOutcome }
pub enum WebCodingError {
State(String), Cache(String), Authorization(String), WorkspaceDenied, CandidateUnavailable,
DependencyUnavailable, Podman(Box<WebPodmanError>), CheckFailed(Box<CheckExecution>),
SourcePreservation(String), PublicReleaseDenied, Projection(String), ProjectionAfterSubmit { submitted: String, message: String },
}
pub struct K1WebCoding;
impl K1WebCoding {
pub fn open(cache_root: impl AsRef<Path>, user: TxId, config: WebCodingConfig, projection: Arc<K1WebProjection>) -> Result<Self, WebCodingError>;
pub fn cache_epoch(&self) -> u64;
pub fn view(&self, id: &WebId, authorize_workspace: &dyn Fn(&WebFamily) -> Result<bool, String>) -> Result<Option<Arc<SourcePackage>>, WebCodingError>;
pub fn write(&mut self, candidate: &SourcePackage, authorize_workspace: &dyn Fn(&WebFamily) -> Result<bool, String>) -> Result<Arc<SourcePackage>, WebCodingError>;
pub fn check(&mut self, id: &WebId, authorize_workspace: &dyn Fn(&WebFamily) -> Result<bool, String>) -> Result<CheckOutcome, WebCodingError>;
pub fn check_fresh(&mut self, id: &WebId, authorize_workspace: &dyn Fn(&WebFamily) -> Result<bool, String>) -> Result<CheckOutcome, WebCodingError>;
pub fn publish(&mut self, id: &WebId, authorize_workspace: &dyn Fn(&WebFamily) -> Result<bool, String>, authorize_public_release: &dyn Fn(&SourcePackage, Digest) -> Result<bool, String>) -> Result<PublishResult, WebCodingError>;
pub fn publish_with_source_preservation(&mut self, id: &WebId, authorize_workspace: &dyn Fn(&WebFamily) -> Result<bool, String>, preserve_source: &dyn Fn(&SourcePackage, Digest) -> Result<(), String>, authorize_public_release: &dyn Fn(&SourcePackage, Digest) -> Result<bool, String>) -> Result<PublishResult, WebCodingError>;
pub fn reset(&mut self) -> Result<(), WebCodingError>;
}
```
`CheckExecution`, `CheckOutcome`, `PublishResult`, and `WebCodingError` implement `Debug`; `WebCodingError` also implements `Display` and `std::error::Error`. Configuration requires nonempty cache and receipt-policy revisions, a canonical ordinary projection directory, and a valid `WebPodmanConfig`. `open` opens the exact per-user cache and Podman runner while retaining the supplied projection. Opens taking more than 100 milliseconds emit a secret-free warning. `reset` runs only between synchronous operations, when no container is retained, and wholly replaces the disposable cache.
`write` first applies its candidate-family workspace gate, atomically materializes all candidate files through the cache, reconstructs the retained complete candidate, and returns it. Identical writes preserve cache generation and receipts; changed identity or bytes invalidate them. `check`, `check_fresh`, and both publication methods first apply the requested identifier's workspace gate and use only its exact retained candidate; an absent or mismatched candidate is `CandidateUnavailable`. `view` returns an exact private candidate only after a successful workspace gate; a denied gate falls back to the exact public projection. With no exact private candidate it reads the exact public projection without workspace authorization or selector resolution. Authorization infrastructure errors are `Authorization`.
Every check captures one coherent projection snapshot and the selection leaf resolves each distinct recursive family-selector pair to the highest matching stable version. Every resolved route, including transitive routes, is paired with its exact selected package; the cache validates and materializes the complete closure under its resolution root. The canonical manifest digest binds selected versions, winners, and bytes without a projection cursor, supplies `CheckIdentity.graph`, and is routed to the checker as the frozen admitted view. Cycles are finite, multiple selectors for one family remain distinct, and absence is concealed as `DependencyUnavailable`. Pure checker runtime identity, receipt identity, and input construction are delegated to `kcode-k1-web-check-plan`.
An exact successful receipt lets `check` and either publication method return `Reused` without Podman. `check_fresh` bypasses receipt reuse, always starts one Podman check after admission, and records an ordinary receipt on success. Unrelated projection publication leaves the frozen manifest, resolution identity, and receipt unchanged; a changed selected version, winner, or byte invalidates them. A check requiring execution starts Podman once with the complete live public projection mounted separately read-only, returns complete execution data, and records only `Outcome::Success`; a completed failure is `CheckFailed`. `publish` checks the retained candidate and freshly authorizes immediately before one projection publication. `publish_with_source_preservation` delegates its source-preservation and release-authorization effect gate to `kcode-k1-web-release-gate`, which calls the source-preservation effect exactly once after the check and before fresh release authorization; preservation failure skips authorization and publication, while later failure may leave an orphan source. Either result retains the complete candidate with completed `Published`, `Idempotent`, or `Conflict` outcomes; an error carrying a submitted transaction exposes its canonical transaction ID text as `ProjectionAfterSubmit`. Installation and observation occur only through the projection.
Configuration validation, identity construction, and graph traversal are unbenchmarked and linear in supplied text, selected package bytes, or graph size as applicable; retained-candidate reconstruction is linear in cached file bytes, and cache epoch access is constant-time. `open` and `reset` are unbenchmarked local filesystem operations. `view` loads one exact package. `write` atomically stages supplied source. `check` adds one bounded local Podman execution on a miss, `check_fresh` always adds one after admission, and either publication method adds its supplied effects plus projection/Peering work whose completion time this library does not own.