[{"data":1,"prerenderedAt":359},["ShallowReactive",2],{"$fYJSw-537pZgIvTaN8FS6sjq5jQbes0x2BmAPJNT-pcY":3},{"newThing":4,"project":5,"cycle":8,"sections":23,"threads":351,"otherDocs":354,"images":356,"archiveItems":357,"links":358},null,{"id":6,"label":7,"liveBase":4},"design","Design",{"id":9,"num":10,"dir":11,"name":12,"title":13,"focus":14,"status":15,"statusNote":4,"created":16,"completed":4,"mode":17,"recordless":18,"thumbnail":4,"imageCount":19,"artifactCount":20,"lastActivity":21,"hasPickup":18,"hasInitialPrompt":22},"c72",72,"c72.integrations-create-manage","integrations-create-manage","Integrations Create & Manage","Create\u002Fconfigure modal for 11 connectors with per-integration custom UI and step-by-step operator guidance","active","2026-08-15","Evolution — iterating the stable c61 integrations form",false,0,4,"2026-09-11",true,[24,47,57,107],{"key":25,"title":26,"empty":18,"ast":27},"why","Why",{"type":28,"children":29},"root",[30],{"type":31,"tag":32,"props":33,"children":34},"element","p",{},[35,38,45],{"type":36,"value":37},"text","c61 shipped qdash ",{"type":31,"tag":39,"props":40,"children":42},"code",{"className":41},[],[43],{"type":36,"value":44},"\u002Fintegrations",{"type":36,"value":46}," (qcontrol repo, feat\u002Fcontrol-center branch) with an 11-connector typed catalog (crates\u002Fqdash\u002Fui\u002Fapp\u002Flib\u002Fintegrations.ts) and per-connector detail pages. But the \"add\" action currently just navigates to a detail page with a disabled stub form (\"Not wired — would require configuration\"). Only the three channel-backed connectors (pagerduty, slack, email) have a real write path (severity routing via \u002Fapi\u002Fchannels). There is no functional create\u002Fconfigure flow, leaving the integrations page incomplete and the operator without guidance on setting up new connectors.",{"key":48,"title":49,"empty":18,"ast":50},"objective","Objective",{"type":28,"children":51},[52],{"type":31,"tag":32,"props":53,"children":54},{},[55],{"type":36,"value":56},"Deliver a create\u002Fconfigure modal launched from the integrations page's add action, with UI custom to each of the 11 connectors — real fields for what each integration actually requires — plus step-by-step operator guidance (where to get tokens\u002Fsecrets\u002FIDs, what to expect) as a mini living tutorial per connector. Reuse the same per-connector config UI for managing existing integrations on detail pages.",{"key":58,"title":59,"empty":18,"ast":60},"scope","Scope",{"type":28,"children":61},[62],{"type":31,"tag":63,"props":64,"children":65},"ul",{},[66,72,77,82,87,92,97,102],{"type":31,"tag":67,"props":68,"children":69},"li",{},[70],{"type":36,"value":71},"Research each of the 11 connectors' real setup requirements",{"type":31,"tag":67,"props":73,"children":74},{},[75],{"type":36,"value":76},"Typed per-connector setup recipes (data model)",{"type":31,"tag":67,"props":78,"children":79},{},[80],{"type":36,"value":81},"Modal shell + stepper UX pattern",{"type":31,"tag":67,"props":83,"children":84},{},[85],{"type":36,"value":86},"Custom per-connector configuration forms",{"type":31,"tag":67,"props":88,"children":89},{},[90],{"type":36,"value":91},"Operator guidance: mini living tutorials for each connector",{"type":31,"tag":67,"props":93,"children":94},{},[95],{"type":36,"value":96},"Reuse on detail pages (edit existing integrations)",{"type":31,"tag":67,"props":98,"children":99},{},[100],{"type":36,"value":101},"Persistence layer so configured connectors flip to active state",{"type":31,"tag":67,"props":103,"children":104},{},[105],{"type":36,"value":106},"Out of scope: actual outbound delivery (qdash stays loopback-bound \u002F projected)",{"key":108,"title":109,"empty":18,"ast":110},"key-changes","Key Changes",{"type":28,"children":111},[112],{"type":31,"tag":63,"props":113,"children":114},{},[115,120,157,192,226,268,286],{"type":31,"tag":67,"props":116,"children":117},{},[118],{"type":36,"value":119},"2026-08-15 — Cycle created; initial-prompt captured, CYCLE.md written.",{"type":31,"tag":67,"props":121,"children":122},{},[123,125,131,133,139,141,147,149,155],{"type":36,"value":124},"2026-08-15 — ",{"type":31,"tag":126,"props":127,"children":128},"strong",{},[129],{"type":36,"value":130},"Requirements research + recipe catalog:",{"type":36,"value":132}," all 11 connectors' real setup requirements researched and encoded as typed setup recipes (",{"type":31,"tag":39,"props":134,"children":136},{"className":135},[],[137],{"type":36,"value":138},"ui\u002Fapp\u002Flib\u002Fintegration-setup.ts",{"type":36,"value":140},") — fields (text\u002Furl\u002Fsecret\u002Fsecret-multiline\u002Fselect, conditional via ",{"type":31,"tag":39,"props":142,"children":144},{"className":143},[],[145],{"type":36,"value":146},"showIf",{"type":36,"value":148},") + tutorial steps (vendor console click-paths, copyable SQL\u002Fopenssl\u002FIAM-policy snippets, caution notes) + \"once connected\" expectations. Summary in ",{"type":31,"tag":39,"props":150,"children":152},{"className":151},[],[153],{"type":36,"value":154},"research-connectors.md",{"type":36,"value":156},".",{"type":31,"tag":67,"props":158,"children":159},{},[160,161,166,168,174,176,182,184,190],{"type":36,"value":124},{"type":31,"tag":126,"props":162,"children":163},{},[164],{"type":36,"value":165},"Guided setup modal:",{"type":36,"value":167}," ",{"type":31,"tag":39,"props":169,"children":171},{"className":170},[],[172],{"type":36,"value":173},"IntegrationSetupModal.vue",{"type":36,"value":175}," — step rail with completion state, per-step instruction content, inline field collection, injected severity-routing step for channel-backed connectors (live local counts, defaults from the Alerts fallback map), generated Review & connect step (masked secrets, expectations, honesty note) gated on required fields. Saves via new ",{"type":31,"tag":39,"props":177,"children":179},{"className":178},[],[180],{"type":36,"value":181},"\u002Fapi\u002Fintegrations",{"type":36,"value":183}," + existing ",{"type":31,"tag":39,"props":185,"children":187},{"className":186},[],[188],{"type":36,"value":189},"\u002Fapi\u002Fchannels",{"type":36,"value":191}," in one action.",{"type":31,"tag":67,"props":193,"children":194},{},[195,196,201,202,208,210,216,218,224],{"type":36,"value":124},{"type":31,"tag":126,"props":197,"children":198},{},[199],{"type":36,"value":200},"Reuse on detail pages:",{"type":36,"value":167},{"type":31,"tag":39,"props":203,"children":205},{"className":204},[],[206],{"type":36,"value":207},"IntegrationSetupFields.vue",{"type":36,"value":209}," shared renderer; ",{"type":31,"tag":39,"props":211,"children":213},{"className":212},[],[214],{"type":36,"value":215},"[id].vue",{"type":36,"value":217}," replaces the disabled stub with the live form (Save \u002F Disconnect \u002F Reopen setup guide), unsaved-edit protection against the 3s poll re-seed. Channel-backed connectors keep the routing panel ",{"type":31,"tag":219,"props":220,"children":221},"em",{},[222],{"type":36,"value":223},"and",{"type":36,"value":225}," gain the config form.",{"type":31,"tag":67,"props":227,"children":228},{},[229,230,235,236,242,244,250,252,258,260,266],{"type":36,"value":124},{"type":31,"tag":126,"props":231,"children":232},{},[233],{"type":36,"value":234},"Persistence:",{"type":36,"value":167},{"type":31,"tag":39,"props":237,"children":239},{"className":238},[],[240],{"type":36,"value":241},"integration_configs",{"type":36,"value":243}," SQLite register mirroring ",{"type":31,"tag":39,"props":245,"children":247},{"className":246},[],[248],{"type":36,"value":249},"channels",{"type":36,"value":251},"; ",{"type":31,"tag":39,"props":253,"children":255},{"className":254},[],[256],{"type":36,"value":257},"GET\u002FPOST\u002FDELETE \u002Fapi\u002Fintegrations",{"type":36,"value":259}," (web.rs\u002Fdb.rs). Configured connectors flip to active stat cards on the overview (",{"type":31,"tag":39,"props":261,"children":263},{"className":262},[],[264],{"type":36,"value":265},"✓ configured",{"type":36,"value":267}," for non-channel connectors).",{"type":31,"tag":67,"props":269,"children":270},{},[271,272,277,279,285],{"type":36,"value":124},{"type":31,"tag":126,"props":273,"children":274},{},[275],{"type":36,"value":276},"Verified:",{"type":36,"value":278}," cargo check clean; API round-trip on a scratch db; Playwright walk-throughs of Splunk (4 steps), Slack (routing), Okta→Entra conditional branch, and Jira detail reuse — screenshots in ",{"type":31,"tag":39,"props":280,"children":282},{"className":281},[],[283],{"type":36,"value":284},"shots\u002F",{"type":36,"value":156},{"type":31,"tag":67,"props":287,"children":288},{},[289,290,295,297,303,305,311,313,319,321,327,329,335,337,343,345,350],{"type":36,"value":124},{"type":31,"tag":126,"props":291,"children":292},{},[293],{"type":36,"value":294},"Thread: message-preview",{"type":36,"value":296}," (",{"type":31,"tag":39,"props":298,"children":300},{"className":299},[],[301],{"type":36,"value":302},"message-preview-prompt.md",{"type":36,"value":304}," \u002F ",{"type":31,"tag":39,"props":306,"children":308},{"className":307},[],[309],{"type":36,"value":310},"message-preview-plan.md",{"type":36,"value":312},") — \"shape the message\" previews for the three notification connectors, each speaking its integration's native language: a Slack window (channel header, APP-badged bot, Block Kit severity bars; knobs for channel, bot name, pixel-pawn vs initials avatar, message detail, and throttling where \"per day\" visibly collapses the sample stream into one rollup), a PagerDuty incident card (urgency mapping, dedup key that rewrites live, auto-resolve toggle whose off-state shows the incident staying open), and an email digest in a mail frame (From\u002Fsubject-prefix\u002Fdelivery-time, live re-grouping by severity\u002Fframework\u002Fagent, headlines vs full detail). Canned sample narrative shared via ",{"type":31,"tag":39,"props":314,"children":316},{"className":315},[],[317],{"type":36,"value":318},"message-samples.ts",{"type":36,"value":320}," (high credential-leak \u002F medium egress \u002F resolution + digest counts). Architecture: knobs are ",{"type":31,"tag":39,"props":322,"children":324},{"className":323},[],[325],{"type":36,"value":326},"preview: true",{"type":36,"value":328}," SetupFields (seed\u002Fpersist\u002Freview\u002Fdirty-tracking ride the c72 machinery free), ",{"type":31,"tag":39,"props":330,"children":332},{"className":331},[],[333],{"type":36,"value":334},"SetupStep.component",{"type":36,"value":336}," + ",{"type":31,"tag":39,"props":338,"children":340},{"className":339},[],[341],{"type":36,"value":342},"integration-preview.ts",{"type":36,"value":344}," registry render the previews in the modal's shape step and as a \"Message shape\" panel on detail pages. Verified with Playwright knob-permutation shots in ",{"type":31,"tag":39,"props":346,"children":348},{"className":347},[],[349],{"type":36,"value":284},{"type":36,"value":156},[352],{"name":353,"prompt":302,"plan":310},"message-preview",[355,154],"initial-prompt.md",[],[],[],1789151081893]