MayLang – Explainable Change Standard CLI for reducing AI tech debt.
Project description
MayLang CLI
Explainable Change Standard — a minimal, universal spec that reduces AI tech debt across ANY language or repo.
MayLang is a lightweight convention: every meaningful change ships with a Change Package (.may.md file) that documents intent, contract, invariants, patch, verification, and debug map in a single, machine-readable Markdown file with YAML frontmatter.
maylang-cli is the tiny Python CLI that creates and validates these packages.
Import note: The Python package is
maylang_cli(underscore) to avoid namespace conflicts. The PyPI name ismaylang-cli. The CLI command ismay.
What Is a MayLang Change Package?
A .may.md file lives at maylang/MC-<id>-<slug>.may.md and contains:
---
id: "MC-0001"
type: change
scope: fullstack
risk: low
owner: "team-alpha"
rollback: revert_commit
ai_used: false
---
# Intent
Add session caching to reduce auth latency by 40%.
# Contract
- Input: session token (JWT)
- Output: cached session object
- Side-effects: writes to Redis
# Invariants
1. Tokens are never stored in plain text.
2. Cache TTL ≤ session expiry.
# Patch
```diff
--- a/auth/sessions.py
+++ b/auth/sessions.py
@@ -12,6 +12,9 @@
def get_session(token: str) -> Session:
- return db.query(Session).filter_by(token=token).first()
+ cached = redis.get(f"sess:{token}")
+ if cached:
+ return Session.from_cache(cached)
+ session = db.query(Session).filter_by(token=token).first()
+ redis.setex(f"sess:{token}", session.ttl, session.to_cache())
+ return session
Verification
pytest tests/test_sessions.pycurl -H "Authorization: Bearer $TOKEN" localhost:8000/me
Debug Map
| Symptom | Likely cause | First file to check |
|---|---|---|
| 401 after deploy | Cache not warmed | auth/sessions.py |
| Stale session data | TTL mismatch | config/redis.yml |
### Required Frontmatter Keys
`id`, `type`, `scope`, `risk`, `owner`, `rollback`, `ai_used`
### Required Headings (in order)
1. `# Intent`
2. `# Contract`
3. `# Invariants`
4. `# Patch`
5. `# Verification` — must contain at least one runnable command
6. `# Debug Map`
---
## Installation
```bash
# Recommended (isolated install)
pipx install maylang-cli
# Or with pip
pip install maylang-cli
For development:
git clone https://github.com/mayankkatulkar/maylang-cli.git
cd maylang-cli
pip install -e ".[dev]"
Usage
Create a New Change Package
may new \
--id MC-0001 \
--slug auth-sessions \
--scope fullstack \
--risk low \
--owner "team-alpha" \
--rollback revert_commit
This creates maylang/MC-0001-auth-sessions.may.md from the built-in template.
Validate Change Packages
# Always require at least one .may.md
may check
# Same as above (explicit)
may check --require always
# Only require when files in specific paths changed
may check --require changed --base origin/main --paths auth/,payments/,db/migrations/
Exit Codes
| Code | Meaning |
|---|---|
0 |
All checks passed |
2 |
Missing required MayLang file |
3 |
Validation error (bad frontmatter, wrong headings, etc.) |
Enforce Diff Block
By default, the Patch section is not strictly validated for a diff block. To require one:
may check --enforce-diff
Bump Version
# Bump patch version (0.1.0 → 0.1.1)
may version --bump patch
# Bump minor version (0.1.0 → 0.2.0)
may version --bump minor
# Bump major version (0.1.0 → 1.0.0)
may version --bump major
This updates the version field in your pyproject.toml.
Project Structure
maylang-cli/
├── maylang_cli/
│ ├── __init__.py # Package marker
│ ├── _version.py # Version via importlib.metadata
│ ├── bumper.py # Version bump helper
│ ├── cli.py # Argparse CLI (entrypoint: may)
│ ├── checker.py # High-level check orchestration
│ ├── parser.py # .may.md parsing & validation
│ └── template.py # Built-in template for `may new`
├── tests/
│ ├── test_check_required.py
│ ├── test_frontmatter.py
│ ├── test_headings_order.py
│ ├── test_verification.py
│ ├── test_enforce_diff.py
│ └── test_version_bump.py
├── .github/workflows/ci.yml
├── .gitignore
├── LICENSE
├── README.md
└── pyproject.toml
Company Adoption Guide
Why Adopt MayLang?
- AI Accountability — Every AI-assisted change has a human-readable spec.
- Cross-team Clarity — Backend, frontend, and infra teams share one format.
- Audit Trail — Change packages live in git; they're versioned and reviewable.
- CI-enforceable — Block PRs that lack proper documentation.
Step-by-Step
- Install:
pip install maylang-cliin your CI environment. - Create a change package for every meaningful PR:
may new --id MC-0001 --slug add-rate-limiter --scope backend --risk medium --owner "platform-team"
- Fill in the template — document intent, contract, invariants, patch, verification steps, and debug map.
- Add CI enforcement (see below).
- Review
.may.mdfiles in PR reviews just like code.
Suggested Team Conventions
| Decision | Recommendation |
|---|---|
| When to require | Use --require changed --paths for gradual adoption |
| ID format | MC-NNNN (monotonically increasing) |
| Who writes it | The PR author, reviewed by the team |
| AI changes | Set ai_used: true in frontmatter |
| Rollback | Always specify a concrete rollback strategy |
Company Adoption: CI Snippet
# In your CI pipeline:
pipx install maylang-cli
may check --require changed --base origin/main --paths auth/,payments/,db/migrations/
Or as a GitHub Actions step:
name: MayLang Check
on:
pull_request:
branches: [main]
jobs:
maylang:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install maylang-cli
- name: Validate MayLang Change Packages
run: may check --require changed --base origin/main --paths auth/,payments/,db/migrations/
For repos that want to enforce MayLang on every PR:
- run: may check --require always
To also enforce diff blocks in the Patch section:
- run: may check --require always --enforce-diff
Manual PyPI Release (Option A)
# 1. Install build tools
python -m pip install -U build twine
# 2. Build wheel + sdist
python -m build
# 3. Upload to TestPyPI first
python -m twine upload --repository testpypi dist/*
# 4. Verify in a fresh venv
python -m venv /tmp/test-maylang && . /tmp/test-maylang/bin/activate
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ maylang-cli
may --version
deactivate && rm -rf /tmp/test-maylang
# 5. Upload to production PyPI
python -m twine upload dist/*
# 6. Install from PyPI
pipx install maylang-cli
See docs/RELEASING.md for the full release checklist.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maylang_cli-0.1.1.tar.gz.
File metadata
- Download URL: maylang_cli-0.1.1.tar.gz
- Upload date:
- Size: 20.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c361d3f356ab5c6d884063bdaa3501869905ba0c221617cbd768a76a7d285798
|
|
| MD5 |
b8498d9eadc674474d1bb903b63bdf6a
|
|
| BLAKE2b-256 |
8ed28a9dac95534d6215bd94a9a14434fe65de5ef785f93fc331a1725d108cd5
|
File details
Details for the file maylang_cli-0.1.1-py3-none-any.whl.
File metadata
- Download URL: maylang_cli-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8c524627636bb8305dbb30aff3f23ceca55abb65b57100b08a8b8ca814f144e
|
|
| MD5 |
81a8115464c27a1587da3e93eeadcf52
|
|
| BLAKE2b-256 |
4eb6fe2d53be770dc4b7d592976b9df61d421d314c9855b6ec98a56e5a013123
|