Record live staging HMR and Boat reconnect retention evidence

This commit is contained in:
Dotta committed 2026-10-10 21:26:30 -05:00
1 parent 29e2aa95d1
commit ea1272d4d8
5 files changed
+115 -15

No files matched your search

+18 -7
View File
@@ -24,7 +24,7 @@ Historical product observations in this table are UTC on 2026-10-10; the retry t
| Legacy CLI UI guard | Staging 2df40da: existing Boat Codex and Claude runtime pages each showed only the corresponding CLI engine, selected. | Read-only UI inspection; no configuration saved and no probe invoked. |
| Native Claude cold → warm → idle → resume | Local 26/8f11a70b: cold 3m46, warm 1m39 with the same runnerPID33242. Checkpoints suspended, PID disappeared, owner retired, and archive completed before ordinary follow-up resumed the same durable session with a replacement runner/new boot and unchanged hashes. Staging 73b2 also passed cold 8m56, warm 1m50, physical idle disappearance, and ordinary post-idle return 6m21 with unchanged proof. | Claude provider subprocesses restart between warm turns; stable runner/session is the claim. Staging did not export the full suspended-checkpoint/ledger timeline. Earlier preparation ownership is not treated as runner identity. |
| Native Codex post-idle and computer use | Local 25/c9c0a47b: second-idle continuation succeeded after exact retirement/archive, with launch/focus/keyboard/window tool receipts. Staging 73b2: Cua and visible desktop passed. | The subsequent 1830 retry failed before a new runner launched; see the retry table. |
| Vite, browser preview, and warm HMR | Local 23/85746677, UI 76a499cc: detached Vite retained runner/provider/server identity across warm turns; a heading hot-reloaded while an unsaved draft and page-session value stayed unchanged. Natural idle later removed the owned processes/listener. Staging 73b2 launched Vite and generated a preview link. | Earlier staging preview navigation returned `ERR_BLOCKED_BY_CLIENT`; no workaround was used. On deployment 13 the normal generated link rendered, and warm runner/provider/Vite identity was preserved. **Staging HMR remains unverified:** the reported edit had not appeared in the browser at this cutoff. |
| Vite, browser preview, and warm HMR | Local 23/85746677, UI 76a499cc: detached Vite retained runner/provider/server identity across warm turns; a heading hot-reloaded while an unsaved draft and page-session value stayed unchanged. Natural idle later removed the owned processes/listener. Staging 73b2 launched Vite and generated a preview link. | Earlier staging preview navigation returned `ERR_BLOCKED_BY_CLIENT`; no workaround was used. On deployment 13 the normal generated link rendered, and warm runner/provider/Vite identity was preserved. Deployment 14 subsequently passed state-preserving HMR; see the dated follow-up below. |
| Desktop viewing and human control | Local 31/19d827a1 and staging73b2: normal embedded viewer keyboard events opened a terminal and entered a command with visible expected output. Native Cua, desktop rendering, and bounded viewer expiry passed. | Deployment 13 direct browser desktop mouse and keyboard subsequently passed; current embedded input remains unverified because automation targeted the outer page. IBus separation was sampled outside the runner cgroup; that sample alone is not an additional expiry test. |
| Durable file editor | Local 30/ac09d6ec: normal Instructions save survived full browser reload, then original content was restored and reread. Local 28/3081b748 onboarding initialized readable remote instructions. | Earlier source-specific pass; the later save/read retry is inconclusive because the fresh read returned 502 provider_error. |
| Shared Boat and separate personal folders | Distinct durable roots, concurrent listener ports, and file persistence across later resumes were observed for native and legacy agents. | One-agent cancellation while a sibling continues remains explicitly unverified. Shared Unix UID and desktop provide no per-agent OS security boundary. |
@@ -46,7 +46,7 @@ These outcomes do not erase earlier source-specific passes. The [retry receipt](
| Staging 610 retirement / persistent proof | Exact owner `f298be2e` retirement marker dates to 01:19:05.647, generation 3. At 01:28:20–01:28:58, no owned processes or listeners remained and the original proof hash was intact. The saved `2ac97bd2` checkpoint remained ready with empty outbox/no pending terminal and authoritative inactive provider turn; that does not override the controller cancellation. Boat was healthy and hydrated at 01:27:43 with no newer provider stop. This is post-cancellation cleanup evidence, not a natural idle-resume pass. |
| Staging 610 native Claude | `a38070b3` failed `setup_failed` after 12m42 (01:18:44→01:31:25). The expanded log identifies a durable ACPX launch-profile digest mismatch after approximately 990MiB provider-pack upload. A later lease-acquisition attempt reported “Computer is connecting or settling a previous stop”; a lease-deadline cause is not proved. Recovery remained bootstrap with provider work not started. Stage sync took 473,763ms; transport connected at 01:27:47. An independent 01:29:48 checkpoint read found suspended state, empty outbox and pending terminal delivery. The reviewed correction on 21deac0abf reuses the package pinned by bound controller state. It passed 33 focused tests and server TypeScript; deployment 14 is pending, with no live recovery pass yet. Earlier Claude passes remain source-specific. |
| Staging 610 provider observation before desktop retry | Read-only provider status at 01:33:52 showed archived and healthy, with stop completed at 01:32:48.421 and no error. No manual stop/wake or post-archive guest read was performed at that point. Normal Computer Connect later resumed the fixture around 01:35; this receipt does not describe its later state. |
| Staging 610 desktop comparison | Normal task Computer Connect from archived state around 01:35 reached the stream around 01:38. The same provider viewer opened directly in a browser tab accepted a native mouse click that opened Chrome and keyboard events that visibly entered `boatlive0141` around 01:41: **direct browser desktop mouse and keyboard passed**. Opening a second stream froze the original embedded frame; after close/reconnect it showed the updated desktop. Embedded Ctrl+A selected the outer Paperclip page, an automation-targeting limitation rather than a validated product input failure. Both viewers closed normally around 01:43; archive after this close is not yet verified. |
| Staging 610 desktop comparison | Normal task Computer Connect from archived state around 01:35 reached the stream around 01:38. The same provider viewer opened directly in a browser tab accepted a native mouse click that opened Chrome and keyboard events that visibly entered `boatlive0141`: **direct browser desktop mouse and keyboard passed**. Opening a second stream froze the original embedded frame; after close/reconnect it showed the updated desktop. Embedded Ctrl+A selected the outer Paperclip page, an automation-targeting limitation rather than a validated product input failure. Both viewers closed normally; exact close time was not captured. A 01:47:06 provider read confirmed archived state, snapshots retained and stop completed at 01:42:11.287. This does not establish exact close-to-archive causality; text marker digits are not timestamps. |
| Staging 610 sibling Stop | Normal Stop around 01:14:44 cancelled an active automatic continuation; UI showed Stopped and the task was blocked. Independent inspection before Stop found no foreground sleeper, so live child-process cancellation and sibling isolation remain unverified. |
| Staging 1830 native Claude / sibling test | Run `3a34` failed during setup before the planned idle/sibling experiment. No sibling isolation pass or root cause is claimed. The fixture later naturally archived. |
| Staging 1830 desktop / close | Stream visible at 00:43 and 00:50 on 2026-10-11. Input attempts produced no observable result, and one timed out before sending input: controls remain unverified on this retry. Normal Close Computer preceded natural archive; stop completed 00:50:43.150 and archived/snapshots-preserved state was observed 00:51:49. No manual provider stop. |
@@ -55,7 +55,18 @@ These outcomes do not erase earlier source-specific passes. The [retry receipt](
| Local instruction save / detach | Two saves returned HTTP 200, but the subsequent fresh read returned 502 `provider_error` during the host-wake failure. Durable bytes were not independently verified; this is not evidence of a missing file. No detach was performed. |
| Local authorization boundary | Authenticated foreign-company issue read and board foreign-task computer connect returned 404; no owner ledger change or foreign computer row was observed. Temporary credentials were revoked. This is a live local boundary pass, not a staging journey. |
Deployment 14 candidate `5cf388845902c88d0406116ed9b2c44f335d8bb2` was dispatched through the official workflow at 01:45 UTC with request `f4e5af86-8ad0-4ebd-ad97-f2a9173015af`. Build and rollout are pending; deployment 13 is the last verified serving source.
Deployment 14 candidate `5cf388845902c88d0406116ed9b2c44f335d8bb2` was dispatched through the official workflow at 01:45 UTC with request `f4e5af86-8ad0-4ebd-ad97-f2a9173015af`. This was pending at the earlier cutoff; deployment 14 later verified serving, as recorded below.
## Deployment 14 follow-up (2026-10-11 02:23 UTC)
Deployment 14 **5cf388845902c88d0406116ed9b2c44f335d8bb2** verified serving at 02:07:08.443. These later results supplement the historical failures above.
- **Staging warm HMR passed.** React Fast Refresh fixture repair executed with Vite 5.4.21, React 18.3.1 and plugin 4.3.2, retaining polling and exact allowed-host protection. An initial browser reconnect lost the first baseline before the edit; after rebaselining, the heading changed while the unsaved input and page-session stayed intact. A complete second warm turn `9c13e199` repeated that result with unchanged runner 35567/start52230, Codex 35991/start52541, Vite 37325/start54717, session/thread, and proof hash. Its checkpoint settled with empty outbox and no pending terminal. [Browser baseline](assets/2026-10-10-boat/staging-14-hmr-rebaseline.png), [final heading](assets/2026-10-10-boat/staging-14-hmr-full-warm-after.png). Input remained `keep-this-unsaved-draft-boat-0213` and page-session remained `1791684735337` across the full second turn.
- **Local detach/reconnect retention passed.** Normal Disconnect reassigned both fixture agents, provider stop completed, and normal Reconnect reused the same environment/computer. The existing instruction marker was reread after reconnect. Original instructions were restored and reread after full reload; both agents were reassigned to their Boat. Experience still needs improvement: provider stop took about ten minutes, and subsequent file access was slow with a transient settling error.
- **Native Claude saved-session resume still failed.** `d529d365` rejected missing controller pack provenance before provider work. The reviewed fix persists the attachment template on cold rotation and recovers existing epochs from matching controller-owned commands; it does not bypass package, identity, or settlement checks. 28 cache and 5 transport tests plus both TypeScript checks passed; live validation awaits the next deployment.
- **Live sibling child cancellation remains unverified.** The legacy agent again returned early; exact child 72165 was absent at 02:21:48 before normal Stop around 02:21:50. Native runner/Codex/Vite identities survived the control cancellation, a narrower pass.
Deployment 15 (compatibility/reconnect fixes) is still building; reviewed saved-session fix is queued on staging branch `2e8859ab762e5b2ce97f2ea774e385fd333f9cee` for the subsequent deployment.
## Checks and their limits
@@ -87,12 +98,12 @@ Automated semantics already have meaningful coverage: the [latest 60-case route/
| Company/owner denial | Route tests: “hides cross-company tasks exactly like missing tasks”; service tests: “rejects cross company scopes before provider access” and “disconnects only the exact company-scoped viewer owned by the current user without provider access”. | Also a live local foreign-issue/task denial with unchanged ledger is recorded in the retry receipt; staging remains unverified. |
| Crash/restart fencing | Service tests: “reconciles a crashed controller reservation only after its durable deadline” and “reuses warm process identity and port while fencing stale callbacks”. | Automated fences passed. A real orderly local restart reached a suspended checkpoint, but continuation was confounded by host sleep; no successful restart journey claimed. |
Still unverified or incomplete at this cutoff:
Still unverified or incomplete after the deployment 14 follow-up:
- Exercise a legitimate saved-session continuation on diagnostic source; UI Retry `5957cc86` requested a fresh session and cannot diagnose the old recovery gate. Fresh and warm turns now passed; ordinary post-idle continuation is still needed for the new session. The old failure remains unresolved. Latest Codex configuration turn was unexpectedly cancelled and both repair attempts were quarantined before work; latest native Claude retry failed during setup. These current-source failures remain unresolved.
- Staging HMR and embedded desktop input. Preview rendering passed before unexpected runner retirement. The on-disk polling change was not proved loaded; React fixture repair did not execute. Direct browser desktop mouse and keyboard passed; embedded input remains unverified because automation targeted the outer page, and the second viewer interfered with the original stream.
- Exercise a legitimate saved-session continuation on diagnostic source; UI Retry `5957cc86` requested a fresh session and cannot diagnose the old recovery gate. Fresh and warm turns now passed; ordinary post-idle continuation is still needed for the new session. The old failure remains unresolved. The prior cancelled Codex turn and quarantined repairs remain historical failures; deployment 14 resumed the saved Codex session and passed warm HMR. Latest native Claude retry still failed before provider work and its correction awaits live deployment.
- Embedded desktop input on latest source remains unverified; direct browser desktop input passed earlier. Deployment 14 HMR passed after actual React fixture repair. Current computer-use navigation and artifact inspection are still being qualified.
- Explicit cancellation of one agent while a sibling continues on the same Boat.
- Product detach with retained-file verification, live feature-off cleanup, staging company denial, and successful controller restart continuation without duplicate execution. The local boundary pass and automated fences remain narrower evidence.
- Live feature-off cleanup, staging company denial, and successful controller restart continuation without duplicate execution. Local product detach/reconnect with retained-file verification passed; slow settling UX is recorded above. The local boundary pass and automated fences remain narrower evidence.
- Checks on subsequent commits and paid-resource state after any further qualification. Diagnostic-head CI is green on the exact sources above; deployment 12 and earlier corrected legacy passes do not imply complete acceptance.
Known v1 limits: cold startup can be expensive; immutable pack reuse avoids repeat large uploads but verification/staging still costs time. Managed snapshots and never-retried private cache uploads can retain disk pending operator cleanup. Arbitrary shell writers can race editor writes; no universal filesystem CAS guarantee is claimed. Dev servers survive warm turns when detached from the provider shell’s process group and still terminate with their owning runner at timeout.
@@ -4,7 +4,7 @@ These allowlisted summaries support the [validation matrix](../../../2026-10-10-
## Current boundary
Canonical candidate is `21deac0abfd2919525114f8cdc4a0d49f139665a`; core is `66ac692e446bd2ce0175613787f82eeb048f2749`. The reviewed fixes scope cleanup to its Boat owner and retain verified ACPX packages across deployment. Fixed-field cancellation diagnostics preserve outcome precedence. Deployment 14 candidate `5cf388845902c88d0406116ed9b2c44f335d8bb2` is pending; the serving evidence below remains deployment 13. Deployment 12 verified serving `1830beb0c26a7ba9d5e21460426936936ffc8db4` at 2026-10-10 22:14:02.236 UTC, runtime-equivalent to earlier 2ef1772. Deployment 13 verified 610c78a5 serving at 2026-10-11 01:05:49 UTC, runtime-equivalent to d502; UI Retry 5957cc86 started a fresh session and succeeded; the ordinary warm follow-up preserved runner/provider/Vite identity. Preview rendered, but HMR and saved-session idle recovery remain unverified. Later `2ac97bd2` was unexpectedly cancelled (not succeeded), its owner retired, and both repair attempts were quarantined before work. Native Claude `a38070b3` failed during setup; the first observed failure was an ACPX durable launch-profile digest mismatch after the pack upload, not a proved lease-deadline failure. The provider naturally archived at 01:32:48.421, confirmed at 01:33:52. A later normal Computer Connect resumed it for a desktop comparison: direct browser mouse and keyboard passed around 01:41; embedded input remains unverified because automation targeted the outer page. Both viewers closed normally around 01:43; no subsequent archive claim is made. The new retry summary records staging failures, local host-sleep limitations, a local authorization boundary pass, and natural viewer-close archive. Earlier receipts retain their exact sources and original cutoffs; the candidate/CI files below are historical, not current-status assertions.
Canonical candidate is `21deac0abfd2919525114f8cdc4a0d49f139665a`; core is `66ac692e446bd2ce0175613787f82eeb048f2749`. The reviewed fixes scope cleanup to its Boat owner and retain verified ACPX packages across deployment. Fixed-field cancellation diagnostics preserve outcome precedence. Deployment 14 candidate `5cf388845902c88d0406116ed9b2c44f335d8bb2` is pending; the serving evidence below remains deployment 13. Deployment 12 verified serving `1830beb0c26a7ba9d5e21460426936936ffc8db4` at 2026-10-10 22:14:02.236 UTC, runtime-equivalent to earlier 2ef1772. Deployment 13 verified 610c78a5 serving at 2026-10-11 01:05:49 UTC, runtime-equivalent to d502; UI Retry 5957cc86 started a fresh session and succeeded; the ordinary warm follow-up preserved runner/provider/Vite identity. Preview rendered, but HMR and saved-session idle recovery remain unverified. Later `2ac97bd2` was unexpectedly cancelled (not succeeded), its owner retired, and both repair attempts were quarantined before work. Native Claude `a38070b3` failed during setup; the first observed failure was an ACPX durable launch-profile digest mismatch after the pack upload, not a proved lease-deadline failure. The provider naturally archived at 01:32:48.421, confirmed at 01:33:52. A later normal Computer Connect resumed it for a desktop comparison: direct browser mouse and keyboard passed; embedded input remains unverified because automation targeted the outer page. Both viewers closed normally, but exact close time was not captured. At 01:47:06 the provider was archived with snapshots retained and stop completed at 01:42:11.287; precise close-to-archive causality is not claimed. The new retry summary records staging failures, local host-sleep limitations, a local authorization boundary pass, and natural viewer-close archive. Earlier receipts retain their exact sources and original cutoffs; the candidate/CI files below are historical, not current-status assertions.
| Receipt | Source / narrow claim |
| --- | --- |
@@ -43,3 +43,5 @@ The frozen full-suite result is not green. Later fixes/retries do not erase it:
This bundle excludes credentials, private hosting/viewer URLs, internal home paths, raw logs/DOM, environment/profile values, and private-cloud links. Run IDs and proof hashes are retained only where they make an acceptance claim inspectable.
Direct Boat browser input proof: [Chromium with the typed marker](../staging-13-direct-desktop-input.png). This proves direct viewer input, not embedded input targeting.
- Deployment 14 follow-up is included in retry-qualification-summary.json: full warm HMR and local detach/reconnect retention passed; Claude saved resume failed and live child cancellation remains inconclusive. Historical failures are preserved.
@@ -1,6 +1,6 @@
{
"schema": "paperclip.boat.validation-retry-summary.v1",
"recordedAt": "2026-10-11T01:45:57.847565+00:00",
"recordedAt": "2026-10-11T01:47:47.596826+00:00",
"scope": "Source-specific retry observations; not complete acceptance.",
"source": {
"canonical": "d50268c932da9e03c304f6a48cdaa5ee477331f2",
@@ -283,7 +283,7 @@
"manualStopOrWakePerformed": false,
"furtherGuestReadAttempted": false,
"limit": "Latest read-only provider state; no post-archive guest checkpoint read was attempted.",
"scopeAfterLaterWork": "Historical01:33:52 archived observation. Normal task Computer Connect resumed the fixture around01:35; both viewers closed around01:43, with no later archive observation included here."
"scopeAfterLaterWork": "Historical01:33:52 archived observation. Normal task Computer Connect later resumed the fixture. Both viewers closed normally before the01:47:06 provider read; exact close time was not captured."
},
"desktopComparison": {
"servingSource": "610c78a5ad97534380c61fa376c96c1b7a73a86a",
@@ -293,11 +293,11 @@
"method": "Normal task Computer Connect; then the same provider viewer was opened directly in a browser tab for comparison. Private viewer URL omitted.",
"streamVisibleAtApproximate": "2026-10-11T01:38:00Z",
"directBrowserInput": {
"observedAtApproximate": "2026-10-11T01:41:00Z",
"mouse": "passed: native click opened Chrome",
"keyboard": "passed: native key events visibly entered the complete marker",
"visibleMarker": "boatlive0141",
"evidenceFile": "staging-13-direct-desktop-input.png"
"evidenceFile": "staging-13-direct-desktop-input.png",
"timestampInferredFromMarker": false
},
"embeddedViewer": {
"streamVisible": true,
@@ -307,9 +307,34 @@
"mouseInputVerified": false,
"automationTargetingLimit": "The embedded Ctrl+A attempt selected the outer Paperclip page; this does not establish an embedded product input failure."
},
"bothViewersClosedNormallyAtApproximate": "2026-10-11T01:43:00Z",
"archiveAfterThisCloseVerified": false,
"scope": "Direct browser desktop keyboard and mouse passed. Embedded input remains unverified; the comparison revealed one-stream interference."
"scope": "Direct browser desktop keyboard and mouse passed. Embedded input remains unverified; the comparison revealed one-stream interference.",
"bothViewersClosedNormally": true,
"exactCloseTimeCaptured": false,
"closedBeforeProviderReadAt": "2026-10-11T01:47:06.987010+00:00",
"closeArchiveCausalityVerified": false,
"markerEncodesTimestamp": false
},
"latestProviderObservation": {
"at": "2026-10-11T01:47:06.987010+00:00",
"state": "archived",
"hydrated": true,
"health": "ok",
"error": null,
"snapshots": true,
"stop": {
"id": "stop_6f2a2286a84c0d41",
"status": "completed",
"requestedAt": null,
"lastAttemptAt": "2026-10-11T01:42:11.287Z",
"error": null,
"endedAt": "2026-10-11T01:42:11.287Z"
},
"guestReadAfterArchive": false,
"manualStopOrWakePerformed": false,
"exactViewerCloseTimeCaptured": false,
"closeArchiveCausalityVerified": false,
"scope": "Confirmed archived provider state at the timestamp shown, with snapshots retained and latest stop complete. Exact viewer-close time was not captured, so stop ordering relative to the close is not established."
}
},
"localRestart": {
@@ -636,6 +661,10 @@
{
"file": "staging-13-direct-desktop-input.png",
"sha256": "02ab563a51e6597b41c0faca3468be0e925901bd46890e37facdaac51ddc67c7"
},
{
"file": "retry-staging-13-post-viewer-close-provider.json",
"sha256": "398825c89d9300c4d48a9bb46408c1f75016d1764c847cbbf830dfc36dc73a08"
}
],
"deployment13": {
@@ -698,5 +727,63 @@
"file": "native-cancellation-diagnostic-tests.log",
"sha256": "b86a444e63cbae19ebe709c79919cc405f7cfbef68aeccbf861e7afdd3c3feea"
}
]
],
"followUp14": {
"recordedAt": "2026-10-11T02:23:00Z",
"servingSha": "5cf388845902c88d0406116ed9b2c44f335d8bb2",
"hmr": {
"result": "passed_after_rebaseline",
"runId": "9c13e199-845c-4bb1-a5a8-2118b1edfb93",
"beforeHeading": "Boat staging hot reload verified 0213",
"afterHeading": "Boat staging warm HMR confirmed 0216",
"preservedInput": "keep-this-unsaved-draft-boat-0213",
"preservedPageSession": "1791684735337",
"unchangedProcesses": [
{
"kind": "runner",
"pid": 35567,
"startTicks": 52230
},
{
"kind": "codex",
"pid": 35991,
"startTicks": 52541
},
{
"kind": "vite",
"pid": 37325,
"startTicks": 54717
}
],
"session": "06496696-b312-4268-ac40-66770aaa6f1a",
"proofSha256": "f9253e57dadaefe9276e99a9cd0cb9fad68d2704dd820b61e026edf6e6527c46",
"checkpointReadyEmptyOutboxNoPendingTerminal": true,
"limit": "Initial 02:12 browser reconnect lost the first baseline before heading change; later rebaseline and complete second warm turn passed."
},
"localDetachRetention": {
"result": "passed",
"environmentId": "c528a21f-b893-4dd0-8be9-5f6e5e02e2b2",
"detachAt": "2026-10-11T01:56:32Z",
"priorStopCompletedAt": "2026-10-11T02:05:09.243Z",
"reconnectAt": "2026-10-11T02:05:35.745Z",
"retainedMarkerObservedBy": "2026-10-11T02:14:00Z",
"cleanup": "Original instruction text restored through UI and reread after full reload; both fixture agents reassigned to same Boat.",
"experience": "Slow provider stop and file read; transient settling error. Retention success does not imply smooth UX."
},
"claudeSavedResume": {
"result": "failed",
"runId": "d529d365-e999-4a38-a4d0-562812df83c8",
"error": "runner_remote_provider_pack_provenance_unavailable",
"fix": "29e2aa95d1",
"validation": "28 cache tests, 5 transport tests, both TypeScript checks, independent review passed; live validation pending."
},
"siblingStop": {
"result": "inconclusive_for_live_child_cancellation",
"reportedPid": 72165,
"pidAbsentBeforeStopAt": "2026-10-11T02:21:48Z",
"uiStopApproxAt": "2026-10-11T02:21:50Z",
"postStopAt": "2026-10-11T02:22:05Z",
"nativeProcessesUnchanged": true
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB