learn
“Manage project learnings.”
aipkg.jsonLICENSE.txtREADME.mdSKILL.mdSKILL.md.tmpl- 01SDI-185%MEDIUM
SKILL.md:5
detailhide
The skill's manifest claims 'Manage project learnings' but the preamble performs extensive telemetry collection, upgrade detection, feature discovery, and onboarding flows unrelated to the stated purpose. This scope creep means the skill executes unexpected side effects (analytics writes, configuration changes, feature prompts) when a user merely invokes a learning management command, violating principle of least surprise and potentially exposing users to telemetry without explicit consent at invocation time.
3preamble-tier: 24version: 1.0.05description: Manage project learnings.6triggers:7 - show learningsfix Separate the core learning management logic from framework boilerplate. Move telemetry, upgrade checks, and feature discovery to a dedicated initialization/setup phase that runs once per session, not on every skill invocation. Make the learn skill do only what its name promises.
- 02SDI-380%MEDIUM
SKILL.md:10
detailhide
The skill declares allowed-tools [Bash, Read, Write, Edit, AskUserQuestion, Glob, Grep] but the preamble executes external binaries (gstack-config, gstack-update-check, gstack-telemetry-log, etc.) and modifies configuration files (~/.gstack/*, ~/.claude.json reads, .gitignore writes, CLAUDE.md appends) without explicit declaration. This creates a hidden capability surface and makes tool scope verification impossible.
08 - what have we learned09 - manage project learnings10allowed-tools:11 - Bash12 - Readfix Either (1) declare all external binaries and config files in allowed-tools, or (2) move all preamble operations that invoke external binaries into a dedicated framework setup script that runs once per session, not inside domain skills.
- 03SDI-282%MEDIUM
SKILL.md:5
detailhide
The skill declares purpose 'Manage project learnings' but invokes telemetry collection (analytics writes to ~/.gstack/analytics/), upgrade detection, feature discovery prompts, and onboarding gates. These are framework concerns that violate separation of concerns and expose users to hidden behavioral changes and data collection when they expect a simple learning lookup/management tool.
3preamble-tier: 24version: 1.0.05description: Manage project learnings.6triggers:7 - show learningsfix Extract all telemetry, upgrade, and feature-discovery logic into a separate gstack framework initialization step. The learn skill should call only learnings-search, learnings-log, and related domain logic. Keep framework concerns in a bootstrap phase, not in domain skills.
- 04SQP-288%MEDIUM
SKILL.md:53
detailhide
Lines 53–67 silently append telemetry data to ~/.gstack/analytics/skill-usage.jsonl without user visibility or consent at the time of skill invocation. The condition `if [ "$_TEL" != "off" ]` gates this, but the default is telemetry 'on' and users may not be aware they are being tracked when invoking a seemingly innocent /learn command. This is especially problematic because telemetry happens in the preamble (automatically, before the user sees the skill's main output).
51_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no")52echo "LAKE_INTRO: $_LAKE_SEEN"53_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true)54_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no")55_TEL_START=$(date +%s)fix (1) Move telemetry writes to the end of the skill workflow, after the skill completes its main task, so users can see what the skill does before side effects occur. (2) Default telemetry to 'off' or 'anonymous' and require explicit opt-in via AskUserQuestion before the first telemetry write. (3) Log telemetry writes visibly (e.g., 'TELEMETRY: sent skill-usage event') so the user knows data is being collected.
- 05SQP-275%LOW
SKILL.md:36
detailhide
The preamble performs extensive file system operations (mkdir -p ~/.gstack/*, touch, find, rm) without user awareness. While these operations are not inherently dangerous, they silently modify the user's home directory structure and may interfere with other tools or user expectations. The operations happen automatically and invisibly whenever the skill runs.
34_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)35[ -n "$_UPD" ] && echo "$_UPD" || true36mkdir -p ~/.gstack/sessions37touch ~/.gstack/sessions/"$PPID"38_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')fix Make all file system side effects visible to the user (log them as output). For non-critical operations (cleanup, session tracking), either make them optional or move them to a scheduled maintenance task, not to every skill invocation. For critical operations (creating directories), do them only once per session, not per skill call.
- 06SQP-275%MEDIUM
SKILL.md.tmpl:100
detailhide
The prune function modifies the learnings.jsonl file by removing lines without proper transactional safety or backup mechanisms. While AskUserQuestion provides user confirmation, there is no rollback capability if deletion corrupts the file or if concurrent skill executions interfere. Loss of project learnings could impact team knowledge continuity.
098- C) Update it (I'll tell you what to change)099100For removals, read the learnings.jsonl file and remove the matching line, then write101back. For updates, append a new entry with the corrected insight (append-only, the102latest entry wins).fix Implement atomic file operations: create a backup before any deletion, use a temporary file for writes, and rename atomically only after validation succeeds. Add error handling to detect file corruption and restore from backup if needed.
- 07TR2Shadow Command Trigger70%MEDIUM
SKILL.md:1
detailhide
The trigger 'show learnings' conflicts with the common built-in command 'show' in many CLI tools and frameworks. A user typing 'show learnings' in a context where 'show' is already a command may invoke the wrong handler or cause ambiguity. This violates predictable command naming.
1---2name: learn3preamble-tier: 2fix (1) Rename the trigger to 'show-learnings' (kebab-case) or 'view learnings' (two-word phrase less likely to conflict). (2) Document the full trigger syntax in the skill README. (3) In the gstack framework, add collision detection for trigger names against reserved words.
- 08TM1Tool Parameter Abuse80%HIGH
SKILL.md:39
detailhide
Line 39 uses `find ... -exec rm {} +` to delete files without explicit user confirmation. Although the command targets only ~/.gstack/sessions files (stale sessions), the use of -exec rm on glob results is a well-known vector for accidental data loss if path expansion is incorrect or if the tool is later refactored. Additionally, the operation is silent (redirects stderr to /dev/null), hiding errors.
mkdir -p ~/.gstack/sessions touch ~/.gstack/sessions/"$PPID" _SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true _PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") _PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no") _BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")fix (1) Replace find -exec rm with explicit rm of specific files identified by find, with error checking. (2) Log which files are deleted and why (e.g., 'CLEANUP: removed stale session ~/.gstack/sessions/12345'). (3) Require explicit user consent (AskUserQuestion) before deleting any files outside the skill's managed directories.
- 09TM1Tool Parameter Abuse78%HIGH
SKILL.md:73
detailhide
Line 73 silently removes pending event files (`rm -f "$_PF"`) without logging or user awareness. While the operation targets framework state files (not user data), the silent deletion pattern is dangerous and makes debugging harder if state corruption occurs.
if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true fi rm -f "$_PF" 2>/dev/null || true fi break donefix (1) Log file deletions: `echo "STATE: removed pending event $_PF"`; (2) Before deleting, verify the file is in the expected directory; (3) If deletion fails, log a warning instead of silently suppressing the error.
- 10TM1Tool Parameter Abuse72%HIGH
SKILL.md:159
detailhide
Line 159 unconditionally removes ~/.gstack/.writing-style-prompt-pending without checking if the file exists or if it belongs to the current user's session. While the command redirects errors, the pattern of modifying shared state files without visibility is a code smell.
Always run (regardless of choice): ```bash rm -f ~/.gstack/.writing-style-prompt-pending touch ~/.gstack/.writing-style-prompted ```fix (1) Verify the file path is correct before removal; (2) Log the action: `echo "PREF: cleared writing-style prompt marker"`; (3) If this file is session-scoped, include the session ID in the filename to avoid collisions.
- 11TM1Tool Parameter Abuse85%HIGH
SKILL.md:271
detailhide
Line 271 proposes `git rm -r .claude/skills/gstack/` as a vendoring migration step. This is a **destructive operation** that deletes an entire directory tree from git. If executed without explicit user confirmation (a hard-stop confirmation, not just a yes/no in an AskUserQuestion), it risks losing the user's vendored gstack copy and breaking the project if the migration fails. The instruction to run `git commit` immediately after makes the deletion permanent.
- B) No, I'll handle it myself If A: 1. Run `git rm -r .claude/skills/gstack/` 2. Run `echo '.claude/skills/gstack/' >> .gitignore` 3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) 4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"`fix (1) Require a hard-stop confirmation: 'This will DELETE .claude/skills/gstack/ from git history. Type YES to confirm or CANCEL to stop.' (2) Dry-run first: show user what files will be deleted before asking for confirmation. (3) Create a backup branch before executing: `git checkout -b pre-gstack-migration-$(date +%s)`. (4) Only proceed if the backup succeeds and the user confirms.
- 12TM1Tool Parameter Abuse68%HIGH
SKILL.md:703
detailhide
Line 703 uses `rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID"` to clean up pending telemetry markers. While the operation targets framework state, the pattern of silent file deletion without logging makes it hard to debug if state gets corrupted or if the cleanup doesn't work as expected.
```bash _TEL_END=$(date +%s) _TEL_DUR=$(( _TEL_END - _TEL_START )) rm -f ~/.gstack/analytics/.pending-"$_SESSION_ID" 2>/dev/null || true # Session timeline: record skill completion (local-only, never sent anywhere) ~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"SKILL_NAME","event":"completed","branch":"'$(git branch --show-current 2>/dev/null || echo unknown)'","outcome":"OUTCOME","duration_s":"'"$_TEL_DUR"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null || true # Local analytics (gated on telemetry setting)fix (1) Log the cleanup action: `echo "TELEMETRY: flushed pending events for session $_SESSION_ID"`; (2) Verify the directory exists before removing files from it; (3) If cleanup fails, log a warning instead of silently suppressing errors with 2>/dev/null.