Icod.Terminal 1.14.0
Icod.Terminal 1.14.0
Icod.Terminal 1.14.0 is the persistent-raster lifecycle-observability release for the stable 1.x line.
It builds directly on 1.13 relative placement ownership. The release does not add a terminal-side object database or passive remote existence probe. Instead, it exposes the lifecycle certainty that Icod.Terminal already owns locally through one immutable, backend-neutral snapshot on each persistent resource and placement handle.
Public API additions
Version 1.14 adds:
public enum TerminalRasterOwnershipStatus {
Current,
Stale,
Released,
Disposed
}
public enum TerminalRasterOwnershipLossReason {
None,
SessionStateLost,
ResourceMissing,
ParentPlacementLost,
AncestorReleased,
ResourceReleased,
ExplicitDisposal
}
public readonly record struct TerminalRasterOwnershipState(
TerminalRasterOwnershipStatus Status,
TerminalRasterOwnershipLossReason LossReason
);and one synchronous read-only property on both opaque persistent handle types:
public TerminalRasterOwnershipState OwnershipState { get; }No other public API is required for the release.
What the states mean
Current means the handle remains current under Icod.Terminal's local ownership model. It is not authentication and is not proof that terminal-resident storage or placement still exists at the instant of observation.
Stale means terminal-resident certainty was lost. The semantic reason distinguishes:
SessionStateLost— explicit/session lifecycle generation invalidation;ResourceMissing— correlated evidence that the resource identity is missing;ParentPlacementLost— correlated evidence that the parent-placement relationship is missing.
Released is placement-specific local lifetime loss caused by another owner:
AncestorReleased— an ancestor placement lifetime ended;ResourceReleased— the placement's owning raster resource ended its direct placement lifetime.
Disposed / ExplicitDisposal means the caller explicitly disposed that public wrapper.
Status and reason are returned in one immutable snapshot. The internal lifecycle state is monotonic; stale or released ownership is not resurrected by late acknowledgement or later observation.
Side-effect-free observation
Reading OwnershipState is synchronous and bounded. It does not:
- emit terminal traffic;
- register or allocate a query;
- acquire the output gate;
- verify a capability;
- trigger cleanup;
- mutate registry ownership;
- replay/re-upload raster content;
- select or expose a graphics backend.
The release deliberately does not add ExistsAsync(), VerifyExistsAsync(), or another API that would imply a truthful passive terminal-side object-existence query where the reviewed backend provides none.
Two-axis resource and placement lifetime
Version 1.13 separated raster-resource ownership from relative parent-placement lifetime. Version 1.14 makes that separation directly observable.
The canonical example is:
Resource A Current / None
Placement A1 Current / None
Resource B Current / None
Placement B1 Current / None, relative to A1
Dispose A1
Placement A1 Disposed / ExplicitDisposal
Placement B1 Released / AncestorReleased
Resource B Current / None
Resource B remains usable for another ordinary placement if no independent evidence invalidated or disposed it.
Existing protocol-loss semantics become observable
The release reuses the existing narrow persistent-raster response classification instead of adding a parallel classifier.
A correlated ENOPARENT publishes Stale / ParentPlacementLost for the affected placement subtree while leaving raster-resource ownership current unless separately invalidated.
A correlated missing-resource ENOENT publishes Stale / ResourceMissing for the affected resource and dependent placements while preserving unrelated resources/placements.
ECYCLE, ETOODEEP, malformed replies, wrong identities, timeout, late responses, and transport failure do not manufacture lifecycle loss merely because an operation failed.
Correlation remains transaction ownership, not terminal authentication.
Internal lifecycle model
Resources and placements carry one packed atomic lifecycle value. Observation uses local atomic reads; lifecycle publication uses compare/exchange transitions.
This provides:
- one indivisible status/reason pair;
- first-transition monotonicity;
- no stale/released-to-current resurrection;
- safe concurrent readers while session/resource/placement ownership changes;
- no new lock or output-gate dependency for observation.
Public wrapper disposal remains separate from the underlying shared ownership state. This allows a descendant wrapper to remain observable as Released until its caller explicitly disposes that wrapper, at which point the wrapper reports Disposed / ExplicitDisposal.
Sample
Icod.Terminal.PersistentRaster.Sample now demonstrates the complete 1.11–1.14 persistent stack:
- verify
PersistentRasterGraphics; - create Resource A and an ordinary placement;
- create independently owned Resource B;
- create a Resource B placement relative to Resource A's placement;
- observe current ownership without extra terminal traffic;
- update common placement geometry and relative offsets;
- dispose the parent placement;
- observe parent
Disposed, childReleased, and Resource B stillCurrent; - explicitly dispose the released child wrapper;
- create a fresh ordinary placement from Resource B.
The sample remains backend-neutral and exposes no protocol-private image, placement, parent, or generation identity.
Package and public API qualification
The persistent-raster package verifier now requires generated XML documentation for the complete lifecycle-observation surface and compiles/runs a fresh NuGet-only consumer on:
net8.0
net9.0
net10.0
The deterministic public API snapshot is identical across all three target frameworks. The final 1.14 fingerprint is:
2a23205217183a602f8fc454c49b47d278ebdc26b5e358c0384ed0d692405696
The machine fingerprint is stored in docs/Public-API-Baseline-1.14.sha256 and the human-readable contract in docs/Public-API-Baseline-1.14.md. Historical fingerprints remain unchanged.
Downstream compatibility
The stable 1.x package-contract shard continues to exercise current Icod.DCurses acceptance/hardening. Version 1.14 does not require DCurses source adoption in order to consume the package successfully.
Higher-level consumers may adopt OwnershipState when useful, while existing consumers that never read it retain the existing 1.13 behavior.
Production dependencies
The direct production package graph is:
Icod.TermInfo 1.13.0
Icod.Timing 1.0.0
Icod.TermInfo.Inspection 1.12.0 remains test/sample-only where used and is not added to the production package graph.
Compatibility
The stable 1.0.0 compatibility floor remains unchanged.
Existing behavior remains intact for consumers that do not read OwnershipState, including:
- acknowledged persistent resource creation;
- ordinary current-cursor placement;
- source rectangles and signed z-order;
- immutable relative parentage and signed cell offsets;
UpdateAsync(...)/UpdateRelativeAsync(...)semantics;- depth-8 portable relative graph limit;
- 256-resource / 4096-placement local capacity ceilings;
- generation-scoped certainty;
- descendant-before-parent cleanup;
- one authoritative query/input path;
- no automatic raster replay.
See docs/Compatibility-and-Versioning.md for the stable-versioning and compatibility policy.
Explicit non-goals
Version 1.14 does not add:
- passive remote
ExistsAsync()/VerifyExistsAsync()semantics; - terminal-authenticated object existence;
- mutating reconciliation probes presented as inspection;
- automatic replay/re-upload/rebind;
- hidden source-image caching;
- public generation numbers;
- public image/placement/parent protocol identities;
- backend selection or raw Kitty dispatch;
- reparenting;
- Unicode placeholder / virtual placements;
- animation/frame lifecycle;
- absolute screen-coordinate placement;
- pixel-within-cell positioning;
- image decoding/transcoding;
- PTY/ConPTY hosting;
- cell/window/layout/damage/scene ownership.
Release qualification
The stable release candidate must pass the complete nine-job PR matrix on its exact final head:
Runtime Windows
Runtime Linux
Runtime macOS
Package candidate / public API freeze
Package Foundation
Package Presentation
Package Semantic and hardening
Package Stable 1.x release line
Validated package artifact
This release-note file deliberately does not self-certify the commit that contains final release closure. Exact-head qualification is recorded on PR #58 after CI completes. Merge, tag, and publication remain maintainer actions.
For the permanent ownership contract, see docs/Persistent-Raster-Ownership.md. For tranche history and design constraints, see Icod.Terminal-1.14.0-Development-Roadmap.md and the 1.14 design/implementation-plan documents under docs/superpowers/.