{"record":{"id":"fe6d318a1605f440","repo":"Hmbown/CodeWhale","slug":"archive-this-pet-recording-before-accepting-more-telemetry","errorCode":null,"errorMessage":"Archive this pet recording before accepting more telemetry.","messagePattern":"Archive this pet recording before accepting more telemetry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":440,"sourceCode":"        this.voices = [];\n    }\n    /** Branch at the current playhead; input is journalled for the next fixed tick.\n     * A live touch never needs to re-simulate the creature's entire lifetime. */\n    interact(kind, x, y) {\n        if (!['attention', 'food'].includes(kind) || !Number.isFinite(x) || !Number.isFinite(y) || Math.abs(x) > 1 || Math.abs(y) > 1)\n            throw new Error('Invalid pet interaction.');\n        if (this.branchTick !== this.tick)\n            this.interactionLog.splice(this.interactionIndex);\n        this.branchTick = this.tick;\n        this.interactionLog.push({ timeMs: (this.tick + 1) * 1000 / HZ, kind, x, y });\n    }\n    /** Accept a live source packet at the next 400ms boundary. The accepted tape,\n     * including any missing intervals, is the exact replay authority for this host. */\n    acceptTelemetry(input) {\n        (0, pet_telemetry_js_1.validatePetBucket)(input);\n        const sequence = Math.floor(this.tick / 12) + 1;\n        if (this.tapeLog.length >= 216_000)\n            throw new Error('Archive this pet recording before accepting more telemetry.');\n        this.hasTelemetry = true;\n        if (this.segmented) {\n            const at = this.tapeLog.findIndex(b => b.sequence >= sequence);\n            const index = at < 0 ? this.tapeLog.length : at;\n            this.tapeLog.splice(index, at >= 0 && this.tapeLog[at].sequence === sequence ? 1 : 0, { ...structuredClone(input), sequence, simTimeMs: sequence * 400 });\n            this.hashTape(index);\n            return;\n        }\n        if (sequence >= 216_000)\n            throw new Error('Archive the legacy recording before accepting more telemetry.');\n        const changedFrom = Math.min(sequence, this.tapeLog.length);\n        while (this.tapeLog.length <= sequence) {\n            const at = this.tapeLog.length;\n            this.tapeLog.push({ version: 1, sequence: at, simTimeMs: at * 400, durationMs: 400,\n                activity: .12, coherence: .25, attention: 0, channel: 'other', observed: 0, roamX: 0, roamY: 0, flip: 1, lit: 1,\n                onsets: Array(13).fill(0), activeMs: Array(13).fill(0), errors: 0, agentIds: [], waiting: false });\n        }\n        this.tapeLog[sequence] = { ...structuredClone(input), sequence, simTimeMs: sequence * 400 };","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L422-L458","documentation":"In segmented mode, acceptTelemetry stores one bucket per 400 ms sequence in tapeLog, which is hard-capped at 216,000 entries (~24 hours). When the tape log is full, further telemetry is refused and the caller must archive the recording first so replay history is never silently overwritten in the live segmented path. This is an explicit capacity guard, not a corruption error.","triggerScenarios":"Calling world.acceptTelemetry(bucket) when this.tapeLog.length >= 216_000 in segmented (petCheckpointVersion 2) mode — i.e. the session has accumulated 216,000 telemetry buckets without being archived.","commonSituations":"A pet session left running for more than ~24 hours of continuous telemetry; a long-lived background watcher never archiving; repeated acceptTelemetry of distinct sequences filling the log in tests.","solutions":["Archive the current pet recording (snapshot and reset the world/tape) before accepting more telemetry.","Start a new PetWorld/session for continued live telemetry and keep the archived one for replay.","If the session must run indefinitely, periodically rotate: persist the tapeLog, then construct a fresh world seeded from the latest checkpoint."],"exampleFix":"// before\nif (world.tapeLog.length >= 216000) world.acceptTelemetry(bucket); // throws\n// after\nif (world.tapeLog.length >= 216000) archivePetRecording(world); // persist & restart\nworld.acceptTelemetry(bucket);","handlingStrategy":"try-catch","validationCode":"function canAcceptTelemetry(world) {\n  return Array.isArray(world.tapeLog) && world.tapeLog.length < 216000;\n}","typeGuard":"null","tryCatchPattern":"try {\n  world.acceptTelemetry(bucket);\n} catch (e) {\n  if (e.message.startsWith('Archive this pet recording')) {\n    await archivePetRecording(world);\n    world = startFreshSegmentedWorld();\n    world.acceptTelemetry(bucket);\n  } else throw e;\n}","preventionTips":["Monitor tapeLog.length and archive before hitting 216,000 buckets","Rotate long-running pet sessions periodically (~24 h of telemetry)","Archive proactively on session milestones rather than on failure","Alert when a live watcher approaches the tape capacity"],"tags":["capacity","telemetry","storage-limit"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}