[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-apache-gh-issue":3,"mdc--4eykzh-key":45,"related-org-apache-gh-issue":1733,"related-repo-apache-gh-issue":1892},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":40,"sourceUrl":43,"mdContent":44},"gh-issue","manage and audit BanyanDB issues","Size-audit, write, and split BanyanDB issues that somebody else or an automated TDD workflow can implement. Use whenever the user asks to file or revise an issue, decide whether an issue is too large, make an issue TDD-ready, turn a design into tickets, or split an umbrella into executable leaves. Do not draft or file an implementation issue before classifying it as a mergeable leaf or a tracking parent.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"apache","Apache Software Foundation","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fapache.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"GitHub","github","tag",{"name":17,"slug":18,"type":15},"Project Management","project-management",{"name":20,"slug":21,"type":15},"QA","qa",{"name":23,"slug":24,"type":15},"Engineering","engineering",344,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fskywalking-banyandb","2026-08-27T13:31:47.882107",null,114,[31,32,33,34,35,36,37,38,39],"apm","database","distributed-tracing","logging","metrics","monitoring","observability","skywalking","time-series",{"repoUrl":26,"stars":25,"forks":29,"topics":41,"description":42},[31,32,33,34,35,36,37,38,39],"An observability database aims to ingest, analyze and store Metrics, Tracing and Logging data.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fskywalking-banyandb\u002Ftree\u002FHEAD\u002Fskills\u002Fgh-issue","---\nname: gh-issue\ndescription: >-\n  Size-audit, write, and split BanyanDB issues that somebody else or an\n  automated TDD workflow can implement. Use whenever the user asks to file or\n  revise an issue, decide whether an issue is too large, make an issue\n  TDD-ready, turn a design into tickets, or split an umbrella into executable\n  leaves. Do not draft or file an implementation issue before classifying it as\n  a mergeable leaf or a tracking parent.\nallowed-tools: Bash, Read, Grep, Glob\n---\n\n# Writing a BanyanDB Issue\n\nBanyanDB's issues live in the **apache\u002Fskywalking** tracker, not in this\nrepository — `apache\u002Fskywalking-banyandb` has issues disabled. Label them\n`database`, which is the component label for BanyanDB.\n\nA good issue is one somebody can implement from **without asking you a\nquestion**. That is a higher bar than \"clear\", and it is the bar that decides\nwhether an issue sits untouched for a year.\n\n## Size the work before polishing the issue\n\nIssue length is not issue size. Inspect the design and the relevant production\ncode before drafting. Count independently testable behaviour, integration seams,\ncallers, format families, lifecycle domains, fixture work, and test suites. A\nshort issue that says \"replace the index\" can be much larger than a long issue\nthat fixes one query operation.\n\nAlways produce a short size audit during review, even if it will not appear in\nthe filed body:\n\n```markdown\n## Size audit\nClassification: executable leaf | tracking parent\nBoundary: \u003Cone seam, or the several seams that make this a parent>\nProduction activation: \u003Cthe caller switched by this merge>\nRED test: \u003Cthe command and the observable failure on current main>\nEnd to end: \u003Cthe real operation proved by the merge>\nFormat\u002Flifecycle scope: \u003Csections or algorithms; read\u002Fwrite\u002Fpublish\u002Fmerge\u002FGC\u002Fetc.>\nFixtures and oracle: \u003Cwho supplies expected values independently of the code under test>\nFocused suites: \u003Ccommands>\nDependencies present on main: yes | no — \u003Cevidence>\nDecision: \u003Cfits one run, or the exact split required>\n```\n\nDo not infer the answers only from the proposal. Use repository evidence such as\ninterfaces, call sites, packages, fixtures, and existing tests. Treat line count\nas supporting evidence, never as the sole sizing rule.\n\n### Executable leaf versus tracking parent\n\nAn **executable leaf** must satisfy all of these:\n\n- It exposes one agreed boundary and delivers one behaviour end to end.\n- The same merge switches at least one named production or CLI caller to it.\n- Every requirement has a RED test that fails on current `main` for a stated\n  reason and passes after the change.\n- One focused end-to-end scenario proves the real caller, not just an isolated\n  codec or helper.\n- Expected values and persisted bytes come from an independent oracle.\n- Its prerequisites and the seam it builds on are already merged to `main`.\n- A contract author can create the boundary and RED tests in one workflow turn,\n  and an implementer can reasonably complete the production change in the next.\n\nA **tracking parent** describes a milestone, replacement, or multi-PR outcome.\nIt owns completion criteria, the dependency graph, and links to children, but it\nis not itself an implementation contract. Mark it clearly as a tracking parent\nand do not put it in an automated implementation queue.\n\n### Mandatory split triggers\n\nClassify the issue as a parent or split it before filing when any of these is\ntrue:\n\n- It mixes lifecycle domains such as read, write, publish\u002Frecovery, merge\u002FGC, or\n  replication.\n- It introduces several independent public seams or several unrelated caller\n  cutovers.\n- It replaces a whole third-party subsystem rather than one observable operation.\n- No test can be named that fails on current `main` without asserting private\n  implementation details.\n- It needs the production implementation to generate its own expected fixture\n  bytes; that is a circular oracle, not a test contract.\n- A required boundary exists only in an open or planned PR. Keep the issue as a\n  parent and decompose it after the blocker merges.\n- It is foundation-only: the merge adds format readers, helpers, or abstractions\n  that no production\u002FCLI path uses.\n\nUse this score as a second check when none of the hard triggers is decisive:\n\n| add | signal |\n|---:|---|\n| +2 | each additional public boundary after the first |\n| +2 | each additional lifecycle domain after the first |\n| +1 | each additional production caller family |\n| +1 | each additional persisted format or algorithm family |\n| +1 | each additional independent fixture family |\n| +1 | each additional focused package test suite |\n| +2 | a prerequisite or seam is not yet on `main` |\n\nScore `0–2`: normally a leaf. Score `3–4`: split unless repository evidence\nshows it is still one small behaviour. Score `5+`: a tracking parent. A hard\ntrigger overrides the score.\n\nFor a TDD workflow, also cap a leaf at roughly four observable requirements,\none fixture family, one activation point, and one focused end-to-end scenario.\nThese are review budgets, not excuses to hide work by combining requirements.\n\n### RED-test feasibility catches false slices\n\nA compatibility-preserving cutover often returns the same result before and\nafter the change, so a new output assertion may pass against the legacy path and\nis not RED. State why the test fails before implementation. Absence of a new\nboundary can be a compile-time RED test, but acceptance must also prove that a\nreal caller uses the boundary; do not use brittle source-text assertions as the\nonly proof.\n\nIf a fixture is required, include its cost in the size audit. Persisted expected\nbytes should be generated by an independent legacy\u002Freference writer and checked\nin with provenance before the native code consumes them. Do not create a\nfixture-only or codec-only ticket when the project requires every merge to\nactivate production behaviour; put the smallest fixture and decoder beside the\nfirst real caller that uses them.\n\n## The body is the specification\n\nAssume the implementer has your issue and the codebase, and nothing else — no\ncontext from a design meeting, no follow-up in the comments. Comments are where\na specification goes to be missed; if a discussion changed the plan, edit the\nbody.\n\nFour things have to be derivable from it:\n\n**A boundary.** The seam the change exposes: a Go interface, the exported\nfunctions, the protobuf message, the HTTP surface. *\"Add an `Authorizer` that\ndecides whether a principal may perform an operation on a group\"* is a boundary.\n*\"Improve permissions\"* is not.\n\n**Expected values from an independent source.** State the concrete answers, not\njust the behaviour. A test whose expected value is derived the way the\nimplementation derives it passes by construction and can never disagree with the\ncode — so the issue is where the real answers come from. Write `a reader scoped\nto group \"ecommerce\" sees only that group`, not `scoping should work`.\n\n**Acceptance criteria provable by a command.** If a criterion is \"a research\ndocument\" or \"benchmark results\", nobody can tell whether it is met. Those are\nworth doing and belong in a proposal, not in an implementable issue.\n\n**Where it lives and how that area is tested.** Name the packages or workspace.\nIt saves the implementer a discovery pass and it scopes the suite they run:\n\n| area | tests |\n|---|---|\n| Go — `banyand\u002F`, `pkg\u002F` | `make test-ci PKG=.\u002Fbanyand\u002Ftrace .\u002Fpkg\u002Findex` |\n| Canopy — `canopy\u002F` | `npm run -w web test`, `npm run -w server test` |\n| Canopy end-to-end | `npx playwright test --config=e2e\u002Fplaywright.config.ts` |\n| everything, before pushing | `make generate && make build && make pre-push` |\n\n`make build` before `make pre-push`: `pre-push` runs `lint`, which typechecks\n`ui\u002F`, and `ui\u002F` embeds `dist` — which only exists after a build. A fresh clone\nfails otherwise, with `pattern dist: no matching files found`.\n\n## What a database issue owes that a service issue does not\n\nWeight the criteria by what fails silently and late. If the change touches any of\nthese, say so in the issue — the implementer should not have to infer it:\n\n- **Anything persisted or on the wire.** A segment, an index, a protobuf\n  message: existing data must still read, and a rolling upgrade must survive a\n  mixed-version cluster. State what an old reader does with new bytes and what a\n  new reader does with old ones. The project labels this class\n  `bydb file compatible change`.\n- **Durability and ordering.** For a flush, a WAL append, a compaction or a\n  snapshot: what is the state after a crash between any two steps?\n- **Concurrency.** Goroutine launches go through the panic-recovery wrappers\n  (`run.Go` \u002F `run.GoOrDie` \u002F `run.GoWithSignal`); a raw `go func(` needs an\n  explicit `\u002F\u002Fpanicdiag:allow-rawgo` directive and the lint baseline only ever\n  shrinks.\n- **Resource bounds.** An unbounded buffer, a query that materialises a whole\n  series, a retention path that cannot reclaim.\n\n## A shape that works\n\n```markdown\n## Summary\nOne paragraph: what this delivers and why.\n\n## Boundary\nThe seam this exposes — the interface, exported functions, or protobuf\u002FHTTP\nsurface. What callers may rely on, and what stays free to change.\n\n## Requirements\nR1. \u003Cobservable behaviour, with its concrete expected value>\nR2. ...\none per behaviour, each independently checkable.\n\n## Acceptance criteria\n- every requirement has a test that fails today and passes after\n- end-to-end: \u003Ca real use of the feature, start to finish>\n- \u003Ccompatibility \u002F durability \u002F concurrency criteria, where they apply>\n\n## Scope\nPackages: banyand\u002Ftrace, pkg\u002Findex — or canopy\u002Fweb.\nOut of scope: \u003Cthe neighbouring thing this is NOT>\n```\n\n## Breaking a design-ready issue into tickets\n\nWhen an issue carries a design and a proof of concept, it is usually several\npieces of work. Split it into **vertical slices** — each cutting a complete path\nthrough the layers it touches, each verifiable on its own — and file them as\n**sub-issues** of the base.\n\nA slice is the right size when it delivers one behaviour end to end and its\nacceptance criteria can be checked by running something. A slice that only makes\nsense alongside the next one is not a slice; it is half of one.\n\nDo not slice a storage replacement horizontally by format section (`container`,\n`postings`, `stored fields`) if those tickets would be unused foundations. Slice\nby **fixture complexity against one real caller** instead. A first read slice may\nactivate document count on a deliberately small fixture; a later slice can widen\nthat same caller to multiple segments and deletion masks; another caller can\nthen activate stored-field decoding. Each merge stays TDD-sized and live.\n\nDecompose just in time. Keep downstream design workstreams as tracking parents\nuntil their blocker lands. Then inspect the boundary that actually merged and\ncreate their executable leaves. Pre-filing speculative leaves commits to stale\nseams and recreates horizontal slicing at the issue layer.\n\n**Order them by dependency and say so.** Put `Blocked by: #NNNN` in the body of\nanything that needs an earlier ticket, and create them in that order so the\nnumbers ascend with the graph. **Do not start a blocked ticket before its blocker\nhas merged** — not merely opened a pull request. Until the merge, `main` does not\ncontain the seam the next ticket builds on.\n\n**A pure refactor is a poor ticket** if the project's convention is to land\nbehaviour with a failing test first: a change that alters no behaviour has no\ntest that fails today. Either land the refactor on its own as an explicit\ncleanup, or fold it into the first ticket that adds behaviour.\n\n**Wide, mechanical changes use expand–contract**, one ticket per phase:\n\n1. **Expand** — add the new form alongside the old.\n2. **Migrate** — move call sites in batches sized by blast radius.\n3. **Contract** — delete the old form once nothing uses it.\n\n### Filing them\n\nCreate each child, then attach it to the base by the child's **`id`**, which is\nnot its number:\n\n```bash\nurl=$(gh issue create --repo apache\u002Fskywalking \\\n        --title \"...\" --body-file .\u002Fticket-1.md --label database)\nn=${url##*\u002F}\nid=$(gh api repos\u002Fapache\u002Fskywalking\u002Fissues\u002F$n -q .id)\ngh api --method POST repos\u002Fapache\u002Fskywalking\u002Fissues\u002F\u003Cbase>\u002Fsub_issues -F sub_issue_id=$id\n```\n\n`-F`, not `-f`: the endpoint takes an integer, and `-f` sends the string form.\nCheck the result with:\n\n```bash\ngh api repos\u002Fapache\u002Fskywalking\u002Fissues\u002F\u003Cbase> -q .sub_issues_summary\n```\n\nThe base issue stays open as the umbrella, and `sub_issues_summary` is the\nprogress bar. Close it when the last ticket merges.\n\nIf automation selects the oldest issue with a queue label such as `Backlog`,\napply that label only to the oldest unblocked executable leaf. Never queue a\ntracking parent or all sibling leaves at once. Create children in dependency\norder so issue numbers reinforce rather than fight the execution order.\n\n## Before you file\n\n- Did you show the size audit and explicitly classify the issue as a leaf or a\n  tracking parent?\n- Could someone write a failing test from this body alone, without asking you\n  anything?\n- Does the test actually fail on current `main`, or would the legacy path already\n  satisfy it?\n- Does every expected value come from the issue rather than from what the code\n  would compute?\n- Is every acceptance criterion provable by running something?\n- Is it one boundary and one production activation, or a plan with phases?\n- Does this merge activate a real caller rather than land dead foundation code?\n- Are all prerequisite seams already merged to `main`?\n- If it touches stored or wire data, does it say what happens to existing data\n  and to a mixed-version cluster?\n",{"data":46,"body":48},{"name":4,"description":6,"allowed-tools":47},"Bash, Read, Grep, Glob",{"type":49,"children":50},"root",[51,60,90,102,109,114,119,239,244,251,263,318,330,336,341,386,391,511,540,545,551,556,561,567,572,577,610,635,645,655,772,837,843,848,937,943,1150,1156,1175,1180,1215,1220,1252,1262,1272,1306,1312,1328,1560,1585,1633,1646,1659,1665,1727],{"type":52,"tag":53,"props":54,"children":56},"element","h1",{"id":55},"writing-a-banyandb-issue",[57],{"type":58,"value":59},"text","Writing a BanyanDB Issue",{"type":52,"tag":61,"props":62,"children":63},"p",{},[64,66,72,74,81,83,88],{"type":58,"value":65},"BanyanDB's issues live in the ",{"type":52,"tag":67,"props":68,"children":69},"strong",{},[70],{"type":58,"value":71},"apache\u002Fskywalking",{"type":58,"value":73}," tracker, not in this\nrepository — ",{"type":52,"tag":75,"props":76,"children":78},"code",{"className":77},[],[79],{"type":58,"value":80},"apache\u002Fskywalking-banyandb",{"type":58,"value":82}," has issues disabled. Label them\n",{"type":52,"tag":75,"props":84,"children":86},{"className":85},[],[87],{"type":58,"value":32},{"type":58,"value":89},", which is the component label for BanyanDB.",{"type":52,"tag":61,"props":91,"children":92},{},[93,95,100],{"type":58,"value":94},"A good issue is one somebody can implement from ",{"type":52,"tag":67,"props":96,"children":97},{},[98],{"type":58,"value":99},"without asking you a\nquestion",{"type":58,"value":101},". That is a higher bar than \"clear\", and it is the bar that decides\nwhether an issue sits untouched for a year.",{"type":52,"tag":103,"props":104,"children":106},"h2",{"id":105},"size-the-work-before-polishing-the-issue",[107],{"type":58,"value":108},"Size the work before polishing the issue",{"type":52,"tag":61,"props":110,"children":111},{},[112],{"type":58,"value":113},"Issue length is not issue size. Inspect the design and the relevant production\ncode before drafting. Count independently testable behaviour, integration seams,\ncallers, format families, lifecycle domains, fixture work, and test suites. A\nshort issue that says \"replace the index\" can be much larger than a long issue\nthat fixes one query operation.",{"type":52,"tag":61,"props":115,"children":116},{},[117],{"type":58,"value":118},"Always produce a short size audit during review, even if it will not appear in\nthe filed body:",{"type":52,"tag":120,"props":121,"children":126},"pre",{"className":122,"code":123,"language":124,"meta":125,"style":125},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","## Size audit\nClassification: executable leaf | tracking parent\nBoundary: \u003Cone seam, or the several seams that make this a parent>\nProduction activation: \u003Cthe caller switched by this merge>\nRED test: \u003Cthe command and the observable failure on current main>\nEnd to end: \u003Cthe real operation proved by the merge>\nFormat\u002Flifecycle scope: \u003Csections or algorithms; read\u002Fwrite\u002Fpublish\u002Fmerge\u002FGC\u002Fetc.>\nFixtures and oracle: \u003Cwho supplies expected values independently of the code under test>\nFocused suites: \u003Ccommands>\nDependencies present on main: yes | no — \u003Cevidence>\nDecision: \u003Cfits one run, or the exact split required>\n","markdown","",[127],{"type":52,"tag":75,"props":128,"children":129},{"__ignoreMap":125},[130,148,158,167,176,185,194,203,212,221,230],{"type":52,"tag":131,"props":132,"children":135},"span",{"class":133,"line":134},"line",1,[136,142],{"type":52,"tag":131,"props":137,"children":139},{"style":138},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[140],{"type":58,"value":141},"## ",{"type":52,"tag":131,"props":143,"children":145},{"style":144},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[146],{"type":58,"value":147},"Size audit\n",{"type":52,"tag":131,"props":149,"children":151},{"class":133,"line":150},2,[152],{"type":52,"tag":131,"props":153,"children":155},{"style":154},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[156],{"type":58,"value":157},"Classification: executable leaf | tracking parent\n",{"type":52,"tag":131,"props":159,"children":161},{"class":133,"line":160},3,[162],{"type":52,"tag":131,"props":163,"children":164},{"style":154},[165],{"type":58,"value":166},"Boundary: \u003Cone seam, or the several seams that make this a parent>\n",{"type":52,"tag":131,"props":168,"children":170},{"class":133,"line":169},4,[171],{"type":52,"tag":131,"props":172,"children":173},{"style":154},[174],{"type":58,"value":175},"Production activation: \u003Cthe caller switched by this merge>\n",{"type":52,"tag":131,"props":177,"children":179},{"class":133,"line":178},5,[180],{"type":52,"tag":131,"props":181,"children":182},{"style":154},[183],{"type":58,"value":184},"RED test: \u003Cthe command and the observable failure on current main>\n",{"type":52,"tag":131,"props":186,"children":188},{"class":133,"line":187},6,[189],{"type":52,"tag":131,"props":190,"children":191},{"style":154},[192],{"type":58,"value":193},"End to end: \u003Cthe real operation proved by the merge>\n",{"type":52,"tag":131,"props":195,"children":197},{"class":133,"line":196},7,[198],{"type":52,"tag":131,"props":199,"children":200},{"style":154},[201],{"type":58,"value":202},"Format\u002Flifecycle scope: \u003Csections or algorithms; read\u002Fwrite\u002Fpublish\u002Fmerge\u002FGC\u002Fetc.>\n",{"type":52,"tag":131,"props":204,"children":206},{"class":133,"line":205},8,[207],{"type":52,"tag":131,"props":208,"children":209},{"style":154},[210],{"type":58,"value":211},"Fixtures and oracle: \u003Cwho supplies expected values independently of the code under test>\n",{"type":52,"tag":131,"props":213,"children":215},{"class":133,"line":214},9,[216],{"type":52,"tag":131,"props":217,"children":218},{"style":154},[219],{"type":58,"value":220},"Focused suites: \u003Ccommands>\n",{"type":52,"tag":131,"props":222,"children":224},{"class":133,"line":223},10,[225],{"type":52,"tag":131,"props":226,"children":227},{"style":154},[228],{"type":58,"value":229},"Dependencies present on main: yes | no — \u003Cevidence>\n",{"type":52,"tag":131,"props":231,"children":233},{"class":133,"line":232},11,[234],{"type":52,"tag":131,"props":235,"children":236},{"style":154},[237],{"type":58,"value":238},"Decision: \u003Cfits one run, or the exact split required>\n",{"type":52,"tag":61,"props":240,"children":241},{},[242],{"type":58,"value":243},"Do not infer the answers only from the proposal. Use repository evidence such as\ninterfaces, call sites, packages, fixtures, and existing tests. Treat line count\nas supporting evidence, never as the sole sizing rule.",{"type":52,"tag":245,"props":246,"children":248},"h3",{"id":247},"executable-leaf-versus-tracking-parent",[249],{"type":58,"value":250},"Executable leaf versus tracking parent",{"type":52,"tag":61,"props":252,"children":253},{},[254,256,261],{"type":58,"value":255},"An ",{"type":52,"tag":67,"props":257,"children":258},{},[259],{"type":58,"value":260},"executable leaf",{"type":58,"value":262}," must satisfy all of these:",{"type":52,"tag":264,"props":265,"children":266},"ul",{},[267,273,278,291,296,301,313],{"type":52,"tag":268,"props":269,"children":270},"li",{},[271],{"type":58,"value":272},"It exposes one agreed boundary and delivers one behaviour end to end.",{"type":52,"tag":268,"props":274,"children":275},{},[276],{"type":58,"value":277},"The same merge switches at least one named production or CLI caller to it.",{"type":52,"tag":268,"props":279,"children":280},{},[281,283,289],{"type":58,"value":282},"Every requirement has a RED test that fails on current ",{"type":52,"tag":75,"props":284,"children":286},{"className":285},[],[287],{"type":58,"value":288},"main",{"type":58,"value":290}," for a stated\nreason and passes after the change.",{"type":52,"tag":268,"props":292,"children":293},{},[294],{"type":58,"value":295},"One focused end-to-end scenario proves the real caller, not just an isolated\ncodec or helper.",{"type":52,"tag":268,"props":297,"children":298},{},[299],{"type":58,"value":300},"Expected values and persisted bytes come from an independent oracle.",{"type":52,"tag":268,"props":302,"children":303},{},[304,306,311],{"type":58,"value":305},"Its prerequisites and the seam it builds on are already merged to ",{"type":52,"tag":75,"props":307,"children":309},{"className":308},[],[310],{"type":58,"value":288},{"type":58,"value":312},".",{"type":52,"tag":268,"props":314,"children":315},{},[316],{"type":58,"value":317},"A contract author can create the boundary and RED tests in one workflow turn,\nand an implementer can reasonably complete the production change in the next.",{"type":52,"tag":61,"props":319,"children":320},{},[321,323,328],{"type":58,"value":322},"A ",{"type":52,"tag":67,"props":324,"children":325},{},[326],{"type":58,"value":327},"tracking parent",{"type":58,"value":329}," describes a milestone, replacement, or multi-PR outcome.\nIt owns completion criteria, the dependency graph, and links to children, but it\nis not itself an implementation contract. Mark it clearly as a tracking parent\nand do not put it in an automated implementation queue.",{"type":52,"tag":245,"props":331,"children":333},{"id":332},"mandatory-split-triggers",[334],{"type":58,"value":335},"Mandatory split triggers",{"type":52,"tag":61,"props":337,"children":338},{},[339],{"type":58,"value":340},"Classify the issue as a parent or split it before filing when any of these is\ntrue:",{"type":52,"tag":264,"props":342,"children":343},{},[344,349,354,359,371,376,381],{"type":52,"tag":268,"props":345,"children":346},{},[347],{"type":58,"value":348},"It mixes lifecycle domains such as read, write, publish\u002Frecovery, merge\u002FGC, or\nreplication.",{"type":52,"tag":268,"props":350,"children":351},{},[352],{"type":58,"value":353},"It introduces several independent public seams or several unrelated caller\ncutovers.",{"type":52,"tag":268,"props":355,"children":356},{},[357],{"type":58,"value":358},"It replaces a whole third-party subsystem rather than one observable operation.",{"type":52,"tag":268,"props":360,"children":361},{},[362,364,369],{"type":58,"value":363},"No test can be named that fails on current ",{"type":52,"tag":75,"props":365,"children":367},{"className":366},[],[368],{"type":58,"value":288},{"type":58,"value":370}," without asserting private\nimplementation details.",{"type":52,"tag":268,"props":372,"children":373},{},[374],{"type":58,"value":375},"It needs the production implementation to generate its own expected fixture\nbytes; that is a circular oracle, not a test contract.",{"type":52,"tag":268,"props":377,"children":378},{},[379],{"type":58,"value":380},"A required boundary exists only in an open or planned PR. Keep the issue as a\nparent and decompose it after the blocker merges.",{"type":52,"tag":268,"props":382,"children":383},{},[384],{"type":58,"value":385},"It is foundation-only: the merge adds format readers, helpers, or abstractions\nthat no production\u002FCLI path uses.",{"type":52,"tag":61,"props":387,"children":388},{},[389],{"type":58,"value":390},"Use this score as a second check when none of the hard triggers is decisive:",{"type":52,"tag":392,"props":393,"children":394},"table",{},[395,415],{"type":52,"tag":396,"props":397,"children":398},"thead",{},[399],{"type":52,"tag":400,"props":401,"children":402},"tr",{},[403,410],{"type":52,"tag":404,"props":405,"children":407},"th",{"align":406},"right",[408],{"type":58,"value":409},"add",{"type":52,"tag":404,"props":411,"children":412},{},[413],{"type":58,"value":414},"signal",{"type":52,"tag":416,"props":417,"children":418},"tbody",{},[419,433,445,458,470,482,494],{"type":52,"tag":400,"props":420,"children":421},{},[422,428],{"type":52,"tag":423,"props":424,"children":425},"td",{"align":406},[426],{"type":58,"value":427},"+2",{"type":52,"tag":423,"props":429,"children":430},{},[431],{"type":58,"value":432},"each additional public boundary after the first",{"type":52,"tag":400,"props":434,"children":435},{},[436,440],{"type":52,"tag":423,"props":437,"children":438},{"align":406},[439],{"type":58,"value":427},{"type":52,"tag":423,"props":441,"children":442},{},[443],{"type":58,"value":444},"each additional lifecycle domain after the first",{"type":52,"tag":400,"props":446,"children":447},{},[448,453],{"type":52,"tag":423,"props":449,"children":450},{"align":406},[451],{"type":58,"value":452},"+1",{"type":52,"tag":423,"props":454,"children":455},{},[456],{"type":58,"value":457},"each additional production caller family",{"type":52,"tag":400,"props":459,"children":460},{},[461,465],{"type":52,"tag":423,"props":462,"children":463},{"align":406},[464],{"type":58,"value":452},{"type":52,"tag":423,"props":466,"children":467},{},[468],{"type":58,"value":469},"each additional persisted format or algorithm family",{"type":52,"tag":400,"props":471,"children":472},{},[473,477],{"type":52,"tag":423,"props":474,"children":475},{"align":406},[476],{"type":58,"value":452},{"type":52,"tag":423,"props":478,"children":479},{},[480],{"type":58,"value":481},"each additional independent fixture family",{"type":52,"tag":400,"props":483,"children":484},{},[485,489],{"type":52,"tag":423,"props":486,"children":487},{"align":406},[488],{"type":58,"value":452},{"type":52,"tag":423,"props":490,"children":491},{},[492],{"type":58,"value":493},"each additional focused package test suite",{"type":52,"tag":400,"props":495,"children":496},{},[497,501],{"type":52,"tag":423,"props":498,"children":499},{"align":406},[500],{"type":58,"value":427},{"type":52,"tag":423,"props":502,"children":503},{},[504,506],{"type":58,"value":505},"a prerequisite or seam is not yet on ",{"type":52,"tag":75,"props":507,"children":509},{"className":508},[],[510],{"type":58,"value":288},{"type":52,"tag":61,"props":512,"children":513},{},[514,516,522,524,530,532,538],{"type":58,"value":515},"Score ",{"type":52,"tag":75,"props":517,"children":519},{"className":518},[],[520],{"type":58,"value":521},"0–2",{"type":58,"value":523},": normally a leaf. Score ",{"type":52,"tag":75,"props":525,"children":527},{"className":526},[],[528],{"type":58,"value":529},"3–4",{"type":58,"value":531},": split unless repository evidence\nshows it is still one small behaviour. Score ",{"type":52,"tag":75,"props":533,"children":535},{"className":534},[],[536],{"type":58,"value":537},"5+",{"type":58,"value":539},": a tracking parent. A hard\ntrigger overrides the score.",{"type":52,"tag":61,"props":541,"children":542},{},[543],{"type":58,"value":544},"For a TDD workflow, also cap a leaf at roughly four observable requirements,\none fixture family, one activation point, and one focused end-to-end scenario.\nThese are review budgets, not excuses to hide work by combining requirements.",{"type":52,"tag":245,"props":546,"children":548},{"id":547},"red-test-feasibility-catches-false-slices",[549],{"type":58,"value":550},"RED-test feasibility catches false slices",{"type":52,"tag":61,"props":552,"children":553},{},[554],{"type":58,"value":555},"A compatibility-preserving cutover often returns the same result before and\nafter the change, so a new output assertion may pass against the legacy path and\nis not RED. State why the test fails before implementation. Absence of a new\nboundary can be a compile-time RED test, but acceptance must also prove that a\nreal caller uses the boundary; do not use brittle source-text assertions as the\nonly proof.",{"type":52,"tag":61,"props":557,"children":558},{},[559],{"type":58,"value":560},"If a fixture is required, include its cost in the size audit. Persisted expected\nbytes should be generated by an independent legacy\u002Freference writer and checked\nin with provenance before the native code consumes them. Do not create a\nfixture-only or codec-only ticket when the project requires every merge to\nactivate production behaviour; put the smallest fixture and decoder beside the\nfirst real caller that uses them.",{"type":52,"tag":103,"props":562,"children":564},{"id":563},"the-body-is-the-specification",[565],{"type":58,"value":566},"The body is the specification",{"type":52,"tag":61,"props":568,"children":569},{},[570],{"type":58,"value":571},"Assume the implementer has your issue and the codebase, and nothing else — no\ncontext from a design meeting, no follow-up in the comments. Comments are where\na specification goes to be missed; if a discussion changed the plan, edit the\nbody.",{"type":52,"tag":61,"props":573,"children":574},{},[575],{"type":58,"value":576},"Four things have to be derivable from it:",{"type":52,"tag":61,"props":578,"children":579},{},[580,585,587,601,603,608],{"type":52,"tag":67,"props":581,"children":582},{},[583],{"type":58,"value":584},"A boundary.",{"type":58,"value":586}," The seam the change exposes: a Go interface, the exported\nfunctions, the protobuf message, the HTTP surface. ",{"type":52,"tag":588,"props":589,"children":590},"em",{},[591,593,599],{"type":58,"value":592},"\"Add an ",{"type":52,"tag":75,"props":594,"children":596},{"className":595},[],[597],{"type":58,"value":598},"Authorizer",{"type":58,"value":600}," that\ndecides whether a principal may perform an operation on a group\"",{"type":58,"value":602}," is a boundary.\n",{"type":52,"tag":588,"props":604,"children":605},{},[606],{"type":58,"value":607},"\"Improve permissions\"",{"type":58,"value":609}," is not.",{"type":52,"tag":61,"props":611,"children":612},{},[613,618,620,626,628,634],{"type":52,"tag":67,"props":614,"children":615},{},[616],{"type":58,"value":617},"Expected values from an independent source.",{"type":58,"value":619}," State the concrete answers, not\njust the behaviour. A test whose expected value is derived the way the\nimplementation derives it passes by construction and can never disagree with the\ncode — so the issue is where the real answers come from. Write ",{"type":52,"tag":75,"props":621,"children":623},{"className":622},[],[624],{"type":58,"value":625},"a reader scoped to group \"ecommerce\" sees only that group",{"type":58,"value":627},", not ",{"type":52,"tag":75,"props":629,"children":631},{"className":630},[],[632],{"type":58,"value":633},"scoping should work",{"type":58,"value":312},{"type":52,"tag":61,"props":636,"children":637},{},[638,643],{"type":52,"tag":67,"props":639,"children":640},{},[641],{"type":58,"value":642},"Acceptance criteria provable by a command.",{"type":58,"value":644}," If a criterion is \"a research\ndocument\" or \"benchmark results\", nobody can tell whether it is met. Those are\nworth doing and belong in a proposal, not in an implementable issue.",{"type":52,"tag":61,"props":646,"children":647},{},[648,653],{"type":52,"tag":67,"props":649,"children":650},{},[651],{"type":58,"value":652},"Where it lives and how that area is tested.",{"type":58,"value":654}," Name the packages or workspace.\nIt saves the implementer a discovery pass and it scopes the suite they run:",{"type":52,"tag":392,"props":656,"children":657},{},[658,674],{"type":52,"tag":396,"props":659,"children":660},{},[661],{"type":52,"tag":400,"props":662,"children":663},{},[664,669],{"type":52,"tag":404,"props":665,"children":666},{},[667],{"type":58,"value":668},"area",{"type":52,"tag":404,"props":670,"children":671},{},[672],{"type":58,"value":673},"tests",{"type":52,"tag":416,"props":675,"children":676},{},[677,708,738,755],{"type":52,"tag":400,"props":678,"children":679},{},[680,699],{"type":52,"tag":423,"props":681,"children":682},{},[683,685,691,693],{"type":58,"value":684},"Go — ",{"type":52,"tag":75,"props":686,"children":688},{"className":687},[],[689],{"type":58,"value":690},"banyand\u002F",{"type":58,"value":692},", ",{"type":52,"tag":75,"props":694,"children":696},{"className":695},[],[697],{"type":58,"value":698},"pkg\u002F",{"type":52,"tag":423,"props":700,"children":701},{},[702],{"type":52,"tag":75,"props":703,"children":705},{"className":704},[],[706],{"type":58,"value":707},"make test-ci PKG=.\u002Fbanyand\u002Ftrace .\u002Fpkg\u002Findex",{"type":52,"tag":400,"props":709,"children":710},{},[711,722],{"type":52,"tag":423,"props":712,"children":713},{},[714,716],{"type":58,"value":715},"Canopy — ",{"type":52,"tag":75,"props":717,"children":719},{"className":718},[],[720],{"type":58,"value":721},"canopy\u002F",{"type":52,"tag":423,"props":723,"children":724},{},[725,731,732],{"type":52,"tag":75,"props":726,"children":728},{"className":727},[],[729],{"type":58,"value":730},"npm run -w web test",{"type":58,"value":692},{"type":52,"tag":75,"props":733,"children":735},{"className":734},[],[736],{"type":58,"value":737},"npm run -w server test",{"type":52,"tag":400,"props":739,"children":740},{},[741,746],{"type":52,"tag":423,"props":742,"children":743},{},[744],{"type":58,"value":745},"Canopy end-to-end",{"type":52,"tag":423,"props":747,"children":748},{},[749],{"type":52,"tag":75,"props":750,"children":752},{"className":751},[],[753],{"type":58,"value":754},"npx playwright test --config=e2e\u002Fplaywright.config.ts",{"type":52,"tag":400,"props":756,"children":757},{},[758,763],{"type":52,"tag":423,"props":759,"children":760},{},[761],{"type":58,"value":762},"everything, before pushing",{"type":52,"tag":423,"props":764,"children":765},{},[766],{"type":52,"tag":75,"props":767,"children":769},{"className":768},[],[770],{"type":58,"value":771},"make generate && make build && make pre-push",{"type":52,"tag":61,"props":773,"children":774},{},[775,781,783,789,791,797,799,805,807,813,815,820,822,828,830,836],{"type":52,"tag":75,"props":776,"children":778},{"className":777},[],[779],{"type":58,"value":780},"make build",{"type":58,"value":782}," before ",{"type":52,"tag":75,"props":784,"children":786},{"className":785},[],[787],{"type":58,"value":788},"make pre-push",{"type":58,"value":790},": ",{"type":52,"tag":75,"props":792,"children":794},{"className":793},[],[795],{"type":58,"value":796},"pre-push",{"type":58,"value":798}," runs ",{"type":52,"tag":75,"props":800,"children":802},{"className":801},[],[803],{"type":58,"value":804},"lint",{"type":58,"value":806},", which typechecks\n",{"type":52,"tag":75,"props":808,"children":810},{"className":809},[],[811],{"type":58,"value":812},"ui\u002F",{"type":58,"value":814},", and ",{"type":52,"tag":75,"props":816,"children":818},{"className":817},[],[819],{"type":58,"value":812},{"type":58,"value":821}," embeds ",{"type":52,"tag":75,"props":823,"children":825},{"className":824},[],[826],{"type":58,"value":827},"dist",{"type":58,"value":829}," — which only exists after a build. A fresh clone\nfails otherwise, with ",{"type":52,"tag":75,"props":831,"children":833},{"className":832},[],[834],{"type":58,"value":835},"pattern dist: no matching files found",{"type":58,"value":312},{"type":52,"tag":103,"props":838,"children":840},{"id":839},"what-a-database-issue-owes-that-a-service-issue-does-not",[841],{"type":58,"value":842},"What a database issue owes that a service issue does not",{"type":52,"tag":61,"props":844,"children":845},{},[846],{"type":58,"value":847},"Weight the criteria by what fails silently and late. If the change touches any of\nthese, say so in the issue — the implementer should not have to infer it:",{"type":52,"tag":264,"props":849,"children":850},{},[851,868,878,927],{"type":52,"tag":268,"props":852,"children":853},{},[854,859,861,867],{"type":52,"tag":67,"props":855,"children":856},{},[857],{"type":58,"value":858},"Anything persisted or on the wire.",{"type":58,"value":860}," A segment, an index, a protobuf\nmessage: existing data must still read, and a rolling upgrade must survive a\nmixed-version cluster. State what an old reader does with new bytes and what a\nnew reader does with old ones. The project labels this class\n",{"type":52,"tag":75,"props":862,"children":864},{"className":863},[],[865],{"type":58,"value":866},"bydb file compatible change",{"type":58,"value":312},{"type":52,"tag":268,"props":869,"children":870},{},[871,876],{"type":52,"tag":67,"props":872,"children":873},{},[874],{"type":58,"value":875},"Durability and ordering.",{"type":58,"value":877}," For a flush, a WAL append, a compaction or a\nsnapshot: what is the state after a crash between any two steps?",{"type":52,"tag":268,"props":879,"children":880},{},[881,886,888,894,896,902,903,909,911,917,919,925],{"type":52,"tag":67,"props":882,"children":883},{},[884],{"type":58,"value":885},"Concurrency.",{"type":58,"value":887}," Goroutine launches go through the panic-recovery wrappers\n(",{"type":52,"tag":75,"props":889,"children":891},{"className":890},[],[892],{"type":58,"value":893},"run.Go",{"type":58,"value":895}," \u002F ",{"type":52,"tag":75,"props":897,"children":899},{"className":898},[],[900],{"type":58,"value":901},"run.GoOrDie",{"type":58,"value":895},{"type":52,"tag":75,"props":904,"children":906},{"className":905},[],[907],{"type":58,"value":908},"run.GoWithSignal",{"type":58,"value":910},"); a raw ",{"type":52,"tag":75,"props":912,"children":914},{"className":913},[],[915],{"type":58,"value":916},"go func(",{"type":58,"value":918}," needs an\nexplicit ",{"type":52,"tag":75,"props":920,"children":922},{"className":921},[],[923],{"type":58,"value":924},"\u002F\u002Fpanicdiag:allow-rawgo",{"type":58,"value":926}," directive and the lint baseline only ever\nshrinks.",{"type":52,"tag":268,"props":928,"children":929},{},[930,935],{"type":52,"tag":67,"props":931,"children":932},{},[933],{"type":58,"value":934},"Resource bounds.",{"type":58,"value":936}," An unbounded buffer, a query that materialises a whole\nseries, a retention path that cannot reclaim.",{"type":52,"tag":103,"props":938,"children":940},{"id":939},"a-shape-that-works",[941],{"type":58,"value":942},"A shape that works",{"type":52,"tag":120,"props":944,"children":946},{"className":122,"code":945,"language":124,"meta":125,"style":125},"## Summary\nOne paragraph: what this delivers and why.\n\n## Boundary\nThe seam this exposes — the interface, exported functions, or protobuf\u002FHTTP\nsurface. What callers may rely on, and what stays free to change.\n\n## Requirements\nR1. \u003Cobservable behaviour, with its concrete expected value>\nR2. ...\none per behaviour, each independently checkable.\n\n## Acceptance criteria\n- every requirement has a test that fails today and passes after\n- end-to-end: \u003Ca real use of the feature, start to finish>\n- \u003Ccompatibility \u002F durability \u002F concurrency criteria, where they apply>\n\n## Scope\nPackages: banyand\u002Ftrace, pkg\u002Findex — or canopy\u002Fweb.\nOut of scope: \u003Cthe neighbouring thing this is NOT>\n",[947],{"type":52,"tag":75,"props":948,"children":949},{"__ignoreMap":125},[950,962,970,979,991,999,1007,1014,1026,1034,1042,1050,1058,1071,1085,1098,1111,1119,1132,1141],{"type":52,"tag":131,"props":951,"children":952},{"class":133,"line":134},[953,957],{"type":52,"tag":131,"props":954,"children":955},{"style":138},[956],{"type":58,"value":141},{"type":52,"tag":131,"props":958,"children":959},{"style":144},[960],{"type":58,"value":961},"Summary\n",{"type":52,"tag":131,"props":963,"children":964},{"class":133,"line":150},[965],{"type":52,"tag":131,"props":966,"children":967},{"style":154},[968],{"type":58,"value":969},"One paragraph: what this delivers and why.\n",{"type":52,"tag":131,"props":971,"children":972},{"class":133,"line":160},[973],{"type":52,"tag":131,"props":974,"children":976},{"emptyLinePlaceholder":975},true,[977],{"type":58,"value":978},"\n",{"type":52,"tag":131,"props":980,"children":981},{"class":133,"line":169},[982,986],{"type":52,"tag":131,"props":983,"children":984},{"style":138},[985],{"type":58,"value":141},{"type":52,"tag":131,"props":987,"children":988},{"style":144},[989],{"type":58,"value":990},"Boundary\n",{"type":52,"tag":131,"props":992,"children":993},{"class":133,"line":178},[994],{"type":52,"tag":131,"props":995,"children":996},{"style":154},[997],{"type":58,"value":998},"The seam this exposes — the interface, exported functions, or protobuf\u002FHTTP\n",{"type":52,"tag":131,"props":1000,"children":1001},{"class":133,"line":187},[1002],{"type":52,"tag":131,"props":1003,"children":1004},{"style":154},[1005],{"type":58,"value":1006},"surface. What callers may rely on, and what stays free to change.\n",{"type":52,"tag":131,"props":1008,"children":1009},{"class":133,"line":196},[1010],{"type":52,"tag":131,"props":1011,"children":1012},{"emptyLinePlaceholder":975},[1013],{"type":58,"value":978},{"type":52,"tag":131,"props":1015,"children":1016},{"class":133,"line":205},[1017,1021],{"type":52,"tag":131,"props":1018,"children":1019},{"style":138},[1020],{"type":58,"value":141},{"type":52,"tag":131,"props":1022,"children":1023},{"style":144},[1024],{"type":58,"value":1025},"Requirements\n",{"type":52,"tag":131,"props":1027,"children":1028},{"class":133,"line":214},[1029],{"type":52,"tag":131,"props":1030,"children":1031},{"style":154},[1032],{"type":58,"value":1033},"R1. \u003Cobservable behaviour, with its concrete expected value>\n",{"type":52,"tag":131,"props":1035,"children":1036},{"class":133,"line":223},[1037],{"type":52,"tag":131,"props":1038,"children":1039},{"style":154},[1040],{"type":58,"value":1041},"R2. ...\n",{"type":52,"tag":131,"props":1043,"children":1044},{"class":133,"line":232},[1045],{"type":52,"tag":131,"props":1046,"children":1047},{"style":154},[1048],{"type":58,"value":1049},"one per behaviour, each independently checkable.\n",{"type":52,"tag":131,"props":1051,"children":1053},{"class":133,"line":1052},12,[1054],{"type":52,"tag":131,"props":1055,"children":1056},{"emptyLinePlaceholder":975},[1057],{"type":58,"value":978},{"type":52,"tag":131,"props":1059,"children":1061},{"class":133,"line":1060},13,[1062,1066],{"type":52,"tag":131,"props":1063,"children":1064},{"style":138},[1065],{"type":58,"value":141},{"type":52,"tag":131,"props":1067,"children":1068},{"style":144},[1069],{"type":58,"value":1070},"Acceptance criteria\n",{"type":52,"tag":131,"props":1072,"children":1074},{"class":133,"line":1073},14,[1075,1080],{"type":52,"tag":131,"props":1076,"children":1077},{"style":138},[1078],{"type":58,"value":1079},"-",{"type":52,"tag":131,"props":1081,"children":1082},{"style":154},[1083],{"type":58,"value":1084}," every requirement has a test that fails today and passes after\n",{"type":52,"tag":131,"props":1086,"children":1088},{"class":133,"line":1087},15,[1089,1093],{"type":52,"tag":131,"props":1090,"children":1091},{"style":138},[1092],{"type":58,"value":1079},{"type":52,"tag":131,"props":1094,"children":1095},{"style":154},[1096],{"type":58,"value":1097}," end-to-end: \u003Ca real use of the feature, start to finish>\n",{"type":52,"tag":131,"props":1099,"children":1101},{"class":133,"line":1100},16,[1102,1106],{"type":52,"tag":131,"props":1103,"children":1104},{"style":138},[1105],{"type":58,"value":1079},{"type":52,"tag":131,"props":1107,"children":1108},{"style":154},[1109],{"type":58,"value":1110}," \u003Ccompatibility \u002F durability \u002F concurrency criteria, where they apply>\n",{"type":52,"tag":131,"props":1112,"children":1114},{"class":133,"line":1113},17,[1115],{"type":52,"tag":131,"props":1116,"children":1117},{"emptyLinePlaceholder":975},[1118],{"type":58,"value":978},{"type":52,"tag":131,"props":1120,"children":1122},{"class":133,"line":1121},18,[1123,1127],{"type":52,"tag":131,"props":1124,"children":1125},{"style":138},[1126],{"type":58,"value":141},{"type":52,"tag":131,"props":1128,"children":1129},{"style":144},[1130],{"type":58,"value":1131},"Scope\n",{"type":52,"tag":131,"props":1133,"children":1135},{"class":133,"line":1134},19,[1136],{"type":52,"tag":131,"props":1137,"children":1138},{"style":154},[1139],{"type":58,"value":1140},"Packages: banyand\u002Ftrace, pkg\u002Findex — or canopy\u002Fweb.\n",{"type":52,"tag":131,"props":1142,"children":1144},{"class":133,"line":1143},20,[1145],{"type":52,"tag":131,"props":1146,"children":1147},{"style":154},[1148],{"type":58,"value":1149},"Out of scope: \u003Cthe neighbouring thing this is NOT>\n",{"type":52,"tag":103,"props":1151,"children":1153},{"id":1152},"breaking-a-design-ready-issue-into-tickets",[1154],{"type":58,"value":1155},"Breaking a design-ready issue into tickets",{"type":52,"tag":61,"props":1157,"children":1158},{},[1159,1161,1166,1168,1173],{"type":58,"value":1160},"When an issue carries a design and a proof of concept, it is usually several\npieces of work. Split it into ",{"type":52,"tag":67,"props":1162,"children":1163},{},[1164],{"type":58,"value":1165},"vertical slices",{"type":58,"value":1167}," — each cutting a complete path\nthrough the layers it touches, each verifiable on its own — and file them as\n",{"type":52,"tag":67,"props":1169,"children":1170},{},[1171],{"type":58,"value":1172},"sub-issues",{"type":58,"value":1174}," of the base.",{"type":52,"tag":61,"props":1176,"children":1177},{},[1178],{"type":58,"value":1179},"A slice is the right size when it delivers one behaviour end to end and its\nacceptance criteria can be checked by running something. A slice that only makes\nsense alongside the next one is not a slice; it is half of one.",{"type":52,"tag":61,"props":1181,"children":1182},{},[1183,1185,1191,1193,1199,1200,1206,1208,1213],{"type":58,"value":1184},"Do not slice a storage replacement horizontally by format section (",{"type":52,"tag":75,"props":1186,"children":1188},{"className":1187},[],[1189],{"type":58,"value":1190},"container",{"type":58,"value":1192},",\n",{"type":52,"tag":75,"props":1194,"children":1196},{"className":1195},[],[1197],{"type":58,"value":1198},"postings",{"type":58,"value":692},{"type":52,"tag":75,"props":1201,"children":1203},{"className":1202},[],[1204],{"type":58,"value":1205},"stored fields",{"type":58,"value":1207},") if those tickets would be unused foundations. Slice\nby ",{"type":52,"tag":67,"props":1209,"children":1210},{},[1211],{"type":58,"value":1212},"fixture complexity against one real caller",{"type":58,"value":1214}," instead. A first read slice may\nactivate document count on a deliberately small fixture; a later slice can widen\nthat same caller to multiple segments and deletion masks; another caller can\nthen activate stored-field decoding. Each merge stays TDD-sized and live.",{"type":52,"tag":61,"props":1216,"children":1217},{},[1218],{"type":58,"value":1219},"Decompose just in time. Keep downstream design workstreams as tracking parents\nuntil their blocker lands. Then inspect the boundary that actually merged and\ncreate their executable leaves. Pre-filing speculative leaves commits to stale\nseams and recreates horizontal slicing at the issue layer.",{"type":52,"tag":61,"props":1221,"children":1222},{},[1223,1228,1230,1236,1238,1243,1245,1250],{"type":52,"tag":67,"props":1224,"children":1225},{},[1226],{"type":58,"value":1227},"Order them by dependency and say so.",{"type":58,"value":1229}," Put ",{"type":52,"tag":75,"props":1231,"children":1233},{"className":1232},[],[1234],{"type":58,"value":1235},"Blocked by: #NNNN",{"type":58,"value":1237}," in the body of\nanything that needs an earlier ticket, and create them in that order so the\nnumbers ascend with the graph. ",{"type":52,"tag":67,"props":1239,"children":1240},{},[1241],{"type":58,"value":1242},"Do not start a blocked ticket before its blocker\nhas merged",{"type":58,"value":1244}," — not merely opened a pull request. Until the merge, ",{"type":52,"tag":75,"props":1246,"children":1248},{"className":1247},[],[1249],{"type":58,"value":288},{"type":58,"value":1251}," does not\ncontain the seam the next ticket builds on.",{"type":52,"tag":61,"props":1253,"children":1254},{},[1255,1260],{"type":52,"tag":67,"props":1256,"children":1257},{},[1258],{"type":58,"value":1259},"A pure refactor is a poor ticket",{"type":58,"value":1261}," if the project's convention is to land\nbehaviour with a failing test first: a change that alters no behaviour has no\ntest that fails today. Either land the refactor on its own as an explicit\ncleanup, or fold it into the first ticket that adds behaviour.",{"type":52,"tag":61,"props":1263,"children":1264},{},[1265,1270],{"type":52,"tag":67,"props":1266,"children":1267},{},[1268],{"type":58,"value":1269},"Wide, mechanical changes use expand–contract",{"type":58,"value":1271},", one ticket per phase:",{"type":52,"tag":1273,"props":1274,"children":1275},"ol",{},[1276,1286,1296],{"type":52,"tag":268,"props":1277,"children":1278},{},[1279,1284],{"type":52,"tag":67,"props":1280,"children":1281},{},[1282],{"type":58,"value":1283},"Expand",{"type":58,"value":1285}," — add the new form alongside the old.",{"type":52,"tag":268,"props":1287,"children":1288},{},[1289,1294],{"type":52,"tag":67,"props":1290,"children":1291},{},[1292],{"type":58,"value":1293},"Migrate",{"type":58,"value":1295}," — move call sites in batches sized by blast radius.",{"type":52,"tag":268,"props":1297,"children":1298},{},[1299,1304],{"type":52,"tag":67,"props":1300,"children":1301},{},[1302],{"type":58,"value":1303},"Contract",{"type":58,"value":1305}," — delete the old form once nothing uses it.",{"type":52,"tag":245,"props":1307,"children":1309},{"id":1308},"filing-them",[1310],{"type":58,"value":1311},"Filing them",{"type":52,"tag":61,"props":1313,"children":1314},{},[1315,1317,1326],{"type":58,"value":1316},"Create each child, then attach it to the base by the child's ",{"type":52,"tag":67,"props":1318,"children":1319},{},[1320],{"type":52,"tag":75,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":58,"value":1325},"id",{"type":58,"value":1327},", which is\nnot its number:",{"type":52,"tag":120,"props":1329,"children":1333},{"className":1330,"code":1331,"language":1332,"meta":125,"style":125},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","url=$(gh issue create --repo apache\u002Fskywalking \\\n        --title \"...\" --body-file .\u002Fticket-1.md --label database)\nn=${url##*\u002F}\nid=$(gh api repos\u002Fapache\u002Fskywalking\u002Fissues\u002F$n -q .id)\ngh api --method POST repos\u002Fapache\u002Fskywalking\u002Fissues\u002F\u003Cbase>\u002Fsub_issues -F sub_issue_id=$id\n","bash",[1334],{"type":52,"tag":75,"props":1335,"children":1336},{"__ignoreMap":125},[1337,1381,1429,1451,1495],{"type":52,"tag":131,"props":1338,"children":1339},{"class":133,"line":134},[1340,1345,1350,1355,1361,1366,1371,1376],{"type":52,"tag":131,"props":1341,"children":1342},{"style":154},[1343],{"type":58,"value":1344},"url",{"type":52,"tag":131,"props":1346,"children":1347},{"style":138},[1348],{"type":58,"value":1349},"=$(",{"type":52,"tag":131,"props":1351,"children":1352},{"style":144},[1353],{"type":58,"value":1354},"gh",{"type":52,"tag":131,"props":1356,"children":1358},{"style":1357},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1359],{"type":58,"value":1360}," issue",{"type":52,"tag":131,"props":1362,"children":1363},{"style":1357},[1364],{"type":58,"value":1365}," create",{"type":52,"tag":131,"props":1367,"children":1368},{"style":1357},[1369],{"type":58,"value":1370}," --repo",{"type":52,"tag":131,"props":1372,"children":1373},{"style":1357},[1374],{"type":58,"value":1375}," apache\u002Fskywalking",{"type":52,"tag":131,"props":1377,"children":1378},{"style":154},[1379],{"type":58,"value":1380}," \\\n",{"type":52,"tag":131,"props":1382,"children":1383},{"class":133,"line":150},[1384,1389,1394,1399,1404,1409,1414,1419,1424],{"type":52,"tag":131,"props":1385,"children":1386},{"style":1357},[1387],{"type":58,"value":1388},"        --title",{"type":52,"tag":131,"props":1390,"children":1391},{"style":138},[1392],{"type":58,"value":1393}," \"",{"type":52,"tag":131,"props":1395,"children":1396},{"style":1357},[1397],{"type":58,"value":1398},"...",{"type":52,"tag":131,"props":1400,"children":1401},{"style":138},[1402],{"type":58,"value":1403},"\"",{"type":52,"tag":131,"props":1405,"children":1406},{"style":1357},[1407],{"type":58,"value":1408}," --body-file",{"type":52,"tag":131,"props":1410,"children":1411},{"style":1357},[1412],{"type":58,"value":1413}," .\u002Fticket-1.md",{"type":52,"tag":131,"props":1415,"children":1416},{"style":1357},[1417],{"type":58,"value":1418}," --label",{"type":52,"tag":131,"props":1420,"children":1421},{"style":1357},[1422],{"type":58,"value":1423}," database",{"type":52,"tag":131,"props":1425,"children":1426},{"style":138},[1427],{"type":58,"value":1428},")\n",{"type":52,"tag":131,"props":1430,"children":1431},{"class":133,"line":160},[1432,1437,1442,1446],{"type":52,"tag":131,"props":1433,"children":1434},{"style":154},[1435],{"type":58,"value":1436},"n",{"type":52,"tag":131,"props":1438,"children":1439},{"style":138},[1440],{"type":58,"value":1441},"=${",{"type":52,"tag":131,"props":1443,"children":1444},{"style":154},[1445],{"type":58,"value":1344},{"type":52,"tag":131,"props":1447,"children":1448},{"style":138},[1449],{"type":58,"value":1450},"##*\u002F}\n",{"type":52,"tag":131,"props":1452,"children":1453},{"class":133,"line":169},[1454,1458,1462,1466,1471,1476,1481,1486,1491],{"type":52,"tag":131,"props":1455,"children":1456},{"style":154},[1457],{"type":58,"value":1325},{"type":52,"tag":131,"props":1459,"children":1460},{"style":138},[1461],{"type":58,"value":1349},{"type":52,"tag":131,"props":1463,"children":1464},{"style":144},[1465],{"type":58,"value":1354},{"type":52,"tag":131,"props":1467,"children":1468},{"style":1357},[1469],{"type":58,"value":1470}," api",{"type":52,"tag":131,"props":1472,"children":1473},{"style":1357},[1474],{"type":58,"value":1475}," repos\u002Fapache\u002Fskywalking\u002Fissues\u002F",{"type":52,"tag":131,"props":1477,"children":1478},{"style":154},[1479],{"type":58,"value":1480},"$n ",{"type":52,"tag":131,"props":1482,"children":1483},{"style":1357},[1484],{"type":58,"value":1485},"-q",{"type":52,"tag":131,"props":1487,"children":1488},{"style":1357},[1489],{"type":58,"value":1490}," .id",{"type":52,"tag":131,"props":1492,"children":1493},{"style":138},[1494],{"type":58,"value":1428},{"type":52,"tag":131,"props":1496,"children":1497},{"class":133,"line":178},[1498,1502,1506,1511,1516,1520,1525,1530,1535,1540,1545,1550,1555],{"type":52,"tag":131,"props":1499,"children":1500},{"style":144},[1501],{"type":58,"value":1354},{"type":52,"tag":131,"props":1503,"children":1504},{"style":1357},[1505],{"type":58,"value":1470},{"type":52,"tag":131,"props":1507,"children":1508},{"style":1357},[1509],{"type":58,"value":1510}," --method",{"type":52,"tag":131,"props":1512,"children":1513},{"style":1357},[1514],{"type":58,"value":1515}," POST",{"type":52,"tag":131,"props":1517,"children":1518},{"style":1357},[1519],{"type":58,"value":1475},{"type":52,"tag":131,"props":1521,"children":1522},{"style":138},[1523],{"type":58,"value":1524},"\u003C",{"type":52,"tag":131,"props":1526,"children":1527},{"style":1357},[1528],{"type":58,"value":1529},"bas",{"type":52,"tag":131,"props":1531,"children":1532},{"style":154},[1533],{"type":58,"value":1534},"e",{"type":52,"tag":131,"props":1536,"children":1537},{"style":138},[1538],{"type":58,"value":1539},">",{"type":52,"tag":131,"props":1541,"children":1542},{"style":1357},[1543],{"type":58,"value":1544},"\u002Fsub_issues",{"type":52,"tag":131,"props":1546,"children":1547},{"style":1357},[1548],{"type":58,"value":1549}," -F",{"type":52,"tag":131,"props":1551,"children":1552},{"style":1357},[1553],{"type":58,"value":1554}," sub_issue_id=",{"type":52,"tag":131,"props":1556,"children":1557},{"style":154},[1558],{"type":58,"value":1559},"$id\n",{"type":52,"tag":61,"props":1561,"children":1562},{},[1563,1569,1570,1576,1578,1583],{"type":52,"tag":75,"props":1564,"children":1566},{"className":1565},[],[1567],{"type":58,"value":1568},"-F",{"type":58,"value":627},{"type":52,"tag":75,"props":1571,"children":1573},{"className":1572},[],[1574],{"type":58,"value":1575},"-f",{"type":58,"value":1577},": the endpoint takes an integer, and ",{"type":52,"tag":75,"props":1579,"children":1581},{"className":1580},[],[1582],{"type":58,"value":1575},{"type":58,"value":1584}," sends the string form.\nCheck the result with:",{"type":52,"tag":120,"props":1586,"children":1588},{"className":1330,"code":1587,"language":1332,"meta":125,"style":125},"gh api repos\u002Fapache\u002Fskywalking\u002Fissues\u002F\u003Cbase> -q .sub_issues_summary\n",[1589],{"type":52,"tag":75,"props":1590,"children":1591},{"__ignoreMap":125},[1592],{"type":52,"tag":131,"props":1593,"children":1594},{"class":133,"line":134},[1595,1599,1603,1607,1611,1615,1619,1623,1628],{"type":52,"tag":131,"props":1596,"children":1597},{"style":144},[1598],{"type":58,"value":1354},{"type":52,"tag":131,"props":1600,"children":1601},{"style":1357},[1602],{"type":58,"value":1470},{"type":52,"tag":131,"props":1604,"children":1605},{"style":1357},[1606],{"type":58,"value":1475},{"type":52,"tag":131,"props":1608,"children":1609},{"style":138},[1610],{"type":58,"value":1524},{"type":52,"tag":131,"props":1612,"children":1613},{"style":1357},[1614],{"type":58,"value":1529},{"type":52,"tag":131,"props":1616,"children":1617},{"style":154},[1618],{"type":58,"value":1534},{"type":52,"tag":131,"props":1620,"children":1621},{"style":138},[1622],{"type":58,"value":1539},{"type":52,"tag":131,"props":1624,"children":1625},{"style":1357},[1626],{"type":58,"value":1627}," -q",{"type":52,"tag":131,"props":1629,"children":1630},{"style":1357},[1631],{"type":58,"value":1632}," .sub_issues_summary\n",{"type":52,"tag":61,"props":1634,"children":1635},{},[1636,1638,1644],{"type":58,"value":1637},"The base issue stays open as the umbrella, and ",{"type":52,"tag":75,"props":1639,"children":1641},{"className":1640},[],[1642],{"type":58,"value":1643},"sub_issues_summary",{"type":58,"value":1645}," is the\nprogress bar. Close it when the last ticket merges.",{"type":52,"tag":61,"props":1647,"children":1648},{},[1649,1651,1657],{"type":58,"value":1650},"If automation selects the oldest issue with a queue label such as ",{"type":52,"tag":75,"props":1652,"children":1654},{"className":1653},[],[1655],{"type":58,"value":1656},"Backlog",{"type":58,"value":1658},",\napply that label only to the oldest unblocked executable leaf. Never queue a\ntracking parent or all sibling leaves at once. Create children in dependency\norder so issue numbers reinforce rather than fight the execution order.",{"type":52,"tag":103,"props":1660,"children":1662},{"id":1661},"before-you-file",[1663],{"type":58,"value":1664},"Before you file",{"type":52,"tag":264,"props":1666,"children":1667},{},[1668,1673,1678,1690,1695,1700,1705,1710,1722],{"type":52,"tag":268,"props":1669,"children":1670},{},[1671],{"type":58,"value":1672},"Did you show the size audit and explicitly classify the issue as a leaf or a\ntracking parent?",{"type":52,"tag":268,"props":1674,"children":1675},{},[1676],{"type":58,"value":1677},"Could someone write a failing test from this body alone, without asking you\nanything?",{"type":52,"tag":268,"props":1679,"children":1680},{},[1681,1683,1688],{"type":58,"value":1682},"Does the test actually fail on current ",{"type":52,"tag":75,"props":1684,"children":1686},{"className":1685},[],[1687],{"type":58,"value":288},{"type":58,"value":1689},", or would the legacy path already\nsatisfy it?",{"type":52,"tag":268,"props":1691,"children":1692},{},[1693],{"type":58,"value":1694},"Does every expected value come from the issue rather than from what the code\nwould compute?",{"type":52,"tag":268,"props":1696,"children":1697},{},[1698],{"type":58,"value":1699},"Is every acceptance criterion provable by running something?",{"type":52,"tag":268,"props":1701,"children":1702},{},[1703],{"type":58,"value":1704},"Is it one boundary and one production activation, or a plan with phases?",{"type":52,"tag":268,"props":1706,"children":1707},{},[1708],{"type":58,"value":1709},"Does this merge activate a real caller rather than land dead foundation code?",{"type":52,"tag":268,"props":1711,"children":1712},{},[1713,1715,1720],{"type":58,"value":1714},"Are all prerequisite seams already merged to ",{"type":52,"tag":75,"props":1716,"children":1718},{"className":1717},[],[1719],{"type":58,"value":288},{"type":58,"value":1721},"?",{"type":52,"tag":268,"props":1723,"children":1724},{},[1725],{"type":58,"value":1726},"If it touches stored or wire data, does it say what happens to existing data\nand to a mixed-version cluster?",{"type":52,"tag":1728,"props":1729,"children":1730},"style",{},[1731],{"type":58,"value":1732},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1734,"total":1891},[1735,1754,1772,1786,1799,1810,1817,1828,1841,1859,1870,1880],{"slug":1736,"name":1737,"fn":1738,"description":1739,"org":1740,"tags":1741,"stars":1751,"repoUrl":1752,"updatedAt":1753},"computer-use","Computer Use","operate local desktop applications","Use when the user asks to inspect or operate a local desktop application UI, including reading windows, clicking controls, filling forms, using menus, scrolling lists, moving windows, or waiting for dialogs. Trigger for requests such as \"operate this app\", \"do this in TextEdit\u002FCalculator\u002FSettings\", \"look at the current window\", or \"click\u002Ftype\u002Fscroll\"; prefer Browser tools for web pages and non-GUI tools for files or terminal work.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1742,1745,1748],{"name":1743,"slug":1744,"type":15},"Automation","automation",{"name":1746,"slug":1747,"type":15},"Desktop","desktop",{"name":1749,"slug":1750,"type":15},"MCP","mcp",1580,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fmaka","2026-08-27T13:05:35.059686",{"slug":1755,"name":1755,"fn":1756,"description":1757,"org":1758,"tags":1759,"stars":1769,"repoUrl":1770,"updatedAt":1771},"datafusion-python","write Apache DataFusion Python code","Use when the user is writing datafusion-python (Apache DataFusion Python bindings) DataFrame or SQL code. Covers imports, data loading, DataFrame operations, expression building, SQL-to-DataFrame mappings, idiomatic patterns, and common pitfalls.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1760,1763,1766],{"name":1761,"slug":1762,"type":15},"Data Analysis","data-analysis",{"name":1764,"slug":1765,"type":15},"Python","python",{"name":1767,"slug":1768,"type":15},"SQL","sql",593,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fdatafusion-python","2026-07-12T08:36:04.957626",{"slug":1773,"name":1773,"fn":1774,"description":1775,"org":1776,"tags":1777,"stars":1783,"repoUrl":1784,"updatedAt":1785},"flink-agents-dev","build and debug Apache Flink agents","Use when building, scaffolding, modifying, debugging, converting, or verifying Apache Flink Agents applications, including Flink Agents YAML, Workflow Agent, ReAct Agent, Actions, Resources, MCP servers, vector stores, runtime skills, Python, or Java. Do not use for ordinary Flink jobs that do not use Flink Agents.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1778,1781,1782],{"name":1779,"slug":1780,"type":15},"Agents","agents",{"name":1743,"slug":1744,"type":15},{"name":1749,"slug":1750,"type":15},421,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fflink-agents","2026-08-07T05:03:37.315408",{"slug":1787,"name":1787,"fn":1788,"description":1789,"org":1790,"tags":1791,"stars":25,"repoUrl":26,"updatedAt":1798},"bydbql","generate and execute BanyanDB BydbQL queries","Generate, validate, and optionally execute read-only BanyanDB BydbQL for STREAM, MEASURE, TRACE, and PROPERTY resources. Use when the user asks to query BanyanDB, translate natural language to BydbQL, inspect BanyanDB schema or data, validate BydbQL, or fetch raw BanyanDB records.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1792,1795,1797],{"name":1793,"slug":1794,"type":15},"Analytics","analytics",{"name":1796,"slug":32,"type":15},"Database",{"name":1767,"slug":1768,"type":15},"2026-07-12T08:31:01.294423",{"slug":1800,"name":1800,"fn":1801,"description":1802,"org":1803,"tags":1804,"stars":25,"repoUrl":26,"updatedAt":1809},"compiling","compile and build BanyanDB projects","Compile and build the SkyWalking BanyanDB project. Use when the user asks to compile, build, or generate code for this project.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1805,1808],{"name":1806,"slug":1807,"type":15},"Build","build",{"name":23,"slug":24,"type":15},"2026-07-12T08:31:06.373309",{"slug":4,"name":4,"fn":5,"description":6,"org":1811,"tags":1812,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1813,1814,1815,1816],{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"slug":1818,"name":1818,"fn":1819,"description":1820,"org":1821,"tags":1822,"stars":25,"repoUrl":26,"updatedAt":1827},"gh-pull-request","create GitHub pull requests for BanyanDB","Create a GitHub pull request for SkyWalking BanyanDB. Use when the user asks to create a PR, submit changes, or open a pull request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1823,1824],{"name":13,"slug":14,"type":15},{"name":1825,"slug":1826,"type":15},"Pull Requests","pull-requests","2026-07-12T08:31:03.792415",{"slug":1829,"name":1829,"fn":1830,"description":1831,"org":1832,"tags":1833,"stars":25,"repoUrl":26,"updatedAt":1840},"vendor-update","update Go and Node.js vendor dependencies","Upgrade Go\u002FNode.js vendor dependencies and sync tool versions. Use whenever the user says \"upgrade dependencies\", \"update vendors\", \"vendor update\", \"run vendor-upgrade\", \"bump dependencies\", \"update packages\", or asks to run the `vendor-update` Make target. This skill also checks `scripts\u002Fbuild\u002Fversion.mk` after upgrading to see if any tracked tool versions need updating too, and removes stale binaries from `bin\u002F` when versions change.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1834,1837],{"name":1835,"slug":1836,"type":15},"Go","go",{"name":1838,"slug":1839,"type":15},"Node.js","node-js","2026-07-12T08:31:02.555555",{"slug":1842,"name":1842,"fn":1843,"description":1844,"org":1845,"tags":1846,"stars":1856,"repoUrl":1857,"updatedAt":1858},"cayenne-cgen","generate Cayenne entity Java classes","Use this skill whenever the user wants to (re)generate Cayenne entity Java classes from a DataMap. Trigger on phrases like 'generate Java classes', 'regenerate entities', 'run cgen', 'create the entity classes', 'why is the Artist class missing fields', 'where did the `_Abstract*` classes come from', 'sync the entity classes with the model', or any request to materialize Java from the DataMap. Also trigger as a follow-up after modeling changes (someone added an entity, attribute, or relationship and now the Java side is stale). This skill exclusively uses the `mcp__cayenne__cgen_run` MCP tool — it does NOT use `mvn cayenne:cgen` or the Gradle cgen task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1847,1850,1853],{"name":1848,"slug":1849,"type":15},"Data Modeling","data-modeling",{"name":1851,"slug":1852,"type":15},"Java","java",{"name":1854,"slug":1855,"type":15},"ORM","orm",343,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fcayenne","2026-08-10T04:19:27.571948",{"slug":1860,"name":1860,"fn":1861,"description":1862,"org":1863,"tags":1864,"stars":1856,"repoUrl":1857,"updatedAt":1869},"cayenne-db-import","import database schema into Cayenne DataMaps","Use this skill when the user wants to import database schema metadata into a Cayenne DataMap — the *model\u002Fmapping only*, not names or Java classes. Trigger on phrases like 'reverse engineer the database', 'import the schema', 'generate a DataMap from my DB', 'add the new tables from the DB into the model', 'import the customer table', 'create entities from these tables', or any request to read database metadata to populate or update a DataMap's XML. This is for *full schema* or *bulk table* import; one-off a-la-carte entity additions belong in the cayenne-modeling skill. IMPORTANT — scope: this imports the mapping ONLY; it does not clean up the Object-layer names or (re)generate Java classes. When the user wants their whole project brought in line with the DB ('sync my project with the database', 'my schema changed, update everything', 'update my entities\u002Fclasses from the DB'), that is the end-to-end `cayenne-full-db-sync` skill, which runs this import and then name cleanup and class generation. To regenerate classes alone use `cayenne-cgen`. The skill runs reverse engineering directly via the `mcp__cayenne__dbimport_run` MCP tool when a DBConnector is already configured; otherwise it opens the CayenneModeler GUI via `mcp__cayenne__open_project` to configure the connection first.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1865,1866,1867,1868],{"name":1796,"slug":32,"type":15},{"name":1851,"slug":1852,"type":15},{"name":1854,"slug":1855,"type":15},{"name":1767,"slug":1768,"type":15},"2026-07-19T05:40:33.655062",{"slug":1871,"name":1871,"fn":1872,"description":1873,"org":1874,"tags":1875,"stars":1856,"repoUrl":1857,"updatedAt":1879},"cayenne-full-db-sync","synchronize Cayenne projects with database","Use this skill when the user wants to bring their WHOLE Cayenne project in line with the database in one shot — the mapping, the Object-layer names, and the generated Java classes together. This is the end-to-end 'sync with the DB' workflow, and it orchestrates three skills in order: `cayenne-db-import` (import schema metadata into the DataMap) → `cayenne-model-naming` (polish the just-imported names) → `cayenne-cgen` (regenerate Java classes). Trigger on holistic phrases like 'sync my project with the database', 'sync with the DB', 'my schema changed, update everything', 'update my entities\u002Fclasses from the database', 'reverse engineer and regenerate the classes', 'import the new tables and rebuild the entities', 'full DB sync', 'bring the model and classes up to date with the DB'. The distinguishing signal is scope: the user wants the whole project (mapping + names + Java code), not just one stage. For the *model\u002Fmapping only* (no name cleanup, no class generation) use `cayenne-db-import`; to (re)generate classes alone use `cayenne-cgen`; to clean names alone use `cayenne-model-naming`. Uses the `mcp__cayenne__dbimport_run` and `mcp__cayenne__cgen_run` MCP tools via the sub-skills; does NOT use Maven or Gradle goals.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1876,1877,1878],{"name":1796,"slug":32,"type":15},{"name":1851,"slug":1852,"type":15},{"name":1854,"slug":1855,"type":15},"2026-07-19T06:03:49.112969",{"slug":1881,"name":1881,"fn":1882,"description":1883,"org":1884,"tags":1885,"stars":1856,"repoUrl":1857,"updatedAt":1890},"cayenne-model-naming","clean up Cayenne object-layer names","Use this skill to clean up Object-layer names in a Cayenne DataMap — ObjEntity, ObjAttribute, and ObjRelationship names, plus DbRelationship names (the first-class unit of relationship cleanup — every FK has one whether or not an ObjRelationship was generated; the ObjRelationship name is synced to it when one exists) — so they read as descriptive, consistent Java. Trigger on phrases like 'clean up the model names', 'fix the entity names', 'these names look ugly', 'make the names descriptive', 'normalize the ObjEntity\u002Fattribute\u002Frelationship names', 'why is this relationship called team1', 'rename entities to be consistent', 'the import produced Gametype instead of GameType'. Invoke it on an explicit user request, or as a manual follow-up after a `cayenne-db-import` to polish the just-imported additions — it is never triggered automatically. IMPORTANT: this is a LIGHT polish pass — CayenneModeler's reverse-engineering already produces good names for the common case; only improve the specific things its deterministic algorithm cannot (run-together names with no separators like `gametype`, meaningless numbered names like `team1` from multiple relationships between two tables, and a common entity prefix that leaks into relationship names like `aaOrders`). Do NOT rewrite names that are already correct. This is Obj-layer naming polish; for structural model edits use `cayenne-modeling`, and for regenerating classes afterward use `cayenne-cgen`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1886,1887,1888,1889],{"name":1848,"slug":1849,"type":15},{"name":1796,"slug":32,"type":15},{"name":1851,"slug":1852,"type":15},{"name":1854,"slug":1855,"type":15},"2026-07-22T05:35:32.342548",116,{"items":1893,"total":178},[1894,1900,1905,1912,1917],{"slug":1787,"name":1787,"fn":1788,"description":1789,"org":1895,"tags":1896,"stars":25,"repoUrl":26,"updatedAt":1798},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1897,1898,1899],{"name":1793,"slug":1794,"type":15},{"name":1796,"slug":32,"type":15},{"name":1767,"slug":1768,"type":15},{"slug":1800,"name":1800,"fn":1801,"description":1802,"org":1901,"tags":1902,"stars":25,"repoUrl":26,"updatedAt":1809},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1903,1904],{"name":1806,"slug":1807,"type":15},{"name":23,"slug":24,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":1906,"tags":1907,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1908,1909,1910,1911],{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"slug":1818,"name":1818,"fn":1819,"description":1820,"org":1913,"tags":1914,"stars":25,"repoUrl":26,"updatedAt":1827},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1915,1916],{"name":13,"slug":14,"type":15},{"name":1825,"slug":1826,"type":15},{"slug":1829,"name":1829,"fn":1830,"description":1831,"org":1918,"tags":1919,"stars":25,"repoUrl":26,"updatedAt":1840},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1920,1921],{"name":1835,"slug":1836,"type":15},{"name":1838,"slug":1839,"type":15}]