Skip to content

Jon's agent skills, rules, and scripts#1

Open
j0ntz wants to merge 52 commits into
mainfrom
jon
Open

Jon's agent skills, rules, and scripts#1
j0ntz wants to merge 52 commits into
mainfrom
jon

Conversation

@j0ntz
Copy link
Copy Markdown
Contributor

@j0ntz j0ntz commented Mar 24, 2026

edge-dev-agents

Complete agent-assisted development workflow for Edge repositories:
slash skills, companion scripts, coding standards, review standards,
and meta-tooling for maintaining the workflow itself.

The distributable Cursor content lives under .cursor/. This repo is the
versioned home for those skills, rules, scripts, and docs.

The canonical local doc lives at ~/.cursor/README.md. During
/convention-sync, that file is mirrored to edge-dev-agents/README.md, and
the repo copy should not keep a second .cursor/README.md.

Installation

Fresh machine (one command): clone this repo and run the bootstrap — it
installs everything (cursor skills/rules, the orchestration system, and shared
memories) into your home dir, seeds credentials.json from the example, and
links skills + shared memory:

git clone <this-repo> ~/git/edge-dev-agents && cd ~/git/edge-dev-agents && ./bootstrap.sh
# then edit ~/.config/agent-watcher/credentials.json with your real asana_token

For incremental onboarding instead of the full bootstrap:

1. Set the required env var in your ~/.zshrc:

export GIT_BRANCH_PREFIX=yourname   # e.g. jon, paul, sam

This drives branch naming and PR discovery across the workflow.

2. Sync the repo copy into ~/.cursor/:

This repo treats ~/.cursor/ as the canonical working copy. Use
/convention-sync to move local changes into edge-dev-agents, or run the
companion script directly when onboarding:

~/.cursor/skills/convention-sync/scripts/convention-sync.sh \
  --repo-to-user --stage

3. Verify prerequisites:

  • gh CLI: gh auth login
  • jq: brew install jq
  • ASANA_TOKEN env var for Asana-backed workflows

Table of Contents

Orchestration & Memory

Beyond cursor skills/rules, this repo mirrors two more portable trees so a
second Mac is reproducible from a single clone + ./bootstrap.sh:

  • agent-watcher/ — the autonomous agent orchestration system (Asana
    watcher daemon + worktree/iOS-sim pool helpers + watchdog). Canonical home is
    ~/.config/agent-watcher (XDG config; ~/.agents is not an established
    standard). Committed: scripts, *.js, asana-config.json, README.md,
    oom-repro/HANDOFF.md+scripts/, and credentials.example.json. Never
    committed:
    credentials.json (secret) and machine-local state
    (pool.json, slots.json, watchdog-state.json, *.state, *.log,
    oom-repro/forensics, oom-repro/logs).
  • memory-shared/ + bin/link-shared-memory.sh — cross-cutting Claude
    memory notes that should surface regardless of working directory. Canonical
    home ~/.claude/memory-shared; link-shared-memory.sh symlinks them into the
    per-project auto-memory dirs (~/.claude/projects/<project>/memory/) and
    maintains a managed block in each MEMORY.md. Claude auto-memory itself is
    machine-local (per Anthropic docs) and is intentionally NOT synced — only the
    shared store is. The only officially global Claude file is ~/.claude/CLAUDE.md
    (generated here from always-apply rules).

/convention-sync keeps all of the above in sync (home → repo); bootstrap.sh
does the reverse (repo → home) on a new machine.

Architecture

edge-dev-agents/
├── README.md          # Synced copy of ~/.cursor/README.md
└── .cursor/
    ├── skills/        # Slash skills (*/SKILL.md) + companion scripts
    ├── scripts/       # Shared portability and dashboard scripts
    ├── commands/      # Minimal command wrappers
    └── rules/         # Coding and workflow standards (.mdc)

Separation of concerns:

  • Skills (SKILL.md) define workflows, rules, and step ordering.
  • Companion scripts (.sh, .js) handle deterministic work like git,
    GitHub, Asana, and JSON processing.
  • Rules (.mdc) provide persistent guidance that gets loaded by context.
  • Repo docs describe the system and how the distribution copy fits
    together.

All GitHub API work uses gh CLI. Deterministic git operations should live in
scripts, not be re-described independently across skills.

Skills (Slash Skills)

Core Implementation

Skill Description
/im Implement an Asana task or ad-hoc feature/fix with clean, structured commits
/one-shot Legacy-style task-to-PR flow built from planning, implementation, and PR creation
/pr-create Create a PR from the current branch with repo-aligned title and body
/dep-pr Create dependent Asana tasks and downstream PR work in another repo
/changelog Update CHANGELOG entries using repo conventions

Planning and Context

Skill Description
/asana-plan Build an implementation plan from Asana or ad-hoc requirements
/task-review Fetch and summarize Asana task context
/q Answer questions before taking action

Review and Landing

Skill Description
/pr-review Review a PR against coding and review standards
/pr-address Address PR feedback with fixup commits, replies, and optional autosquash
/pr-land Land approved PRs, including prepare, merge, publish, GUI dep updates, staging cherry-picks, and Asana updates
/staging-cherry-pick Cherry-pick landed staging-targeted commits onto the staging branch

Asana and Utility

Skill Description
/asana-task-update Generic Asana mutations such as attach PR, assign, unassign, and status updates
/standup Generate daily standup notes from Asana and GitHub activity
/chat-audit Audit Cursor chat sessions for waste, drift, and workflow gaps
/convention-sync Sync ~/.cursor/ with this repo, mirror the local README to repo root, and update PR descriptions from README.md
/author Create, revise, and debug skills, scripts, and rules
/fix-eslint Apply documented fixes for recurring Edge React GUI ESLint warnings

Companion Scripts

PR Operations

Script What it does API
pr-create.sh Create a PR for the current branch with standardized body formatting gh pr create
pr-address.sh Fetch unresolved feedback, reply, resolve threads, and mark items addressed gh api REST + GraphQL
github-pr-review.sh Fetch PR context and submit reviews gh pr view + gh api
github-pr-activity.sh Gather recent PR activity and CI context for standups gh api graphql

PR Landing Pipeline (/pr-land)

Script Phase What it does
pr-land-discover.sh Discovery Find relevant PRs and approval state
pr-land-comments.sh Comment check Detect unresolved inline, review-body, and top-level comments
git-branch-ops.sh Shared git ops Run deterministic autosquash and push operations for multiple skills
pr-land-prepare.sh Prepare Autosquash, rebase, detect conflicts, and verify
pr-land-merge.sh Merge Rebase again, verify, and merge sequentially
pr-land-publish.sh Publish Version bump, changelog update, commit, and tag
pr-land-extract-asana-task.sh Asana extraction Pull task IDs from landed PR metadata
upgrade-dep.sh GUI deps Bump one package on the current branch, run yarn/prepare, commit lockfile updates. Caller must sync develop first.
staging-cherry-pick.sh Staging Cherry-pick staging-qualified commits onto staging
verify-repo.sh Verification Run changelog and code verification

Build, Lint, and Analysis

Script What it does
lint-commit.sh Run lint-assisted commits and autosquash fixups through the shared git helper
lint-warnings.sh Auto-fix and summarize remaining TypeScript/ESLint warnings
install-deps.sh Install dependencies and run project prepare steps
cursor-chat-extract.js Parse Cursor chat exports into structured summaries

Asana and Portability

Script What it does
asana-get-context.sh Fetch task details, comments, subtasks, and attachments
asana-task-update.sh Apply reusable Asana task mutations
asana-create-dep-task.sh Create dependent Asana tasks
asana-whoami.sh Return current Asana identity
convention-sync.sh Sync ~/.cursor/ and edge-dev-agents in either direction, mirroring ~/.cursor/README.md to repo root README.md
generate-claude-md.sh Regenerate ~/.claude/CLAUDE.md from always-apply rules
tool-sync.sh Sync Cursor assets into OpenCode and Claude-compatible formats
port-to-opencode.sh Convert Cursor files into OpenCode-friendly mirrors

Shared Modules

Module Purpose
edge-repo.js Shared repo resolution, git wrappers, conflict detection, verification, and gh helpers for the pr-land pipeline

Rules (.mdc files)

Rule Purpose
workflow-halt-on-error.mdc Stop skill execution on script failures and fix the workflow definition first
load-standards-by-filetype.mdc Load language standards before editing or investigating file-specific issues
answer-questions-first.mdc Answer user questions before editing or mutating state
no-format-lint.mdc Avoid manual formatting and formatting-only lint work
typescript-standards.mdc TypeScript and React editing standards
review-standards.mdc Review-specific bug patterns and conventions
eslint-warnings.mdc Documented fixes for recurring ESLint warnings
after_each_chat.mdc Post-chat automation rule used in the local workflow

Design Principles

  1. Scripts over duplicated reasoning. Deterministic git, API, and parsing
    work belongs in shared scripts.
  2. gh over raw GitHub HTTP calls. Use the authenticated CLI for GitHub
    workflows.
  3. Shared helpers over drift. Reusable mechanics like autosquash and push
    should live in one script and be consumed by multiple skills.
  4. Rules before edits. Load the relevant standards before editing code or
    evaluating lint/type failures.
  5. Workflow fixes before workarounds. If a skill is wrong, fix the skill or
    script instead of patching around it in an ad-hoc way.
  6. Canonical local copy. ~/.cursor/ is the working source of truth;
    edge-dev-agents is the distribution and review copy.

j0ntz added 8 commits April 13, 2026 18:20
Document the current repo structure, workflow skills, and shared
scripts using the older conventions README format as a template.
task-review: resolve target repo by grepping code for concrete symbols,
not task text. Title/description demoted to hints; prefix table kept as
an exception shortcut; linked PRs short-circuit; cross-repo work splits
into Asana subtasks.

pr-create: drop all reviewer-assignment logic. Reviewer choice is a
human step; status-setting and review-hour estimation went with it.
--asana-attach remains.

one-shot: stop defaulting --asana-assign. --asana-attach only.

pr-land: add CHANGELOG placement warning handling so dated-release
entries can be moved to Unreleased/staging before pushing.
- New slot-fixup.sh: slot HEAD fixup next to its target's group (used by pr-address and bugbot after each lint-commit.sh).
- pr-finalize-fixups.sh: derive mode (autosquash | preserve) from the latest human activity on the PR; new squash-stale subcommand for the Fixups-A-before-B trigger; finalize action now push-only in preserve mode, autosquash+force-push in autosquash mode.
- pr-address review-mode subcommand: returns mode + latestHumanActivity for shared use.
- Simplified human-reviewer detection across pr-address and pr-land scripts: exclude only currentUser + bots (drop prAuthor exclusion). Works uniformly for solo and collab PRs — author gets no special treatment.
- pr-address and bugbot SKILL.md: new Step 1.5 (squash-stale before address-pass) and per-fixup slot-fixup.sh after every lint-commit.sh.
@j0ntz j0ntz changed the title Bootstrap edge-dev-agents with skills, rules, and scripts Jon's agent skills, rules, and scripts May 1, 2026
j0ntz added 2 commits May 1, 2026 13:43
- Pull-before-push gate: auto-fetch origin every run; abort --stage/--commit if origin is ahead.
- Per-file divergence warnings: compare each affected path's most-recent commit timestamp to the local file's mtime; flag stale-local, deletion, and re-adding-deleted cases.
- New JSON output fields: originBranch, originAhead, warnings.
- SKILL.md: present new warnings in the dry-run summary; document the new policy and edge cases.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

Identified several concrete security issues in newly added workflow scripts/rules. Leaving inline comments on the affected lines only.

Open in Web View Automation 

Sent by Cursor Security Review Agent: Security Reviewer

Checkout the PR branch to ensure file reads reflect the PR's code, not the current local branch:

```bash
git fetch origin <headRef> && git checkout <headRef>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
<headRef> is inserted unquoted into a shell command (git fetch ... && git checkout ...) even though PR branch names are attacker-controlled input.

Impact: A crafted branch name containing shell metacharacters (for example command substitution) can execute arbitrary commands in the review agent environment.

Resolve the full 40-char SHA for the PR's head branch:

```bash
HEAD_SHA=$(git rev-parse origin/<BRANCH>)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
<BRANCH> is interpolated directly into git rev-parse origin/<BRANCH> in a shell command path that derives branch names from PR metadata.

Impact: Malicious branch names can trigger command injection during bugbot workflow execution, leading to arbitrary code execution in automation context.

IMPLEMENTOR_NAME="current user"

# Phase 3: Create the task
NOTES_JSON=$(python3 -c "import json; print(json.dumps('''$TASK_NOTES'''))")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
User/task-controlled content is embedded directly into inline Python source via triple-quoted interpolation ('''$TASK_NOTES''' / '''$TASK_NAME''') in python3 -c calls.

