feat(code-intel): dev task enhancement with IDS G4 automation [Story NOG-3]#178
feat(code-intel): dev task enhancement with IDS G4 automation [Story NOG-3]#178Pedrovaleriolopez wants to merge 4 commits intomainfrom
Conversation
…NOG-3] Integrate code intelligence into @dev development tasks for automatic duplicate detection (IDS Gate G4), conventions checking, and blast radius assessment. All integrations use graceful fallback when no provider available. - Create dev-helper.js with 4 public functions (checkBeforeWriting, suggestReuse, getConventionsForPath, assessRefactoringImpact) - Modify dev-develop-story.md: add Code Intelligence Check step - Modify create-service.md: add pre-scaffold duplicate check - Modify dev-suggest-refactoring.md: add blast radius in analysis - Modify build-autonomous.md: add IDS G4 check in build loop - Add 24 unit tests (all passing) covering T1-T9 scenarios - Register dev-helper entity in entity-registry.yaml - QA gate: PASS (quality score 100/100) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds a new dev-helper code-intel module with non-throwing utilities for duplicate detection, reuse suggestions, convention lookup, and refactoring impact assessment; wires non-blocking checks into several developer workflows, registers the module in the entity registry and install manifest, and adds unit tests, CLI triage tooling, templates, and QA/story documentation. Changes
Sequence DiagramssequenceDiagram
participant Dev as Developer/Workflow
participant DH as Dev-Helper
participant CI as Code Intelligence\n(enricher/client)
participant DB as Analysis DB
Dev->>DH: checkBeforeWriting(fileName, description)
activate DH
DH->>CI: isCodeIntelAvailable()
CI-->>DH: true/false
alt available
DH->>CI: getEnricher()
CI-->>DH: enricher
DH->>enricher: detectDuplicates(fileName)
enricher->>DB: search duplicates
DB-->>enricher: duplicates[]
enricher-->>DH: duplicates
DH->>CI: getClient()
CI-->>DH: client
DH->>client: findReferences(fileName)
client->>DB: search references
DB-->>client: references[]
client-->>DH: references
DH->>DH: _formatSuggestion(duplicates, references)
DH-->>Dev: {duplicates, references, suggestion}
else unavailable
DH-->>Dev: null
end
deactivate DH
sequenceDiagram
participant Dev as Developer/Workflow
participant DH as Dev-Helper
participant CI as Code Intelligence\n(enricher/client)
participant DB as Analysis DB
Dev->>DH: assessRefactoringImpact(files)
activate DH
DH->>CI: isCodeIntelAvailable()
CI-->>DH: true/false
alt available
DH->>CI: getEnricher()
CI-->>DH: enricher
DH->>enricher: assessImpact(files)
enricher->>DB: analyze references/impact
DB-->>enricher: analysis results
enricher-->>DH: {blastRadius, references, complexity}
DH->>DH: _calculateRiskLevel(blastRadius)
DH-->>Dev: {blastRadius, riskLevel, references, complexity}
else unavailable
DH-->>Dev: null
end
deactivate DH
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly Related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📊 Coverage ReportCoverage report not available
Generated by PR Automation (Story 6.1) |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (6)
.aios-core/core/code-intel/helpers/dev-helper.js (2)
1-13: Well-structured module header with clear constants.The
'use strict'directive, clear constant documentation, and module-level JSDoc contract ("Never throws") set good expectations. The threshold values are properly extracted as named constants rather than magic numbers.One minor linter issue on line 9: the trailing comment is aligned for readability but triggers ESLint's indentation rule (21 spaces instead of 2).
Fix ESLint indentation warning
const RISK_THRESHOLDS = { LOW_MAX: 4, // 0-4 refs = LOW MEDIUM_MAX: 15, // 5-15 refs = MEDIUM - // >15 refs = HIGH + // >15 refs = HIGH };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.aios-core/core/code-intel/helpers/dev-helper.js around lines 1 - 13, The trailing inline comment after MEDIUM_MAX in the RISK_THRESHOLDS constant is over-indented and triggers ESLint's indentation rule; update the spacing so the comment uses standard indentation (e.g., two spaces before the comment) or align all inline comments consistently, adjusting the RISK_THRESHOLDS object lines (especially MEDIUM_MAX) to remove the 21-space gap and match the project's indentation style.
55-57: Consider minimal logging incatchblocks for debuggability.All four public functions use bare
catchblocks that silently discard errors. While this correctly upholds the zero-throw contract, completely swallowing exceptions makes it hard to diagnose provider issues in a core module consumed by all agents. Even a lightweight debug-level log (if a logger is available in this context) would help operators troubleshoot failures.Example: capture and optionally log the error
- } catch { + } catch (err) { + // Debug-level: provider errors are expected when unavailable + // console.debug('[dev-helper] checkBeforeWriting:', err.message); return null; }As per coding guidelines,
.aios-core/core/**: "Verify error handling is comprehensive with proper try/catch and error context."Also applies to: 93-95, 113-115, 144-146
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.aios-core/core/code-intel/helpers/dev-helper.js around lines 55 - 57, The catch blocks in dev-helper.js currently swallow errors (e.g., the bare "catch { return null; }" cases) making failures opaque; update each catch to capture the exception (catch (err)) and emit a lightweight debug-level log before returning null—use the local logger if available (logger.debug or similar) or fallback to console.debug, include the function name/context (the public helper function name surrounding the catch) and err.message/stack to aid debugging while preserving the no-throw behavior.docs/stories/epics/epic-nogic-code-intelligence/story-NOG-3-dev-task-enhancement.md (2)
156-180: Minor markdown lint: fenced code block missing language specifier.The source tree block at Line 156 uses a bare fenced code block without a language identifier. Adding
textorplaintextwould satisfy markdownlint MD040.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/stories/epics/epic-nogic-code-intelligence/story-NOG-3-dev-task-enhancement.md` around lines 156 - 180, Add a language specifier to the fenced code block (the triple-backtick block showing the aios-core directory tree) in story-NOG-3-dev-task-enhancement.md so markdownlint MD040 is satisfied; change the opening ``` to ```text or ```plaintext to mark it as plain text. Locate the directory tree code block (the block containing "aios-core/" and its subfolders) and update only the opening fence to include the language identifier.
328-337: Minor markdown lint: table not surrounded by blank lines.The table at Line 329 should be preceded by a blank line to satisfy markdownlint MD058.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/stories/epics/epic-nogic-code-intelligence/story-NOG-3-dev-task-enhancement.md` around lines 328 - 337, The markdown table in docs/stories/epics/epic-nogic-code-intelligence/story-NOG-3-dev-task-enhancement.md is not separated by a blank line (markdownlint MD058); open that file and insert a single blank line immediately before the "### File List (Implementation)" table so the table is preceded by an empty line; ensure you only add whitespace (no other text) and save the change so the table block is properly fenced from the preceding paragraph.tests/code-intel/dev-helper.test.js (1)
324-375: Boundary testing for_calculateRiskLeveland_formatSuggestionis thorough.The risk level tests exercise both sides of each boundary (
LOW_MAX,LOW_MAX + 1,MEDIUM_MAX,MEDIUM_MAX + 1) and the zero case. The_formatSuggestiontests cover all three input combinations (both, dupes-only, refs-only).One minor observation: there's no test for
_formatSuggestion(null, null)or_formatSuggestion({ matches: [] }, [])(empty inputs). If the function is expected to handle these gracefully, a test would document that behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/code-intel/dev-helper.test.js` around lines 324 - 375, Add two tests for _formatSuggestion to cover empty inputs: one calling _formatSuggestion(null, null) and another calling _formatSuggestion({ matches: [] }, []); in each test assert the call does not throw and returns a string, and verify it does not contain "similar match" or "location" (and optionally still contains the IDS article if that's the expected behavior); place these tests alongside the existing _formatSuggestion specs so empty-input handling is documented..aios-core/development/tasks/build-autonomous.md (1)
169-179: Integration section doesn't list the newdev-helperdependency.The workflow now references
checkBeforeWritingfromdev-helperandisCodeIntelAvailablefromcode-intel, but the Integration/Uses section doesn't mention these. Consider adding them for discoverability. As per coding guidelines, referenced dependencies should be validated and documented.Suggested addition
- **Uses:** - `AutonomousBuildLoop` from `core/execution/autonomous-build-loop.js` - `BuildStateManager` from `core/execution/build-state-manager.js` - `RecoveryTracker` from `infrastructure/scripts/recovery-tracker.js` + - `checkBeforeWriting` from `core/code-intel/helpers/dev-helper.js` (advisory, non-blocking) + - `isCodeIntelAvailable` from `core/code-intel/index.js`🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.aios-core/development/tasks/build-autonomous.md around lines 169 - 179, The Integration section omits newly referenced dependencies; update the "Uses" list to include the dev-helper and code-intel modules by naming the specific symbols used (checkBeforeWriting from dev-helper and isCodeIntelAvailable from code-intel) so readers can discover and validate them; modify the Integration/Uses block near AutonomousBuildLoop/BuildStateManager/RecoveryTracker to add entries for dev-helper (checkBeforeWriting) and code-intel (isCodeIntelAvailable) and ensure any referenced task/checklist notes reflect these additions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.aios-core/core/code-intel/helpers/dev-helper.js:
- Around line 186-194: _calculateRiskLevel currently relies on loose comparisons
and treats null/undefined/NaN inconsistently; update the function to defensively
coerce and validate the input (blastRadius) before comparing against
RISK_THRESHOLDS: convert blastRadius to a Number, if it is not finite
(NaN/Infinity) or is undefined, default it to 0 (or another safe baseline), then
perform the existing comparisons against RISK_THRESHOLDS.LOW_MAX and
RISK_THRESHOLDS.MEDIUM_MAX so LOW/MEDIUM/HIGH are returned consistently;
reference the _calculateRiskLevel function and the RISK_THRESHOLDS constants
when making the change.
- Around line 30-58: Add explicit input validation at the start of each public
API function (checkBeforeWriting, suggestReuse, getConventionsForPath,
assessRefactoringImpact) to verify required arguments are present, of the
expected type (e.g., string for fileName, description, symbol, targetPath; array
for files) and not empty; if validation fails, throw a descriptive TypeError (do
not rely on the outer try/catch to swallow caller mistakes). Ensure these guards
run before calling downstream provider methods (e.g., enricher.detectDuplicates,
client.findReferences) so invalid inputs are rejected with clear messages.
- Around line 196-206: Add unit tests that import REUSE_MIN_REFS from dev-helper
and explicitly assert suggestReuse() returns 'REUSE' when refCount is <=
REUSE_MIN_REFS and 'ADAPT' when refCount is > REUSE_MIN_REFS; specifically
create two boundary tests that call suggestReuse({ refCount: REUSE_MIN_REFS })
and suggestReuse({ refCount: REUSE_MIN_REFS + 1 }) (or equivalent inputs used by
suggestReuse) and assert the expected suggestion values so the threshold
behavior is covered.
In @.aios-core/data/entity-registry.yaml:
- Around line 6000-6026: Update the dev-helper registry entry so its checksum is
populated: in the dev-helper block (identifier "dev-helper", path
".aios-core/core/code-intel/helpers/dev-helper.js") replace the empty checksum
value with the provided SHA-256 string
"sha256:2418a5f541003c73cc284e88a6b0cb666896a47ffd5ed4c08648269d281efc4c" to
match the actual file and satisfy validation.
In @.aios-core/development/tasks/create-service.md:
- Around line 154-175: The require paths for the pre-scaffold check are
incorrect and will be resolved as packages; update the two require calls so they
use relative paths (add the leading ./) when importing the module that exposes
isCodeIntelAvailable and the helper that exposes checkBeforeWriting;
specifically change the current require('.aios-core/core/code-intel') and
require('.aios-core/core/code-intel/helpers/dev-helper') references used around
the isCodeIntelAvailable and checkBeforeWriting calls to
require('./.aios-core/core/code-intel') and
require('./.aios-core/core/code-intel/helpers/dev-helper') so the code correctly
imports the local modules while leaving the rest of the logic (serviceName,
description, and the advisory logging) unchanged.
---
Nitpick comments:
In @.aios-core/core/code-intel/helpers/dev-helper.js:
- Around line 1-13: The trailing inline comment after MEDIUM_MAX in the
RISK_THRESHOLDS constant is over-indented and triggers ESLint's indentation
rule; update the spacing so the comment uses standard indentation (e.g., two
spaces before the comment) or align all inline comments consistently, adjusting
the RISK_THRESHOLDS object lines (especially MEDIUM_MAX) to remove the 21-space
gap and match the project's indentation style.
- Around line 55-57: The catch blocks in dev-helper.js currently swallow errors
(e.g., the bare "catch { return null; }" cases) making failures opaque; update
each catch to capture the exception (catch (err)) and emit a lightweight
debug-level log before returning null—use the local logger if available
(logger.debug or similar) or fallback to console.debug, include the function
name/context (the public helper function name surrounding the catch) and
err.message/stack to aid debugging while preserving the no-throw behavior.
In @.aios-core/development/tasks/build-autonomous.md:
- Around line 169-179: The Integration section omits newly referenced
dependencies; update the "Uses" list to include the dev-helper and code-intel
modules by naming the specific symbols used (checkBeforeWriting from dev-helper
and isCodeIntelAvailable from code-intel) so readers can discover and validate
them; modify the Integration/Uses block near
AutonomousBuildLoop/BuildStateManager/RecoveryTracker to add entries for
dev-helper (checkBeforeWriting) and code-intel (isCodeIntelAvailable) and ensure
any referenced task/checklist notes reflect these additions.
In
`@docs/stories/epics/epic-nogic-code-intelligence/story-NOG-3-dev-task-enhancement.md`:
- Around line 156-180: Add a language specifier to the fenced code block (the
triple-backtick block showing the aios-core directory tree) in
story-NOG-3-dev-task-enhancement.md so markdownlint MD040 is satisfied; change
the opening ``` to ```text or ```plaintext to mark it as plain text. Locate the
directory tree code block (the block containing "aios-core/" and its subfolders)
and update only the opening fence to include the language identifier.
- Around line 328-337: The markdown table in
docs/stories/epics/epic-nogic-code-intelligence/story-NOG-3-dev-task-enhancement.md
is not separated by a blank line (markdownlint MD058); open that file and insert
a single blank line immediately before the "### File List (Implementation)"
table so the table is preceded by an empty line; ensure you only add whitespace
(no other text) and save the change so the table block is properly fenced from
the preceding paragraph.
In `@tests/code-intel/dev-helper.test.js`:
- Around line 324-375: Add two tests for _formatSuggestion to cover empty
inputs: one calling _formatSuggestion(null, null) and another calling
_formatSuggestion({ matches: [] }, []); in each test assert the call does not
throw and returns a string, and verify it does not contain "similar match" or
"location" (and optionally still contains the IDS article if that's the expected
behavior); place these tests alongside the existing _formatSuggestion specs so
empty-input handling is documented.
| module.exports = { | ||
| checkBeforeWriting, | ||
| suggestReuse, | ||
| getConventionsForPath, | ||
| assessRefactoringImpact, | ||
| // Exposed for testing | ||
| _formatSuggestion, | ||
| _calculateRiskLevel, | ||
| RISK_THRESHOLDS, | ||
| REUSE_MIN_REFS, | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if REUSE_MIN_REFS is tested or referenced in the test file
rg -n 'REUSE_MIN_REFS' tests/code-intel/dev-helper.test.jsRepository: SynkraAI/aios-core
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Check if REUSE_MIN_REFS is used anywhere in the codebase
rg -n 'REUSE_MIN_REFS' --type jsRepository: SynkraAI/aios-core
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Look at the test file to understand what is being tested
wc -l tests/code-intel/dev-helper.test.js
head -50 tests/code-intel/dev-helper.test.jsRepository: SynkraAI/aios-core
Length of output: 1338
🏁 Script executed:
#!/bin/bash
# Check how REUSE_MIN_REFS is defined and used in dev-helper.js
rg -n 'REUSE_MIN_REFS' .aios-core/core/code-intel/helpers/dev-helper.js -B 2 -A 2Repository: SynkraAI/aios-core
Length of output: 480
🏁 Script executed:
#!/bin/bash
# Check where suggestReuse is implemented since it likely uses REUSE_MIN_REFS
rg -n 'function suggestReuse\|const suggestReuse' .aios-core/core/code-intel/helpers/dev-helper.js -A 30Repository: SynkraAI/aios-core
Length of output: 44
Test coverage gap: REUSE_MIN_REFS threshold behavior is not tested.
The constant is exported intentionally to follow the test-exposure pattern, but the test file doesn't import or verify it. Since REUSE_MIN_REFS is used internally at line 85 to determine the 'REUSE' vs 'ADAPT' suggestion threshold in suggestReuse(), test cases should validate this threshold logic explicitly by importing the constant and testing boundary conditions (refCount ≤ 2 and > 2).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/core/code-intel/helpers/dev-helper.js around lines 196 - 206, Add
unit tests that import REUSE_MIN_REFS from dev-helper and explicitly assert
suggestReuse() returns 'REUSE' when refCount is <= REUSE_MIN_REFS and 'ADAPT'
when refCount is > REUSE_MIN_REFS; specifically create two boundary tests that
call suggestReuse({ refCount: REUSE_MIN_REFS }) and suggestReuse({ refCount:
REUSE_MIN_REFS + 1 }) (or equivalent inputs used by suggestReuse) and assert the
expected suggestion values so the threshold behavior is covered.
| dev-helper: | ||
| path: .aios-core/core/code-intel/helpers/dev-helper.js | ||
| type: module | ||
| purpose: Code intelligence helper for @dev agent tasks - IDS G4 automation, duplicate detection, conventions, blast radius | ||
| keywords: | ||
| - code-intel | ||
| - dev-helper | ||
| - ids-g4 | ||
| - duplicate-detection | ||
| - blast-radius | ||
| - conventions | ||
| - reuse | ||
| usedBy: | ||
| - dev-develop-story | ||
| - create-service | ||
| - dev-suggest-refactoring | ||
| - build-autonomous | ||
| dependencies: | ||
| - code-intel | ||
| adaptability: | ||
| score: 0.7 | ||
| constraints: | ||
| - Requires code-intel module (NOG-1) | ||
| extensionPoints: | ||
| - Additional helper functions for other agents | ||
| checksum: '' | ||
| lastVerified: '2026-02-16T00:00:00.000Z' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
registry=".aios-core/data/entity-registry.yaml"
module_file=".aios-core/core/code-intel/helpers/dev-helper.js"
# Check if registry file exists
if [ ! -f "$registry" ]; then
echo "❌ Registry file not found: $registry"
exit 1
fi
echo "=== Checksum line for dev-helper ==="
rg -n "dev-helper:" -A 30 "$registry" | grep -A 1 "checksum:" || echo "No checksum field found"
echo ""
echo "=== Sample of other checksums in registry ==="
rg "checksum:" "$registry" | head -20
echo ""
echo "=== Check if dev-helper.js file exists ==="
if [ -f "$module_file" ]; then
echo "✓ File exists: $module_file"
echo "File size: $(wc -c < "$module_file") bytes"
echo "Computed sha256:"
sha256sum "$module_file"
else
echo "❌ File not found: $module_file"
fi
echo ""
echo "=== Lines 6000-6026 of registry ==="
sed -n '6000,6026p' "$registry"Repository: SynkraAI/aios-core
Length of output: 1981
🏁 Script executed:
#!/bin/bash
set -euo pipefail
registry=".aios-core/data/entity-registry.yaml"
echo "=== All entries with empty checksums ==="
rg "checksum: ''" "$registry" -B 5 | grep -E "(^\s*[a-zA-Z-]+:|checksum)" | head -40
echo ""
echo "=== Search for dev-helper.js ==="
fd "dev-helper\.js" .
echo ""
echo "=== Lines 6020-6030 of registry (context) ==="
sed -n '6020,6030p' "$registry"Repository: SynkraAI/aios-core
Length of output: 671
🏁 Script executed:
#!/bin/bash
echo "=== Search for any dev-helper file ==="
fd "dev-helper" .
echo ""
echo "=== Search for files in expected directory ==="
fd . ".aios-core/core/code-intel/helpers/" 2>/dev/null || echo "Directory does not exist or is empty"
echo ""
echo "=== Search for dev-helper in codebase (any mention) ==="
rg "dev-helper" --type yaml --type js | head -20Repository: SynkraAI/aios-core
Length of output: 396
🏁 Script executed:
#!/bin/bash
file=".aios-core/core/code-intel/helpers/dev-helper.js"
if [ -f "$file" ]; then
echo "✓ File EXISTS"
stat "$file"
echo ""
echo "File checksum:"
sha256sum "$file"
else
echo "✗ File DOES NOT EXIST: $file"
ls -la ".aios-core/core/code-intel/helpers/" 2>&1 || echo "Directory not found"
fi
echo ""
echo "=== Verify test import ==="
cat -n tests/code-intel/dev-helper.test.js | head -10Repository: SynkraAI/aios-core
Length of output: 474
🏁 Script executed:
#!/bin/bash
file=".aios-core/core/code-intel/helpers/dev-helper.js"
echo "=== File info ==="
ls -lh "$file"
wc -l "$file"
echo ""
echo "=== Compute sha256 checksum ==="
python3 <<'EOF'
import hashlib
file_path = ".aios-core/core/code-intel/helpers/dev-helper.js"
try:
with open(file_path, 'rb') as f:
file_hash = hashlib.sha256(f.read()).hexdigest()
print(f"sha256:{file_hash}")
except Exception as e:
print(f"Error: {e}")
EOFRepository: SynkraAI/aios-core
Length of output: 335
Populate the checksum for dev-helper entry.
Line 6025 has an empty checksum (checksum: ''), inconsistent with every other entry in the registry. The file exists at .aios-core/core/code-intel/helpers/dev-helper.js and its checksum is sha256:2418a5f541003c73cc284e88a6b0cb666896a47ffd5ed4c08648269d281efc4c. Update line 6025 to populate this value to maintain registry integrity and pass validation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/data/entity-registry.yaml around lines 6000 - 6026, Update the
dev-helper registry entry so its checksum is populated: in the dev-helper block
(identifier "dev-helper", path
".aios-core/core/code-intel/helpers/dev-helper.js") replace the empty checksum
value with the provided SHA-256 string
"sha256:2418a5f541003c73cc284e88a6b0cb666896a47ffd5ed4c08648269d281efc4c" to
match the actual file and satisfy validation.
| ### Step 0: Code Intelligence Duplicate Check (Pre-Scaffold) | ||
|
|
||
| Before scaffolding the service, check if a similar service already exists using code intelligence: | ||
|
|
||
| ```javascript | ||
| // Code Intelligence pre-scaffold check (graceful — never blocks) | ||
| const { isCodeIntelAvailable } = require('.aios-core/core/code-intel'); | ||
| const { checkBeforeWriting } = require('.aios-core/core/code-intel/helpers/dev-helper'); | ||
|
|
||
| if (isCodeIntelAvailable()) { | ||
| const result = await checkBeforeWriting(serviceName, description); | ||
| if (result) { | ||
| // Display as advisory — does NOT block scaffold | ||
| console.log('⚠️ Code Intelligence Suggestion:'); | ||
| console.log(` ${result.suggestion}`); | ||
| console.log(' Consider REUSE or ADAPT before creating a new service.'); | ||
| // In interactive mode: prompt user to confirm proceeding | ||
| // In YOLO mode: log and continue | ||
| } | ||
| } | ||
| // If code intelligence not available: proceed normally (no impact) | ||
| ``` |
There was a problem hiding this comment.
Step 0 integration is well-positioned and non-blocking — but require paths need ./ prefix.
The pre-scaffold duplicate check is a good addition: it's advisory, doesn't block scaffolding, and has clear fallback. However, the require paths in the code snippet are missing the leading ./:
- Line 160:
require('.aios-core/core/code-intel')→ Node.js would look for this as a package name, not a relative path - Line 161:
require('.aios-core/core/code-intel/helpers/dev-helper')→ same issue
Since this is an instructional code snippet for the agent, the path should be correct to avoid confusion.
Suggested fix
-const { isCodeIntelAvailable } = require('.aios-core/core/code-intel');
-const { checkBeforeWriting } = require('.aios-core/core/code-intel/helpers/dev-helper');
+const { isCodeIntelAvailable } = require('./.aios-core/core/code-intel');
+const { checkBeforeWriting } = require('./.aios-core/core/code-intel/helpers/dev-helper');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/development/tasks/create-service.md around lines 154 - 175, The
require paths for the pre-scaffold check are incorrect and will be resolved as
packages; update the two require calls so they use relative paths (add the
leading ./) when importing the module that exposes isCodeIntelAvailable and the
helper that exposes checkBeforeWriting; specifically change the current
require('.aios-core/core/code-intel') and
require('.aios-core/core/code-intel/helpers/dev-helper') references used around
the isCodeIntelAvailable and checkBeforeWriting calls to
require('./.aios-core/core/code-intel') and
require('./.aios-core/core/code-intel/helpers/dev-helper') so the code correctly
imports the local modules while leaving the rest of the logic (serviceName,
description, and the advisory logging) unchanged.
- Add input validation guards on all 4 public API methods - Fix _calculateRiskLevel for non-numeric inputs (NaN/undefined) - Fix ESLint indentation on RISK_THRESHOLDS comment - Add 7 new tests for input validation (31 total, 123 suite) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.aios-core/core/code-intel/helpers/dev-helper.js (1)
38-61: Consider adding minimal debug logging in catch blocks for observability.All four public functions silently swallow errors via bare
catch {}. While the zero-throw guarantee is the correct design choice here, completely discarding errors makes it difficult to diagnose provider issues in production. A debug-level log (e.g., via an existing logger orconsole.debug) would preserve the non-blocking contract while aiding troubleshooting.Example for one function (apply similarly to the others)
} catch (err) { + // Non-blocking: log for diagnostics only + if (typeof console !== 'undefined' && console.debug) { + console.debug('[dev-helper] checkBeforeWriting failed silently:', err.message); + } return null; }Also applies to: 78-101, 119-125, 142-159
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.aios-core/core/code-intel/helpers/dev-helper.js around lines 38 - 61, The catch blocks in the public helpers (e.g., the try/catch around getEnricher().detectDuplicates, getClient().findReferences, and the return that uses _formatSuggestion) silently swallow errors; update each bare catch to log the caught error at debug level (using the existing logger or console.debug) and include context (function name and relevant symbols like getEnricher, detectDuplicates, getClient, findReferences, _formatSuggestion) before returning null so observability is preserved without changing the zero-throw behavior; apply the same change to the other three public functions mentioned (the catch blocks covering lines ~78-101, ~119-125, and ~142-159).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.aios-core/core/code-intel/helpers/dev-helper.js:
- Around line 209-219: Add unit tests that exercise the boundary behavior of
REUSE_MIN_REFS: import REUSE_MIN_REFS and the suggestReuse function (and/or
_calculateRiskLevel if relevant) and create two cases with refCount equal to
REUSE_MIN_REFS and refCount equal to REUSE_MIN_REFS + 1; assert that the
decision flips as expected (e.g., returns REUSE for one side and
ADAPT/alternative for the other) to close the coverage gap for the threshold
logic.
---
Nitpick comments:
In @.aios-core/core/code-intel/helpers/dev-helper.js:
- Around line 38-61: The catch blocks in the public helpers (e.g., the try/catch
around getEnricher().detectDuplicates, getClient().findReferences, and the
return that uses _formatSuggestion) silently swallow errors; update each bare
catch to log the caught error at debug level (using the existing logger or
console.debug) and include context (function name and relevant symbols like
getEnricher, detectDuplicates, getClient, findReferences, _formatSuggestion)
before returning null so observability is preserved without changing the
zero-throw behavior; apply the same change to the other three public functions
mentioned (the catch blocks covering lines ~78-101, ~119-125, and ~142-159).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.aios-core/install-manifest.yaml (1)
1194-1194: Numerous size-only changes without corresponding hash updates.Many entries throughout this manifest (e.g., lines 1194, 1206, 1214, 1218, and dozens more) show updated
sizevalues but unchangedhashvalues. If these files were actually modified, their hashes should also change. If this is an artifact of the manifest generator recalculating sizes differently (e.g., different environment, line-ending normalization), then it's benign but noisy.Consider investigating whether the generator's size calculation changed, or whether these size-only deltas are expected. This inflates the diff and makes it harder to spot meaningful changes.
#!/bin/bash # Count how many entries have size changes (~ marked) vs hash changes # This helps understand the scope of size-only updates echo "=== Lines with size changes (marked ~) ===" grep -c "^[0-9]*~.*size:" .aios-core/install-manifest.yaml || echo "N/A - checking diff instead" echo "" echo "=== Spot-check: compare a few file sizes with actual sizes ===" # Pick a few files that had size-only changes and verify for f in "development/scripts/approval-workflow.js" "development/scripts/backup-manager.js" "development/scripts/branch-manager.js"; do found=$(fd "$(basename "$f")" --type f --full-path | grep "$f" | head -1) if [ -n "$found" ]; then actual_size=$(wc -c < "$found") echo "$f: actual=$actual_size" fi done🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.aios-core/install-manifest.yaml at line 1194, The manifest shows many entries where only the size field changed without corresponding hash updates, indicating either a generator inconsistency or incorrect partial updates; open the manifest generator or script that produces .aios-core/install-manifest.yaml (the generator that writes each entry's size and hash) and re-run it in a consistent environment to regenerate both size and hash atomically, ensure the generator recalculates and writes both fields together (update the code that writes size for the same record that computes hash), normalize line endings/encoding before size/hash computation, and if these changes are not real revert the noisy size-only edits from the diff and add a test to assert size/hash pair consistency for entries to prevent future size-only diffs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.aios-core/install-manifest.yaml:
- Line 1194: The manifest shows many entries where only the size field changed
without corresponding hash updates, indicating either a generator inconsistency
or incorrect partial updates; open the manifest generator or script that
produces .aios-core/install-manifest.yaml (the generator that writes each
entry's size and hash) and re-run it in a consistent environment to regenerate
both size and hash atomically, ensure the generator recalculates and writes both
fields together (update the code that writes size for the same record that
computes hash), normalize line endings/encoding before size/hash computation,
and if these changes are not real revert the noisy size-only edits from the diff
and add a test to assert size/hash pair consistency for entries to prevent
future size-only diffs.
nikolasdehor
left a comment
There was a problem hiding this comment.
Review: feat(code-intel): dev task enhancement with IDS G4 automation
This is a well-executed PR. The dev-helper.js module is clean, the test coverage is thorough (24 tests), and the integration into the 4 task files follows a consistent non-blocking advisory pattern. Approving with minor observations.
Code Quality — dev-helper.js
The implementation quality is high:
- Zero-throw guarantee is correctly implemented — every public function guards with
isCodeIntelAvailable()and wraps provider calls in try/catch, returningnullon any failure path. - Clean API surface — 4 public functions (
checkBeforeWriting,suggestReuse,getConventionsForPath,assessRefactoringImpact), 2 private helpers (_formatSuggestion,_calculateRiskLevel), and 2 exported constants (RISK_THRESHOLDS,REUSE_MIN_REFS). Promise.allinsuggestReusefor concurrentfindDefinition+findReferencescalls is a good performance pattern.- Input validation is consistent — null/undefined/empty checks at the top of every function before touching the provider.
- JSDoc on all public functions with proper
@paramand@returnstypes.
Test Quality — dev-helper.test.js
The test suite is well-structured:
- Mock setup helpers (
setupProviderAvailable,createMockEnricher,createMockClient) reduce boilerplate. - All 9 test scenarios from the story (T1-T9) are covered plus additional edge cases (null inputs, empty arrays, provider errors, boundary values).
- Boundary testing for
_calculateRiskLevelcovers 0, LOW_MAX (4), LOW_MAX+1 (5), MEDIUM_MAX (15), MEDIUM_MAX+1 (16), NaN, negative numbers, and Infinity. - The T9 integration test validates all 4 functions simultaneously with provider unavailable.
Task Integration
The modifications to the 4 task files (dev-develop-story.md, create-service.md, dev-suggest-refactoring.md, build-autonomous.md) all follow the same pattern:
- Check
isCodeIntelAvailable()first - Call the appropriate
dev-helperfunction - Display result as non-blocking advisory
- Skip silently if no provider
This is the right approach — it keeps the existing workflow intact when code intelligence is unavailable.
Minor Observations (non-blocking)
-
create-service.mdStep 0 usesrequire('.aios-core/...')(without leading dot or using the absolute import convention). Since this is instructional markdown (not executed directly), it is not a bug, but it would be clearer to show the import path that actually works in the project context:require('../../.aios-core/core/code-intel'). -
install-manifest.yamlhas many size-only changes — dozens of files show changed sizes without hash changes. This appears to be a regeneration artifact. Not a concern for this PR, but worth noting that running the manifest generator touched many unrelated entries. -
Entity registry
checksumis empty (checksum: '') for thedev-helperentry. If other entries have real checksums, this should be populated for consistency.
Story Documentation
The story file (story-NOG-3-dev-task-enhancement.md) is comprehensive — acceptance criteria, test matrix, QA results, and implementation notes are all filled in. The QA gate file passes all checks. This is a good example of story-driven development done properly.
LGTM. Well-designed module with thorough testing and clean integration.
reviewed by @nikolasdehor
|
Hey @Pedrovaleriolopez, great work on the IDS G4 automation! The dev-helper.js implementation is clean with proper zero-throw guarantees. Quick heads up — I've submitted 9 PRs today that are all waiting for review/CI approval: Bug fixes (high priority):
Feature:
Test coverage (175 new tests, refs #52):
Infra:
All have passed CodeRabbit review and addressed its feedback. Would you be able to approve the CI workflows so they can run? The Vercel deploy auth is also pending. Thanks! 🙏 |
Complete GitHub issue management with 3 phases: - Phase 1: Label taxonomy (44 labels with prefixes), 3 YAML issue forms, config.yml - Phase 2: GitHub Actions (issue-labeler, stale, welcome), labeler configs - Phase 3: Triage task, checklist, batch script, 31 issues triaged Includes research documentation and QA-reviewed corrections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Story GHIM-001: GitHub Issue Management SystemThis commit adds a complete GitHub issue management system: Phase 1: Foundation
Phase 2: Automation
Phase 3: Triage Process
QA Review: PASS (Quinn) — All concerns addressed before commit. |
There was a problem hiding this comment.
Actionable comments posted: 15
🧹 Nitpick comments (2)
.aios-core/development/scripts/issue-triage.js (1)
32-32: WrapJSON.parsecalls in try/catch to handle unexpectedghoutput.While
gh()exits on command failure, ifghemits a success message alongside JSON (e.g., deprecation warnings on stderr that bleed into stdout, or an empty result) the raw string passed toJSON.parsemay not be valid JSON, throwing an unhandled exception with no user-friendly message. Applies to both line 32 and line 79.♻️ Proposed fix
- const issues = JSON.parse(raw); + let issues; + try { + issues = JSON.parse(raw); + } catch { + console.error('Failed to parse gh output as JSON. Ensure gh CLI is authenticated.'); + process.exit(1); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.aios-core/development/scripts/issue-triage.js at line 32, Wrap the JSON.parse(raw) call that sets the issues variable in a try/catch and do the same for the other JSON.parse call around line 79: detect empty or invalid raw output, catch the SyntaxError, log a clear error including the raw output and context (e.g., "failed to parse gh output for issues"/the other context), and exit or throw a controlled error instead of letting an unhandled exception propagate; update the assignments that reference issues (and the second parsed variable) to only proceed when parsing succeeds..github/issue-labeler.yml (1)
10-30: Unescaped.wildcards in several regex patterns may cause unintended false positives.In the regexes:
isn.t(line 10),packages.installer(line 20),\.aios-core.core(line 22), and\.aios-core.cli(line 26), the unescaped.matches any character. The practical false-positive risk for an issue labeler is low, but escaping them makes the intent explicit.♻️ Proposed fix
- - '(\[Bug\]|bug report|something.*(isn.t|not) working|broken|crash|regression)' + - '(\[Bug\]|bug report|something.*(isn'\''t|not) working|broken|crash|regression)' - - '(npx aios-core|aios-core install|installer|wizard|onboarding|packages.installer)' + - '(npx aios-core|aios-core install|installer|wizard|onboarding|packages\.installer)' - - '(\.aios-core.core|orchestration|config.*loader|core framework)' + - '(\.aios-core\.core|orchestration|config.*loader|core framework)' - - '(aios-core info|aios-core update|aios-core doctor|bin/|\.aios-core.cli)' + - '(aios-core info|aios-core update|aios-core doctor|bin/|\.aios-core\.cli)'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/issue-labeler.yml around lines 10 - 30, Several regex patterns use unescaped dot wildcards which match any character instead of a literal period; update the affected label patterns by escaping the dots: change "isn.t" to "isn\.t", "packages.installer" to "packages\.installer", "\.aios-core.core" to "\.aios-core\.core", and "\.aios-core.cli" to "\.aios-core\.cli" so each pattern matches a literal dot as intended (ensure the YAML string quoting preserves the backslashes).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.aios-core/development/scripts/issue-triage.js:
- Around line 149-156: The code assumes values exist after the flags but doesn't
guard against missing tokens; before reading args[typeIdx+1], args[prioIdx+1],
and args[areaIdx+1] (used to set type, priority, and areas), validate that each
index+1 is within bounds and the token is a non-empty string; if any is missing,
print the same usage/error message and exit(1). Update the existing check that
uses typeIdx/prioIdx/areaIdx or add explicit guards for args[typeIdx + 1],
args[prioIdx + 1], and args[areaIdx + 1] to avoid calling .split on undefined
when constructing areas.
- Around line 67-73: The current code builds a shell string using
addLabels/addStr (from extra) and calls gh(...) which invokes the shell,
allowing injection via labels; change gh to use child_process.execFileSync (or
spawnSync) and accept an argv array instead of a single interpolated string,
then update the apply-labels callsite to pass arguments like ['issue','edit',
String(number), '--add-label', addLabels.join(','), '--remove-label', 'status:
needs-triage'] (stop using addStr and string interpolation). Also
sanitize/validate label values before joining (e.g., match against a label regex
or an allowlist) to be extra-safe. Ensure all other gh(...) callsites are
converted to the new array form.
In @.aios-core/development/tasks/github-issue-triage.md:
- Around line 18-22: Update the prerequisites section to add explicit
error-handling guidance: for "gh auth status" failures instruct running "gh auth
login" and how to verify auth, for missing label taxonomy reference "GHIM-001
Phase 1" and block progress with a short checklist/link to the setup steps, and
for a non-zero exit from "issue-triage.js" advise inspecting logs, re-running
with a "--dry-run" or verbose flag if supported, and retry steps; ensure the new
guidance is concise, uses the exact tokens "gh auth status", "GHIM-001 Phase 1",
and "issue-triage.js" so agents can find and follow the recovery actions.
- Around line 83-94: The fenced ASCII decision tree block lacks a language
specifier causing markdownlint MD040; update the code fence around the tree to
include a plaintext language (e.g., change the opening fence from ``` to
```text) so the block becomes ```text ... ``` and leave the contents unchanged;
locate the ASCII tree block in the decision flow (the block beginning with
"Issue received" and the tree of branches) and add the language tag to that
opening fence.
In @.github/workflows/issue-labeler.yml:
- Line 21: Replace the mutable action pin "uses: github/issue-labeler@v3.4" with
a full commit SHA reference for the issue-labeler action (e.g., "uses:
github/issue-labeler@<full-commit-sha>"); find the exact commit SHA from the
issue-labeler repository's commits page or the release tag's commit and update
the workflow entry that currently reads "uses: github/issue-labeler@v3.4" to
that immutable SHA so the action is pinned to a specific commit.
In @.github/workflows/stale.yml:
- Line 16: Replace the mutable tag "uses: actions/stale@v9" with a pinned commit
SHA for the actions/stale action to eliminate supply-chain risk; locate the
actions/stale repository commit you want to lock to (e.g., the latest v9 stable
commit), then update the workflow entry "uses: actions/stale@v9" to "uses:
actions/stale@<commit-sha>" so the workflow references that exact commit SHA
instead of the mutable tag.
In @.github/workflows/welcome.yml:
- Line 12: The workflow uses pull_request_target with mutable action refs —
update the action refs to pinned commit SHAs to remove the supply-chain risk:
replace actions/first-interaction@v1 and actions/github-script@v7 with their
corresponding commit SHA pins (use the specific commit SHAs for those releases)
so the workflow references immutable commits; ensure both occurrences are
updated in the welcome.yml and verify the SHA pins match the intended release
commits.
In `@docs/research/2026-02-20-github-issue-management/02-research-report.md`:
- Around line 229-241: The fenced CODEOWNERS snippet beginning with ``` and
containing lines like "# Default owners" and "*.test.js
`@oalanicolas`" should include a language identifier to satisfy MD040; update the
opening fence from ``` to ```text (or ```gitconfig) so the block is fenced as
```text while leaving the content and closing ``` unchanged.
In `@docs/research/2026-02-20-github-issue-management/03-recommendations.md`:
- Around line 36-43: The recommendations list includes two area labels (`area:
docs` and `area: devops`) that are not present in the GHIM-001 story's Label
Taxonomy; either remove those two entries from the recommendations block or
update the GHIM-001 Label Taxonomy and label-creation steps to include `area:
docs` and `area: devops` (or add a short note stating they were intentionally
dropped). Locate the recommendations list (the lines with `area: core`, `area:
installer`, ..., `area: devops`) and the GHIM-001 Label Taxonomy section, then
make the taxonomy and implementation steps consistent with the recommendations
or annotate the change explaining the omission.
- Around line 17-51: The two fenced code blocks are missing language specifiers
and should declare them to satisfy markdownlint MD040: update the label taxonomy
block (the first fenced block containing the "type:", "priority:", "status:",
"area:", "community:", etc. entries) to begin with a language tag such as
```text and update the CODEOWNERS fenced block (the block showing
".github/CODEOWNERS" lines and entries) to begin with a language tag such as
```gitconfig so both fenced code blocks include explicit languages.
In `@docs/stories/active/GHIM-001.story.md`:
- Line 56: The AC checkbox "Cada Action executou pelo menos 1 vez com sucesso em
issue de teste" is still unchecked while the Change Log declares "Phase 2
complete"; either mark that AC as checked after a confirmed test-run or change
the Change Log entry to indicate conditional/partial completion; update the
GHIM-001.story.md AC line to "- [x] Cada Action..." when you have a successful
run, or edit the Change Log's "Phase 2 complete" note to clarify it is
conditional/pending that AC (referencing the AC text and the Phase 2 Change Log
entry) so they are consistent.
- Line 173: Update the Definition of Done entry in GHIM-001.story.md that
currently reads "27 issues existentes re-triados com novas labels aplicadas" to
match the Acceptance Criteria and Change Log which record 31 triaged issues;
locate the "Definition of Done" / "DoD" block (the line containing that
Spanish/Portuguese sentence) and change the numeral 27 to 31 so all sections
(DoD, AC, Change Log) are consistent.
- Around line 132-151: The fenced code block in GHIM-001.story.md has no
language tag and triggers markdownlint MD040; update the opening fence (the
triple backticks that precede the lines starting with "type: bug..." etc.) to
include a neutral language tag such as text or plaintext (e.g., change ``` to
```text) so the block is explicitly marked as plain text and the linter warning
is resolved.
- Around line 220-222: Remove the duplicated table row for
`.github/issue-labeler.yml` (there are two identical entries in the file list);
keep a single entry and delete the redundant one so the markdown table remains
valid and consistent.
- Line 31: The doc references inconsistent versions of the GitHub Action: update
the pinned reference from "actions/stale@v9" to "actions/stale@v10" so it
matches the earlier mention "actions/stale v10" and the rest of the document;
search for the string "actions/stale@v9" (or the exact line that pins the
action) and replace it with "actions/stale@v10" to keep the story and
recommendations consistent.
---
Nitpick comments:
In @.aios-core/development/scripts/issue-triage.js:
- Line 32: Wrap the JSON.parse(raw) call that sets the issues variable in a
try/catch and do the same for the other JSON.parse call around line 79: detect
empty or invalid raw output, catch the SyntaxError, log a clear error including
the raw output and context (e.g., "failed to parse gh output for issues"/the
other context), and exit or throw a controlled error instead of letting an
unhandled exception propagate; update the assignments that reference issues (and
the second parsed variable) to only proceed when parsing succeeds.
In @.github/issue-labeler.yml:
- Around line 10-30: Several regex patterns use unescaped dot wildcards which
match any character instead of a literal period; update the affected label
patterns by escaping the dots: change "isn.t" to "isn\.t", "packages.installer"
to "packages\.installer", "\.aios-core.core" to "\.aios-core\.core", and
"\.aios-core.cli" to "\.aios-core\.cli" so each pattern matches a literal dot as
intended (ensure the YAML string quoting preserves the backslashes).
| if (extra) { | ||
| addLabels.push(...extra); | ||
| } | ||
|
|
||
| const addStr = addLabels.map(l => `"${l}"`).join(','); | ||
| console.log(`Applying to #${number}: ${addLabels.join(', ')}`); | ||
| gh(`issue edit ${number} --add-label ${addStr} --remove-label "status: needs-triage"`); |
There was a problem hiding this comment.
Shell injection via unvalidated --extra labels.
extra values coming from CLI args (line 157) are appended to addLabels without any validation, then each label is wrapped in double quotes and interpolated into the shell string passed to execSync. In bash, $(...) and backtick expressions are still expanded inside double quotes, so --extra '$(id)' would execute id as a shell command. execSync with a plain string argument runs through /bin/sh -c, making shell meta-characters active.
Two recommended mitigations:
Option 1 (preferred): switch to execFileSync with an arg array — eliminates the shell entirely:
🛡️ Proposed fix — execFileSync
-function gh(cmd) {
+function gh(args) {
try {
- return execSync(`gh ${cmd}`, { encoding: 'utf8', timeout: 60000 });
+ const { execFileSync } = require('child_process');
+ return execFileSync('gh', args, { encoding: 'utf8', timeout: 60000 });
} catch (err) {
console.error(`gh command failed: ${err.message}`);
process.exit(1);
}
}Then update all gh(...) callsites to pass argument arrays, e.g.:
// listUntriaged
gh(['issue', 'list', '--label', 'status: needs-triage', '--json', 'number,title,labels,createdAt,author', '--limit', '100']);
// applyLabels
gh(['issue', 'edit', String(number),
'--add-label', addLabels.join(','),
'--remove-label', 'status: needs-triage']);Option 2 (minimal): validate extra labels against an allowlist before use:
🛡️ Proposed fix — allowlist validation
+const VALID_COMMUNITY_LABELS = ['community: good first issue', 'community: help wanted'];
+
if (extra) {
+ for (const label of extra) {
+ if (!VALID_COMMUNITY_LABELS.includes(label)) {
+ console.error(`Invalid extra label: ${label}. Valid: ${VALID_COMMUNITY_LABELS.join(', ')}`);
+ process.exit(1);
+ }
+ }
addLabels.push(...extra);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/development/scripts/issue-triage.js around lines 67 - 73, The
current code builds a shell string using addLabels/addStr (from extra) and calls
gh(...) which invokes the shell, allowing injection via labels; change gh to use
child_process.execFileSync (or spawnSync) and accept an argv array instead of a
single interpolated string, then update the apply-labels callsite to pass
arguments like ['issue','edit', String(number), '--add-label',
addLabels.join(','), '--remove-label', 'status: needs-triage'] (stop using
addStr and string interpolation). Also sanitize/validate label values before
joining (e.g., match against a label regex or an allowlist) to be extra-safe.
Ensure all other gh(...) callsites are converted to the new array form.
| if (!number || typeIdx === -1 || prioIdx === -1 || areaIdx === -1) { | ||
| console.error('Usage: --apply <number> --type <type> --priority <P1-P4> --area <area> [--extra "label1,label2"]'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const type = args[typeIdx + 1]; | ||
| const priority = args[prioIdx + 1]; | ||
| const areas = args[areaIdx + 1].split(','); |
There was a problem hiding this comment.
Missing value guard for --area (and --type/--priority) arguments.
Line 149 verifies that the --area flag is present (areaIdx !== -1) but does not check whether a value token follows it. If the invocation is --apply 174 --type bug --priority P2 --area (flag at the end, no value), then args[areaIdx + 1] is undefined, and undefined.split(',') throws a TypeError at line 156 before any user-visible error message is printed.
The same gap exists for args[typeIdx + 1] and args[prioIdx + 1], though those reach validation inside applyLabels before crashing.
🐛 Proposed fix
- if (!number || typeIdx === -1 || prioIdx === -1 || areaIdx === -1) {
+ if (!number || typeIdx === -1 || !args[typeIdx + 1] ||
+ prioIdx === -1 || !args[prioIdx + 1] ||
+ areaIdx === -1 || !args[areaIdx + 1]) {
console.error('Usage: --apply <number> --type <type> --priority <P1-P4> --area <area> [--extra "label1,label2"]');
process.exit(1);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/development/scripts/issue-triage.js around lines 149 - 156, The
code assumes values exist after the flags but doesn't guard against missing
tokens; before reading args[typeIdx+1], args[prioIdx+1], and args[areaIdx+1]
(used to set type, priority, and areas), validate that each index+1 is within
bounds and the token is a non-empty string; if any is missing, print the same
usage/error message and exit(1). Update the existing check that uses
typeIdx/prioIdx/areaIdx or add explicit guards for args[typeIdx + 1],
args[prioIdx + 1], and args[areaIdx + 1] to avoid calling .split on undefined
when constructing areas.
| ## Prerequisites | ||
|
|
||
| - GitHub CLI authenticated (`gh auth status`) | ||
| - Label taxonomy deployed (see GHIM-001 Phase 1) | ||
| - Access to repository issue list |
There was a problem hiding this comment.
Add error handling guidance for prerequisite failures and command failures.
The task's prerequisites section notes dependencies on gh auth status and the label taxonomy, but provides no guidance on what @devops should do when these fail. Per the task format requirements, this gap means the agent has no recovery path.
Consider adding an error-handling section covering at minimum:
gh auth statusfails → point togh auth login- Labels from GHIM-001 Phase 1 are missing → block with reference to setup steps
issue-triage.jsexits non-zero → inspect logs, re-run with--dry-runif supported
As per coding guidelines, tasks under .aios-core/development/tasks/** must include proper error handling guidance.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/development/tasks/github-issue-triage.md around lines 18 - 22,
Update the prerequisites section to add explicit error-handling guidance: for
"gh auth status" failures instruct running "gh auth login" and how to verify
auth, for missing label taxonomy reference "GHIM-001 Phase 1" and block progress
with a short checklist/link to the setup steps, and for a non-zero exit from
"issue-triage.js" advise inspecting logs, re-running with a "--dry-run" or
verbose flag if supported, and retry steps; ensure the new guidance is concise,
uses the exact tokens "gh auth status", "GHIM-001 Phase 1", and
"issue-triage.js" so agents can find and follow the recovery actions.
| ``` | ||
| Issue received | ||
| ├── Is it a duplicate? → Label "duplicate", close with reference | ||
| ├── Is it spam/invalid? → Label "status: invalid", close | ||
| ├── Needs more info? → Label "status: needs-info", comment asking for details | ||
| └── Valid issue | ||
| ├── Bug → "type: bug" + priority + area | ||
| ├── Feature → "type: feature" + priority + area | ||
| ├── Enhancement → "type: enhancement" + priority + area | ||
| ├── Docs → "type: docs" + priority: P3/P4 | ||
| └── Tests → "type: test" + area | ||
| ``` |
There was a problem hiding this comment.
Add language specifier to the decision tree code block.
Flagged by markdownlint (MD040). Use text or plaintext for the ASCII tree.
📝 Proposed fix
-```
+```text
Issue received
├── Is it a duplicate? → Label "duplicate", close with reference🧰 Tools
🪛 markdownlint-cli2 (0.21.0)
[warning] 83-83: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.aios-core/development/tasks/github-issue-triage.md around lines 83 - 94,
The fenced ASCII decision tree block lacks a language specifier causing
markdownlint MD040; update the code fence around the tree to include a plaintext
language (e.g., change the opening fence from ``` to ```text) so the block
becomes ```text ... ``` and leave the contents unchanged; locate the ASCII tree
block in the decision flow (the block beginning with "Issue received" and the
tree of branches) and add the language tag to that opening fence.
| triage: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: github/issue-labeler@v3.4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if gh CLI is available and attempt to resolve the commit SHA
if command -v gh &> /dev/null; then
gh api repos/github/issue-labeler/git/refs/tags/v3.4 --jq '.object.sha' 2>/dev/null || echo "gh CLI failed"
else
echo "gh CLI not available"
fiRepository: SynkraAI/aios-core
Length of output: 187
🌐 Web query:
github/issue-labeler v3.4 tag commit SHA releases
💡 Result:
- Tag
v3.4→ commit SHA:c1b0f9f52a63158c4adc09425e858e87b32e9685(short:c1b0f9f) [1][2] - GitHub Release
v3.4is published for the same tag/commit (dated Jan 31, 2024) [3]
Sources: [1] [2] [3]
Pin the action to a full commit SHA instead of a mutable tag.
github/issue-labeler@v3.4 is a mutable tag — it can be silently repointed to different code, creating a supply-chain attack surface. GitHub recommends pinning actions to a commit SHA; to get a newer version you update the SHA, while referencing a tag or branch means the action may change without warning.
🔒 Proposed fix
- - uses: github/issue-labeler@v3.4
+ - uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/issue-labeler.yml at line 21, Replace the mutable action
pin "uses: github/issue-labeler@v3.4" with a full commit SHA reference for the
issue-labeler action (e.g., "uses: github/issue-labeler@<full-commit-sha>");
find the exact commit SHA from the issue-labeler repository's commits page or
the release tag's commit and update the workflow entry that currently reads
"uses: github/issue-labeler@v3.4" to that immutable SHA so the action is pinned
to a specific commit.
| Pesquisa completa em `docs/research/2026-02-20-github-issue-management/` cobrindo: | ||
| - GitHub Issue Forms YAML (GitHub Docs) | ||
| - GitHub Agentic Workflows (2026) | ||
| - actions/stale v10, github/issue-labeler v3.4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, find the story file and check the versions at the mentioned lines
echo "=== Checking GHIM-001.story.md ==="
fd "GHIM-001.story.md" . --type f 2>/dev/nullRepository: SynkraAI/aios-core
Length of output: 96
🏁 Script executed:
#!/bin/bash
# Find and list relevant files
fd "(GHIM-001|recommendations)" . --type f 2>/dev/null | head -20Repository: SynkraAI/aios-core
Length of output: 214
🏁 Script executed:
#!/bin/bash
# Look for the stale workflow file
fd "stale.yml" . --type f 2>/dev/nullRepository: SynkraAI/aios-core
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Search more broadly for story files
fd "\.story\.md" docs/ --type f 2>/dev/nullRepository: SynkraAI/aios-core
Length of output: 99
🏁 Script executed:
#!/bin/bash
# Look for files containing "GHIM" or "stale"
rg "GHIM-001|actions/stale" docs/ --type md 2>/dev/null | head -30Repository: SynkraAI/aios-core
Length of output: 1363
🏁 Script executed:
#!/bin/bash
# Check the docs/stories directory structure
ls -la docs/stories/ 2>/dev/null || echo "docs/stories not found"Repository: SynkraAI/aios-core
Length of output: 418
🏁 Script executed:
#!/bin/bash
# Search for any reference to actions/stale in the entire repository
rg "actions/stale" . --type md --type yaml --type yml 2>/dev/nullRepository: SynkraAI/aios-core
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Read the GHIM-001.story.md file to verify line numbers and exact content
cat -n docs/stories/active/GHIM-001.story.md | grep -A 2 -B 2 "actions/stale"Repository: SynkraAI/aios-core
Length of output: 1120
🏁 Script executed:
#!/bin/bash
# Also get line counts around the mentioned lines to be precise
wc -l docs/stories/active/GHIM-001.story.mdRepository: SynkraAI/aios-core
Length of output: 103
Update actions/stale version to v10 for consistency.
Line 31 cites actions/stale v10, but line 163 pins it to actions/stale@v9. The research documentation also references v10 across recommendations and analysis. Align line 163 to match:
Suggested fix for Line 163
-`actions/stale@v9` — stale issue lifecycle
+`actions/stale@v10` — stale issue lifecycle🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/stories/active/GHIM-001.story.md` at line 31, The doc references
inconsistent versions of the GitHub Action: update the pinned reference from
"actions/stale@v9" to "actions/stale@v10" so it matches the earlier mention
"actions/stale v10" and the rest of the document; search for the string
"actions/stale@v9" (or the exact line that pins the action) and replace it with
"actions/stale@v10" to keep the story and recommendations consistent.
| - [x] GitHub Action: `stale.yml` — marca stale 30d, fecha 7d, exempt P1/P2 | ||
| - [x] GitHub Action: `welcome.yml` — atualizada com labels novos + `pull_request_target` | ||
| - [x] Configuracao: `.github/issue-labeler.yml` regex para issues + `.github/labeler.yml` atualizado para PRs | ||
| - [ ] Cada Action executou pelo menos 1 vez com sucesso em issue de teste |
There was a problem hiding this comment.
Unchecked Phase 2 AC item conflicts with "Phase 2 complete" in the Change Log.
Line 56's AC — - [ ] Cada Action executou pelo menos 1 vez com sucesso em issue de teste — is still unchecked, yet the Change Log (line 236) declares Phase 2 complete. Either the item needs to be checked once an actual test-run succeeds, or the Change Log entry should note this as a conditional completion.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/stories/active/GHIM-001.story.md` at line 56, The AC checkbox "Cada
Action executou pelo menos 1 vez com sucesso em issue de teste" is still
unchecked while the Change Log declares "Phase 2 complete"; either mark that AC
as checked after a confirmed test-run or change the Change Log entry to indicate
conditional/partial completion; update the GHIM-001.story.md AC line to "- [x]
Cada Action..." when you have a successful run, or edit the Change Log's "Phase
2 complete" note to clarify it is conditional/pending that AC (referencing the
AC text and the Phase 2 Change Log entry) so they are consistent.
| ``` | ||
| type: bug (#d73a4a) type: feature (#a2eeef) | ||
| type: enhancement (#a2eeef) type: docs (#0075ca) | ||
| type: test (#ededed) type: chore (#ededed) | ||
|
|
||
| priority: P1 (#b60205) priority: P2 (#d93f0b) | ||
| priority: P3 (#fbca04) priority: P4 (#0e8a16) | ||
|
|
||
| status: needs-triage (#ededed) status: needs-info (#d876e3) | ||
| status: confirmed (#0e8a16) status: in-progress (#1d76db) | ||
| status: stale (#ffffff) | ||
|
|
||
| area: core (#006b75) area: installer (#006b75) | ||
| area: synapse (#006b75) area: cli (#006b75) | ||
| area: pro (#006b75) area: health-check (#006b75) | ||
|
|
||
| community: good first issue (#7057ff) | ||
| community: help wanted (#008672) | ||
| governance (#006b75) duplicate (#cfd3d7) wontfix (#ffffff) | ||
| ``` |
There was a problem hiding this comment.
Fenced code block is missing a language tag (MD040).
markdownlint-cli2 flags this block. Adding text (or plaintext) satisfies the rule without implying syntax highlighting.
📝 Suggested fix
-```
+```text
type: bug (`#d73a4a`) type: feature (`#a2eeef`)
...📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ``` | |
| type: bug (#d73a4a) type: feature (#a2eeef) | |
| type: enhancement (#a2eeef) type: docs (#0075ca) | |
| type: test (#ededed) type: chore (#ededed) | |
| priority: P1 (#b60205) priority: P2 (#d93f0b) | |
| priority: P3 (#fbca04) priority: P4 (#0e8a16) | |
| status: needs-triage (#ededed) status: needs-info (#d876e3) | |
| status: confirmed (#0e8a16) status: in-progress (#1d76db) | |
| status: stale (#ffffff) | |
| area: core (#006b75) area: installer (#006b75) | |
| area: synapse (#006b75) area: cli (#006b75) | |
| area: pro (#006b75) area: health-check (#006b75) | |
| community: good first issue (#7057ff) | |
| community: help wanted (#008672) | |
| governance (#006b75) duplicate (#cfd3d7) wontfix (#ffffff) | |
| ``` |
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)
[warning] 132-132: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/stories/active/GHIM-001.story.md` around lines 132 - 151, The fenced
code block in GHIM-001.story.md has no language tag and triggers markdownlint
MD040; update the opening fence (the triple backticks that precede the lines
starting with "type: bug..." etc.) to include a neutral language tag such as
text or plaintext (e.g., change ``` to ```text) so the block is explicitly
marked as plain text and the linter warning is resolved.
| - [ ] Todas as labels criadas e visiveis no repositorio (`gh label list` retorna taxonomia completa) | ||
| - [ ] Issue forms renderizam corretamente no GitHub (testar criando issue de teste) | ||
| - [ ] GitHub Actions executam sem erros no primeiro run (check Actions tab) | ||
| - [ ] 27 issues existentes re-triados com novas labels aplicadas |
There was a problem hiding this comment.
Definition of Done still says "27 issues" while AC and Change Log both record 31.
Line 63 (AC) and line 237 (Change Log) both confirm 31 issues were triaged. The DoD on line 173 was never updated from the original 27.
📝 Suggested fix
-- [ ] 27 issues existentes re-triados com novas labels aplicadas
+- [x] 31 issues existentes re-triados com novas labels aplicadas📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - [ ] 27 issues existentes re-triados com novas labels aplicadas | |
| - [x] 31 issues existentes re-triados com novas labels aplicadas |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/stories/active/GHIM-001.story.md` at line 173, Update the Definition of
Done entry in GHIM-001.story.md that currently reads "27 issues existentes
re-triados com novas labels aplicadas" to match the Acceptance Criteria and
Change Log which record 31 triaged issues; locate the "Definition of Done" /
"DoD" block (the line containing that Spanish/Portuguese sentence) and change
the numeral 27 to 31 so all sections (DoD, AC, Change Log) are consistent.
| | `.github/issue-labeler.yml` | Create | Done | | ||
| | `.github/labeler.yml` | Update | Done | | ||
| | `.github/issue-labeler.yml` | Create | Done | |
There was a problem hiding this comment.
Duplicate row for .github/issue-labeler.yml in the File List.
Lines 220 and 222 are identical entries. Remove one.
📝 Suggested fix
| `.github/issue-labeler.yml` | Create | Done |
-| `.github/issue-labeler.yml` | Create | Done |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/stories/active/GHIM-001.story.md` around lines 220 - 222, Remove the
duplicated table row for `.github/issue-labeler.yml` (there are two identical
entries in the file list); keep a single entry and delete the redundant one so
the markdown table remains valid and consistent.
Summary
Integrates code intelligence into 4 @dev development tasks for automatic IDS Gate G4 duplicate detection, conventions checking, and blast radius assessment — all with graceful fallback when no provider is available.
Changes
dev-helper.js(new) — 4 public functions:checkBeforeWriting,suggestReuse,getConventionsForPath,assessRefactoringImpact+RISK_THRESHOLDSandREUSE_MIN_REFSconstantsdev-develop-story.md— Added step 2 "Code Intelligence Check (IDS G4)" before file creationcreate-service.md— Added Step 0: pre-scaffold duplicate checkdev-suggest-refactoring.md— Added blast radius + risk level (LOW/MEDIUM/HIGH) in analysis phasebuild-autonomous.md— Added IDS G4 check in autonomous build loopentity-registry.yaml— Registered dev-helper entity with dependencies and usedBydev-helper.test.js(new) — 24 unit tests covering scenarios T1-T9 + edge casesKey Design Decisions
nullgracefully when no provider availableAcceptance Criteria
Test plan
docs/qa/gates/nog-3-dev-task-enhancement.yml🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Tests
Chores
Tooling