Files
Flash5/AGENTS.md
T
Zakaria El OrcheandClaude Opus 5 5c163b7f8d feat(ext-scheduler): add interval and cron background jobs
jobs.every(Duration.ofMinutes(5), reports::refresh);
    jobs.cron("0 0 3 * * *", archive::sweep);

One daemon platform thread keeps time; every job body runs on a virtual thread,
so a slow job delays nothing but its own next run and cannot occupy the timer.

Cron expressions compile once into a bitmask per field — a long for seconds and
minutes, an int for the rest — so matching an instant is a shift and a mask
rather than a parse or a set lookup. Next-fire advances by the largest unit
that cannot match instead of ticking second by second, so a yearly expression
resolves in a few dozen iterations rather than thirty million. Five or six
fields, ranges, steps, lists, named months and weekdays, both Sunday encodings,
and the standard union semantics when both day fields are restricted. A
malformed expression throws when the job is registered, not when it would have
fired.

Overlapping runs are skipped, and deliberately not configurable: two copies of
one job at once is a bug in every case anyone has needed, and a flag would only
let it be set wrongly. A skipped run logs how long the previous one has been
going.

A throwing job is logged and keeps its schedule. scheduleAtFixedRate cancels
the task on first exception, silently — a job that dies at 3am and is never
heard from again is the failure this avoids.

Shutdown goes through FlashContext.onClose, so app.stop() drains HTTP first,
then gives running jobs a grace period before forcing them down. Nothing runs
after the app stops. The grace period is the only knob.

Known ceiling, marked in the source: schedules are per-instance, so two
replicas run every job twice. A distributed lock should not exist until there
is a second replica.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 12:23:34 +00:00

122 lines
4.7 KiB
Markdown

# Flash — Agent Guidelines
This document defines the conventions and rules that all agents (AI or human) must follow
when working on this repository. Read it entirely before making any change.
---
## Git Workflow
### Branch Naming
| Type | Pattern | Example |
|------|---------|---------|
| New feature | `feature/<scope>/<short-description>` | `feature/ext-oidc/pkce-support` |
| Bug fix | `fix/<scope>/<short-description>` | `fix/core/router-npe` |
| Hotfix on released version | `hotfix/<version>/<short-description>` | `hotfix/2.0.1/auth-bypass` |
| CI/infra changes | `feature/ci/<short-description>` | `feature/ci/add-snapshot-workflow` |
Rules:
- Always branch from `master`.
- Branch names are lowercase, words separated by `-`.
- Never push directly to `master`.
- Never create `develop`, `release/*`, or any other long-lived branch.
### Commit Messages — Conventional Commits
Format: `<type>(<scope>): <short description>`
| Type | When to use |
|------|-------------|
| `feat` | New feature |
| `fix` | Bug fix |
| `refactor` | Code change without feature/fix |
| `test` | Adding or updating tests |
| `docs` | Documentation only |
| `chore` | Build, deps, tooling — no production code |
| `ci` | Changes to GitHub Actions workflows |
Allowed scopes: `core`, `testing`, `ext-jackson`, `ext-openapi`, `ext-oidc`, `ext-routeviewer`,
`ext-view-core`, `ext-view-jte`, `ext-view-thymeleaf`, `ext-limiter`, `ext-web-bundler`,
`ext-mcp`, `ext-scheduler`, `ext-data-core`, `ext-data-jdbc`, `ext-data-hibernate`, `release`, `deps`, `ci`.
Examples:
```
feat(ext-oidc): add PKCE support
fix(core): fix NPE in RouteHandler when path is null
chore(deps): upgrade jackson to 2.18.0
ci: add timeout to snapshot workflow
chore(release): 2.1.0
```
### Pull Requests
- Every branch must be merged via PR, never with a direct push.
- PR title must follow Conventional Commits format.
- CI (`ci.yml`) must be green before merging.
- Squash merge is preferred for `feature/*` and `fix/*` to keep history clean.
- Merge commit is preferred for hotfixes (preserves the fix commit intact).
---
## Versioning
- All modules share a single version defined in the root `pom.xml` (`flash-parent`).
- Never change the version in child POMs — always and only in the parent.
- Current scheme: `MAJOR.MINOR.PATCH`
- MAJOR: breaking API changes
- MINOR: new backward-compatible features
- PATCH: backward-compatible bug fixes on an already-released version
- During development, master always carries a `-SNAPSHOT` version.
- **Never manually edit the version** — versions are bumped exclusively by the
`prepare-release` GitHub Actions workflow.
### Release Process (for maintainers only)
1. Ensure `master` is green (CI passing).
2. Go to GitHub Actions → `Prepare Release``Run workflow`.
3. Input `version` (e.g. `2.1.0`) and `next_version` (e.g. `2.2.0`).
4. The workflow handles everything: bump, commit, tag, push.
5. The `release` workflow then triggers automatically on the tag.
---
## Maven & Module Structure
- Root POM: `flash-parent` — defines all dependency versions and plugin config.
- `flash` module: the core framework JAR.
- `flash-testing` module: JUnit 5 harness for testing Flash applications. Deliberately not
under `flash-extensions/` — it is not something you `install()`, and it carries
`junit-jupiter-api` at compile scope.
- `flash-extensions` POM: aggregator for all extension modules.
- Extensions live under `flash-extensions/flash-ext-*/`.
- When adding a new extension:
1. Add the module to `flash-extensions/pom.xml` `<modules>`.
2. Add the dependency to `flash-extensions/pom.xml` `<dependencyManagement>`.
3. Add the dependency to the root `pom.xml` `<dependencyManagement>`.
4. Do **not** declare a `<version>` in the new module's POM — it inherits from the parent.
---
## CI/CD Pipelines
| Workflow | Trigger | What it does |
|----------|---------|--------------|
| `ci.yml` | Push to any branch, PR to master | Compile + test — required gate |
| `snapshot.yml` | Push to `master` | Deploy `-SNAPSHOT` to `maven.relism.dev/snapshots` |
| `prepare-release.yml` | Manual `workflow_dispatch` | Bump version, commit, tag, push |
| `release.yml` | Push of tag `v*` | GPG sign, deploy to `/releases`, JavaDoc to GitHub Pages, GitHub Release |
**Agents must never manually trigger `prepare-release` or modify version strings.**
---
## What Agents Must NOT Do
- Push directly to `master` or `gh-pages`.
- Manually edit `<version>` tags in any POM.
- Add new `<repositories>` or `<distributionManagement>` entries without explicit instruction.
- Modify `.github/workflows/*.yml` files without explicit instruction.
- Commit generated files (`target/`, `*.class`, `*.versionsBackup`).
- Use `git push --force` on any branch.