Impact: An input containing ''' can break out of the string literal and inject executable Python statements, resulting in code execution in the automation runtime.

ext = os.path.splitext(name)[1].lower()
if ext in DOWNLOAD_EXTS and url:
os.makedirs(download_dir, exist_ok=True)
dest = os.path.join(download_dir, name)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
Attachment filename name is treated as a trusted path segment via os.path.join(download_dir, name) before writing downloaded content.

Impact: Filenames containing traversal segments (for example ../) can write files outside the intended task download directory, enabling workspace boundary bypass and arbitrary file overwrite in reachable paths.


<rules>
<rule id="every-turn">Execute at the end of every chat turn without exception.</rule>
<rule id="full-response">Send the complete response content, not an abbreviated summary.</rule>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
[Privacy Guard] This rule mandates forwarding the complete chat response every turn to an external Telegram sink without user confirmation or selective minimization.

Impact: Sensitive content (credentials, proprietary code, internal data) can be exfiltrated outside the expected trust boundary by policy.

jq --arg k "$KEY" --arg v "$VALUE" '.[$k] = $v' env.json > env.json.tmp
mv env.json.tmp env.json

git add env.json
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
[Privacy Guard] The script stages and commits env.json updates after accepting raw secret values as direct inputs.

Impact: Secret material can become durable plaintext in git history and propagate through clones/backups, creating long-lived credential exposure risk.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

Net-new security findings on current head after deduplication against prior automation comments and threads.

Open in Web View Automation 

Sent by Cursor Security Review Agent: Security Reviewer

if (!existsSync(path.join(repoDir, ".git"))) {
console.error(`Cloning ${repo}...`);
try {
execSync(`git clone git@github.com:EdgeApp/${repo}.git "${repoDir}"`, {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
repo is interpolated into a shell command string passed to execSync (git clone git@github.com:EdgeApp/${repo}.git ...) without validation or argument separation.

Impact: A crafted repo value can trigger shell command injection and arbitrary code execution in the automation environment.


function fetchPrBody(repo, prNumber) {
const endpoint = `repos/EdgeApp/${repo}/pulls/${prNumber}`;
const result = execSync(`gh api "${endpoint}" --jq '.body'`, {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
fetchPrBody() builds a shell command string with untrusted repo (gh api "repos/EdgeApp/${repo}/pulls/${prNumber}" ...) and executes it via execSync.

Impact: Malicious input can exploit shell expansion and execute arbitrary commands while extracting PR metadata.

COMMIT_MSG="Update $KEY in env.json"
fi

ssh "$SERVER" bash -s -- "$KEY" "$VALUE" "$COMMIT_MSG" "$REMOTE_REPO" <<'REMOTE'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM
The secret value is passed as a positional CLI argument ("$VALUE") into ssh ... bash -s -- ..., which exposes it in process arguments and often shell history.

Impact: Sensitive credentials can be disclosed to local observers or process-monitoring tooling on the calling host.

Re-validate eslint after update-eslint-warnings runs; if the staged
config fails lint (e.g. a naive graduation of a still-dirty file),
restore eslint.config.mjs and abort. With this safety net in place,
/pr-land's --skip-lint patch (e21dca8) is no longer needed — revert
verify-repo.sh, pr-land-{prepare,merge}.sh, edge-repo.js, SKILL.md
back to file-scoped lint.

Also fixes pr-land-discover.sh's reviewer-state computation: only
APPROVED/CHANGES_REQUESTED/DISMISSED change effective state, so a
later COMMENTED reply doesn't shadow a prior APPROVED.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

Net-new security findings on current head after module triage, severity filtering, and duplicate suppression against existing automation threads/comments.

Open in Web View Automation 

Sent by Cursor Security Review Agent: Security Reviewer


function checkNpmPublished(packageName, version) {
try {
const info = execSync(`npm view ${packageName}@${version} version`, {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
checkNpmPublished builds an execSync shell string using packageName and version from package.json (npm view ${packageName}@${version} version) without argument-safe execution.

Impact: A crafted package name/version can trigger command injection and arbitrary code execution in automation environments running this publish flow.

const fileCount = changedFiles.split("\n").length;
console.log(`▶ eslint (${fileCount} changed file${fileCount === 1 ? "" : "s"} vs ${baseRef})...`);
const eslintResult = runCommandWithLog(
`npx eslint ${fileList}`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
verify-repo.sh builds an eslint command string from git-derived filenames and executes it via execSync; wrapping paths in quotes is not sufficient shell escaping.

Impact: A malicious filename in a branch can break command quoting and execute arbitrary shell commands during repository verification.

"skills",
"verify-repo.sh"
);
const baseArg = baseRef != null ? ` --base "${baseRef}"` : "";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
runVerification/related helpers interpolate derived repo/path values into execSync shell strings instead of passing argument arrays.

Impact: If attacker-influenced repo/path metadata reaches these call sites, command injection can occur during pr-land preparation/verification operations.

</sub-step>
</step>

<step id="4" name="Upload to gist and clean up">
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
The standup workflow templates externally sourced task/PR text directly into markdown and then requires uploading the rendered output to a persistent GitHub gist, without a mandatory scrub/redaction step.

Impact: Sensitive code-adjacent content (paths, snippets, internal details) from source systems can be durably exfiltrated to an external artifact.

Comment thread .cursor/commands/hudl.md
</sub-step>
</step>

<step id="4" name="Upload to gist and clean up">
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
The HUDL flow maps GitHub-derived PR text fields into a generated markdown report and uploads it to a gist, but does not require sanitization/minimization of potentially sensitive content.

Impact: Code-related or sensitive operational details can leak into externally stored summaries.

# Copy file only if changed, respecting --dry-run
sync_file() {
local src="$1" dest="$2"
if [[ ! -f "$dest" ]]; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
sync_file copies directly to destination paths without rejecting symlink destinations or enforcing canonical containment.

Impact: A pre-positioned symlink under the sync tree can redirect writes to unintended files, enabling arbitrary file overwrite as the current user.

for oc_skill_dir in "$OPENCODE_DIR"/skills/*/; do
[[ -d "$oc_skill_dir" ]] || continue
local name
name=$(basename "$oc_skill_dir")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
Cleanup uses rm -rf on globbed skill directories without symlink validation.

Impact: A symlinked directory entry can cause deletion outside the intended sync root, leading to destructive data loss in attacker-chosen paths.

j0ntz and others added 3 commits May 27, 2026 16:38
…es), no-slop, asana ↔ GitHub graceful degrade, yarn→npm migration support

- skills/build-and-test: real iOS UI test path via maestro for edge-react-gui
- skills/debugger: attach to Hermes JS VM via CDP; set file:line breakpoints
- skills/no-slop: writing-style rule + bad/good examples
- skills/one-shot: yolo-stop-at-pr, pr-watch-loop, agent_status-on-pending-task
- skills/asana-task-update: --attach-pr graceful when ASANA_GITHUB_SECRET unset
- skills/install-deps.sh, verify-repo.sh: npm vs yarn auto-detect
- scripts/tool-sync.sh: strip trailing slash from glob (double-slash fix)
…ts, slots)

Host-local snapshot mirrored for paper trail. The live copy under
~/.config/agent-watcher/ is what runs; this directory is not deployed from.

Run up to MAX_CONCURRENT (default 2) agent sessions in parallel, each in its own
git worktree, on its own cloned iOS sim, on its own Metro port, behind a
load/RAM resource guardrail. Slot accounting is by live tmux sessions, not Asana
state, so a dead-but-in-flight task frees its lane.

Changed for this work:
- asana-watcher.js: multi-pick per tick (cap by live sessions, guardrail, pick
  oldest N Pending, per-task setup -> clone -> allocate -> spawn). --simulate-* dry-run flags.
- rc-watchdog.js: completion sweep reaps the slot (delete sim, remove
  worktree+branch, release slot) via shared helpers.
- spawn-test-session.sh: slot mode (--slot-index ...) exports $AGENT_SIM_UDID /
  $AGENT_METRO_PORT and cwd=worktree; legacy positional mode preserved.
- resume-agent.sh: --recover re-provisions a missing slot for an in-flight task.
- asana-config.json: new .watcher.* knobs.
- NEW lib/slots.js: atomic, lock-guarded slot allocator (lib + CLI).
- NEW clone-ios-sim.sh / delete-ios-sim.sh: per-slot sim clone / delete.
- NEW setup-task-workspace.sh / cleanup-task-workspace.sh: per-task worktree.
- NEW gc-worktrees.sh: manual orphan cleanup.
- NEW slots.json: slot state (initial empty template).
- NEW README.md: design doc (architecture, knobs, env contract, limitations).

All 5 smoke checks pass (cap, guardrail, worktree setup/cleanup, sim
clone/boot/delete, atomic concurrent slot writes).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

maxBuffer: 10 * 1024 * 1024,
})
} catch (err) {
throw new Error(`curl failed for ${method} ${endpoint}: ${err.message}`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM
err.message from execSync is rethrown verbatim here. In Node, that message includes the failed command string, which in this call contains Authorization: Bearer ${TOKEN}.

Impact: if this error is logged or surfaced, the Asana PAT can be exposed to logs/observers and used for API impersonation.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 50180c1. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

const slot = slots.allocate({ task_gid: task.gid, worktree_path: worktreePath, sim_udid: simUdid })
log(` slot ${slot.slot_index}: metro ${slot.metro_port}, sim ${simUdid}`)

const r = spawnSync(`${DIR}/spawn-test-session.sh`, [
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
This watcher launches unattended --yolo sessions and then auto-accepts the permissions-bypass dialog before injecting /one-shot --yolo from Asana task content.

Impact: anyone who can move/create tasks in the watched project can trigger autonomous privileged command execution on the runner without a human confirmation boundary.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 6f8419f. Configure here.

j0ntz added 2 commits May 29, 2026 18:21
…, with actionable gist in the auto-loaded index description
…e -p for one-off low-volume tests; keep orchestration interactive)
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

<step id="1" name="Pipe response to send script">
Pipe your full response to the send script via a heredoc in a single Shell command:
```bash
python3 ~/.cursor-autopilot/telegram-send.py << 'ENDOFMSG'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
The rule instructs embedding full response content in a heredoc with a fixed delimiter (ENDOFMSG). If attacker-controlled content includes a standalone ENDOFMSG line, the heredoc closes early and trailing lines are interpreted as shell input.

Impact: This can turn reflected content into command execution in the agent runtime when the prescribed command is executed.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 28149b4. Configure here.

j0ntz added 8 commits May 30, 2026 11:07
…intended note folder missing); refine working-style memory with cost-conscious -p/included-credits framing
Replace the brittle login denylist (cursor / chatgpt-codex-connector) with
__typename-based bot detection so all automated reviewers, including the
Cursor Security Reviewer, are classified correctly. Mirrors pr-land-comments.sh.
Add a hard ownership override: when currentUser != prAuthor, review-mode
forces preserve mode and squash-stale becomes a noop, so /pr-address and
/bugbot never autosquash or force-rewrite another author's branch. Leave
fixups on top for the owner to squash at merge.
Extend the ownership guard to thread resolution. fetch now emits isOwner;
when currentUser != prAuthor the workflow replies to threads but never
resolves them or posts mark-addressed markers — leave them for the owner.
Pairs with the finalize preserve-mode guard (no history rewrite).
- .cursor/rules/act-autonomously.mdc: act-first/investigate-yourself autonomy rule
- agent-watcher/rc-watchdog.js: dismiss the /remote-control modal (Esc) after the
  revive probe so it can never wedge session input (the idle-session 'hang').
- Branch guard: refuse user-to-repo --stage on the default branch or any branch
  that isn't the open sync PR's head (--force-branch override). Stops a fresh
  clone (on main) from pushing the sync to main and bypassing the PR.
- Blocking warnings: deletion/stale-local/re-adding-deleted now HARD-BLOCK
  staging (were advisory) — the hole that let a stale machine clobber. --force
  override; the fix is --repo-to-user first. Divergence-aware message.
- .syncignore read from the repo (canonical) so a fresh machine inherits excludes.
- Extra trees: staleness + deletion warnings AND reverse-sync (--repo-to-user now
  restores agent-watcher/memory-shared/bin, never deleting home-local state).
- Content-hash (rsync -c) compare so mtime churn no longer inflates the diff.
- SKILL.md updated to match.
From edge-referral-server PR #86 review: list keys built solely from
optional fields collapse to identical keys, and unguarded date query
params turn empty/garbage input into NaN-keyed range queries.
The pane footer 'Remote Control active' is now the signal, replacing the blunt
20-min idle timer that spuriously pinged (and modal-wedged) healthy idle sessions.
- indicator ABSENT + idle>threshold -> revive
- indicator PRESENT -> never ping on idleness; only a slow 3h backstop re-register
  clears a half-open bridge the near-end indicator can't detect.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

fi
local t0 t1
t0=$(date +%s)
if cp -cR "$src" "$dst" 2>/tmp/setup-clone.log; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM
This script writes to fixed log paths in shared /tmp (/tmp/setup-clone.log, and similarly for worktree/cherry-pick logs). On multi-user hosts, predictable /tmp filenames can be pre-created as symlinks and then clobbered via shell redirection.

Impact: A local attacker on the same host can redirect these writes to victim-writable files and cause cross-user file overwrite.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 2c043ec. Configure here.

j0ntz added 5 commits June 4, 2026 17:56
- asana-watcher: spawn cwd is now ~/git (not a pre-made gui worktree). The agent
  reads the task, determines the target repo(s), and creates its own co-located
  per-task worktrees — so server tasks aren't forced into the gui worktree.
- setup-task-workspace: removed the npm-migration cherry-pick (a one-off bridge,
  not script logic; yarn->npm migration is finishing). Now works on ANY repo; base
  ref resolves per-repo (prefer origin/develop, else the repo's default branch).
- one-shot SKILL: create co-located worktrees per touched repo; for gui+dependency
  tasks, updot-link the modified dep into the gui worktree; keep DEBUG_* false.
Indicator-up sessions now get ZERO pings — the 3h backstop re-register is gone.
A half-open bridge (indicator up but unreachable) is left for the operator to
reconnect on next attach. Reversible: re-add the rcUp+backstop branch (constant
kept). Trying zero-ping-on-healthy for now.
countActiveSessions counted every claude-asana-* tmux session, so a non-task
session sharing the prefix (e.g. interactive claude-asana-main) ate a slot and
blocked task pickup. Now counts only claude-asana-<numeric-gid>.
…letion, testID commits

- one-shot: finalize-gate (single 'done' definition: CI + all reviewer_bots clean
  -> set Complete), owned by the continuous monitor; reviewer-bots allowlist
  (config) + semantic catch for unknown bots -> flagged as report follow-up;
  run-report doc now posts ONLY at Complete (never on block).
- bugbot: owns completion via finalize-gate when invoked standalone with a task
  GID (manual finish after a blocker).
- pr-address: never sets completion (one-off; automated reviews land after it).
- build-and-test: add missing testIDs in a separate commit when a maestro run had
  to coordinate-fall-back (scoped exception to no-mutation).
- asana-config: reviewer_bots allowlist (default [cursor[bot]]).
…st: dep-in-gui integration

- one-shot: local /build-and-test now runs BEFORE /pr-create (steps 4/5 swapped),
  and ONLY in --yolo (orchestration) — manual runs skip it. Status stays
  Developing through local verification; Testing = the external PR watch. Watch
  loop now semantically re-tests after a fix only when the change is behavioral.
- build-and-test: gui-dependency-integration — a change to an Edge gui dependency
  (core/accb/plugins/piratechain/zcash/...) is not done until it runs in the app:
  create a co-located edge-react-gui worktree, updot-link the modified dep, run
  the maestro app test, make required gui-side changes autonomously.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

exit 2
}

MAIN_REPO="$REPOS_ROOT/$REPO"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
--repo is used as an untrusted path segment when building MAIN_REPO and WT ($HOME/git/$REPO, $HOME/git/.agent-worktrees/$TASK_GID/$REPO) without normalization or containment checks.

Impact: A crafted repo value like ../../../workspace can escape the intended worktree root and create worktrees outside ~/.agent-worktrees, enabling out-of-bound filesystem writes from task-controlled inputs.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 845431a. Configure here.

}

MAIN_REPO="$REPOS_ROOT/$REPO"
WT="$WORKTREES_ROOT/$TASK_GID/$REPO"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
WT is derived from untrusted --task-gid and --repo segments and then used in rm -f "$WT/env.json" before any containment validation.

Impact: Traversal values can redirect deletion outside the intended worktree root and remove arbitrary files reachable by the automation user.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 845431a. Configure here.

j0ntz added 5 commits June 5, 2026 14:02
gui-dependency-integration now picks the right link mechanism per dep instead of
'leave DEBUG_ false + updot':
- webview-plugin deps (accountbased :8082, exchange :8083, currency-plugins :8084,
  plugins :8101, core) -> set DEBUG_<DEP> in env.json + run the dep's webpack
  dev-server; app loads the local bundle live, no gui rebuild.
- metro/native deps (login-ui, monero, piratechain/zcash/zano) -> updot bake.
- login: YOLO_USERNAME/YOLO_PIN auto-login the test account (edge-rjqa3/1111).
…ev-server steps

- edge-core-js -> updot, not DEBUG_CORE: DEBUG_CORE loads the core webview from
  hardcoded http://localhost:8080 (races init, cleartext/ATS, and a core hiccup
  kills the whole app). updot bakes core in statically — reliable for headless.
- Webview-plugin DEBUG_ path now spells out the dep-repo side: 'yarn start'
  (webpack serve) backgrounded in the DEP worktree for the test's duration, with
  an updot fallback if the dev-server link is flaky.
- build-and-test gui-dependency-integration: detect each repo's PM by lockfile;
  dep dev-server is 'yarn start' OR 'npm start'; updot/prepare shown for both
  (npm form uses 'npm run updot -- <dep>'). Explicit 'yarn is going away' note.
- one-shot worktree note: defer the link/test mechanism to build-and-test's
  gui-dependency-integration (single source of truth), PM-by-lockfile.
…escribed

- one-shot: drop all DEBUG_/updot/env.json references — it only provisions the
  task's worktrees; build-and-test owns linking + the gui integration test (and
  creates the co-located gui worktree itself).
- build-and-test: reframe the dep-link step as a toolbox the agent picks per task
  (updot = any-dep safe default; DEBUG_<dep>+dev-server = webview plugins, your
  call; core: prefer updot). Whether DEBUG_ is true/false follows what the task
  actually linked — not a fixed per-dep table.
… tests

For a single-asset task that drives a wallet, the agent MAY comment out unrelated
currency plugins in src/util/corePlugins.ts (currencyPlugins map) to cut app
load/init time. LOCAL-ONLY — never committed; verify corePlugins.ts isn't in any
commit. Also updated no-mutation to list its (now several) scoped exceptions.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

if [[ -f "$CACHE_FILE" ]]; then
cached=$(cat "$CACHE_FILE")
else
cached=$(curl -s "https://app.asana.com/api/1.0/users/me?opt_fields=gid,name" \
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM
The Asana token is sent via a literal Authorization: Bearer ... header in a curl command line. On shared hosts, command-line arguments are often observable to other local users/process tools.

Impact: local observers can recover the bearer token and use it to perform unauthorized Asana API actions as the token owner.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 1463a4c. Configure here.

j0ntz added 3 commits June 5, 2026 14:39
…n docs

- branch: setup-task-workspace takes --branch; defaults to $GIT_BRANCH_PREFIX/<gid>
  (prefix=jon) instead of opaque agent/<gid>. one-shot passes jon/<short-name>
  (kebab slug from task title), same across all repos of a task.
- cleanup-task-workspace: reads the worktree's ACTUAL branch (no longer derivable
  from gid), deletes only if it matches agent/* or $GIT_BRANCH_PREFIX/* (safety).
- session UUID: spawn-test-session generates+exports AGENT_SESSION_UUID (logged);
  recorded in the run-report frontmatter + the plan, for traceability.
- plan + run-report filenames now carry <gid>-<short-name>, not gid alone.
…ap-* yamls

Canonical buy-quote* flows still sync (harness default). Per-task GUI dev
flows (swap-*) stay local-only via .syncignore until the orch yaml strategy
is decided.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Stale comment

// npx/npm calls) resolve to the real binaries. Tradeoff: this bypasses Socket's
// supply-chain scanning for yarn commands. Only applied when the repo uses
// yarn; npm runs keep the working socket wrapper.
function shimFreePath() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: HIGH
The new shimFreePath() helper deliberately strips ~/.agent-shims from PATH, which disables the Socket package-manager wrapper for yarn install and subsequent yarn script execution paths in this verifier.

Impact: verification on untrusted PR branches can execute attacker-controlled dependency lifecycle or repo scripts outside the intended package-manager trust guardrails.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 4e027ad. Configure here.

… rc-watchdog→session-watchdog

- session-watchdog: completions retire (rename + keep claude alive) and free
  sim+Metro+slot; blocked=Yes sheds sim+Metro but keeps the session/slot for
  unblock; keep_completed_sessions caps retired sessions; Metro port freed to
  avoid slot-index collision.
- author: name-tracks-scope principle + confirm-before-rename checklist item.
- build-and-test: blocking-in-turn-waits rule (no unbounded background waits).
- max_concurrent/sim_pool bumped to 3.
command -v gh &>/dev/null || { echo "Error: gh CLI not found. Install: https://cli.github.com" >&2; exit 2; }
gh auth status &>/dev/null 2>&1 || { echo "Error: gh not authenticated. Run: gh auth login" >&2; exit 2; }

STATE_DIR="${TMPDIR:-/tmp}/pr-watch-${OWNER}-${REPO:-all}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Agentic Security Review
Severity: MEDIUM
This new cache directory is created under ${TMPDIR:-/tmp} and subsequent JSON cache files are written with default permissions, which are commonly world-readable on shared hosts.

Impact: private PR metadata/comment content can be exposed to other local users or processes on multi-user runners.

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 087c93b. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant