Files
Flash5/AGENTS.md
T
Zakaria El OrcheandClaude Opus 5 24bb10175d feat(ext-cache-core): add the caching contract and a Caffeine backend
Split the way flash-ext-data and flash-ext-view are: cache-core defines
Cache, CacheManager, CacheSpec and CacheStats and talks to nothing;
cache-caffeine implements them in process.

    users = require(CacheManager.class).build("users", spec -> spec
            .maxSize(10_000).ttl(Duration.ofMinutes(10)));

    return users.get(id, repo::findById);

get(key, loader) is the only shape most code needs and the only one that is
hard to get right: the loader runs once per key across concurrent callers
rather than each racing its own. A null result stores nothing, because caching
absence is a decision rather than a default.

build(name, spec) is idempotent per name, so two handlers wanting one cache get
one cache without coordinating who creates it. Disagreeing about the spec
throws rather than resolving to whichever handler initialised first, which is a
bug that only surfaces under load.

recordStats() is opt-in — counting is two atomic increments per lookup, and a
cache nobody measures should not pay for numbers nobody reads. Unmeasured
caches return CacheStats.DISABLED rather than zeroes that look like a cold
cache.

Caffeine rather than a hand-rolled LRU: for genuinely low traffic
ConcurrentHashMap::computeIfAbsent is one line and needs no module at all, and
this exists for when that stops being true. W-TinyLFU admission, striped
counters and amortised eviction are not a weekend's work, and getting them
wrong yields a cache slower than no cache. The adapter is deliberately thin —
every method delegates, adding no wrapper, copy or locking of its own.

Caches are dropped through FlashContext.onClose, so values do not outlive the
app holding them. Invisible with one app per process; immediate under test.

flash-ext-cache-redis is designed but not built, and has docs only — no module,
no pom, no source. An empty module that builds an empty jar is dead weight in
the reactor. The docs record what changes once the cache can fail: get() must
decide whether to fall through to the loader, values need a codec,
invalidateAll needs a key prefix that becomes wire contract, and eviction stats
stop meaning anything. Those are decisions that want a real second replica to
check them against.

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

4.7 KiB

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-data-core, ext-data-jdbc, ext-data-hibernate, ext-cache-core, ext-cache-caffeine, 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 ReleaseRun 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.