Skip to content

Latest commit

 

History

History
105 lines (91 loc) · 8.59 KB

File metadata and controls

105 lines (91 loc) · 8.59 KB

Maintainer Cycle

Vision

Locutus is the reference implementation for cross-language standard library functions in JavaScript. Every function should be:

  1. Verified - Tested against actual language runtimes (not just JS unit tests)
  2. Documented - Clear examples, edge cases, and differences from native
  3. Typed - Full TypeScript definitions
  4. Modern - ESM, ES2022 dist target, and browser-facing compatibility aligned to baseline widely available with downstream
  5. Dependency Free - Locutus only has devDependencies for tooling, but zero for consumers

Workflow

These steps cover the most important maintainer tasks. When you finish the last, start again at step 1.

Note that for any task, it's important to first get ample context. Search past issues, check project goals, review recent commits, and search the codebase. See if the work was already done and whether it fits the project philosophy.

  1. Finish any pending work that is still open locally. This can be determined by looking at docs/prompts/LOG.md and inspecting the worktree. Update the last iteration if needed according to the rules in docs/prompts/LOG.md, open a new one for the current iteration, updating it with plans, key learinngs, progress as you go. Revise the document if it is in violation of its rules.

  2. Use gh to check on pending PRs. First run gh auth status to understand what our GitHub identity is. Make sure all PRs have reviews by other people than our identity (fixable only when PRs are submitted by others), that PRs pass (fixable only if they were submitted by US), fix what can be fixed, then re-check next iteration. If all is green, merge. LLMs should refrain from commenting on PRs, but deep reviews on PRs by others are allowed.

  3. Check GitHub Security separately from issues/PRs:

    • inspect repository security advisories and dependency/vulnerability alerts
    • use concrete commands, not memory:
      gh auth status
      gh api repos/locutusjs/locutus/security-advisories --paginate --jq 'map(.state) | group_by(.) | map({state: .[0], count: length})'
      gh api repos/locutusjs/locutus/security-advisories --paginate --jq 'map(select(.state=="triage")) | map({ghsa_id, summary, severity, created_at})'
      gh api graphql -f query='query { repository(owner:"locutusjs", name:"locutus") { vulnerabilityAlerts(first: 100, states: OPEN) { nodes { number createdAt securityVulnerability { package { name ecosystem } advisory { ghsaId summary severity } vulnerableVersionRange } } } } }'
    • distinguish between:
      • published historical advisories (record/history)
      • open advisory triage work
      • automated dependency alerts
    • do not trust automated reports blindly; verify:
      • whether the affected package is actually in our dependency tree
      • whether it affects the published runtime library or only build/test/website tooling
      • whether the vulnerable path is realistically reachable in our usage
      • whether there is a narrow upstream or transitive remediation available
    • prefer the smallest honest response:
      • fix and release if runtime/package users are affected
      • fix without release if it is website/build-only
      • dismiss/close with a precise rationale if the report is not a real Locutus vulnerability
    • when in doubt, preserve a high bar for package-level advisories; parity semantics or caller misuse are not automatically GHSA-worthy
  4. Triage issues. Confirm repro, decide scope, and say no when needed to protect project goals (see ## Vision, README.md, CHANGELOG.md, and website/source/about.md). LLMs should refrain from commenting on Issues.

  5. To continuously modernize the project, revise the Backlog/Roadmap in CHANGELOG.md. Don't forget about the website, which lives in this repo and is deployed via GHA. Check off items and/or move them into releases as appropriate.

  6. Before any new product work, audit upstream discovery and tracked scope. The flow is:

    • run corepack yarn discover:upstream-surface <language> to materialize the raw canonical catalog from runtime/docs/source
    • inspect the raw diff and fix discovery first if it over- or under-shoots
    • run corepack yarn fold:upstream-surface <language> when the discovered catalog looks right and you want to accept it into the tracked snapshot YAML
    • run corepack yarn audit:upstream-scope <language> to compare tracked scope against raw canonical discovery
    • use docs/upstream-surface-scope.yml as the explicit audit/planning contract for tracked scope, not as a discovery input
    • if official namespaces are missing from tracked scope, broaden scope first
    • if a namespace is too broad, either narrow/exclude it at the source layer or keep it with a broad inventory default after folding
    • only resume product work once raw discovery is trustworthy and the tracked target surface for the chosen area is explicit and sane
  7. Decide an issue to work on. Before starting, check: What areas have received attention in the last 5 iterations? Prioritize neglected areas. Balance time across: verification (all languages), modernization, TypeScript, website, dependencies.

    It could come from:

    • a security concern
    • the Backlog/Roadmap in CHANGELOG.md (balance across different items)
    • a verified GitHub issue
    • a PR failure
    • upgrading outdated dependencies, checking release notes, taking care of the potential migration, leveraging new capabilities
    • unfinished business

    Do what is most important and impactful first. First search what is already available, and what we can already re-use, even if it takes a little refactoring. Define what a successful outcome looks like and how you'll validate it (tests, browser checks, screenshots for design changes, or a working migration). This is imperative: no changes without validation. Anything that can't be validated should not be PR'ed or merged.

  8. NEVER commit directly to main. Always create or re-use a goal-oriented branch:

    git checkout [-]b feat/descriptive-goal  # or fix/, chore/, docs/

    Exceptions: CORE_MAINTAINER.md, CHANGELOG.md, and docs/prompts/LOG.md can be pushed directly to main.

  9. Log the plan in docs/prompts/LOG.md. Work can span multiple iterations on the same branch.

  10. Start implementing. Make incremental commits as you go.

  11. Create a PR only when you've made significant progress (not after each small change):

    • Expansion: ~10-15% coverage increase or ~10+ functions
    • Verification/Refactoring: 10+ functions fixed or complete a coherent unit
    • Bug fixes/security: Individual PRs are fine for discrete issues

    Before creating the PR:

    • Validate the work (tests, browser checks, etc.)
    • Run yarn check
    • Update documentation if needed
    • For new functions: Check if semantic equivalents exist in other languages and update src/rosetta.yml
    • For website changes: After merge, verify the live site at https://locutus.io using Playwright MCP
  12. Release recently merged PRs that contain new/changed functions (not just build tools, tests, or docs).

    • Before tagging, classify the release using CONTRIBUTING.md#versioning and include a one-line rationale in CHANGELOG.md.
  13. Log iteration results in docs/prompts/LOG.md.

  14. → Back to step 1

Quality Standards

  • Zero tolerance: failing tests, Biome errors, unverified implementations (eventually).
  • Acceptable warnings: LGPL code (src/php/_helpers/_bc.js, src/php/bc/*) that can't be modified; intentional eval/new Function with biome-ignore + explanation; style warnings in complex algorithms.
  • Keep one plan: update existing docs (like CHANGELOG.md and CORE_MAINTAINER.md) instead of creating new plans.

Lessons Learned

  • Always use branches: Never push to main directly. Create a branch, open a PR, let CI run, then merge. This applies even for "small fixes" - they often aren't.
  • Verify against reality: unit tests aren't enough; run actual PHP/Go/Python/Ruby/C when possible.
  • Don't duplicate infrastructure: check src/_util/ before creating new tools.
  • Document in the right place: LICENSE, README, SPDX headers, not just issues.
  • Biome unsafe fixes can break code: always test after auto-fix.
  • eval() is sometimes necessary: suppress with explanation, don't fight it.
  • Batch related work: Accumulate related changes before creating a PR. For expansion, aim for 10+ functions per PR to avoid noise.
  • Rosetta Stone mappings: When adding functions, check src/rosetta.yml for semantic equivalents (e.g., PHP strtolower ↔ Ruby downcase ↔ Go ToLower). This enables cross-language discovery on the website.