Skip to content

release: v0.3.0 \u2014 P0 hardening + full test suite + CI#3

Merged
alphacrack merged 13 commits into
mainfrom
development
Apr 17, 2026
Merged

release: v0.3.0 \u2014 P0 hardening + full test suite + CI#3
alphacrack merged 13 commits into
mainfrom
development

Conversation

@alphacrack

Copy link
Copy Markdown
Owner

Summary

Release PR consolidating development into main. This unfreezes main, which has been stuck at the initial commit. After this lands, main reflects the 0.3.0 release.

Contains 13 commits ahead of main:

What's in 0.3.0

See CHANGELOG.md for the complete entry. Highlights:

Security

  • Sandboxed exec() with safe-builtins map (no exec/eval/open/compile/breakpoint) and import whitelist driven from MAITHILI_MODULES. Closes audit finding SEC-001 (CRITICAL).
  • Two-layer import defense: static _validate_imports + runtime __import__ wrapper.
  • SECURITY.md with threat model and responsible-disclosure process.

Correctness (data-loss bugs fixed)

  • Transpiler no longer replaces keywords inside string literals. छपाउ("यह में है") stays intact instead of becoming print("यह in है").
  • Transpiler no longer replaces keywords inside longer identifiers. नवयुग stays intact instead of becoming __init__युग.
  • Linter no longer flags == comparisons as assignments.
  • Linter no longer flags नव (constructor) as unused.

Infrastructure

  • pyproject.toml (PEP 517/518) with pytest + coverage config.
  • 142-test pytest suite across 6 files (functional / linter / security / CLI / smoke). 95% coverage; critical modules ≥90%.
  • GitHub Actions CI: Python 3.9/3.10/3.11/3.12 × Ubuntu/macOS = 8-job matrix on every push and PR.
  • python -m maithili_dsl entry point; --version flag; named exit codes.

Compliance

  • LICENSE text completed (was [Your Name] / [MIT terms continued...] placeholders). Closes LIC-001 (CRITICAL).
  • CHANGELOG.md in Keep-a-Changelog format.
  • PR template enforcing test evidence + audit references.
  • README placeholder fixed (youruseralphacrack); CONTRIBUTING rewritten with real dev/test workflow.

Test Evidence

PR #2 shipped with all 8 CI jobs green (Python 3.9/3.10/3.11/3.12 × Ubuntu/macOS). CI will re-run on this PR against main — expected to pass identically.

Local verification before the PR #2 merge:

FUNCTIONAL 83 ✓   SECURITY 41 ✓   LOCAL 12 ✓   SMOKE 6 ✓
TOTAL 142 passed · 95% coverage · critical modules 98/90/98%

Breaking Changes

  • Python 3.6–3.8 no longer supported — bumped python_requires to >=3.9. Users still on 3.6–3.8 must pin python_maithili<0.3.
  • cli.run_dmai_file and cli.main now return an integer exit code (previously implicit None). Callers treating any return as "success" should now check for 0.

No other API changes.

Post-merge cleanup

After this merges:

Checklist

🤖 Generated with Claude Code

alphacrack and others added 13 commits October 4, 2025 22:05
Introduces the formal audit artifacts that drive the rest of this
change set: 16 findings across security, license, code quality,
packaging, and compliance, prioritized P0-P3. The follow-up commits
on this branch close every P0 item.

Also adds scripts/create_issues.sh for pushing the backlog into
GitHub Issues, and updates .gitignore to exclude pytest/coverage
artifacts and local Claude Code config.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the two placeholders that made the previous LICENSE
legally non-functional:
  - "Copyright (c) 2025 [Your Name]" -> "Copyright (c) 2025 Bishwas Jha"
  - "[MIT terms continued...]" -> full MIT grant + warranty disclaimer

