Guidance for AI coding agents working in the Floci repository.
This file defines repository-specific operating rules for autonomous or semi-autonomous coding agents. Follow these instructions unless a maintainer explicitly tells you otherwise.
Floci is a Java-based local AWS emulator built on Quarkus.
Its goal is full AWS SDK and AWS CLI compatibility through real AWS wire protocols, not convenience APIs or simplified abstractions.
Floci acts as an open-source alternative to LocalStack Community.
- Port: 4566
- Stack:
- Java 25
- Quarkus 3.32.3
- JUnit 5
- RestAssured
- Jackson
- Docker integrations for Lambda, RDS, and ElastiCache
When making changes, follow these priorities:
- Preserve AWS protocol compatibility
- Match AWS SDK and CLI behavior
- Reuse existing Floci patterns
- Prefer correctness over convenience
- Keep changes narrow and testable
Critical rules:
- Do not introduce custom endpoint shapes
- Do not change request or response formats for convenience
- Do not perform broad refactors unless the task explicitly requires them
- Keep behavior aligned with AWS expectations and existing Floci conventions
Floci follows a layered design:
-
Controller / Handler
- Parses AWS protocol input
- Produces AWS-compatible responses
-
Service
- Contains business logic
- Throws
AwsException
-
Model
- Domain objects
EmulatorConfigServiceRegistryStorageBackend+StorageFactoryAwsJson11ControllerAwsQueryControllerAwsException+AwsExceptionMapperEmulatorLifecycle
io.github.hectorvent.floci.configio.github.hectorvent.floci.core.commonio.github.hectorvent.floci.core.storageio.github.hectorvent.floci.lifecycleio.github.hectorvent.floci.services.<service>
Typical service structure:
services/<svc>/*Controller.java*Service.javamodel/
Rule: Copy an existing service pattern before introducing a new one.
Floci must implement real AWS wire protocols.
| Protocol | Services | Request Format | Response Format | Implementation |
|---|---|---|---|---|
| Query | SQS, SNS, IAM, STS, RDS, ElastiCache, CloudFormation, CloudWatch Metrics | form-encoded POST + Action |
XML | AwsQueryController |
| JSON 1.1 | SSM, EventBridge, CloudWatch Logs, Kinesis, KMS, Cognito, Secrets Manager, ACM | POST + X-Amz-Target |
JSON | AwsJson11Controller |
| REST JSON | Lambda, API Gateway, SES V2 | REST paths | JSON | JAX-RS |
| REST XML | S3 | REST paths | XML | JAX-RS |
| TCP | ElastiCache, RDS | raw protocol | native | proxies |
- CloudWatch Metrics supports both Query and JSON 1.1; handlers must remain aligned
- SQS and SNS may expose multiple compatibility paths; do not let them drift
- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs
- Data-plane protocols may use raw TCP sockets
- Management APIs should be validated with AWS SDK clients, not only handcrafted HTTP requests
- Use
XmlBuilderfor XML responses - Use
XmlParserfor XML parsing; do not use regex - Use
AwsNamespacesconstants - JSON errors must follow AWS error structures
- Types returned directly from controllers must remain compatible with native-image reflection requirements
Supported storage modes:
memorypersistenthybridwal
Rules:
- Always use
StorageFactory - Do not instantiate storage implementations directly inside services
- Respect lifecycle hooks for load and flush behavior
Important nuance:
Configuration interfaces may declare fallback defaults, but application.yml defines effective runtime behavior. Treat repository YAML as the source of truth unless a task explicitly changes configuration semantics.
When adding storage-related behavior:
- Update
EmulatorConfig - Update main
application.yml - Update test
application.yml - Wire through
StorageFactory - Verify lifecycle integration
Configuration lives under floci.*.
When adding config:
- Add it to
EmulatorConfig - Add it to main
application.yml - Add it to test
application.ymlif needed - Update documentation if user-facing
- Follow
FLOCI_*environment variable conventions
Critical areas:
base-urlhostname- region and account defaults
- port ranges
- persistence paths
- Docker networking
./mvnw quarkus:dev
./mvnw test
./mvnw clean package
./mvnw clean package -DskipTests
./mvnw test -Dtest=SsmIntegrationTest
./mvnw test -Dtest=SsmIntegrationTest#putParameter
Compatibility test suite: ./compatibility-tests/
Guidelines:
- Prefer AWS SDK clients over raw HTTP for management-plane validation
- Use this suite when changes may affect real SDK behavior
- Unit tests:
*ServiceTest.java - Integration tests:
*IntegrationTest.java - Prefer package-private constructors for testability
- Integration tests may use ordered execution when stateful behavior requires it
- Test any behavior affecting AWS compatibility
- Do not rely only on manual HTTP testing
- Prefer SDK-based validation where possible
If a change affects request parsing, response shape, error handling, persistence semantics, URL generation, or service enablement:
- Add or update automated tests
- Prefer SDK-based verification where possible
- Check compatibility across alternate protocol paths
- Document intentional deviations clearly
- Services should throw
AwsException - Query and REST XML flows should use
AwsExceptionMapper - JSON 1.1 flows should return structured AWS error responses where required
- Controller return types must remain reflection-safe
When adding functionality:
- Identify the AWS protocol
- Reuse an existing service pattern
- Keep controllers thin
- Use
AwsExceptionfor domain errors - Reuse shared utilities
- Update config, storage, docs, and tests together
- Validate behavior against AWS SDK expectations
- Create a package under
services/ - Add:
- Controller
- Service
model/
- Register the service in
ServiceRegistry - Add config to
EmulatorConfig - Add YAML config in main and test config files
- Wire storage through
StorageFactory - Add tests
- Update documentation
- Use constructor injection
- Prefer self-explanatory code over comments
- Avoid unnecessary comments
- Always use braces in conditionals
- Follow existing project patterns
- Use modern Java features only when they improve clarity
- Use JBoss Logging
- Keep logs structured
- Avoid noisy logs in hot paths
- Keep changes focused
- Avoid unrelated refactors
- Preserve behavior unless the task explicitly requires change
- Update docs when necessary
- Explain missing tests when behavior changed but no automated coverage was added
Conventional commits:
feat:fix:perf:docs:chore:
Do not add Co-Authored-By trailers for AI tools in commit messages. Keep attribution limited to human contributors.
- Changes merged into
maindo not automatically imply a stable release - Release branches define stable release lines
- Tags trigger publishing workflows
Treat release workflows as critical infrastructure.
- Identify service and protocol
- Locate an existing implementation to mirror
- Check config impact
- Check storage impact
- Check documentation impact
- Define the minimal useful test plan
- Run relevant tests
- Validate protocol behavior
- Ensure no custom endpoints were introduced
- Verify config and docs updates
- Creating non-AWS endpoints
- Bypassing
StorageFactory - Changing wire formats without tests
- Forgetting YAML updates
- Producing inconsistent URLs or ARNs
- Testing only with raw HTTP
- Introducing unnecessary new patterns
If behavior is unclear:
- Prefer AWS behavior
- Then existing Floci behavior
- Then compatibility test expectations
If a task would require broad architectural changes, stop and surface the tradeoffs instead of refactoring across services blindly.