Skip to main content

alissa-tools-github-devloop

The alissa.tools.github.devloop module: a GitHub watcher that turns alissa:develop-labeled issues into fresh developer sessions — the developer-side counterpart of alissa-tools-github-reviewloop.

This distribution ships only that module. Everything above it — alissa, alissa.tools, alissa.tools.github — is a PEP 420 namespace package with no __init__.py, so other distributions in other repositories can contribute their own packages under the same namespace:

alissa/                                  ← namespace (no __init__.py)
└── tools/                               ← namespace
    └── github/                          ← namespace
        ├── devloop/      __init__.py    ← THIS distribution
        └── reviewloop/   __init__.py    ← ships from alissa-github-review-daemon

The rule: a distribution owns a leaf package and declares only that subtree (find_namespace_packages(include=[PACKAGE, f"{PACKAGE}.*"])). Adding an __init__.py at any namespace level would claim it for one distribution and shadow the others.

Install

pip install -e ./alissa-tools-github-devloop

Console scripts

Command Entry point
alissa-devloop alissa.tools.github.devloop.__main__:main

Layout

src/main holds the package tree, src/test mirrors it as test_*. The distribution version lives in the plain-text version file next to the module it versions (src/main/alissa/tools/github/devloop/version), read by both setup.py and version.py.

Account-level conditions

The prompt responder (prompts.py classifies, loop.py acts) treats four pane conditions as the ACCOUNT's, not the worker's — nothing a keystroke can answer: login_expired, auth_rejected (a 401), usage_limit and out_of_credits. Each pages the operator once per kind per 6 h on the lane's issue/PR and holds every new spawn while it stands (at most 1 h on one pane, then kill-and-retry re-confirms) — except usage_limit, whose session is never killed and whose hold is the ledger's (below).

Usage limits (issues #142, #144). usage_limit admits the window wordings (You've hit your weekly limit, Usage limit reached, …), the "limit reached … resets …" family (Claude usage limit reached. Your limit will reset at 5pm (America/New_York)., 5-hour limit reached ∙ resets 3pm, Opus weekly limit reached ∙ resets Oct 6, 1pm) and the MODEL-named one Claude Code prints now — You've reached your Fable limit. Run /usage-credits to continue or switch models with /model. (also Opus, Sonnet, …): one capitalised model token, a known family name or any token corroborated by that trailing hint on the same line. An over-limit account answers the directive with that notice as the worker's ONLY assistant turn and leaves the session idle at ❯, which the banner rule (never a ● row) cannot see, so the first-turn limit check reads the responder's capture of any young worker (develop-*, fix-*, maintain-*, revert-*, spawned by this ledger inside the last stale_minutes): the notice, above an idle prompt, with no other ● turn since the directive. A match (source: "first_turn", matched: "model_limit", the model) is:

  • held — the daemon-wide spawn hold, clocked on the ledger from the newest limit (it survives a restart and a listing failure) and lifted only when a spawn made AFTER the limit gets through its first turn: after 1 h ONE probe spawn is admitted at a time (none while a probe is in flight, none while another account notice holds; under max_sessions the probe is judged without the kept limited sessions, which would otherwise fill the cap for good); a probe whose first turn is the notice again is refunded, re-arms the clock and is killed — it did no work, and keeping it would add one session per hour of the limit (past max_sessions too), so the live sessions stay at the ones the limit found at work plus at most the one probe in flight; the first probe that does real work lifts the hold (usage-limit-lifted: on the escalation ledger, escalation.usage_limit_lifted on the wire) and each kept limited session's lane gets a line saying to resume it;
  • paged — once per 6 h window, through the account-kind page;
  • never killed (issue #144; a failed probe, above, is the one exception) — a retry would hit the same wall, and the idle session is the lane's own work for the operator to resume once the account is back (or alissa tmux kill, to let the retry edge respawn); the wedge kills skip a limited session too;
  • refunded — the spawn row is stamped limited_at, and every attempt_cap count leaves limited rows out (numbering stays monotonic, so session names never repeat). An account over its limit never caps a lane.

A usage-limit BANNER on a working session (source: "pane") is held the same way: its row is stamped (refunded), the hold is the ledger's, and the session is never killed. The same notice after real worker output (a tool call, the worker's own prose, a quoted tool row) stays worker output. Each limited session is one usage.limited loop event: data: { kind: "usage_limit", source: "pane" | "first_turn", matched: "model_limit" | "usage_limit", model, resetsAt? } — resetsAt only when the notice states a reset, as an ISO-8601 UTC instant when that needs no guess (the legacy |<epoch> form, or a clock time with an explicit zone) and as the stated phrase otherwise; no pane text, no credential material.

The fix edge stops presuming. A stale fix round with no triage reply from the author used to be re-enqueued on the timer alone ("presumed dead"). It now reads the tmux roster first: ALIVE is in flight (the responder owns a live idle pane; a once-per-episode "Fix loop stalled?" ping floors the wait), INDETERMINATE defers one pass, and only DEAD respawns — "CONFIRMED dead", or, after a refunded limit, "previous session limited (usage limit; attempt refunded)". A kept limited session reads ALIVE, so no edge respawns over it.

The re-enqueue guard (issue #144)

The issue edge's respawn rule reads the linked-PR signal over every PR state: GitHub.linked_pull_requests walks the timeline once and reports each same-repo cross-referenced PR as open, merged or closed. When a stale attempt's session is CONFIRMED dead with no open PR, a merged PR of the daemon's own that closes the issue is SKIPPED "finished (PR #n merged)" and a closed-unmerged one is SKIPPED "closed unmerged — orchestrator's page" — never a respawn (provenance: token author and a closing keyword, fetched; an unreadable candidate stands the respawn down). And _spawn re-reads the issue immediately before every enqueue: a closed issue is SKIPPED "issue closed between search and spawn", nothing is claimed, and the reserved slot is handed back. The respawn-with-resume on an open draft PR is unchanged.

License

Licensed under the Apache License, Version 2.0 — the LICENSE and NOTICE files shipped with this distribution carry the full text and the attribution and trademark terms. Both ship inside the sdist and the wheel's .dist-info.

"Alissa" and "Fahera" are trademarks of CORE FAHERA ENTERPRISE HOLDINGS S. DE R.L. and are not covered by the license — the grant covers the code, not the names.

Metadata

Release files for alissa-tools-github-devloop 0.8.33

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for alissa-tools-github-devloop 0.8.33
File Size Uploaded
alissa_tools_github_devloop-0.8.33.tar.gz 349.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for alissa-tools-github-devloop 0.8.33
File Interpreter ABI Platform
alissa_tools_github_devloop-0.8.33-py3-none-any.whl Python 3 none any Details

Total release size: 711.5 kB

Release files / alissa_tools_github_devloop-0.8.33.tar.gz

Download URL alissa_tools_github_devloop-0.8.33.tar.gz
Size 349.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c30812b95a82bc43c393b7e187df765d7b0927690ed559c609a40ecf9f0568f7
BLAKE2b-256 checksum
How to use checksums
5c1f132b7e4284a11eb9f568ab51b0ab45cbc213a09009a73c8f2177bd070a8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / alissa_tools_github_devloop-0.8.33-py3-none-any.whl

Download URL alissa_tools_github_devloop-0.8.33-py3-none-any.whl
Size 361.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
562dbbd6b6e613e9c523fe66447bfc25c7dc383ca7388a928c7bd8521a586f1a
BLAKE2b-256 checksum
How to use checksums
e22e7f50127f0529b70c9b2cbb1eae891a578133499bccd07211b4ce26ee3a14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

0.8.45

2 release files

0.8.44

2 release files

0.8.43

2 release files

0.8.42

2 release files

0.8.41

2 release files

0.8.40

2 release files

0.8.35

2 release files

0.8.34

2 release files

This release

0.8.33 This release

2 release files

0.8.32

2 release files

0.8.31

2 release files

0.8.30

2 release files

0.8.29

2 release files

0.8.28

2 release files

0.8.27

2 release files

0.8.26

2 release files

0.8.25

2 release files

0.8.24

2 release files

0.8.23

2 release files

0.8.22

2 release files

0.8.21

2 release files

0.8.20

2 release files

0.8.19

2 release files

0.8.18

2 release files

0.8.12

2 release files

0.8.11

2 release files

0.8.10

2 release files

0.8.9

2 release files

0.8.8

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page