Closes AUDIT_REPORT.md finding LIC-001 (CRITICAL): until now the
project had no enforceable license and could not legally be used
or redistributed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces naive str.replace() with a two-pass algorithm that splits
input into (string-literal, code) regions and only applies keyword
substitution to code regions, using custom lookbehind/lookahead for
the Devanagari block so keywords embedded in longer identifiers are
not matched.

Fixes two data-corrupting bugs proven in AUDIT_REPORT.md finding
CQ-001 (CRITICAL):
  - छपाउ("यह में है") no longer becomes print("यह in है")
    (the word में inside the string literal is preserved)
  - नवयुग = ५ no longer becomes __init__युग = 5
    (नव -> __init__ only fires at word boundaries)

The pre-compiled pattern cache keeps the hot path fast despite the
regex overhead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two false-positive fixes that blocked idiomatic Maithili code from
linting cleanly:

  1. Comparison operators (==, !=, <=, >=) were being parsed as
     assignments by the naive .split("=") logic, producing spurious
     "invalid variable name" errors on any conditional. Now detects
     the operator context before treating an = as an assignment.

  2. नव (mapped to __init__) was flagged as an unused function
     because it is never called by name — Python invokes it
     implicitly on class instantiation. Skipped from the unused-
     function post-scan.

Also ignores attribute assignments (e.g., स्वयं.नाम = ...) which
are never new-variable declarations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes AUDIT_REPORT.md finding SEC-001 (CRITICAL): previously any
.dmai file could do "आयात os" (which transpiled to "import os")
and then perform arbitrary filesystem or process operations with
the full authority of the CLI user.

The new execution model:
  - exec_globals no longer inherits the CLI's globals(); it gets a
    fresh {"__builtins__": safe_builtins} dict.
  - safe_builtins excludes __import__, exec, eval, compile, open,
    and breakpoint. __import__ is replaced with a whitelist-only
    variant that only permits modules in MAITHILI_MODULES values.
  - translate_imports() now returns the set of modules it actually
    translated so raw Python "import os" lines injected post-
    transpile (never surfaced from a Maithili import) are rejected.
  - _validate_imports() catches the rejected imports BEFORE exec
    runs, since Python's import statement does not always route
    through __import__.

Belt-and-suspenders: both layers (static validator + runtime
__import__ hook) must pass for a module to load, so bypassing one
still leaves the other in place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n -m entry

Wraps several packaging and CLI-ergonomics improvements that the
audit and tests both depend on:

  - Adds pyproject.toml (PEP 517/518) as the canonical metadata source,
    with pytest + coverage configuration co-located (closes PKG-001).
  - setup.py kept as legacy shim; reads version via regex (not import)
    so it works in isolated build envs. Bumps python_requires from
    >=3.6 (EOL) to >=3.9, aligning with the CI matrix.
  - maithili_dsl/__init__.py now exposes __version__ = "0.3.0" and
    __all__ (closes PKG-002, PKG-003). Single source of truth.
  - Adds maithili_dsl/__main__.py so `python -m maithili_dsl <file>`
    works without relying on the installed console script.
  - cli.main() now returns an integer exit code, accepts argv for
    testability, and supports --version / -V. run_dmai_file() uses
    named EXIT_* constants (NOT_FOUND, LINT_ERROR, IMPORT_BLOCKED,
    RUNTIME_ERROR, USAGE) so CI and smoke tests can assert on
    specific failure paths instead of just "non-zero".
  - requirements-dev.txt pins pytest + pytest-cov + pytest-timeout
    with compatible-range bounds.
  - .gitignore ignores .venv/ (in addition to the previously added
    pytest/coverage/claude entries).

No runtime dependencies added — the package still has zero runtime
deps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tiers

Closes AUDIT_REPORT.md finding CQ-002 (HIGH): the project had zero
automated tests. This commit adds 142 tests across 6 files:

  - tests/test_numeral.py       — every Devanagari digit + mixed text
  - tests/test_transpile.py     — every keyword in DEVNAGIRI_KEYWORD_MAP
      parametrized + explicit CQ-001 regression cases (string literals
      and word boundaries) + "transpiled output is valid Python"
  - tests/test_linter.py        — clean-code pass, == not flagged,
      नव constructor not flagged as unused, unbalanced paren/quote,
      line length, snake_case toggle, all known exception translations
  - tests/test_security.py      — _validate_imports rejects raw
      Python imports; _make_safe_import only permits whitelist;
      exec/eval/open/compile/breakpoint absent from safe_builtins;
      end-to-end attacks (import os, exec(), eval(), open()) rejected
      by run_dmai_file with correct exit codes
  - tests/test_cli.py           — every EXIT_* code is reachable by
      a test; subprocess invocation via `python -m maithili_dsl`
      works for --version, usage, and file execution
  - tests/test_smoke.py         — every example in examples/ runs
      end-to-end (parametrized); error.dmai is expected to be
      rejected by the linter, not executed

Coverage (measured locally with pytest-cov):

  maithili_dsl/__init__.py             100%
  maithili_dsl/cli.py                   98%
  maithili_dsl/transpiler/__init__.py  100%
  maithili_dsl/transpiler/linter.py     90%
  maithili_dsl/transpiler/mappings.py  100%
  maithili_dsl/transpiler/numeral.py   100%
  maithili_dsl/transpiler/transpile.py  98%
  TOTAL                                 95%

Critical modules (cli, transpile, linter) all at or above the
90% gate set in the implementation plan.

Run with: pytest -v --cov=maithili_dsl --cov-report=term-missing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes AUDIT_REPORT.md finding #6 (P1): the project had no CI/CD
gate — code could merge without any automated verification.

The workflow runs on every push and PR to main and development:

  - Matrix: 4 Python versions x 2 operating systems = 8 jobs.
  - Installs the package editable + dev deps with pip caching keyed
    on requirements-dev.txt + pyproject.toml.
  - Verifies both CLI entry points (`python -m maithili_dsl` and the
    `python_maithili` console script) respond to --version.
  - Runs the full pytest suite with coverage.
  - Runs a bash smoke loop over every .dmai in examples/, treating
    error.dmai as expected-to-fail so a regression that starts
    executing it would be caught immediately.
  - Uploads coverage.xml as an artifact from the ubuntu + 3.12 job.

Also adds .github/PULL_REQUEST_TEMPLATE.md to enforce test evidence
and audit-reference fields on future PRs — so the thing that's in
the root of this branch (a PR body tied to specific BACKLOG items)
becomes the default for everyone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… CONTRIBUTING

Closes four compliance / docs findings from AUDIT_REPORT.md:

  - SEC-003 / compliance "SECURITY.md MISSING": adds SECURITY.md with
    a responsible-disclosure contact, supported-version table, an
    explicit threat model pinned to the sandbox's enforcement layers,
    and an SLA for acknowledgement / triage / patch.

  - DOCS P3 "README references `youruser`": clone URL now points at
    alphacrack/python-maithili-dsl. Also adds a Security section
    linking to SECURITY.md, a Testing section documenting the
    pytest + coverage-gate workflow, and moves "Unit testing + CI/CD"
    out of Future Goals (it ships in this release). Replaces the
    future-goals list with still-open items (while / try-except /
    mypy).

  - DOCS P2 "CONTRIBUTING.md has duplicated README content": the
    entire README was pasted above the actual contributing section.
    Rewrites CONTRIBUTING.md from scratch with real dev setup
    (venv + editable install + requirements-dev), a test-tier table,
    the coverage gate, and a security-change policy requiring a new
    test + a "Security Considerations" PR section.

  - Adds CHANGELOG.md in Keep-a-Changelog format. The 0.3.0 section
    documents every Added / Fixed / Changed item on this branch,
    cross-referenced to the AUDIT_REPORT.md finding IDs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alphacrack alphacrack merged commit b96c51a into main Apr 17, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant