Skip to content

Align issue-intent rationale limits to GitHub API 280-char constraint#42809

Merged
pelikhan merged 8 commits into
mainfrom
copilot/fix-rationale-maxlength-issue
Jul 1, 2026
Merged

Align issue-intent rationale limits to GitHub API 280-char constraint#42809
pelikhan merged 8 commits into
mainfrom
copilot/fix-rationale-maxlength-issue

Conversation

Copilot AI commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Issue-intent mutations were accepting effectively unbounded rationale values in tool schemas and validator paths, while the GitHub API enforces a 280-character limit. This mismatch caused valid-looking agent output to fail at mutation time.

  • Schema contract alignment

    • Added maxLength: 280 to all issue-intent rationale fields in safe output tool schemas:
      • set_issue_type.rationale
      • set_issue_field.rationale
      • add_labels.labels[].rationale
      • remove_labels.labels[].rationale
      • update_issue.labels[].rationale
    • Updated schema text to: Optional rationale for the change (max 280 characters).
    • Applied the same updates to both runtime and compiler schema copies to keep them in sync.
  • Runtime enforcement alignment

    • Reduced ISSUE_INTENT_RATIONALE_MAX_LENGTH from 1024 to 280 in issue_intents.cjs.
    • Reduced label-intent rationale sanitization limit from 1024 to 280 in safe_output_type_validator.cjs.
    • Kept explicit post-sanitize clamping to guarantee outbound rationale payloads never exceed 280 characters.
  • Regression coverage

    • Updated validator config expectations from 1024 to 280.
    • Added focused truncation coverage for:
      • issue-type intent rationale (set_issue_type GraphQL path)
      • structured label intent rationale (add_labels path)
const ISSUE_INTENT_RATIONALE_MAX_LENGTH = 280;

rationale: {
  type: "string",
  maxLength: 280,
  description: "Optional rationale for the change (max 280 characters)."
}

Generated by 👨‍🍳 PR Sous Chef · 12.7 AIC · ⌖ 10.4 AIC · ⊞ 6.4K ·

Copilot AI and others added 2 commits July 1, 2026 17:27
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Align rationale maxLength to GitHub API limit of 280 characters Align issue-intent rationale limits to GitHub API 280-char constraint Jul 1, 2026
Copilot AI requested a review from pelikhan July 1, 2026 17:31
@pelikhan pelikhan marked this pull request as ready for review July 1, 2026 17:49
Copilot AI review requested due to automatic review settings July 1, 2026 17:49
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #42809 does not have the 'implementation' label and has only 10 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns issue-intent rationale handling with the GitHub API’s 280-character limit by tightening tool schema contracts and adding/adjusting runtime truncation behavior, with regression tests to prevent future drift.

Changes:

  • Added maxLength: 280 + updated descriptions for issue-intent rationale fields in both safe output tool schema copies.
  • Reduced runtime rationale limits to 280 and added explicit post-sanitize clamping to guarantee outbound payloads never exceed 280 chars.
  • Added/updated tests to cover truncation behavior for set_issue_type and structured label rationales.
Show a summary per file
File Description
pkg/workflow/js/safe_outputs_tools.json Tightens tool schema contract for issue-intent rationales (maxLength 280).
actions/setup/js/safe_outputs_tools.json Mirrors the same schema contract tightening for the setup action runtime copy.
actions/setup/js/issue_intents.cjs Lowers rationale cap to 280 and clamps post-sanitize before emitting intent metadata.
actions/setup/js/safe_output_type_validator.cjs Clamps structured label rationale sanitization to 280 and enforces hard cap.
actions/setup/js/safe_output_type_validator.test.cjs Updates expected rationale maxLength and adds truncation coverage for structured label rationale.
actions/setup/js/set_issue_type.test.cjs Adds truncation regression coverage for issue-intent rationale in the GraphQL mutation path.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 6/6 changed files
  • Comments generated: 2
  • Review effort level: Low

issue_number: { issueOrPRNumber: true },
issue_type: { required: true, type: "string", sanitize: true, maxLength: 128 },
rationale: { type: "string", sanitize: true, maxLength: 1024 },
rationale: { type: "string", sanitize: true, maxLength: 280 },
field_node_id: { type: "string", maxLength: 256 },
value: { required: true, type: "string", sanitize: true, maxLength: 256 },
rationale: { type: "string", sanitize: true, maxLength: 1024 },
rationale: { type: "string", sanitize: true, maxLength: 280 },
@github-actions github-actions Bot mentioned this pull request Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100 — Excellent

