Repository navigation
Conversation
…ction Parse /review teach [F<n>|<link>] <rule> and /review teach org <rule>. The review step words the issue with no model call; the publish step opens it, labelled review-guidance, with a second app token that can write only issues, and replies with a link, or says the app lacks the permission. npm run train copies the rules of teach org issues closed as completed into training/feedback.md.
There was a problem hiding this comment.
🤖 NCode Review at 3d44647: 11 new findings on the changed lines.
🤖 Review completeVerdict: 💬 Comment — This PR adds 8 reviewers run — 8 findings (run details)
Skipped: api-compat, data-model, infrastructure, intent, performance Findings
Trial: findings are posted as review threads and in the check run. $0.69 on Amazon Bedrock, 94s, at c44bb79. (how to interact) |
…rker and issue source type
ensureLabel takes a 422 from the label create as success, so two teach commands racing on a repository without the label both open their issue. ruleFromIssue compares against guidanceMarker('org'), IssueSource derives from TeachContext, and the guidance-issue page size is one constant. Tests cover the race, a private repository's finding in an org issue, a link ref through planTeaching, and an issue body with no comment URL or finding line.
|
/review |
There was a problem hiding this comment.
🤖 NCode Review at 8aa5a0b: 9 new findings on the changed lines.
1 more was already posted on this pull request.
# Conflicts: # src/main.ts
|
Autopilot: Round 2 answered. No blocker or should-fix is left open; the remaining threads are nits, answered above. Recommend merging once you've resolved them. (The branch also has |
There was a problem hiding this comment.
🤖 NCode Review at c44bb79: 5 new findings on the changed lines.
3 more were already posted on this pull request.
| rule: command.rule, | ||
| title: issueTitle(command.rule), | ||
| body: issueBody(command.scope, command.rule, source, finding), | ||
| }, |
There was a problem hiding this comment.
🟠 Should fix: No end-to-end test that planTeaching hides a private repository's finding F1 · tests
The org-scope privacy rule is only tested by calling issueBody directly. No test runs planTeaching with a finding ref and isPrivate: true, which is the path main.ts actually takes.
Consequence: A regression that drops isPrivate or passes the finding differently would leak a private repository's finding text, path and name into a public NCodeGroup/code-review issue without any test failing.
Fix: Add a planTeaching test for teach org F<n> <rule> with isPrivate: true and a reader that returns the finding. Assert that the body has no ### From finding, no finding path or text, and no private repository name.
Evidence
In test/teach.test.ts, the 'planTeaching for teach org ... hidden' test uses no ref, and 'issueBody keeps a private repository's finding out' calls issueBody directly.
Confidence 0.55.
There was a problem hiding this comment.
Autopilot: fixed in #85 (f296477): a new end-to-end planTeaching test reads the finding through the reader for an org rule from a private repository. It asserts that the body has no ### From finding section, none of the finding's path, title, text or link, and no repository name. As the parser stands, teach org F2 ... keeps F2 in the rule and names no finding, so the test builds the command directly. It also checks the parsed form, which reads nothing.
| if (error instanceof GitHubError && error.status === 410) return { refused: 'disabled' }; | ||
| throw error; | ||
| } | ||
| } |
There was a problem hiding this comment.
🟠 Should fix: No test for what postTeaching does when issue creation fails with a non-permission error F2 · tests
openGuidanceIssue rethrows any refusal other than 403/404/410, for example a 422 or a 500. No test calls postTeaching with such a failure, so the behavior the user sees (no reply, the step fails) is not pinned down.
Consequence: A later change could swallow the error and post a misleading 'can't write issues' reply or a success reply, and no test would catch it.
Fix: Add a postTeaching test where the issue POST returns a 500 (or a 422). Assert that it rejects and that no reply comment was posted.
Evidence
The only postTeaching failure tests cover the 403 reply and the secret scan. The rethrow in openGuidanceIssue is only tested by calling it directly.
Confidence 0.50.
| if (ref && ref.kind !== 'invalid') return { kind: 'teach', scope: 'repository', ref, rule: (first![2] ?? '').trim() }; | ||
| return { kind: 'teach', scope: 'repository', rule: rest }; | ||
| } | ||
|
|
There was a problem hiding this comment.
🟡 Nit: No test for a first word that is an invalid link, which falls back to rule text F4 · tests
When the first word is an invalid finding link, such as an http URL or a URL that isn't a comment link, parseTeach keeps the whole text as the rule. No test covers this fallback.
Consequence: A change in this behavior, for example a link silently becoming part of the rule or becoming an error, would go unnoticed.
Fix: Add a parseCommand('/review teach https://example.com/x a rule') assertion that the whole text is kept as the rule.
Evidence
The parseCommand tests cover F-ids, valid links and 'organizations', but not an invalid link as the first word.
Confidence 0.30.
| return `That rule is ${length.toLocaleString('en-US')} characters long; teach one of at most ${maxRuleChars.toLocaleString('en-US')} characters.`; | ||
| } | ||
|
|
||
| export function teachUnknownRefBody(ref: FindingRef, validIds: string[]): string { |
There was a problem hiding this comment.
🟡 Nit: The unknown-link branch of teachUnknownRefBody is untested F5 · tests
The reply for an unknown link ("That link isn't to one of NCode Review's finding comments") is never tested; the only unknown-ref test uses an id (F9).
Consequence: A wrong message for a bad link would go unnoticed.
Fix: Add a planTeaching case with a link to a missing comment and assert the link wording.
Evidence
The only unknown-ref test uses parseCommand('/review teach F9 a rule').
Confidence 0.30.
| ? `issues are turned off in ${teaching.target}` | ||
| : `the NCode Review app can't write issues in ${teaching.target}. A maintainer needs to give the app the Issues: Read and write permission${teaching.scope === 'org' ? ` and install it on ${orgGuidanceRepository}` : ''}`; | ||
| return `I couldn't open a \`${guidanceLabel}\` issue: ${why}. The rule, to add by hand meanwhile:\n\n${fenced(teaching.rule)}`; | ||
| } |
There was a problem hiding this comment.
🟡 Nit: Several functions take four or more data parameters F7 · conventions, rule-check
postTeaching, publishTeaching and issueBody take four data parameters, and writeForPublish in src/main.ts (line 83) now takes five. The same api/issuesApi/secrets group appears in several of these signatures. Does the C#-oriented 2–3 parameter rule apply to this TypeScript code?
Consequence: The signatures are harder to read, and it is easy to swap the two API callbacks without the compiler noticing.
Fix: If the rule applies, group api, issuesApi and secrets into a PublishContext, pass issueBody a single input object, and use an options object for writeForPublish (or split file writing from output writing).
Evidence
The rule says 'at most 2–3 data parameters ... Turn recurring parameter groups into a type' (csharp-production.instructions.md).
Confidence 0.30.
There was a problem hiding this comment.
Autopilot: declined: the 2-3 parameter rule is C# guidance. In this TypeScript the parameters are typed, and the tests record calls on api and issuesApi separately, so swapping them would fail a test. Grouping them into a PublishContext is a refactor with no behavior change, so it stays out of this fix.
Stacked on #75; GitHub retargets this to main when #75 merges.
Adds
/review teach <rule>,/review teach F<n> <rule>(or a finding comment's link) and/review teach org <rule>: writer-only, top-level comments only, no forks, no model call. The review step words the issue (rule fenced as data with mentions defused, link to the comment, and forF<n>the finding's file, line, text and link); the publish step, after everything else, creates thereview-guidancelabel if missing, opens the issue in this repository (or NCodeGroup/code-review fororg) and replies with a short comment linking it. Everything posted is scanned withassertNoSecrets.npm run trainnow copies the rules ofteach orgissues closed as completed into a "Taught with /review teach" section oftraining/feedback.md(injectable fetch, hermetic tests).Decisions
permission-issues: write, scoped to the one target repository,continue-on-error: true), not the existing token: asking for a permission the installation lacks fails the mint, which would break every review until the app setting changes. When that mint fails, or GitHub answers 403/404, the reply says the app lacks the permission and quotes the rule to add by hand; 410 says issues are off.teach orgissue lands in the public NCodeGroup/code-review, so from a private repository it names neither the repository nor its pull request.teach orgtakes no finding, for the same reason.npm run trainreads only bot-opened,scope=orgissues in NCodeGroup/code-review closed as completed (not planned drops them); project rules belong in that repository's.github/code-review/guidance.md(Read per-repository settings from.github/code-review/on the default branch #43).--no-taught-rulesskips it.Left for the maintainer
teach org, make sure the installation includes NCodeGroup/code-review. Until then,/review teachreplies that the app lacks the permission.npm run typecheckandnpm test(207 tests) pass.Closes #45