[{"data":1,"prerenderedAt":373},["ShallowReactive",2],{"cycle-doc-design-c133-tyler-walk.md":3},{"cycle":4,"project":7,"path":10,"title":11,"toc":12,"ast":15},{"id":5,"title":6},"c133","Remediation Training",{"id":8,"label":9},"design","Design","tyler-walk.md","c133 · The walk for Tyler: the record, in ten minutes",[13,14],"The walk","After the walk",{"type":16,"children":17},"root",[18,79,102,108,134,182,213,251,267,283,345,355,360],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23,30,32,37,39,44,46,53,55,61,63,68,70,77],{"type":19,"tag":24,"props":25,"children":26},"strong",{},[27],{"type":28,"value":29},"text","For:",{"type":28,"value":31}," Tyler, with Mark. ",{"type":19,"tag":24,"props":33,"children":34},{},[35],{"type":28,"value":36},"Written:",{"type":28,"value":38}," 2026-11-11. ",{"type":19,"tag":24,"props":40,"children":41},{},[42],{"type":28,"value":43},"The page:",{"type":28,"value":45}," ",{"type":19,"tag":47,"props":48,"children":50},"a",{"href":49},"\u002Fcycles\u002Fdesign\u002Fsketches\u002Fc133-record",[51],{"type":28,"value":52},"The record: one event, three reads",{"type":28,"value":54},", drawn in the design system from ",{"type":19,"tag":47,"props":56,"children":58},{"href":57},"\u002Fcycles\u002Fdesign\u002Fc133\u002Fdoc\u002Fevent-shape",[59],{"type":28,"value":60},"event-shape.md",{"type":28,"value":62},". ",{"type":19,"tag":24,"props":64,"children":65},{},[66],{"type":28,"value":67},"What is asked:",{"type":28,"value":69}," six assumptions Mark set on 2026-11-11 (plan.md D22–D27, event-shape.md §8), one question each; the four items that are Tyler's alone come last. Nothing is implemented in qcontrol or the plane; the lab shows the record at ",{"type":19,"tag":71,"props":72,"children":74},"code",{"className":73},[],[75],{"type":28,"value":76},"\u002Fpages\u002Fphase4\u002Fmock\u002Ftraining?findingId=F-A&at=recorded",{"type":28,"value":78},".",{"type":19,"tag":20,"props":80,"children":81},{},[82,88],{"type":19,"tag":83,"props":84,"children":87},"img",{"alt":85,"src":86},"From the policy's detection to one small event in the plane's audit log, and the three places that read it: the finding, Reports, the operator's inbox.","\u002Fcycles\u002Fdesign\u002Fc133-sketch-record.png",[],{"type":19,"tag":89,"props":90,"children":91},"em",{},[92,94,100],{"type":28,"value":93},"The sketch as the sketches shot program captures it (",{"type":19,"tag":71,"props":95,"children":97},{"className":96},[],[98],{"type":28,"value":99},"c133-sketch-record.png",{"type":28,"value":101},"); the page is the live version.",{"type":19,"tag":103,"props":104,"children":106},"h2",{"id":105},"the-walk",[107],{"type":28,"value":13},{"type":19,"tag":20,"props":109,"children":110},{},[111,116,118,124,126,132],{"type":19,"tag":24,"props":112,"children":113},{},[114],{"type":28,"value":115},"0. Where we are (one minute).",{"type":28,"value":117}," The top row of the sketch. A policy with a training detects a finding; the plane sends the person a ",{"type":19,"tag":71,"props":119,"children":121},{"className":120},[],[122],{"type":28,"value":123},"training-assignment",{"type":28,"value":125}," message and writes ",{"type":19,"tag":71,"props":127,"children":129},{"className":128},[],[130],{"type":28,"value":131},"message.sent",{"type":28,"value":133},"; the person opens it in the native app, reads the lesson and passes the check on the web app, and presses Finish having seen what will be written (D14). The plane learns nothing between the send and that press (D13). Everything below the row is what the press produces. No question here; this is the ground both sides stand on.",{"type":19,"tag":20,"props":135,"children":136},{},[137,142,144,149,151,157,159,165,167,173,175,180],{"type":19,"tag":24,"props":138,"children":139},{},[140],{"type":28,"value":141},"1. The store, D22 (two minutes).",{"type":28,"value":143}," The ink box. The record lives in the plane's audit log, one row per completion, in the shape the log already uses for ",{"type":19,"tag":71,"props":145,"children":147},{"className":146},[],[148],{"type":28,"value":131},{"type":28,"value":150}," and ",{"type":19,"tag":71,"props":152,"children":154},{"className":153},[],[155],{"type":28,"value":156},"message.done",{"type":28,"value":158},". The finding reads its rows by ",{"type":19,"tag":71,"props":160,"children":162},{"className":161},[],[163],{"type":28,"value":164},"finding_id",{"type":28,"value":166},"; Reports sum them; nothing is stored twice. A ",{"type":19,"tag":71,"props":168,"children":170},{"className":169},[],[171],{"type":28,"value":172},"training_records",{"type":28,"value":174}," table exists only if a read needs one. ",{"type":19,"tag":89,"props":176,"children":177},{},[178],{"type":28,"value":179},"The question:",{"type":28,"value":181}," is the audit log the store, with the finding and Reports as reads, or does one of those reads need a table of its own from day one?",{"type":19,"tag":20,"props":183,"children":184},{},[185,190,192,198,199,205,207,211],{"type":19,"tag":24,"props":186,"children":187},{},[188],{"type":28,"value":189},"2. The contract, D23 (two minutes).",{"type":28,"value":191}," The grape crate and the grey box beside it. The event is small and follows the existing pattern, a tagged enum with ",{"type":19,"tag":71,"props":193,"children":195},{"className":194},[],[196],{"type":28,"value":197},"type",{"type":28,"value":150},{"type":19,"tag":71,"props":200,"children":202},{"className":201},[],[203],{"type":28,"value":204},"payload",{"type":28,"value":206}," and dotted names; the plane's richer record object consumes it and adds the links and the finding's context. The event is produced by the web app on the plane's side, never by an endpoint. ",{"type":19,"tag":89,"props":208,"children":209},{},[210],{"type":28,"value":179},{"type":28,"value":212}," which crate declares it, qevents' public contracts with their generated schemas and TypeScript, or the plane's own API types?",{"type":19,"tag":20,"props":214,"children":215},{},[216,221,223,228,230,236,238,243,245,249],{"type":19,"tag":24,"props":217,"children":218},{},[219],{"type":28,"value":220},"3. Both rows, and the association, D24 (one minute).",{"type":28,"value":222}," The bottom rug. Assignment and completion are both audit rows: ",{"type":19,"tag":71,"props":224,"children":226},{"className":225},[],[227],{"type":28,"value":131},{"type":28,"value":229}," is the only assignment record, ",{"type":19,"tag":71,"props":231,"children":233},{"className":232},[],[234],{"type":28,"value":235},"training.completed",{"type":28,"value":237}," the only completion record. The event carries ",{"type":19,"tag":71,"props":239,"children":241},{"className":240},[],[242],{"type":28,"value":164},{"type":28,"value":244}," alone; the plane associates the completion with the person's earlier findings under the same policy, so each of those findings shows the training taken after a later one, and the association drives the policy's next step after a repeat. ",{"type":19,"tag":89,"props":246,"children":247},{},[248],{"type":28,"value":179},{"type":28,"value":250}," does the plane make that association, and is it the thing that drives what remediation comes next?",{"type":19,"tag":20,"props":252,"children":253},{},[254,259,261,265],{"type":19,"tag":24,"props":255,"children":256},{},[257],{"type":28,"value":258},"4. Every completion a row, D25 (one minute).",{"type":28,"value":260}," The arrow into the ink box. No de-duplication and no row per action: one grouped object per completion, in Mark's words type training, completed, the training's id and name, proof of understanding true. A second Finish for the same finding writes a second row; Reports count the finding as answered once. ",{"type":19,"tag":89,"props":262,"children":263},{},[264],{"type":28,"value":179},{"type":28,"value":266}," a row per completion with the count de-duplicated in the read, rather than one record per (training, finding, person) with the second Finish a no-op, agreed?",{"type":19,"tag":20,"props":268,"children":269},{},[270,275,277,281],{"type":19,"tag":24,"props":271,"children":272},{},[273],{"type":28,"value":274},"5. Version and hash, D26 (one minute).",{"type":28,"value":276}," The middle note. A published training carries an integer version and a hash of its published JSON; the record names both, so the plane can prove which text was passed and a later edit never rewrites a pass. The design site's publish step computes the hash and its API serves both (D21). ",{"type":19,"tag":89,"props":278,"children":279},{},[280],{"type":28,"value":179},{"type":28,"value":282}," does the plane keep the hash as the record states it, or verify it against the published JSON at write time?",{"type":19,"tag":20,"props":284,"children":285},{},[286,291,293,299,301,307,308,314,316,322,324,330,332,336,338,343],{"type":19,"tag":24,"props":287,"children":288},{},[289],{"type":28,"value":290},"6. Separate events per assigner, D27 (one minute).",{"type":28,"value":292}," The crate's first field. A completion after a policy's, an operator's or HQ's assignment is its own event type, so the audit log reads who asked without opening the message: ",{"type":19,"tag":71,"props":294,"children":296},{"className":295},[],[297],{"type":28,"value":298},"training.completed.policy",{"type":28,"value":300},", ",{"type":19,"tag":71,"props":302,"children":304},{"className":303},[],[305],{"type":28,"value":306},".operator",{"type":28,"value":300},{"type":19,"tag":71,"props":309,"children":311},{"className":310},[],[312],{"type":28,"value":313},".hq",{"type":28,"value":315}," proposed, the payload the same, ",{"type":19,"tag":71,"props":317,"children":319},{"className":318},[],[320],{"type":28,"value":321},"assigned_by",{"type":28,"value":323}," dropped because the type carries it, ",{"type":19,"tag":71,"props":325,"children":327},{"className":326},[],[328],{"type":28,"value":329},"message_id",{"type":28,"value":331}," kept. ",{"type":19,"tag":89,"props":333,"children":334},{},[335],{"type":28,"value":179},{"type":28,"value":337}," three types, or one type with ",{"type":19,"tag":71,"props":339,"children":341},{"className":340},[],[342],{"type":28,"value":321},{"type":28,"value":344},", and if three, what are their names?",{"type":19,"tag":20,"props":346,"children":347},{},[348,353],{"type":19,"tag":24,"props":349,"children":350},{},[351],{"type":28,"value":352},"7. What stays Tyler's (one minute).",{"type":28,"value":354}," The orange note. Four items are not assumptions and have no lab default: which crate declares the event (question 2 settles it); the type names (question 6); retention of the audit rows against Reports' windows, since Corrections reads as a state as of the cutoff (D17); and whether the plane or the app ends the assignment message on completion, where c137's bones §5 says the app. Tyler names each or takes it away to decide.",{"type":19,"tag":103,"props":356,"children":358},{"id":357},"after-the-walk",[359],{"type":28,"value":14},{"type":19,"tag":20,"props":361,"children":362},{},[363,365,371],{"type":28,"value":364},"Each answer lands in ",{"type":19,"tag":71,"props":366,"children":368},{"className":367},[],[369],{"type":28,"value":370},"plan.md",{"type":28,"value":372}," as the decision's ruling and amends event-shape.md §2 and §3 where it changes them. Once the shape is agreed, the Corrections block becomes the finding's default and the history row stays as the same event (D20); c134 keeps the record, c128 reads it, c137 carries the completion back. The one question that is not Tyler's stays open: whether a completed training counts as personnel data in the organisations Peterson knows (D10).",1794599382757]