Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/onenot8/issueLoop/llms.txt

Use this file to discover all available pages before exploring further.

The fix-apply API lets you attach a proposed shell command to a ticket, verify it against a configured allowlist, execute it, re-run the associated test to confirm the fix worked, and resolve the ticket automatically on success. Every command execution — whether allowed or denied — is written to an audit log. The fix-apply layer is disabled by default; you must explicitly allowlist commands in config/permission.yaml before any command can be run.

propose_fix

Stores a shell command in the ticket’s proposed_fix field. This does not execute anything — it is a staging step before calling apply_fix.
ticket = issueloop.propose_fix(ticket_id, "sed -i 's/old_value/new_value/' src/config.py")
ticket_id
str
required
UUID of the ticket to attach the proposed fix to.
patch_or_command
str
required
Shell command string to store. This value is checked against the permission allowlist when apply_fix is called.
Returns the updated ticket dict with proposed_fix set, or None if the ticket was not found.

apply_fix

Checks the ticket’s proposed_fix against the permission allowlist, runs it if allowed, re-runs the ticket’s test, and advances the ticket status based on the outcome.
result = issueloop.apply_fix(ticket_id)
# {"status": "resolved", "ticket_id": "...", "attempts": 1}
ticket_id
str
required
UUID of the ticket to fix. Must have a proposed_fix set (call propose_fix first).
max_retries
int
default:"3"
Maximum number of fix attempts before the ticket is automatically escalated to needs_human.
timeout
int
default:"600"
Timeout in seconds for the shell command execution.
Returns a dict with the following fields:
status
str
One of:
  • "resolved" — command ran, test passed, ticket is now done
  • "retry" — command ran, test failed, attempts incremented, ticket reset to pending
  • "escalated" — command ran, test failed, max_retries exhausted, ticket is now needs_human
  • "denied" — command was not in the allowlist, ticket state unchanged
ticket_id
str
UUID of the ticket that was processed.
attempts
int
The attempt count at the time of the result (present for resolved, retry, and escalated).
reason
str
Present only when status is "denied" — describes which allowlist rule blocked the command.
apply_fix requires propose_fix to have been called first. If ticket.proposed_fix is empty, a ValueError is raised. When the ticket has a test_id, the outcome is determined by re-running that specific test. When no test_id is set, the fix command’s own exit code is used as the pass/fail signal.

check_permission

Returns True if the command is allowlisted for the given repository, False otherwise. This is a read-only check — it writes an audit entry but does not execute the command.
allowed = issueloop.check_permission("pytest tests/unit/", "myrepo")
cmd
str
required
Shell command string to check.
repo
str
required
Repository name to check against. The allowlist merges global rules with per-repo rules from config/permission.yaml, and also auto-allows any command listed in the repo’s test_manifest.json.
Returns True or False. Does not raise on denial — call run_guarded from the permissions module directly if you want an exception on denial.

get_permission_audit_log

Returns audit log entries recorded by the permission system. Every call to check_permission or apply_fix writes an entry — both allowed and denied outcomes are logged.
log = issueloop.get_permission_audit_log(repo="myrepo", limit=20)
repo
str
Optional repository filter. None returns entries across all repos.
limit
int
default:"50"
Maximum number of entries to return. Returns the most recent limit entries.
Returns a list of audit entry dicts, newest entries last:
ts
str
ISO 8601 UTC timestamp of the permission check.
event
str
One of allowed_exact, allowed_pattern, or denied.
repo
str
Repository the command was checked for.
command
str
The command string that was evaluated.
detail
str
For allowed_pattern events, the regex pattern that matched. Empty for other events.
Use get_permission_audit_log() to diagnose unexpected denials. If a command you expect to be allowed is showing up as denied, check that its exact text matches an allowed_exact entry or that it fully matches one of the allowed_patterns regexes (patterns use re.fullmatch, not substring search).

Build docs developers (and LLMs) love