Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Code owners for ForgeLM.
#
# When a pull request is opened, GitHub requests a review from the owner of each
# path it changes. This file only routes those review requests: whether a review
# is *required* before merging is a branch-protection setting, not anything an
# entry here can turn on. See docs/standards/code-review.md for the review
# standard and GOVERNANCE.md for how ownership is granted.
#
# These rules are evaluated last-match-wins, so a more specific pattern placed
# below `*` overrides it. When an area gets its own owner, add their line below
# the default rather than replacing it, so the default owner stays on every path
# an area owner does not name. GitHub does not request a review for a draft or a
# draft pull request.

* @cemililik

# Repository scaffolding and policy files stay with the default owner even after
# an area owner is added, because these paths define the rules the area owners
# work under.
/.github/ @cemililik
/CONTRIBUTING.md @cemililik
/GOVERNANCE.md @cemililik
/MAINTAINERS.md @cemililik
/SECURITY.md @cemililik
/pyproject.toml @cemililik
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ contact_links:
- name: Report a security vulnerability
url: https://github.com/HodeTech/ForgeLM/security/advisories/new
about: Report vulnerabilities privately, never in a public issue (see SECURITY.md)
- name: Documentation
- name: Browse the documentation
url: https://github.com/HodeTech/ForgeLM/tree/main/docs
about: Check the docs and guides before opening an issue
about: Read the docs and guides before opening a documentation issue
- name: Discussions (Q&A)
url: https://github.com/HodeTech/ForgeLM/discussions
about: Ask questions and get help from the community
52 changes: 52 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Documentation
description: Report a documentation error, or propose an improvement to a guide or its Turkish mirror
labels: ["documentation", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for improving the docs! One correction per issue is easiest to review.

User-facing documentation is kept as an English page **and** a Turkish
mirror, and the two are updated together — see
[CONTRIBUTING.md](https://github.com/HodeTech/ForgeLM/blob/development/CONTRIBUTING.md).
You do not need to write the Turkish yourself: open the pull request with
the English change and say so, and a maintainer will complete the mirror.
Tell us below which copy you were reading. Documentation pull requests are
welcome directly.

- type: input
id: page
attributes:
label: Page or file
description: The repository path or the documentation-site page you were reading.
placeholder: docs/guides/quickstart.md — or the Quick start page on the docs site
validations:
required: true

- type: textarea
id: problem
attributes:
label: What is wrong or missing?
description: What does the page say, and what does the reader need instead?
validations:
required: true

- type: textarea
id: suggestion
attributes:
label: Suggested wording (optional)
description: If you already know the fix, propose the text. We will tidy the language if needed.

- type: dropdown
id: language
attributes:
label: Which copy is affected?
description: User-facing docs are maintained as an English page and a Turkish mirror. An issue that needs mirror work is labelled `i18n` when it is triaged.
options:
- English
- Turkish
- Both
- Not sure
validations:
required: true
69 changes: 69 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Dependabot configuration for ForgeLM.
#
# Dependabot opens a pull request when a dependency's declared range no longer
# covers the newest release. It is the upstream half of the supply-chain story:
# `tools/check_pip_audit.py` and the nightly CVE job catch known advisories, and
# these pull requests make a fix reachable.
#
# `versioning-strategy: widen` matters here. ForgeLM declares bounded ranges
# (`>=floor,<next-major`) with no lockfile and no pins, so Dependabot's default
# `increase` strategy would try to raise a floor the ceiling already covers — a
# no-op — instead of admitting a new major. `widen` keeps the declared floor and
# raises the ceiling, which is the change the ranges actually need.
#
# `ruff`, `mypy` and `bandit` are ignored on purpose. They are blocking CI gates
# and `tests/test_packaging.py` requires their `[dev]` range to equal the one
# `ci.yml`'s lint job installs. Dependabot edits only `pyproject.toml`, so a bump
# would fail that test the moment it arrived. Those three are raised deliberately,
# in one commit, with the CI pin moved in step.
#
# Note: `requirements.txt`, `requirements-eval.txt` and `requirements-linux.txt`
# are stale and referenced by nothing — the Dockerfile, CI and the tests all use
# `pyproject.toml` extras. Dependabot will still raise their floors; those pull
# requests should be closed, and the files removed, when the tracked cleanup
# lands.

version: 2
updates:
- package-ecosystem: "pip"
Comment thread
cemililik marked this conversation as resolved.
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
versioning-strategy: "widen"
labels:
- "dependencies"
- "area: packaging-ci"
commit-message:
prefix: "chore(deps)"
ignore:
- dependency-name: "ruff"
- dependency-name: "mypy"
- dependency-name: "bandit"
groups:
python-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "area: packaging-ci"
commit-message:
prefix: "chore(ci)"
groups:
actions-minor-and-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ All notable changes to ForgeLM are documented here.
and valid port; schemeless addresses are rejected instead of silently becoming `<malformed-url>`
in evidence. Use `https://monitor.example.com:8443/plan` or an `endpoint_env` name (#93).

### Added

- `CITATION.cff`, so the repository can be cited through GitHub's "Cite this
repository" panel (#964).
- `GOVERNANCE.md` and `MAINTAINERS.md` at the repository root, recording how
decisions are made, how the maintainer roles work, and which areas the current
maintainer owns (#964).
- `.github/dependabot.yml`, so dependency updates arrive as reviewed pull requests
rather than waiting for a manual version check; `.github/CODEOWNERS` to route
review requests without gating a merge; and a Documentation issue template, since
the issue chooser previously offered only a bug and a feature form (#964).

### Changed

- Record monitoring default provenance in `defaulted_fields` and mark literal URL projection with
Expand Down
37 changes: 37 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
cff-version: 1.2.0
message: "If you use ForgeLM in your work, please cite it using the metadata below."
title: "ForgeLM"
abstract: >-
Config-driven LLM fine-tuning: validated YAML in, a fine-tuned model and an
audit trail out. Covers SFT, DPO, SimPO, KTO, ORPO and GRPO, with optional
dataset auditing, safety evaluation, evaluation gates, human approval and
EU AI Act compliance artifacts. The same configuration runs from a terminal,
a notebook, or a CI/CD pipeline.
type: software
authors:
- name: "ForgeLM Contributors"
repository-code: "https://github.com/HodeTech/ForgeLM"
url: "https://hodetech.github.io/ForgeLM/"
license: Apache-2.0
keywords:
- llm
- fine-tuning
- lora
- qlora
- peft
- trl
- dpo
- grpo
- reproducibility
- mlops
- eu-ai-act
- ai-governance
# `version` and `date-released` are intentionally omitted for now: the released
# version is single-sourced in `pyproject.toml` (read at runtime by
# `forgelm/_version.py` via `importlib.metadata`, which carries no literal of its
# own) and the site's displayed version is derived from `CHANGELOG.md` by
# `tools/update_site_version.py --check`. This file is not one of that tool's
# targets, so a version here would be an un-guarded copy that no check keeps in
# sync — exactly what `docs/standards/release.md` exists to prevent. Extending the
# tool to rewrite this file (and adding a Zenodo DOI for citable releases) is
# tracked separately.
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Thanks for your interest in contributing! ForgeLM is an open-source project and
3. Make the change and, for a code fix, add a regression test that reproduces the issue;
follow the [testing standard](docs/standards/testing.md).
Documentation changes update the English page and its Turkish mirror together.
If you do not write Turkish, open the pull request with the English change and say
so in the description — a maintainer will complete the mirror for you.
4. Run fast checks before pushing (replace the example test module with the one you touched):

```bash
Expand Down
123 changes: 123 additions & 0 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# ForgeLM Governance

> **How decisions are made in ForgeLM, who makes them, and how you can take on
> more responsibility over time.** For how to contribute, see
> [CONTRIBUTING.md](CONTRIBUTING.md); for behaviour expectations, see
> [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).

## Current model

ForgeLM is **maintainer-led**. The project has a small group of maintainers who
are accountable for the code, the standards and the releases — today, one
(see [MAINTAINERS.md](MAINTAINERS.md)). There is no foundation and no steering
committee; the goal of this document is not to describe a large organisation but
to make the path into one explicit.

The project's product principles — reliability before features, enterprise
differentiation over feature parity, every capability config-driven and testable
— are recorded in [`docs/roadmap.md`](docs/roadmap.md) and are not restated here.
How decisions get made rests on two rules:

1. **The standards are the rulebook.** `docs/standards/` holds the engineering
standards, `docs/roadmap/` holds what ships next, and the
[CHANGELOG.md](CHANGELOG.md) records what shipped. A decision that changes
behaviour is written into one of them; a decision that exists only in a chat
is not a decision.
2. **Public reasoning.** Non-trivial proposals, breaking changes and anything
that changes a documented contract are discussed in an **issue** before a
pull request is opened, so the reasoning is reviewable and linkable.

## Roles

| Role | What they do | How it is granted |
|---|---|---|
| **Contributor** | Reports bugs, opens pull requests, reviews others' changes, improves docs | Anyone; no appointment |
| **Maintainer** | Sets direction, merges to `development`, cuts releases, holds the standards | A maintainer invites them (see below) |

Everyone contributing is bound by the
[Code of Conduct](CODE_OF_CONDUCT.md) and asked to follow the
[code-review standard](docs/standards/code-review.md).

## How decisions are made

- **Routine changes** — bug fixes, documentation and mirror updates, dependency
bumps — are decided in the pull request. A pull request merges once the
required status checks pass, every review conversation is resolved, and a
maintainer has reviewed it. The exact gate is a branch-protection setting, not
this document. While the project has one maintainer, that maintainer merges
their own pull requests under the same conditions, which is what
[docs/standards/code-review.md](docs/standards/code-review.md) records.
- **Non-trivial changes** — a new config field, a new module, a new optional
dependency, a change to an exit code, the audit-event vocabulary or a
documented guarantee — start as an issue. Work that has no issue may be asked
to open one first, so the design is agreed before code is written. If the
change is larger than one issue, it becomes a roadmap phase under
[docs/roadmap/](docs/roadmap/).
- **Breaking changes** to the YAML schema or the CLI contract require a
deprecation period. Removing a YAML field is a MAJOR change; the release a
removal lands in is named by a single constant,
`DEPRECATION_REMOVAL_VERSION` in `forgelm/config.py`, and the
[release standard](docs/standards/release.md) governs the sequence.
Comment thread
cemililik marked this conversation as resolved.
- **Disagreement** is resolved by discussion on the issue. If a consensus does
not form, the maintainer decides and records the reasoning in the issue and,
when it sets a lasting constraint, in
[docs/roadmap/risks-and-decisions.md](docs/roadmap/risks-and-decisions.md).
- **Security reports** do not follow this path. They go through a private
advisory as [SECURITY.md](SECURITY.md) describes.

## Becoming a maintainer

There is no exam and no vote — and no promise. A maintainer role is offered when
the project needs a second maintainer and someone has earned it, not
automatically after a number of merged pull requests. The invitation is normally
made when all of the following hold:

- they have landed a handful of pull requests across more than one area;
- they have reviewed other people's pull requests with useful, specific
feedback, and respected the standards while doing so;
- they have shown judgement on the edge cases — an error path, a documented
contract, a supply-chain or compliance question;
- they are willing to be reachable, and to triage issues and review pull
requests on a predictable cadence rather than only when they feel like it.

Area ownership follows the same idea: `MAINTAINERS.md` names who owns which area,
and `.github/CODEOWNERS` routes reviews there. The list is kept accurate rather
than flattering, and a maintainer who needs to step back can say so; that is not
held against them.

## Access and continuity

GitHub permissions are granted per role, and the smallest permission that does
the job is the default:

| Role | Repository permission | Why |
|---|---|---|
| Contributor | None — fork and pull request | Every contribution arrives as a pull request, so no repository access is needed |
| Maintainer | *Write* | Can merge to `development`, push branches and manage issues |
| Owner | *Admin* | Also carries branch protection, the tag ruleset and the release workflow's environment approval |

*Admin* is not the next rung of the contribution ladder — it is the ability to
change the rules the other roles work under, so it stays with the project owner
and moves only on a deliberate decision, with two-factor authentication required
on any account that holds it.

**Continuity: a known gap, recorded rather than promised.** There is one owner
today, and nothing in the release path is asynchronous — the same single account
holds the tag ruleset and approves the release workflow's `pypi` environment. An
unplanned absence therefore stops merges, releases and security advisories at
once. The fix is a second organisation owner (or an organisation-level owner with
the release environment's approval); it is not scheduled, and this paragraph is
what says so.

## Releases

Releases are cut from `main` by a maintainer, following
[docs/standards/release.md](docs/standards/release.md). `development` is the
integration branch and the default branch; changes land there first and reach
`main` through a release pull request. Only maintainers merge to `main` and tag
releases.

## Changing this document

This document is a normal file in the repository: propose a change with a pull
request, and explain the reasoning in the pull request description.
47 changes: 47 additions & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# ForgeLM Maintainers

> **Who maintains ForgeLM, what each of them owns, and how to reach them.**
> See [GOVERNANCE.md](GOVERNANCE.md) for how the roles work and how to take one
> on, and [CONTRIBUTING.md](CONTRIBUTING.md) for how to contribute.

## Current maintainers

| GitHub | Areas | Reachable for |
|---|---|---|
| [@cemililik](https://github.com/cemililik) | All areas — the repository's `area:` label set (cli, compliance, config, data-audit, dev-tooling, eval-gates, gdpr-approval, ingestion, integrations, model-data, onboarding, operator-cmds, packaging-ci, pipeline, post-training, site, trainer, verify) | Triage, design questions, reviews, releases |

The project has a single maintainer today. When a co-maintainer takes
responsibility for an area, they are added here and to
[`.github/CODEOWNERS`](.github/CODEOWNERS), which routes reviews for that area to
them. The "Areas" column mirrors the repository's `area:` labels, so an issue
labelled `area: site` and this table name the same area.

## How to reach a maintainer

- **A bug or a feature request** — open an
[issue](https://github.com/HodeTech/ForgeLM/issues/new/choose).
- **A question** — start a
[discussion](https://github.com/HodeTech/ForgeLM/discussions); questions are not
filed on the public issue tracker. Asking in public means the answer is
searchable for the next person.
- **A security vulnerability** — never in public. Use the repository's
**Security** tab, as [SECURITY.md](SECURITY.md) describes.
- **Anything covered by the Code of Conduct** — follow the enforcement section of
the [Code of Conduct](CODE_OF_CONDUCT.md#enforcement).

## Review cadence

Issues are triaged and pull requests are reviewed on a best-effort basis, with an
initial-reply target of **72 hours** — the same window [SECURITY.md](SECURITY.md)
commits to for a vulnerability report, so the project has one number rather than
two. An unanswered first pull request is the most expensive thing a young project
can ship, so a **first-time contributor**'s pull request is answered first. If a
pull request has not been reviewed for a while, a polite nudge on it is welcome;
it is not rude.

## Contributors

This file names maintainers and area owners only; it is not the contributor list.
Everyone whose work is merged appears in the repository's commit history and on
its GitHub contributors page, and non-maintainer contributions are credited in
the release notes.
Loading
Loading