From 6a2a89f3726f4650324ae30c4134489cd073bdfa Mon Sep 17 00:00:00 2001 From: Rahul Krishna Date: Mon, 14 Sep 2026 16:32:15 -0400 Subject: [PATCH] Put bug reports and feature requests on the house forms bug_report.md and feature_request.md were stock GitHub boilerplate -- "a clear and concise description of what the bug is" -- while epic.yml and work_item.yml ask for a scope boundary, caveats and a definition of done. Two shapes in one ISSUE_TEMPLATE directory, and the two markdown ones set the weaker example. Both become issue forms, so the required fields are enforced at submit time rather than by review. They keep the house discipline without borrowing maintainer-only sections that a reporter cannot fill: - bug_report: reproduction and observed-vs-expected are pasted, not paraphrased. The scope-boundary slot becomes "What you have not checked" -- a reporter knows their unknowns, not the fix's boundary. - feature_request: scope boundary, alternatives considered, caveats, and an observable "what done would look like". Says up front that schema and public-API changes get designed before they get built, so proposals stop arriving with a field layout already chosen. CONTRIBUTING's "Writing a good issue" said "both templates" and now covers all four plus the PR template, with the rule that `gh issue create --body` bypasses the form silently. --- .github/CONTRIBUTING.md | 19 +++++- .github/ISSUE_TEMPLATE/bug_report.md | 24 ------- .github/ISSUE_TEMPLATE/bug_report.yml | 79 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ------ .github/ISSUE_TEMPLATE/feature_request.yml | 74 ++++++++++++++++++++ 5 files changed, 169 insertions(+), 47 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 327acf1..099b128 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -81,11 +81,24 @@ Each issue gets a branch `/issue-NNN-` and one PR that closes ## Writing a good issue -Two sections carry most of the weight, and both templates require them: +**Use a form.** Every issue and every pull request in this org is filed on one of the templates — +`epic.yml`, `work_item.yml`, `bug_report.yml`, `feature_request.yml`, or +`pull_request_template.md`. Not an approximation of one, and not your own headings covering the +same ground. `gh issue create --body` and `gh pr create --body` bypass the form silently: pass +`--template`, or reproduce the sections exactly — same names, same order, none added, none +dropped. A section that does not apply is filled with the reason it does not apply, never deleted. + +Two fields carry most of the weight, and every form requires them or their analogue: - **Scope boundary** — what this issue does *not* do. Usually the most useful sentence in the - issue; it is what stops a PR sprawling. + issue; it is what stops a PR sprawling. On a bug report it is *What you have not checked*. - **Definition of done** — exact conditions. Prefer an exact expected set over "non-empty", and a demonstrated behaviour over an asserted one. "Works correctly" is not a definition of done. -Cite `file:line` wherever you can. An issue that names the line is one someone can pick up cold. +**Show, don't describe.** Cite `file:line` wherever you can, and paste the command and its output +rather than summarising it. An issue that names the line is one someone can pick up cold. Every +sentence is a fact with a citation, a consequence that follows from one, or a guess marked as a +guess — an unmarked guess sends the next person to fix something that is not broken. + +**Keep it short.** Under 400 words outside code blocks. Code blocks do not count; they are the +evidence the words exist to avoid restating. An issue that needs more is usually two issues. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index fe72e49..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: ["bug"] -assignees: '' -projects_v2: codellm-devkit/1 ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Logs** -If applicable, add logs to help explain your problem. - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..8e226ff --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,79 @@ +name: Bug report +description: Something in a codellm-devkit repo behaves differently from what it documents. +title: "" +labels: ["bug"] +projects: ["codellm-devkit/1"] +body: + - type: markdown + attributes: + value: | + **Show, don't describe.** A pasted command and its output is worth a paragraph of + prose and is checkable. Every claim here is one of three things: a fact with a + citation (`file:line`, or a number with the command that produced it), a consequence + that follows from one, or a guess you mark as a guess. + + **Search open issues first** and comment on the duplicate instead of filing. Say + what is new. + + Keep it short. A bug report over 400 words outside its code blocks is usually two + bug reports. + + - type: input + id: repo + attributes: + label: Repo and version + description: Which repo, and the exact version or commit. `codeanalyzer --version`, the installed package version, or a SHA. + placeholder: codeanalyzer-python 2.1.3 (or commit a1b2c3d) + validations: + required: true + + - type: textarea + id: repro + attributes: + label: Reproduction + description: The smallest input that shows it, and the exact command. Paste them; do not describe them. If you cannot reduce it, say what you tried. + placeholder: | + ```python + # fixture.py + @app.route("/x") + def handler(): ... + ``` + ``` + $ codeanalyzer -i fixture.py -a 2 + ``` + render: markdown + validations: + required: true + + - type: textarea + id: observed + attributes: + label: Observed vs expected + description: Paste the real output, then say what it should have been. An abridged paste is fine; a paraphrased one is not. + placeholder: | + Observed: + L2 body{"34:15"} kind=call callee=null + + Expected: callee resolved to the @external id, as L2 does for module-level calls. + render: markdown + validations: + required: true + + - type: textarea + id: unchecked + attributes: + label: What you have not checked + description: The honest part. Sibling analyzers you did not try, versions you did not test, whether it predates a recent change. An unmarked guess sends someone to fix a thing that is not broken. + placeholder: | + - Not tried on codeanalyzer-typescript; guess, untested: the shared resolver means it is affected too. + - Did not bisect. Present in 2.1.3; unknown before that. + validations: + required: true + + - type: textarea + id: context + attributes: + label: Additional context + description: Logs, OS, runtime version, anything else. Optional. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index ea37009..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature Request -about: Create a report to help us improve -title: '' -labels: ["enhancement"] -assignees: '' -projects_v2: codellm-devkit/1 ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..ad060bc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,74 @@ +name: Feature request +description: Propose a capability a codellm-devkit repo does not have yet. +title: "" +labels: ["enhancement"] +projects: ["codellm-devkit/1"] +body: + - type: markdown + attributes: + value: | + **This is a proposal, not a work item.** It becomes a Work item when a maintainer + picks it up, and an Epic only if it spans repos or several pull requests. You do not + need to decompose it here. + + **Anything touching the canonical schema or a public SDK API gets designed before it + gets built** — a committed spec, decided with a maintainer. Propose the capability + and the constraint; leave the schema shape to that conversation. + + **Search open issues first.** Keep it under 400 words outside code blocks. + + - type: textarea + id: problem + attributes: + label: Problem + description: What you cannot do today, and what you do instead. One or two paragraphs. Cite `file:line` or paste the workaround — a concrete blocked task beats a described one. + placeholder: | + Resolving a call to a third-party callable returns null at L2, so downstream + reachability stops at the project boundary (codeanalyzer-python, resolver.py:214). + We currently re-resolve against a hand-kept map of ~40 framework entrypoints. + validations: + required: true + + - type: textarea + id: scope + attributes: + label: Scope boundary + description: What this should NOT do. The most useful field in the form — it is what stops the eventual PR sprawling. + placeholder: | + Identity and provenance for out-of-project targets only. Not signature + reconstruction, not stub generation, and not a bundled type-stub corpus. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: What else would solve it, and why you are not proposing that. "None" is a valid answer if you say so explicitly. + placeholder: | + - Resolve in each SDK instead — rejected, four SDKs would diverge on the id format. + - Ship stubs with the analyzer — rejected, licensing and size. + validations: + required: true + + - type: textarea + id: caveats + attributes: + label: Caveats and known risks + description: Substrate limits, inherited unsoundness, cost, anything that makes this harder than it looks. If you genuinely know of none, write that. + placeholder: | + - Python has no import-time guarantee that a name resolves to one target; the id is a best effort. + - Guess, untested: which SDKs already read this field. + validations: + required: true + + - type: textarea + id: done + attributes: + label: What "done" would look like + description: An observable condition, not "works correctly". Prefer an exact expected set over "non-empty", and a demonstrated behaviour over an asserted one. + placeholder: | + - Calls to a third-party callable carry a stable id at L2 on the fixture corpus. + - The id is identical across two runs and across two machines. + validations: + required: true