pl8-base
pl8-base is the data layer for PL8,
a lightweight issue tracker for AI agents and the people working alongside
them, backed by DynamoDB. It's a Python library, not a service: it defines
PL8's entities (Issue, Space, IssueBlocker), its events, and the
BasePL8 manager that reads and writes them against a DynamoDB table. It's
the source of truth for PL8's data model, consumed by the Lambda functions
that actually run PL8 in AWS.
To use PL8, you don't need this library. Deploy PL8 to your own AWS
account and use it through pl8-cli;
see the setup
and usage
guides. pl8-base is for working on PL8 itself.
Status: alpha (0.0.x). Interfaces may change between releases.
Getting started
Install
pip install pl8-base
or with uv:
uv add pl8-base
Basic usage
BasePL8 wraps a boto3 DynamoDB client and a structured logger. Error
logging passes arbitrary keyword args through to be merged into the log
record (e.g. self.logger.error(msg, item=item)), which a stdlib
logging.Logger rejects — pass an
aws-lambda-powertools
Logger instead (pip install aws-lambda-powertools — it's not a dependency
of this package, since only your logger instance needs it, not pl8-base
itself). It also expects a table already provisioned with PK/SK and a
GSI1 global secondary index (GSI1PK/GSI1SK) — see
Deploying below.
import boto3
from aws_lambda_powertools import Logger
from pl8_base.manager import BasePL8
from pl8_base.types import IssueStatus
pl8 = BasePL8(
dynamodb_client=boto3.client("dynamodb"),
table_name="pl8",
logger=Logger(),
)
space = pl8.create_space(
space_id="eng",
name="Engineering",
description="Issues for the engineering team",
)
issue = pl8.create_issue(
space_id="eng",
title="Fix login bug",
description="Users can't log in on Safari",
status=IssueStatus.TODO,
)
pl8.transition_issue(space_id="eng", issue_id=issue.issue_id,
status=IssueStatus.IN_PROGRESS)
Rules
BasePL8 enforces PL8's entity rules and raises an error from
pl8_base.errors when a call breaks one:
| Rule | Error |
|---|---|
| Create a Space before creating Issues in it | DDBMissingError |
| Delete a Space's Issues before deleting the Space | DDBSpaceNotEmptyError |
DONE is final: an Issue can't move from DONE to any other status |
DDBTerminalStatusError |
An Issue with unfinished blockers can't leave BLOCKED |
DDBStillBlockedError |
A DONE Issue can't be added as a blocker |
DDBBlockingIssueDoneError |
A write passed version= fails if the item has changed since |
DDBVersionConflictError |
Retrying one of these unchanged won't help. DDBTransactionConflictError is
different: it means contention that BasePL8 already retried, nothing was
applied, and the same call can be retried. The full rules are in
Entities.
Some updates happen in the background rather than in the call that caused
them, such as moving a blocked Issue back to TODO when its last blocker
finishes. The handle_* methods apply them, driven by the DynamoDB stream
and events that pl8-services wires up; see
Events.
Deploying
pl8-base only talks to a DynamoDB table you already have; it doesn't
provision or run anything in AWS itself.
pl8-services provisions the
table, event bus and queues, and runs the Lambdas that use this library. See
the setup guide
to deploy it.
Repositories
| Repo | What it is |
|---|---|
| pl8-docs | User docs and architecture docs |
| pl8-services | OpenTofu infrastructure and Lambda code you deploy |
| pl8-cli | The pl8 command line (PyPI) |
| pl8-base | This repo: Python data layer and source of truth for the data model (PyPI) |
Contributing
See CONTRIBUTING.md.
License
Release files for pl8-base 0.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pl8_base-0.0.4.tar.gz | 25.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pl8_base-0.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 58.3 kB
Release files / pl8_base-0.0.4.tar.gz
| Download URL | pl8_base-0.0.4.tar.gz |
|---|---|
| Size | 25.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6af5817f6fac78e4e9d038c2a67c1e32f38d19e5126a03c4a7d77200e0b705fa
|
|
BLAKE2b-256 checksum How to use checksums |
e3760fc6dcc14e559948e7761b0a10f7e60f4f95e5711f7719ff297aa616da4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency logRelease files / pl8_base-0.0.4-py3-none-any.whl
| Download URL | pl8_base-0.0.4-py3-none-any.whl |
|---|---|
| Size | 33.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
acafe84f108369b0aba0d0e6a22cc5765a671dd9c824f6caf1278b8d0dfdd477
|
|
BLAKE2b-256 checksum How to use checksums |
4fe657171dc6c383102578d7d276a8565f700be7b9cd8f8eae802dd31e2d905c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency log