[{"data":1,"prerenderedAt":712},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Fcognets\u002Fengine\u002Fobservability":3},{"id":4,"title":5,"body":6,"description":704,"extension":705,"meta":706,"navigation":707,"path":708,"seo":709,"stem":710,"__hash__":711},"docs\u002Fdocs\u002Fv2\u002Fcognets\u002Fengine\u002Fobservability.md","Observability",{"type":7,"value":8,"toc":697},"minimark",[9,13,17,20,105,123,128,135,141,179,184,221,226,263,268,313,324,328,331,334,464,467,478,482,492,499,502,508,514,518,526,557,560,568,572,578,683,690,693],[10,11,5],"h1",{"id":12},"observability",[14,15,16],"p",{},"The hardest part of building a mind is not making it work. It is finding out what it did.",[14,18,19],{},"A cognet emits its own structured record as it thinks: every tick, every named phase,\nevery unit of work, every world mutation — each one stamped with where it sat in the\nclock. Not logging you add afterward. The execution wrappers you already use to structure\nthe loop are the same ones that produce the trace.",[21,22,27],"pre",{"className":23,"code":24,"language":25,"meta":26,"style":26},"language-ts shiki shiki-themes dark-plus","await phase(\"think\", async () => {\n    await system(\"score-candidates\", async () => { \u002F* ... *\u002F })\n})\n","ts","",[28,29,30,67,99],"code",{"__ignoreMap":26},[31,32,35,39,43,47,51,54,58,61,64],"span",{"class":33,"line":34},"line",1,[31,36,38],{"class":37},"sYbnZ","await",[31,40,42],{"class":41},"sCudf"," phase",[31,44,46],{"class":45},"sTNBD","(",[31,48,50],{"class":49},"sKc5r","\"think\"",[31,52,53],{"class":45},", ",[31,55,57],{"class":56},"scz_3","async",[31,59,60],{"class":45}," () ",[31,62,63],{"class":56},"=>",[31,65,66],{"class":45}," {\n",[31,68,70,73,76,78,81,83,85,87,89,92,96],{"class":33,"line":69},2,[31,71,72],{"class":37},"    await",[31,74,75],{"class":41}," system",[31,77,46],{"class":45},[31,79,80],{"class":49},"\"score-candidates\"",[31,82,53],{"class":45},[31,84,57],{"class":56},[31,86,60],{"class":45},[31,88,63],{"class":56},[31,90,91],{"class":45}," { ",[31,93,95],{"class":94},"sOLPB","\u002F* ... *\u002F",[31,97,98],{"class":45}," })\n",[31,100,102],{"class":33,"line":101},3,[31,103,104],{"class":45},"})\n",[14,106,107,108,53,111,114,115,118,119,122],{},"That code emits ",[28,109,110],{},"cognet:phase:start",[28,112,113],{},"cognet:system:start",",\n",[28,116,117],{},"cognet:system:complete"," with a duration, and ",[28,120,121],{},"cognet:phase:complete"," — in order, tick-\nand phase-stamped. You get the trace because you named the stage, not because you\ninstrumented it.",[124,125,127],"h2",{"id":126},"the-vocabulary","The vocabulary",[14,129,130,131,134],{},"Restricted to ",[28,132,133],{},"cognet:*",", enforced at the call site rather than only in the types. A\ncognet narrates its own world; it can never forge kernel machinery events like engine\ncalls or run records.",[14,136,137],{},[138,139,140],"strong",{},"The world clock",[21,142,144],{"className":23,"code":143,"language":25,"meta":26,"style":26},"\"cognet:tick:start\"        \u002F\u002F { tick }\n\"cognet:tick:complete\"     \u002F\u002F { tick }\n\"cognet:tick:failed\"       \u002F\u002F { tick, error }\n\"cognet:tick:interrupted\"  \u002F\u002F { tick }\n",[28,145,146,154,162,170],{"__ignoreMap":26},[31,147,148,151],{"class":33,"line":34},[31,149,150],{"class":49},"\"cognet:tick:start\"",[31,152,153],{"class":94},"        \u002F\u002F { tick }\n",[31,155,156,159],{"class":33,"line":69},[31,157,158],{"class":49},"\"cognet:tick:complete\"",[31,160,161],{"class":94},"     \u002F\u002F { tick }\n",[31,163,164,167],{"class":33,"line":101},[31,165,166],{"class":49},"\"cognet:tick:failed\"",[31,168,169],{"class":94},"       \u002F\u002F { tick, error }\n",[31,171,173,176],{"class":33,"line":172},4,[31,174,175],{"class":49},"\"cognet:tick:interrupted\"",[31,177,178],{"class":94},"  \u002F\u002F { tick }\n",[14,180,181],{},[138,182,183],{},"Phases — named stages within a tick",[21,185,187],{"className":23,"code":186,"language":25,"meta":26,"style":26},"\"cognet:phase:start\"        \u002F\u002F { tick, phase }\n\"cognet:phase:complete\"     \u002F\u002F { tick, phase }\n\"cognet:phase:failed\"       \u002F\u002F { tick, phase, error }\n\"cognet:phase:interrupted\"  \u002F\u002F { tick, phase }\n",[28,188,189,197,205,213],{"__ignoreMap":26},[31,190,191,194],{"class":33,"line":34},[31,192,193],{"class":49},"\"cognet:phase:start\"",[31,195,196],{"class":94},"        \u002F\u002F { tick, phase }\n",[31,198,199,202],{"class":33,"line":69},[31,200,201],{"class":49},"\"cognet:phase:complete\"",[31,203,204],{"class":94},"     \u002F\u002F { tick, phase }\n",[31,206,207,210],{"class":33,"line":101},[31,208,209],{"class":49},"\"cognet:phase:failed\"",[31,211,212],{"class":94},"       \u002F\u002F { tick, phase, error }\n",[31,214,215,218],{"class":33,"line":172},[31,216,217],{"class":49},"\"cognet:phase:interrupted\"",[31,219,220],{"class":94},"  \u002F\u002F { tick, phase }\n",[14,222,223],{},[138,224,225],{},"Systems — units of work within a phase",[21,227,229],{"className":23,"code":228,"language":25,"meta":26,"style":26},"\"cognet:system:start\"        \u002F\u002F { tick, phase, system }\n\"cognet:system:complete\"     \u002F\u002F { tick, phase, system, durationMs }\n\"cognet:system:failed\"       \u002F\u002F { tick, phase, system, error }\n\"cognet:system:interrupted\"  \u002F\u002F { tick, phase, system }\n",[28,230,231,239,247,255],{"__ignoreMap":26},[31,232,233,236],{"class":33,"line":34},[31,234,235],{"class":49},"\"cognet:system:start\"",[31,237,238],{"class":94},"        \u002F\u002F { tick, phase, system }\n",[31,240,241,244],{"class":33,"line":69},[31,242,243],{"class":49},"\"cognet:system:complete\"",[31,245,246],{"class":94},"     \u002F\u002F { tick, phase, system, durationMs }\n",[31,248,249,252],{"class":33,"line":101},[31,250,251],{"class":49},"\"cognet:system:failed\"",[31,253,254],{"class":94},"       \u002F\u002F { tick, phase, system, error }\n",[31,256,257,260],{"class":33,"line":172},[31,258,259],{"class":49},"\"cognet:system:interrupted\"",[31,261,262],{"class":94},"  \u002F\u002F { tick, phase, system }\n",[14,264,265],{},[138,266,267],{},"World mutation",[21,269,271],{"className":23,"code":270,"language":25,"meta":26,"style":26},"\"cognet:entity:add\"        \u002F\u002F { tick, phase, entity }\n\"cognet:entity:remove\"     \u002F\u002F { tick, phase, entity }\n\"cognet:component:add\"     \u002F\u002F { tick, phase, entity, component }\n\"cognet:component:update\"  \u002F\u002F { tick, phase, entity, component }\n\"cognet:component:remove\"  \u002F\u002F { tick, phase, entity, component }\n",[28,272,273,281,289,297,305],{"__ignoreMap":26},[31,274,275,278],{"class":33,"line":34},[31,276,277],{"class":49},"\"cognet:entity:add\"",[31,279,280],{"class":94},"        \u002F\u002F { tick, phase, entity }\n",[31,282,283,286],{"class":33,"line":69},[31,284,285],{"class":49},"\"cognet:entity:remove\"",[31,287,288],{"class":94},"     \u002F\u002F { tick, phase, entity }\n",[31,290,291,294],{"class":33,"line":101},[31,292,293],{"class":49},"\"cognet:component:add\"",[31,295,296],{"class":94},"     \u002F\u002F { tick, phase, entity, component }\n",[31,298,299,302],{"class":33,"line":172},[31,300,301],{"class":49},"\"cognet:component:update\"",[31,303,304],{"class":94},"  \u002F\u002F { tick, phase, entity, component }\n",[31,306,308,311],{"class":33,"line":307},5,[31,309,310],{"class":49},"\"cognet:component:remove\"",[31,312,304],{"class":94},[14,314,315,316,319,320,323],{},"Every payload carries ",[28,317,318],{},"tick",", and everything below tick level carries ",[28,321,322],{},"phase",". That is\nwhat makes the stream a tree rather than a list: start and complete events nest by\nconstruction, so a flame graph falls out of the ordering without any correlation ids to\njoin on.",[124,325,327],{"id":326},"interrupted-is-not-failed","Interrupted is not failed",[14,329,330],{},"The distinction runs through the whole vocabulary, and it matters more than it looks.",[14,332,333],{},"When a wake is aborted — the user pressed Escape, the process is shutting down — whatever\nthe in-flight phase threw is cancellation surfacing through the call stack, not a failure\nof that phase's work. The wrappers check the wake's signal before classifying:",[21,335,337],{"className":23,"code":336,"language":25,"meta":26,"style":26},"catch (cause) {\n    if (signal?.aborted) {\n        void emit(\"cognet:phase:interrupted\", { tick, phase: name })\n        throw cause\n    }\n    void emit(\"cognet:phase:failed\", { tick, phase: name, error: err(cause) })\n    throw failure\n}\n",[28,338,339,354,372,399,407,412,449,458],{"__ignoreMap":26},[31,340,341,344,347,351],{"class":33,"line":34},[31,342,343],{"class":37},"catch",[31,345,346],{"class":45}," (",[31,348,350],{"class":349},"s3F5K","cause",[31,352,353],{"class":45},") {\n",[31,355,356,359,361,364,367,370],{"class":33,"line":69},[31,357,358],{"class":37},"    if",[31,360,346],{"class":45},[31,362,363],{"class":349},"signal",[31,365,366],{"class":45},"?.",[31,368,369],{"class":349},"aborted",[31,371,353],{"class":45},[31,373,374,377,380,382,384,387,389,391,394,397],{"class":33,"line":101},[31,375,376],{"class":56},"        void",[31,378,379],{"class":41}," emit",[31,381,46],{"class":45},[31,383,217],{"class":49},[31,385,386],{"class":45},", { ",[31,388,318],{"class":349},[31,390,53],{"class":45},[31,392,393],{"class":349},"phase:",[31,395,396],{"class":349}," name",[31,398,98],{"class":45},[31,400,401,404],{"class":33,"line":172},[31,402,403],{"class":37},"        throw",[31,405,406],{"class":349}," cause\n",[31,408,409],{"class":33,"line":307},[31,410,411],{"class":45},"    }\n",[31,413,415,418,420,422,424,426,428,430,432,434,436,439,442,444,446],{"class":33,"line":414},6,[31,416,417],{"class":56},"    void",[31,419,379],{"class":41},[31,421,46],{"class":45},[31,423,209],{"class":49},[31,425,386],{"class":45},[31,427,318],{"class":349},[31,429,53],{"class":45},[31,431,393],{"class":349},[31,433,396],{"class":349},[31,435,53],{"class":45},[31,437,438],{"class":349},"error:",[31,440,441],{"class":41}," err",[31,443,46],{"class":45},[31,445,350],{"class":349},[31,447,448],{"class":45},") })\n",[31,450,452,455],{"class":33,"line":451},7,[31,453,454],{"class":37},"    throw",[31,456,457],{"class":349}," failure\n",[31,459,461],{"class":33,"line":460},8,[31,462,463],{"class":45},"}\n",[14,465,466],{},"A system that conflates the two produces a trace full of red that means nothing. Every\nuser interrupt looks like a crash, and real crashes stop standing out. Keeping them\nseparate is what lets \"failed\" retain its meaning.",[14,468,469,470,473,474,477],{},"Real failures still emit ",[28,471,472],{},"*:failed"," and rethrow. ",[138,475,476],{},"Telemetry never swallows."," An event\nis emitted and the error continues propagating; observability is never the reason\nsomething was handled.",[124,479,481],{"id":480},"fire-and-forget-durably","Fire-and-forget, durably",[14,483,484,487,488,491],{},[28,485,486],{},"kernel.emit()"," returns ",[28,489,490],{},"void",". A cognet never awaits its own telemetry, and a slow\nobserver can never apply backpressure to thinking.",[14,493,494,495,498],{},"The machine treats it more seriously than that. Events are committed to the session log's\ntelemetry view — alongside ",[28,496,497],{},"kernel:*"," — and the commit pipeline forwards them to the\nruntime bus. At some level a cognet's events have to reach a log for the brain to be\ndebuggable, and this is that level.",[14,500,501],{},"Two consequences worth knowing:",[14,503,504,507],{},[138,505,506],{},"Telemetry is durable, not ephemeral."," You can replay a wake from the log and get the\nsame trace, including from a process that has since died.",[14,509,510,513],{},[138,511,512],{},"A fast cognet is chatty."," A continuous cognet ticking at 125Hz emits at least three\nworld-clock events per tick before it does anything of its own. That is a known cost of\nthe current design. If it bites, the gate belongs at the write path, not in cognet code\nthat stops naming its phases.",[124,515,517],{"id":516},"what-is-not-yours","What is not yours",[14,519,520,522,523,525],{},[28,521,486],{}," accepts ",[28,524,133],{}," and nothing else. A call naming anything outside that\nprefix throws — not a type error you can cast around, a refusal at the seam:",[21,527,529],{"className":23,"code":528,"language":25,"meta":26,"style":26},"kernel.emit(\"kernel:run:complete\", { \u002F* ... *\u002F })  \u002F\u002F throws COGNET_EMIT_FORBIDDEN\n",[28,530,531],{"__ignoreMap":26},[31,532,533,536,539,542,544,547,549,551,554],{"class":33,"line":34},[31,534,535],{"class":349},"kernel",[31,537,538],{"class":45},".",[31,540,541],{"class":41},"emit",[31,543,46],{"class":45},[31,545,546],{"class":49},"\"kernel:run:complete\"",[31,548,386],{"class":45},[31,550,95],{"class":94},[31,552,553],{"class":45}," })  ",[31,555,556],{"class":94},"\u002F\u002F throws COGNET_EMIT_FORBIDDEN\n",[14,558,559],{},"The durable record around a wake — engine calls, capsule runs, their results — is the\nkernel's and only the kernel's. A cognet that could write those could claim to have run\ncode it never ran.",[14,561,562,563,538],{},"This is the same boundary as everywhere else in the contract, applied to the trace:\n",[564,565,567],"a",{"href":566},"\u002Fdocs\u002Fv2\u002Fcognets\u002Fengine\u002Fkernel-contract","the cognet emits, the kernel records",[124,569,571],{"id":570},"naming-as-instrumentation","Naming as instrumentation",[14,573,574,575],{},"The practical consequence for authoring: ",[138,576,577],{},"the names you choose are the trace you get.",[21,579,581],{"className":23,"code":580,"language":25,"meta":26,"style":26},"await phase(\"sense\", async () => { \u002F* ... *\u002F })\nawait phase(\"render\", async () => { \u002F* ... *\u002F })\nawait phase(\"invoke\", async () => { \u002F* ... *\u002F })\nawait phase(\"act\", async () => { \u002F* ... *\u002F })\n",[28,582,583,608,633,658],{"__ignoreMap":26},[31,584,585,587,589,591,594,596,598,600,602,604,606],{"class":33,"line":34},[31,586,38],{"class":37},[31,588,42],{"class":41},[31,590,46],{"class":45},[31,592,593],{"class":49},"\"sense\"",[31,595,53],{"class":45},[31,597,57],{"class":56},[31,599,60],{"class":45},[31,601,63],{"class":56},[31,603,91],{"class":45},[31,605,95],{"class":94},[31,607,98],{"class":45},[31,609,610,612,614,616,619,621,623,625,627,629,631],{"class":33,"line":69},[31,611,38],{"class":37},[31,613,42],{"class":41},[31,615,46],{"class":45},[31,617,618],{"class":49},"\"render\"",[31,620,53],{"class":45},[31,622,57],{"class":56},[31,624,60],{"class":45},[31,626,63],{"class":56},[31,628,91],{"class":45},[31,630,95],{"class":94},[31,632,98],{"class":45},[31,634,635,637,639,641,644,646,648,650,652,654,656],{"class":33,"line":101},[31,636,38],{"class":37},[31,638,42],{"class":41},[31,640,46],{"class":45},[31,642,643],{"class":49},"\"invoke\"",[31,645,53],{"class":45},[31,647,57],{"class":56},[31,649,60],{"class":45},[31,651,63],{"class":56},[31,653,91],{"class":45},[31,655,95],{"class":94},[31,657,98],{"class":45},[31,659,660,662,664,666,669,671,673,675,677,679,681],{"class":33,"line":172},[31,661,38],{"class":37},[31,663,42],{"class":41},[31,665,46],{"class":45},[31,667,668],{"class":49},"\"act\"",[31,670,53],{"class":45},[31,672,57],{"class":56},[31,674,60],{"class":45},[31,676,63],{"class":56},[31,678,91],{"class":45},[31,680,95],{"class":94},[31,682,98],{"class":45},[14,684,685,686,689],{},"Those four names are ",[28,687,688],{},"zero","'s entire cognitive cycle, and they're also its trace. Reading\na session's telemetry tells you exactly how the brain spent its time, which phase a\nfailure happened in, and which tick a decision was made on.",[14,691,692],{},"A cognet that does all its work in one unnamed block runs identically and tells you\nnothing. Naming stages is not documentation — it is the observability.",[694,695,696],"style",{},"html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}html pre.shiki code .sCudf, html code.shiki .sCudf{--shiki-default:#DCDCAA}html pre.shiki code .sTNBD, html code.shiki .sTNBD{--shiki-default:#D4D4D4}html pre.shiki code .sKc5r, html code.shiki .sKc5r{--shiki-default:#CE9178}html pre.shiki code .scz_3, html code.shiki .scz_3{--shiki-default:#569CD6}html pre.shiki code .sOLPB, html code.shiki .sOLPB{--shiki-default:#6A9955}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}",{"title":26,"searchDepth":69,"depth":69,"links":698},[699,700,701,702,703],{"id":126,"depth":69,"text":127},{"id":326,"depth":69,"text":327},{"id":480,"depth":69,"text":481},{"id":516,"depth":69,"text":517},{"id":570,"depth":69,"text":571},"A thought, recorded as a flame graph — the cognet event vocabulary.","md",{},true,"\u002Fdocs\u002Fv2\u002Fcognets\u002Fengine\u002Fobservability",{"title":5,"description":704},"docs\u002Fv2\u002Fcognets\u002Fengine\u002Fobservability","ceTruug_SfcaL6BKL8G0ryhVqZ9SE1IRKxhC7ymjmW0",1785156432077]