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).
Usage limits (issue #142). usage_limit admits the window wordings
(You've hit your weekly limit, Usage limit reached, …) 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 for 1 h from the newest limit (it outlives the killed session and a restart); when it expires the retry edges respawn as they would have, and a fresh pane still showing the notice re-arms it;
- paged — once per 6 h window, through the account-kind page;
- killed — the session is idle and useless;
- refunded — the spawn row is stamped
limited_at, and everyattempt_capcount leaves limited rows out (numbering stays monotonic, so session names never repeat). An account over its limit never caps a lane.
The same notice after real worker output (a tool call, the worker's own
prose, a quoted tool row) stays worker output. Each observation is one
usage.limited loop event per session: data: { kind: "usage_limit", source: "pane" | "first_turn", matched: "model_limit" | "usage_limit", model } — 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 (… attempt refunded)".
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.31
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| alissa_tools_github_devloop-0.8.31.tar.gz | 337.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| alissa_tools_github_devloop-0.8.31-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 687.0 kB
Release files / alissa_tools_github_devloop-0.8.31.tar.gz
| Download URL | alissa_tools_github_devloop-0.8.31.tar.gz |
|---|---|
| Size | 337.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8596bda8af059675e093efc52a7da1f97d2cdef9b1759b82baa5a7c47a6fc8a
|
|
BLAKE2b-256 checksum How to use checksums |
c183b944e6bc532994773f97672d85192a47bc650408a2627a744d1b2efa01d8
|
| 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.31-py3-none-any.whl
| Download URL | alissa_tools_github_devloop-0.8.31-py3-none-any.whl |
|---|---|
| Size | 349.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
daae1f03cb6dbfb2ab163c39055b5b91ffd73cfbd6828a83555b477b48c42667
|
|
BLAKE2b-256 checksum How to use checksums |
49f7a6d478440db328e8be4ce2b313c773c5040b5b5ca431923896bab7ec056a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.12
|