Analyzed 2 test(s): 2 design, 0 implementation, 0 violation(s).

📊 Metrics (2 tests)
Metric Value
Analyzed 2 (Go: 0, JS: 2)
✅ Design 2 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 2 (100%)
Duplicate clusters 0
Inflation Yes (both test files exceed 2:1 vs production additions)
🚨 Violations 0
Test File Classification Issues
should truncate structured label rationale to 280 characters safe_output_type_validator.test.cjs:~331 ✅ design_test / behavioral_contract / high_value None
should truncate issue_intents rationale to 280 characters set_issue_type.test.cjs:~387 ✅ design_test / behavioral_contract / high_value Inspects mock call args (acceptable — required to verify API boundary truncation)
📐 Inflation Detail (2 files flagged)
Test File Test +lines Prod File Prod +lines Ratio
safe_output_type_validator.test.cjs +19 safe_output_type_validator.cjs +3 6.3:1 ⚠️
set_issue_type.test.cjs +47 issue_intents.cjs +3 15.7:1 ⚠️

Note: The inflation ratios are high but contextually justified. The production change is a 1-line constant update (1024→280), while the tests add full integration coverage including setup, mock orchestration, and boundary assertion. The test-to-production ratio reflects the thoroughness of the coverage, not bloat.

Verdict

Passed. 0% implementation tests (threshold: 30%). No guideline violations. Inflation is flagged (−10 pts) but tests are contextually justified as comprehensive boundary coverage for the GitHub API 280-char constraint.

References:

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 40.4 AIC · ⌖ 15.8 AIC · ⊞ 6.8K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 90/100. 0% implementation tests (threshold: 30%). Both new tests are design-level behavioral contracts covering the 280-char truncation boundary.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Align issue-intent rationale limits to GitHub API 280-char constraint

This is a clean, focused fix that correctly aligns runtime enforcement to the GitHub API constraint and updates all relevant schema copies and tests.

Correctness

  • ISSUE_INTENT_RATIONALE_MAX_LENGTH in issue_intents.cjs correctly drops from 1024 → 280.
  • The double-sanitize + clamp pattern is sound: sanitizeContent strips unsafe chars first, then the hard clamp guarantees the final payload length. Defensive-in-depth.
  • The label-path in validateIssueIntentLabels also clamps to 280, consistent with the intent-level path.
  • Both actions/setup/js/ and pkg/workflow/js/ schema copies updated in lockstep.

Tests

  • New truncation test in set_issue_type.test.cjs verifies the GraphQL mutation payload carries the truncated value.
  • New truncation test in safe_output_type_validator.test.cjs covers the label-intent path.

Non-blocking suggestion (see inline comment)
The literal 280 is hard-coded twice in validateIssueIntentLabels in safe_output_type_validator.cjs. Extracting a named constant would make a future limit change a one-liner and eliminate the risk of the two occurrences drifting apart.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 62.2 AIC · ⌖ 6.53 AIC · ⊞ 4.9K

allowedAliases: options?.allowedAliases || [],
maxBotMentions: options?.maxBotMentions,
}).trim();
const rationale = sanitizedRationale.length > 280 ? sanitizedRationale.slice(0, 280) : sanitizedRationale;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The literal 280 is hard-coded twice in this function (passed to sanitizeContent on line 136 and used in the clamp on line 140). This value must stay in sync with ISSUE_INTENT_RATIONALE_MAX_LENGTH in issue_intents.cjs. Consider extracting a module-level constant (e.g. const LABEL_RATIONALE_MAX_LENGTH = 280) to make future limit changes a one-line update and signal intent.\n\n@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — no blocking correctness issues, but several improvements worth addressing before this pattern spreads.

📋 Key Themes & Highlights

Key Themes

  • Undocumented defensive clamp: The post-sanitize slice in both issue_intents.cjs and safe_output_type_validator.cjs is unexplained. It is either dead code (if sanitizeContent already honours maxLength) or a workaround for a latent bug in sanitizeContent — either way it should be documented or tested.
  • Magic literal 280: The limit appears as a bare literal twice in safe_output_type_validator.cjs without a named constant. If the limit changes again, two spots will need updating independently.
  • Boundary and path coverage gaps: The new regression tests cover a single over-length input on two paths (set_issue_type, add_labels). The remove_labels and update_issue paths are unverified, and the boundary conditions (exactly 280, exactly 281, empty post-sanitize) are missing.
  • Test coupling to GraphQL internals: The set_issue_type truncation test reaches into the raw GraphQL mock call to assert the value. Testing normalizeIssueIntentMetadata directly would be simpler and more resilient.

Positive Highlights

  • ✅ Multi-layer defence (schema maxLength + runtime constant + explicit clamp) is the right approach for an API constraint this critical.
  • ✅ Both JSON schema files (actions/setup and pkg/workflow) updated in sync — good discipline.
  • ✅ Clean variable rename (rationalesanitizedRationale) makes the two-step processing explicit.
  • ✅ PR description is thorough and clearly explains the mismatch and the fix strategy.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 77.7 AIC · ⌖ 9.22 AIC · ⊞ 6.6K
Comment /matt to run again

const rationale = sanitizeContent(source.rationale, { maxLength: ISSUE_INTENT_RATIONALE_MAX_LENGTH }).trim();
const sanitizedRationale = sanitizeContent(source.rationale, { maxLength: ISSUE_INTENT_RATIONALE_MAX_LENGTH }).trim();
const rationale = sanitizedRationale.length > ISSUE_INTENT_RATIONALE_MAX_LENGTH ? sanitizedRationale.slice(0, ISSUE_INTENT_RATIONALE_MAX_LENGTH) : sanitizedRationale;
if (rationale) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The post-sanitize clamp is undocumented — it's unclear whether sanitizeContent already enforces maxLength or can overshoot it.

If sanitizeContent always honours its maxLength parameter, the guard is dead code. If it can exceed the limit (e.g. due to word-boundary logic), that is a bug in sanitizeContent that warrants its own test rather than a silent fallback.

💡 Suggested improvement

Add a brief comment explaining the guard:

// sanitizeContent may produce slightly more than maxLength in some edge cases;
// slice enforces the GitHub API hard limit of 280 chars.
const rationale = sanitizedRationale.length > ISSUE_INTENT_RATIONALE_MAX_LENGTH
  ? sanitizedRationale.slice(0, ISSUE_INTENT_RATIONALE_MAX_LENGTH)
  : sanitizedRationale;

Or, if sanitizeContent already guarantees the limit, remove the guard and add an assertion.

@copilot please address this.

const rationale = sanitizedRationale.length > 280 ? sanitizedRationale.slice(0, 280) : sanitizedRationale;
if (rationale) {
normalizedLabel.rationale = rationale;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The magic literal 280 is duplicated here instead of referencing a shared constant — if the limit changes again, this will need a separate update.

ISSUE_INTENT_RATIONALE_MAX_LENGTH is defined in issue_intents.cjs; the validator has no access to it, so the limit is hardcoded as 280 twice in this file.

💡 Suggested improvement

Extract a module-level constant in safe_output_type_validator.cjs:

const RATIONALE_MAX_LENGTH = 280;

Then use it in both the sanitizeContent call and the clamp guard so the limit is defined once.

@copilot please address this.

);

expect(result.success).toBe(true);
const mutationCall = mockGithub.graphql.mock.calls.find(([query]) => typeof query === "string" && query.includes("IssueTypeUpdateInput"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The new truncation test only checks the happy path (350-char input → 280-char output). Edge cases at the boundary are not covered.

Missing boundary conditions: exactly 280 chars (should pass through unchanged), exactly 281 chars (first value that needs truncation), and empty string / whitespace-only (should produce no rationale field).

💡 Suggested additional tests
it('should not truncate rationale of exactly 280 characters', async () => {
  const exactRationale = 'a'.repeat(280);
  // ... same mock setup ...
  expect(mutationCall[1].issueType.rationale).toBe(exactRationale);
});

it('should truncate rationale of 281 characters to 280', async () => {
  // ... same mock setup, longRationale = 'a'.repeat(281) ...
  expect(mutationCall[1].issueType.rationale).toBe('a'.repeat(280));
});

it('should omit rationale when it is empty after sanitization', async () => {
  // ... same mock setup, rationale = '' ...
  expect(mutationCall[1].issueType.rationale).toBeUndefined();
});

@copilot please address this.


expect(result.isValid).toBe(true);
expect(result.normalizedItem.labels[0].rationale).toBe("a".repeat(280));
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The label-rationale truncation test only exercises the add_labels path. The same clamp logic also runs for remove_labels and update_issue label entries, but those paths are untested.

If the clamp is extracted into a shared helper (as suggested in the constant comment above), a single test of the helper covers all callers — otherwise add parallel tests for each mutating label intent type.

@copilot please address this.

const mutationCall = mockGithub.graphql.mock.calls.find(([query]) => typeof query === "string" && query.includes("IssueTypeUpdateInput"));
expect(mutationCall).toBeDefined();
expect(mutationCall[1].issueType.rationale).toBe("a".repeat(280));
} finally {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] The test inspects the raw GraphQL mutation call to assert the rationale value, which couples the test to the internal mutation shape rather than the observable contract.

A higher-signal assertion would verify that the returned result object contains (or doesn't contain) a truncated rationale, rather than inspecting the mock call internals — or, better, test normalizeIssueIntentMetadata directly in issue_intents.test.cjs.

💡 Alternative approach

Test the normalizer directly so the test does not depend on GraphQL mock wiring:

// In a dedicated issue_intents.test.cjs or existing test file:
const { normalizeIssueIntentMetadata } = require('./issue_intents.cjs');

it('truncates rationale to 280 characters', () => {
  const meta = normalizeIssueIntentMetadata({ rationale: 'a'.repeat(350) });
  expect(meta.rationale).toHaveLength(280);
});

@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: request changes — PR partially achieves its stated goal

The schema updates and JS runtime limits are correctly aligned to 280, but the Go config (the real source of truth for GH_AW_VALIDATION_CONFIG) was not updated, so set_issue_type.rationale and set_issue_field.rationale will still accept up to 1024 chars at runtime.

Blocking issues

pkg/workflow/safe_outputs_validation_config.go lines 138 and 152 still use MaxLength: 1024.

The test file's SAMPLE_VALIDATION_CONFIG was updated to 280, but that object is a local fixture — it does not affect what gets emitted into GH_AW_VALIDATION_CONFIG. At runtime, safe_output_type_validator.cjs reads the config generated from the Go struct, which still has 1024 for both set_issue_type.rationale and set_issue_field.rationale. The schema says 280, the validator won't enforce it.

(Already flagged inline by existing review comments — confirming those findings are correct.)

Additional issues
  • issue_intents.cjs:29 — The secondary .slice(0, 280) is essential (not redundant): sanitizeContent's applyTruncation appends "\n[Content truncated due to length]" which inflates output beyond maxLength. Without a comment, this will get removed as a "cleanup", sending the marker to the GitHub API. See inline comment.
  • safe_output_type_validator.cjs:140280 is a bare magic number, used twice with no named constant, diverging from the ISSUE_INTENT_RATIONALE_MAX_LENGTH pattern in issue_intents.cjs. See inline comment.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • patchdiff.githubusercontent.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "patchdiff.githubusercontent.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · 148.8 AIC · ⌖ 7.36 AIC · ⊞ 1.6K
Comment /review to run again

if (typeof source.rationale === "string") {
const rationale = sanitizeContent(source.rationale, { maxLength: ISSUE_INTENT_RATIONALE_MAX_LENGTH }).trim();
const sanitizedRationale = sanitizeContent(source.rationale, { maxLength: ISSUE_INTENT_RATIONALE_MAX_LENGTH }).trim();
const rationale = sanitizedRationale.length > ISSUE_INTENT_RATIONALE_MAX_LENGTH ? sanitizedRationale.slice(0, ISSUE_INTENT_RATIONALE_MAX_LENGTH) : sanitizedRationale;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secondary clamp is essential but will look redundant to future readers — without a comment, this slice is one refactor away from being removed, which would silently ship the sanitizeContent truncation marker to the GitHub API.

💡 Why this is non-obvious

sanitizeContent internally calls applyTruncation, which — when the input exceeds maxLength — returns content.substring(0, maxLength) + "\n[Content truncated due to length]". This means for a 350-char input:

  1. sanitizeContent(source.rationale, { maxLength: 280 })"a"×280 + "\n[Content truncated due to length]" (311 chars)
  2. .trim() → no change (the \n is interior, not at the boundary)
  3. Without the slice: sanitizedRationale (311 chars) would be stored as metadata.rationale
  4. With the slice: sanitizedRationale.slice(0, 280)"a"×280

The secondary clamp is what keeps the truncation annotation out of the API payload. Add a comment:

// sanitizeContent appends "\n[Content truncated due to length]" when input exceeds maxLength,
// which inflates the result beyond the limit. Slice again to guarantee the API constraint.
const rationale = sanitizedRationale.length > ISSUE_INTENT_RATIONALE_MAX_LENGTH
  ? sanitizedRationale.slice(0, ISSUE_INTENT_RATIONALE_MAX_LENGTH)
  : sanitizedRationale;

allowedAliases: options?.allowedAliases || [],
maxBotMentions: options?.maxBotMentions,
}).trim();
const rationale = sanitizedRationale.length > 280 ? sanitizedRationale.slice(0, 280) : sanitizedRationale;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number 280 used twice with no named constantissue_intents.cjs correctly defines ISSUE_INTENT_RATIONALE_MAX_LENGTH = 280; this file hardcodes the same value on both line 136 (maxLength: 280) and here, so they can drift independently on the next limit change.

💡 Suggested fix

Add a module-level constant (or import from a shared location):

const ISSUE_INTENT_RATIONALE_MAX_LENGTH = 280;

// then use it:
const sanitizedRationale = sanitizeContent(unfenceMarkdown(label.rationale), {
  maxLength: ISSUE_INTENT_RATIONALE_MAX_LENGTH,
  ...
}).trim();
const rationale = sanitizedRationale.length > ISSUE_INTENT_RATIONALE_MAX_LENGTH
  ? sanitizedRationale.slice(0, ISSUE_INTENT_RATIONALE_MAX_LENGTH)
  : sanitizedRationale;

This also pairs with the note above: having a named constant makes it clear that the maxLength in the sanitizeContent call and the slice boundary must always be the same value.

Copilot AI and others added 2 commits July 1, 2026 18:29
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address these unresolved review threads (newest first):

Addressed in 2e19410 and b781414.

  • updated the Go validation config source of truth to 280 for set_issue_type and set_issue_field
  • added focused Go/JS regression coverage for the 280-char boundary and all issue-intent label mutation paths
  • documented the secondary clamp and deduplicated the label-rationale normalization helper
  • ran make fmt, targeted Go/JS tests, make lint, make test-unit, make test, and make agent-report-progress

The branch is up to date with main. CI on this HEAD is still unverified/stale after the agent push, so a maintainer will need to re-trigger checks.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk 🟡 Medium
Score 65 / 100
Action fast_track

Score breakdown: Impact 35 + Urgency 20 + Quality 10

Rationale: Fixes schema mismatch (rationale maxLength) that causes agent output to silently fail at GitHub API mutation time. Changes requested by automated reviewer — expedited human review recommended to resolve and unblock agent workflows.

Generated by 🔧 PR Triage Agent · 49.4 AIC · ⌖ 11.7 AIC · ⊞ 1.6K ·

@pelikhan

pelikhan commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

@copilot merge main and recompile
Run pr-finisher skill

Copilot AI and others added 2 commits July 1, 2026 21:03
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…fix-rationale-maxlength-issue

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and recompile
Run pr-finisher skill

Addressed in 1d8c15e.

  • merged main into this branch and ran make recompile
  • re-ran make fmt, make lint, make test-unit, make test, and make agent-report-progress
  • the branch is up to date with main; CI on this HEAD is still unverified/stale after the agent push and needs a maintainer re-trigger

@pelikhan pelikhan merged commit e8b9dc7 into main Jul 1, 2026
37 checks passed
@pelikhan pelikhan deleted the copilot/fix-rationale-maxlength-issue branch July 1, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

issue intents: align rationale maxLength to API limit of 280 characters

4 participants