{"owner":"floci-io","repo":"floci","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md",".github/copilot-instructions.md"],"skills":{"AGENTS.md":"Guidance for AI coding agents working in the Floci repository.\n\nThis file defines repository-specific operating rules for autonomous or semi-autonomous coding agents. Follow these instructions unless a maintainer explicitly tells you otherwise.\n\n---\n\n## Project Overview\n\nFloci is a Java-based local AWS emulator built on Quarkus.\n\nIts goal is full AWS SDK and AWS CLI compatibility through real AWS wire protocols, not convenience APIs or simplified abstractions.\n\nFloci acts as an open-source alternative to LocalStack Community.\n\n- Port: 4566\n- Stack:\n  - Java 25\n  - Quarkus 3.32.3\n  - JUnit 5\n  - RestAssured\n  - Jackson\n  - Docker integrations for Lambda, RDS, and ElastiCache\n\n---\n\n## First Principles\n\nWhen making changes, follow these priorities:\n\n1. Preserve AWS protocol compatibility\n2. Match AWS SDK and CLI behavior\n3. Reuse existing Floci patterns\n4. Prefer correctness over convenience\n5. Keep changes narrow and testable\n\nCritical rules:\n\n- Do not introduce custom endpoint shapes\n- Do not change request or response formats for convenience\n- Do not perform broad refactors unless the task explicitly requires them\n- Keep behavior aligned with AWS expectations and existing Floci conventions\n\n---\n\n## Architecture\n\nFloci follows a layered design:\n\n- **Controller / Handler**\n  - Parses AWS protocol input\n  - Produces AWS-compatible responses\n\n- **Service**\n  - Contains business logic\n  - Throws `AwsException`\n\n- **Model**\n  - Domain objects\n\n### Core Infrastructure\n\n- `EmulatorConfig`\n- `ServiceRegistry`\n- `StorageBackend` + `StorageFactory`\n- `AwsJson11Controller`\n- `AwsQueryController`\n- `AwsException` + `AwsExceptionMapper`\n- `EmulatorLifecycle`\n\n---\n\n## Package Layout\n\n- `io.github.hectorvent.floci.config`\n- `io.github.hectorvent.floci.core.common`\n- `io.github.hectorvent.floci.core.storage`\n- `io.github.hectorvent.floci.lifecycle`\n- `io.github.hectorvent.floci.services.<service>`\n\nTypical service structure:\n\n- `services/<svc>/`\n  - `*Controller.java`\n  - `*Service.java`\n  - `model/`\n\nRule:\nCopy an existing service pattern before introducing a new one.\n\n---\n\n## AWS Protocol Rules\n\nFloci must implement real AWS wire protocols.\n\n| Protocol | Services | Request Format | Response Format | Implementation |\n|----------|----------|----------------|-----------------|----------------|\n| Query | SQS, SNS, IAM, STS, RDS, ElastiCache, CloudFormation, CloudWatch Metrics | form-encoded POST + `Action` | XML | `AwsQueryController` |\n| JSON 1.1 | SSM, EventBridge, CloudWatch Logs, Kinesis, KMS, Cognito, Secrets Manager, ACM | POST + `X-Amz-Target` | JSON | `AwsJson11Controller` |\n| REST JSON | Lambda, API Gateway, SES V2 | REST paths | JSON | JAX-RS |\n| REST XML | S3 | REST paths | XML | JAX-RS |\n| TCP | ElastiCache, RDS | raw protocol | native | proxies |\n\n### Important exceptions\n\n- CloudWatch Metrics supports both Query and JSON 1.1; handlers must remain aligned\n- SQS and SNS may expose multiple compatibility paths; do not let them drift\n- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs\n- Data-plane protocols may use raw TCP sockets\n- Management APIs should be validated with AWS SDK clients, not only handcrafted HTTP requests\n\n---\n\n## XML / JSON Rules\n\n- Use `XmlBuilder` for XML responses\n- Use `XmlParser` for XML parsing; do not use regex\n- Use `AwsNamespaces` constants\n- JSON errors must follow AWS error structures\n- Types returned directly from controllers must remain compatible with native-image reflection requirements\n\n---\n\n## Storage Rules\n\nSupported storage modes:\n\n- `memory`\n- `persistent`\n- `hybrid`\n- `wal`\n\nRules:\n\n- Always use `StorageFactory`\n- Do not instantiate storage implementations directly inside services\n- Respect lifecycle hooks for load and flush behavior\n\nImportant nuance:\n\nConfiguration 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.\n\nWhen adding storage-related behavior:\n\n1. Update `EmulatorConfig`\n2. Update main `application.yml`\n3. Update test `application.yml`\n4. Wire through `StorageFactory`\n5. Verify lifecycle integration\n\n---\n\n## Configuration Rules\n\nConfiguration lives under `floci.*`.\n\nWhen adding config:\n\n1. Add it to `EmulatorConfig`\n2. Add it to main `application.yml`\n3. Add it to test `application.yml` if needed\n4. Update documentation if user-facing\n5. Follow `FLOCI_*` environment variable conventions\n\nCritical areas:\n\n- `base-url`\n- `hostname`\n- region and account defaults\n- port ranges\n- persistence paths\n- Docker networking\n\n---\n\n## Build & Run\n\n    ./mvnw quarkus:dev\n    ./mvnw test\n    ./mvnw clean package\n    ./mvnw clean package -DskipTests\n\n### Focused tests\n\n    ./mvnw test -Dtest=SsmIntegrationTest\n    ./mvnw test -Dtest=SsmIntegrationTest#putParameter\n\n---\n\n## Compatibility Project\n\nCompatibility test suite: `./compatibility-tests/`\n\nGuidelines:\n\n- Prefer AWS SDK clients over raw HTTP for management-plane validation\n- Use this suite when changes may affect real SDK behavior\n\n---\n\n## Testing Rules\n\n### Conventions\n\n- Unit tests: `*ServiceTest.java`\n- Integration tests: `*IntegrationTest.java`\n- Prefer package-private constructors for testability\n- Integration tests may use ordered execution when stateful behavior requires it\n\n### Expectations\n\n- Test any behavior affecting AWS compatibility\n- Do not rely only on manual HTTP testing\n- Prefer SDK-based validation where possible\n\n### When touching protocol behavior\n\nIf a change affects request parsing, response shape, error handling, persistence semantics, URL generation, or service enablement:\n\n1. Add or update automated tests\n2. Prefer SDK-based verification where possible\n3. Check compatibility across alternate protocol paths\n4. Document intentional deviations clearly\n\n---\n\n## Error Handling\n\n- Services should throw `AwsException`\n- Query and REST XML flows should use `AwsExceptionMapper`\n- JSON 1.1 flows should return structured AWS error responses where required\n- Controller return types must remain reflection-safe\n\n---\n\n## Service Implementation Pattern\n\nWhen adding functionality:\n\n1. Identify the AWS protocol\n2. Reuse an existing service pattern\n3. Keep controllers thin\n4. Use `AwsException` for domain errors\n5. Reuse shared utilities\n6. Update config, storage, docs, and tests together\n7. Validate behavior against AWS SDK expectations\n\n---\n\n## Adding a New AWS Service\n\n1. Create a package under `services/`\n2. Add:\n   - Controller\n   - Service\n   - `model/`\n3. Register the service in `ServiceRegistry`\n4. Add config to `EmulatorConfig`\n5. Add YAML config in main and test config files\n6. Wire storage through `StorageFactory`\n7. Add tests\n8. Update documentation\n\n---\n\n## Adding a CloudFormation Resource Type\n\n**Do not add cases to `CloudFormationResourceProvisioner`.** That class is a legacy\nmonolith being dismantled; new types go in per-service provisioners under\n`services/cloudformation/provisioners/`.\n\n1. Add the type to the existing `<Service>CfnProvisioner`, or create one:\n   `@ApplicationScoped`, injecting only the service it wraps. CDI discovery via\n   `CloudFormationResourceRegistry` handles registration — no manual wiring, but a\n   missing `@ApplicationScoped` silently means the type is never provisioned.\n2. `resourceTypes()` lists the `AWS::*` types; `provision(resource, props, ctx)`\n   does the work, switching on `resource.getResourceType()` when it serves several.\n3. Set **both** reference mechanisms — they are separate:\n   - `resource.setPhysicalId(...)` backs `Ref`\n   - `resource.getAttributes().put(...)` backs `Fn::GetAtt`, one entry per attribute\n   Omitting an attribute does not fail; `Fn::GetAtt` resolves to the literal\n   `\"LogicalId.Attr\"`. Source the attribute names from the type's registry schema in\n   `local/aws/cfn-resource-schemas/us-east-1/` (`readOnlyProperties`), and validate\n   `required` from the same file.\n4. **`provision` serves create *and* update.** On `UpdateStack` it is re-invoked with\n   the prior physical id and attributes already populated on the resource. Branch on\n   that instead of creating unconditionally.\n5. Override `delete(...)` when the type has a backing delete; tolerate already-deleted.\n6. Tests: focused unit test mocking one service (`SqsCfnProvisionerTest` is the\n   pattern) plus an integration test asserting the **exact `Fn::GetAtt` keys**. An\n   unmapped type is stubbed as `CREATE_COMPLETE` with a fake ARN, so asserting status\n   alone cannot detect a type that was never wired.\n7. Update the resource-type table in `docs/services/cloudformation.md`.\n\nReferences: `SqsCfnProvisioner` (smallest), `Ec2LaunchTemplateCfnProvisioner`\n(update-in-place and replacement).\n\n---\n\n## Code Style\n\n- Use constructor injection\n- Prefer self-explanatory code over comments\n- Avoid unnecessary comments\n- Always use braces in conditionals\n- Never leave a `catch` block empty. If an exception is intentionally tolerated, log it with enough context to diagnose it later.\n- Follow existing project patterns\n- Use modern Java features only when they improve clarity\n\n---\n\n## Logging\n\n- Use JBoss Logging\n- Keep logs structured\n- Avoid noisy logs in hot paths\n\n---\n\n## Pull Request Guidelines\n\n- Keep changes focused\n- Avoid unrelated refactors\n- Preserve behavior unless the task explicitly requires change\n- Update docs when necessary\n- Explain missing tests when behavior changed but no automated coverage was added\n\nConventional commits:\n\n- `feat:`\n- `fix:`\n- `perf:`\n- `docs:`\n- `chore:`\n\nDo not add `Co-Authored-By` trailers for AI tools in commit messages. Keep attribution limited to human contributors.\n\n---\n\n## Release Awareness\n\n- Changes merged into `main` do not automatically imply a stable release\n- Releases are cut from `main` via the \"Release Cut\" workflow (`workflow_dispatch`\n  on `.github/workflows/release-cut.yml`), which runs semantic-release: it bumps\n  `pom.xml`, writes `CHANGELOG.md`, commits, tags, and creates the GitHub Release\n- `release/x.y.x` branches are retired for now\n- Tags still trigger the publishing workflows (`release.yml`)\n\nTreat release workflows as critical infrastructure.\n\n---\n\n## Agent Workflow\n\n### Before editing\n\n1. Identify service and protocol\n2. Locate an existing implementation to mirror\n3. Check config impact\n4. Check storage impact\n5. Check documentation impact\n6. Define the minimal useful test plan\n\n### Before finishing\n\n1. Run relevant tests\n2. Validate protocol behavior\n3. Ensure no custom endpoints were introduced\n4. Verify config and docs updates\n\n---\n\n## Common Mistakes\n\n- Creating non-AWS endpoints\n- Bypassing `StorageFactory`\n- Changing wire formats without tests\n- Forgetting YAML updates\n- Producing inconsistent URLs or ARNs\n- Testing only with raw HTTP\n- Introducing unnecessary new patterns\n- Adding a CloudFormation type to `CloudFormationResourceProvisioner` instead of a\n  per-service provisioner\n- Setting a CloudFormation resource's physical id but not its `Fn::GetAtt`\n  attributes (they are two separate mechanisms, and the miss is silent)\n\n---\n\n## Human Handoff\n\nIf behavior is unclear:\n\n1. Prefer AWS behavior\n2. Then existing Floci behavior\n3. Then compatibility test expectations\n\nIf a task would require broad architectural changes, stop and surface the tradeoffs instead of refactoring across services blindly.\n",".github/copilot-instructions.md":"# Copilot Instructions for Pull Request Review\n\nReview pull requests in the Floci repository with AWS compatibility as the primary concern.\n\nFloci is a Java-based local AWS emulator built on Quarkus. Its goal is to match AWS SDK and AWS CLI behavior through real AWS wire protocols, not convenience APIs or custom abstractions.\n\n## Review Priorities\n\nEvaluate changes in this order:\n\n1. Preserve AWS protocol compatibility\n2. Match AWS SDK and AWS CLI behavior\n3. Reuse existing Floci patterns\n4. Prefer correctness over convenience\n5. Keep changes focused and testable\n\n## What to Flag\n\nRaise concerns when a PR introduces any of the following without strong justification:\n\n- Non-AWS endpoint shapes\n- Request or response format changes made for convenience\n- Broad refactors unrelated to the PR goal\n- New service patterns where an existing Floci pattern should be reused\n- Direct storage implementation usage instead of `StorageFactory`\n\n## Architecture Expectations\n\nFloci follows a layered design:\n\n- Controllers / handlers parse AWS protocol input and produce AWS-compatible responses\n- Services contain business logic and should throw `AwsException`\n- Models hold domain data\n\nCore infrastructure commonly relevant in reviews:\n\n- `EmulatorConfig`\n- `ServiceRegistry`\n- `StorageFactory`\n- `AwsQueryController`\n- `AwsJson11Controller`\n- `AwsException`\n- `AwsExceptionMapper`\n- `EmulatorLifecycle`\n\nCheck that controllers stay thin, business logic remains in services, and new changes fit existing repository patterns.\n\n## Protocol Review Rules\n\nFloci implements real AWS wire protocols. Review protocol-affecting changes carefully.\n\n- Query services should keep form-encoded POST requests with `Action` and XML responses\n- JSON 1.1 services should keep `X-Amz-Target` requests and AWS-style JSON responses\n- REST JSON and REST XML services should stay aligned with AWS path and payload conventions\n- TCP-based services should not drift into HTTP-style abstractions\n\nPay extra attention to these cases:\n\n- CloudWatch Metrics supports both Query and JSON 1.1 and both paths must stay aligned\n- SQS and SNS may have multiple compatibility paths that must not drift\n- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs\n- Management APIs should ideally be validated with AWS SDK clients, not only handcrafted HTTP\n\n## XML and JSON Rules\n\nFlag PRs that:\n\n- Ignore `AwsNamespaces` constants\n- Return JSON errors that do not follow AWS error structures\n- Change controller return types in ways that may break reflection or native-image compatibility\n\n## Config and Storage Review\n\nWhen a PR changes configuration or persistence behavior, verify the change is wired consistently.\n\nCheck for updates to:\n\n- `EmulatorConfig`\n- main `application.yml`\n- test `application.yml`\n- `StorageFactory`\n- lifecycle hooks when relevant\n\nSupported storage modes include:\n\n- `memory`\n- `persistent`\n- `hybrid`\n- `wal`\n\nTreat repository YAML as the source of truth for runtime behavior unless the PR explicitly changes configuration semantics.\n\n## Testing Expectations\n\nExpect automated coverage for changes that affect:\n\n- request parsing\n- response shape\n- error handling\n- persistence semantics\n- URL generation\n- service enablement\n\nPrefer:\n\n- AWS SDK-based validation over raw HTTP-only testing\n- integration tests for compatibility-sensitive behavior\n- existing naming conventions such as `*ServiceTest.java` and `*IntegrationTest.java`\n\nIf behavior changes without automated coverage, call that out explicitly.\n\n## Review Checklist\n\nWhen analyzing a PR, check:\n\n- Is the change focused?\n- Does it preserve AWS-compatible wire behavior?\n- Does it reuse an existing Floci pattern?\n- Are controllers thin and services responsible for domain logic?\n- Are `AwsException` and existing error-mapping patterns used correctly?\n- Are config and YAML updates complete?\n- Are storage changes wired through `StorageFactory`?\n- Are tests added or updated where compatibility is affected?\n- Are docs updated when user-facing behavior changes?\n\n## How to Write Feedback\n\nWrite review comments that are:\n\n- specific\n- repository-aware\n- grounded in AWS compatibility risk\n\nUse severity when helpful:\n\n- `high`: likely breaks AWS SDK / CLI compatibility or protocol behavior\n- `medium`: inconsistent with Floci architecture, wiring, or testing expectations\n- `low`: maintainability, clarity, or minor convention issue\n\nPrefer comments that explain:\n\n- what is risky\n- why it matters in Floci\n- which existing pattern should be followed instead\n\n## If Behavior Is Unclear\n\nUse this fallback order:\n\n1. Prefer AWS behavior\n2. Then existing Floci behavior\n3. Then compatibility test expectations\n\nIf correctness would require a broader architectural change, call out the tradeoff instead of suggesting blind refactoring.\n"},"files":{"AGENTS.md":"Guidance for AI coding agents working in the Floci repository.\n\nThis file defines repository-specific operating rules for autonomous or semi-autonomous coding agents. Follow these instructions unless a maintainer explicitly tells you otherwise.\n\n---\n\n## Project Overview\n\nFloci is a Java-based local AWS emulator built on Quarkus.\n\nIts goal is full AWS SDK and AWS CLI compatibility through real AWS wire protocols, not convenience APIs or simplified abstractions.\n\nFloci acts as an open-source alternative to LocalStack Community.\n\n- Port: 4566\n- Stack:\n  - Java 25\n  - Quarkus 3.32.3\n  - JUnit 5\n  - RestAssured\n  - Jackson\n  - Docker integrations for Lambda, RDS, and ElastiCache\n\n---\n\n## First Principles\n\nWhen making changes, follow these priorities:\n\n1. Preserve AWS protocol compatibility\n2. Match AWS SDK and CLI behavior\n3. Reuse existing Floci patterns\n4. Prefer correctness over convenience\n5. Keep changes narrow and testable\n\nCritical rules:\n\n- Do not introduce custom endpoint shapes\n- Do not change request or response formats for convenience\n- Do not perform broad refactors unless the task explicitly requires them\n- Keep behavior aligned with AWS expectations and existing Floci conventions\n\n---\n\n## Architecture\n\nFloci follows a layered design:\n\n- **Controller / Handler**\n  - Parses AWS protocol input\n  - Produces AWS-compatible responses\n\n- **Service**\n  - Contains business logic\n  - Throws `AwsException`\n\n- **Model**\n  - Domain objects\n\n### Core Infrastructure\n\n- `EmulatorConfig`\n- `ServiceRegistry`\n- `StorageBackend` + `StorageFactory`\n- `AwsJson11Controller`\n- `AwsQueryController`\n- `AwsException` + `AwsExceptionMapper`\n- `EmulatorLifecycle`\n\n---\n\n## Package Layout\n\n- `io.github.hectorvent.floci.config`\n- `io.github.hectorvent.floci.core.common`\n- `io.github.hectorvent.floci.core.storage`\n- `io.github.hectorvent.floci.lifecycle`\n- `io.github.hectorvent.floci.services.<service>`\n\nTypical service structure:\n\n- `services/<svc>/`\n  - `*Controller.java`\n  - `*Service.java`\n  - `model/`\n\nRule:\nCopy an existing service pattern before introducing a new one.\n\n---\n\n## AWS Protocol Rules\n\nFloci must implement real AWS wire protocols.\n\n| Protocol | Services | Request Format | Response Format | Implementation |\n|----------|----------|----------------|-----------------|----------------|\n| Query | SQS, SNS, IAM, STS, RDS, ElastiCache, CloudFormation, CloudWatch Metrics | form-encoded POST + `Action` | XML | `AwsQueryController` |\n| JSON 1.1 | SSM, EventBridge, CloudWatch Logs, Kinesis, KMS, Cognito, Secrets Manager, ACM | POST + `X-Amz-Target` | JSON | `AwsJson11Controller` |\n| REST JSON | Lambda, API Gateway, SES V2 | REST paths | JSON | JAX-RS |\n| REST XML | S3 | REST paths | XML | JAX-RS |\n| TCP | ElastiCache, RDS | raw protocol | native | proxies |\n\n### Important exceptions\n\n- CloudWatch Metrics supports both Query and JSON 1.1; handlers must remain aligned\n- SQS and SNS may expose multiple compatibility paths; do not let them drift\n- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs\n- Data-plane protocols may use raw TCP sockets\n- Management APIs should be validated with AWS SDK clients, not only handcrafted HTTP requests\n\n---\n\n## XML / JSON Rules\n\n- Use `XmlBuilder` for XML responses\n- Use `XmlParser` for XML parsing; do not use regex\n- Use `AwsNamespaces` constants\n- JSON errors must follow AWS error structures\n- Types returned directly from controllers must remain compatible with native-image reflection requirements\n\n---\n\n## Storage Rules\n\nSupported storage modes:\n\n- `memory`\n- `persistent`\n- `hybrid`\n- `wal`\n\nRules:\n\n- Always use `StorageFactory`\n- Do not instantiate storage implementations directly inside services\n- Respect lifecycle hooks for load and flush behavior\n\nImportant nuance:\n\nConfiguration 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.\n\nWhen adding storage-related behavior:\n\n1. Update `EmulatorConfig`\n2. Update main `application.yml`\n3. Update test `application.yml`\n4. Wire through `StorageFactory`\n5. Verify lifecycle integration\n\n---\n\n## Configuration Rules\n\nConfiguration lives under `floci.*`.\n\nWhen adding config:\n\n1. Add it to `EmulatorConfig`\n2. Add it to main `application.yml`\n3. Add it to test `application.yml` if needed\n4. Update documentation if user-facing\n5. Follow `FLOCI_*` environment variable conventions\n\nCritical areas:\n\n- `base-url`\n- `hostname`\n- region and account defaults\n- port ranges\n- persistence paths\n- Docker networking\n\n---\n\n## Build & Run\n\n    ./mvnw quarkus:dev\n    ./mvnw test\n    ./mvnw clean package\n    ./mvnw clean package -DskipTests\n\n### Focused tests\n\n    ./mvnw test -Dtest=SsmIntegrationTest\n    ./mvnw test -Dtest=SsmIntegrationTest#putParameter\n\n---\n\n## Compatibility Project\n\nCompatibility test suite: `./compatibility-tests/`\n\nGuidelines:\n\n- Prefer AWS SDK clients over raw HTTP for management-plane validation\n- Use this suite when changes may affect real SDK behavior\n\n---\n\n## Testing Rules\n\n### Conventions\n\n- Unit tests: `*ServiceTest.java`\n- Integration tests: `*IntegrationTest.java`\n- Prefer package-private constructors for testability\n- Integration tests may use ordered execution when stateful behavior requires it\n\n### Expectations\n\n- Test any behavior affecting AWS compatibility\n- Do not rely only on manual HTTP testing\n- Prefer SDK-based validation where possible\n\n### When touching protocol behavior\n\nIf a change affects request parsing, response shape, error handling, persistence semantics, URL generation, or service enablement:\n\n1. Add or update automated tests\n2. Prefer SDK-based verification where possible\n3. Check compatibility across alternate protocol paths\n4. Document intentional deviations clearly\n\n---\n\n## Error Handling\n\n- Services should throw `AwsException`\n- Query and REST XML flows should use `AwsExceptionMapper`\n- JSON 1.1 flows should return structured AWS error responses where required\n- Controller return types must remain reflection-safe\n\n---\n\n## Service Implementation Pattern\n\nWhen adding functionality:\n\n1. Identify the AWS protocol\n2. Reuse an existing service pattern\n3. Keep controllers thin\n4. Use `AwsException` for domain errors\n5. Reuse shared utilities\n6. Update config, storage, docs, and tests together\n7. Validate behavior against AWS SDK expectations\n\n---\n\n## Adding a New AWS Service\n\n1. Create a package under `services/`\n2. Add:\n   - Controller\n   - Service\n   - `model/`\n3. Register the service in `ServiceRegistry`\n4. Add config to `EmulatorConfig`\n5. Add YAML config in main and test config files\n6. Wire storage through `StorageFactory`\n7. Add tests\n8. Update documentation\n\n---\n\n## Adding a CloudFormation Resource Type\n\n**Do not add cases to `CloudFormationResourceProvisioner`.** That class is a legacy\nmonolith being dismantled; new types go in per-service provisioners under\n`services/cloudformation/provisioners/`.\n\n1. Add the type to the existing `<Service>CfnProvisioner`, or create one:\n   `@ApplicationScoped`, injecting only the service it wraps. CDI discovery via\n   `CloudFormationResourceRegistry` handles registration — no manual wiring, but a\n   missing `@ApplicationScoped` silently means the type is never provisioned.\n2. `resourceTypes()` lists the `AWS::*` types; `provision(resource, props, ctx)`\n   does the work, switching on `resource.getResourceType()` when it serves several.\n3. Set **both** reference mechanisms — they are separate:\n   - `resource.setPhysicalId(...)` backs `Ref`\n   - `resource.getAttributes().put(...)` backs `Fn::GetAtt`, one entry per attribute\n   Omitting an attribute does not fail; `Fn::GetAtt` resolves to the literal\n   `\"LogicalId.Attr\"`. Source the attribute names from the type's registry schema in\n   `local/aws/cfn-resource-schemas/us-east-1/` (`readOnlyProperties`), and validate\n   `required` from the same file.\n4. **`provision` serves create *and* update.** On `UpdateStack` it is re-invoked with\n   the prior physical id and attributes already populated on the resource. Branch on\n   that instead of creating unconditionally.\n5. Override `delete(...)` when the type has a backing delete; tolerate already-deleted.\n6. Tests: focused unit test mocking one service (`SqsCfnProvisionerTest` is the\n   pattern) plus an integration test asserting the **exact `Fn::GetAtt` keys**. An\n   unmapped type is stubbed as `CREATE_COMPLETE` with a fake ARN, so asserting status\n   alone cannot detect a type that was never wired.\n7. Update the resource-type table in `docs/services/cloudformation.md`.\n\nReferences: `SqsCfnProvisioner` (smallest), `Ec2LaunchTemplateCfnProvisioner`\n(update-in-place and replacement).\n\n---\n\n## Code Style\n\n- Use constructor injection\n- Prefer self-explanatory code over comments\n- Avoid unnecessary comments\n- Always use braces in conditionals\n- Never leave a `catch` block empty. If an exception is intentionally tolerated, log it with enough context to diagnose it later.\n- Follow existing project patterns\n- Use modern Java features only when they improve clarity\n\n---\n\n## Logging\n\n- Use JBoss Logging\n- Keep logs structured\n- Avoid noisy logs in hot paths\n\n---\n\n## Pull Request Guidelines\n\n- Keep changes focused\n- Avoid unrelated refactors\n- Preserve behavior unless the task explicitly requires change\n- Update docs when necessary\n- Explain missing tests when behavior changed but no automated coverage was added\n\nConventional commits:\n\n- `feat:`\n- `fix:`\n- `perf:`\n- `docs:`\n- `chore:`\n\nDo not add `Co-Authored-By` trailers for AI tools in commit messages. Keep attribution limited to human contributors.\n\n---\n\n## Release Awareness\n\n- Changes merged into `main` do not automatically imply a stable release\n- Releases are cut from `main` via the \"Release Cut\" workflow (`workflow_dispatch`\n  on `.github/workflows/release-cut.yml`), which runs semantic-release: it bumps\n  `pom.xml`, writes `CHANGELOG.md`, commits, tags, and creates the GitHub Release\n- `release/x.y.x` branches are retired for now\n- Tags still trigger the publishing workflows (`release.yml`)\n\nTreat release workflows as critical infrastructure.\n\n---\n\n## Agent Workflow\n\n### Before editing\n\n1. Identify service and protocol\n2. Locate an existing implementation to mirror\n3. Check config impact\n4. Check storage impact\n5. Check documentation impact\n6. Define the minimal useful test plan\n\n### Before finishing\n\n1. Run relevant tests\n2. Validate protocol behavior\n3. Ensure no custom endpoints were introduced\n4. Verify config and docs updates\n\n---\n\n## Common Mistakes\n\n- Creating non-AWS endpoints\n- Bypassing `StorageFactory`\n- Changing wire formats without tests\n- Forgetting YAML updates\n- Producing inconsistent URLs or ARNs\n- Testing only with raw HTTP\n- Introducing unnecessary new patterns\n- Adding a CloudFormation type to `CloudFormationResourceProvisioner` instead of a\n  per-service provisioner\n- Setting a CloudFormation resource's physical id but not its `Fn::GetAtt`\n  attributes (they are two separate mechanisms, and the miss is silent)\n\n---\n\n## Human Handoff\n\nIf behavior is unclear:\n\n1. Prefer AWS behavior\n2. Then existing Floci behavior\n3. Then compatibility test expectations\n\nIf a task would require broad architectural changes, stop and surface the tradeoffs instead of refactoring across services blindly.\n",".github/copilot-instructions.md":"# Copilot Instructions for Pull Request Review\n\nReview pull requests in the Floci repository with AWS compatibility as the primary concern.\n\nFloci is a Java-based local AWS emulator built on Quarkus. Its goal is to match AWS SDK and AWS CLI behavior through real AWS wire protocols, not convenience APIs or custom abstractions.\n\n## Review Priorities\n\nEvaluate changes in this order:\n\n1. Preserve AWS protocol compatibility\n2. Match AWS SDK and AWS CLI behavior\n3. Reuse existing Floci patterns\n4. Prefer correctness over convenience\n5. Keep changes focused and testable\n\n## What to Flag\n\nRaise concerns when a PR introduces any of the following without strong justification:\n\n- Non-AWS endpoint shapes\n- Request or response format changes made for convenience\n- Broad refactors unrelated to the PR goal\n- New service patterns where an existing Floci pattern should be reused\n- Direct storage implementation usage instead of `StorageFactory`\n\n## Architecture Expectations\n\nFloci follows a layered design:\n\n- Controllers / handlers parse AWS protocol input and produce AWS-compatible responses\n- Services contain business logic and should throw `AwsException`\n- Models hold domain data\n\nCore infrastructure commonly relevant in reviews:\n\n- `EmulatorConfig`\n- `ServiceRegistry`\n- `StorageFactory`\n- `AwsQueryController`\n- `AwsJson11Controller`\n- `AwsException`\n- `AwsExceptionMapper`\n- `EmulatorLifecycle`\n\nCheck that controllers stay thin, business logic remains in services, and new changes fit existing repository patterns.\n\n## Protocol Review Rules\n\nFloci implements real AWS wire protocols. Review protocol-affecting changes carefully.\n\n- Query services should keep form-encoded POST requests with `Action` and XML responses\n- JSON 1.1 services should keep `X-Amz-Target` requests and AWS-style JSON responses\n- REST JSON and REST XML services should stay aligned with AWS path and payload conventions\n- TCP-based services should not drift into HTTP-style abstractions\n\nPay extra attention to these cases:\n\n- CloudWatch Metrics supports both Query and JSON 1.1 and both paths must stay aligned\n- SQS and SNS may have multiple compatibility paths that must not drift\n- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs\n- Management APIs should ideally be validated with AWS SDK clients, not only handcrafted HTTP\n\n## XML and JSON Rules\n\nFlag PRs that:\n\n- Ignore `AwsNamespaces` constants\n- Return JSON errors that do not follow AWS error structures\n- Change controller return types in ways that may break reflection or native-image compatibility\n\n## Config and Storage Review\n\nWhen a PR changes configuration or persistence behavior, verify the change is wired consistently.\n\nCheck for updates to:\n\n- `EmulatorConfig`\n- main `application.yml`\n- test `application.yml`\n- `StorageFactory`\n- lifecycle hooks when relevant\n\nSupported storage modes include:\n\n- `memory`\n- `persistent`\n- `hybrid`\n- `wal`\n\nTreat repository YAML as the source of truth for runtime behavior unless the PR explicitly changes configuration semantics.\n\n## Testing Expectations\n\nExpect automated coverage for changes that affect:\n\n- request parsing\n- response shape\n- error handling\n- persistence semantics\n- URL generation\n- service enablement\n\nPrefer:\n\n- AWS SDK-based validation over raw HTTP-only testing\n- integration tests for compatibility-sensitive behavior\n- existing naming conventions such as `*ServiceTest.java` and `*IntegrationTest.java`\n\nIf behavior changes without automated coverage, call that out explicitly.\n\n## Review Checklist\n\nWhen analyzing a PR, check:\n\n- Is the change focused?\n- Does it preserve AWS-compatible wire behavior?\n- Does it reuse an existing Floci pattern?\n- Are controllers thin and services responsible for domain logic?\n- Are `AwsException` and existing error-mapping patterns used correctly?\n- Are config and YAML updates complete?\n- Are storage changes wired through `StorageFactory`?\n- Are tests added or updated where compatibility is affected?\n- Are docs updated when user-facing behavior changes?\n\n## How to Write Feedback\n\nWrite review comments that are:\n\n- specific\n- repository-aware\n- grounded in AWS compatibility risk\n\nUse severity when helpful:\n\n- `high`: likely breaks AWS SDK / CLI compatibility or protocol behavior\n- `medium`: inconsistent with Floci architecture, wiring, or testing expectations\n- `low`: maintainability, clarity, or minor convention issue\n\nPrefer comments that explain:\n\n- what is risky\n- why it matters in Floci\n- which existing pattern should be followed instead\n\n## If Behavior Is Unclear\n\nUse this fallback order:\n\n1. Prefer AWS behavior\n2. Then existing Floci behavior\n3. Then compatibility test expectations\n\nIf correctness would require a broader architectural change, call out the tradeoff instead of suggesting blind refactoring.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"Guidance for AI coding agents working in the Floci repository.\n\nThis file defines repository-specific operating rules for autonomous or semi-autonomous coding agents. Follow these instructions unless a maintainer explicitly tells you otherwise.\n\n---\n\n## Project Overview\n\nFloci is a Java-based local AWS emulator built on Quarkus.\n\nIts goal is full AWS SDK and AWS CLI compatibility through real AWS wire protocols, not convenience APIs or simplified abstractions.\n\nFloci acts as an open-source alternative to LocalStack Community.\n\n- Port: 4566\n- Stack:\n  - Java 25\n  - Quarkus 3.32.3\n  - JUnit 5\n  - RestAssured\n  - Jackson\n  - Docker integrations for Lambda, RDS, and ElastiCache\n\n---\n\n## First Principles\n\nWhen making changes, follow these priorities:\n\n1. Preserve AWS protocol compatibility\n2. Match AWS SDK and CLI behavior\n3. Reuse existing Floci patterns\n4. Prefer correctness over convenience\n5. Keep changes narrow and testable\n\nCritical rules:\n\n- Do not introduce custom endpoint shapes\n- Do not change request or response formats for convenience\n- Do not perform broad refactors unless the task explicitly requires them\n- Keep behavior aligned with AWS expectations and existing Floci conventions\n\n---\n\n## Architecture\n\nFloci follows a layered design:\n\n- **Controller / Handler**\n  - Parses AWS protocol input\n  - Produces AWS-compatible responses\n\n- **Service**\n  - Contains business logic\n  - Throws `AwsException`\n\n- **Model**\n  - Domain objects\n\n### Core Infrastructure\n\n- `EmulatorConfig`\n- `ServiceRegistry`\n- `StorageBackend` + `StorageFactory`\n- `AwsJson11Controller`\n- `AwsQueryController`\n- `AwsException` + `AwsExceptionMapper`\n- `EmulatorLifecycle`\n\n---\n\n## Package Layout\n\n- `io.github.hectorvent.floci.config`\n- `io.github.hectorvent.floci.core.common`\n- `io.github.hectorvent.floci.core.storage`\n- `io.github.hectorvent.floci.lifecycle`\n- `io.github.hectorvent.floci.services.<service>`\n\nTypical service structure:\n\n- `services/<svc>/`\n  - `*Controller.java`\n  - `*Service.java`\n  - `model/`\n\nRule:\nCopy an existing service pattern before introducing a new one.\n\n---\n\n## AWS Protocol Rules\n\nFloci must implement real AWS wire protocols.\n\n| Protocol | Services | Request Format | Response Format | Implementation |\n|----------|----------|----------------|-----------------|----------------|\n| Query | SQS, SNS, IAM, STS, RDS, ElastiCache, CloudFormation, CloudWatch Metrics | form-encoded POST + `Action` | XML | `AwsQueryController` |\n| JSON 1.1 | SSM, EventBridge, CloudWatch Logs, Kinesis, KMS, Cognito, Secrets Manager, ACM | POST + `X-Amz-Target` | JSON | `AwsJson11Controller` |\n| REST JSON | Lambda, API Gateway, SES V2 | REST paths | JSON | JAX-RS |\n| REST XML | S3 | REST paths | XML | JAX-RS |\n| TCP | ElastiCache, RDS | raw protocol | native | proxies |\n\n### Important exceptions\n\n- CloudWatch Metrics supports both Query and JSON 1.1; handlers must remain aligned\n- SQS and SNS may expose multiple compatibility paths; do not let them drift\n- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs\n- Data-plane protocols may use raw TCP sockets\n- Management APIs should be validated with AWS SDK clients, not only handcrafted HTTP requests\n\n---\n\n## XML / JSON Rules\n\n- Use `XmlBuilder` for XML responses\n- Use `XmlParser` for XML parsing; do not use regex\n- Use `AwsNamespaces` constants\n- JSON errors must follow AWS error structures\n- Types returned directly from controllers must remain compatible with native-image reflection requirements\n\n---\n\n## Storage Rules\n\nSupported storage modes:\n\n- `memory`\n- `persistent`\n- `hybrid`\n- `wal`\n\nRules:\n\n- Always use `StorageFactory`\n- Do not instantiate storage implementations directly inside services\n- Respect lifecycle hooks for load and flush behavior\n\nImportant nuance:\n\nConfiguration 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.\n\nWhen adding storage-related behavior:\n\n1. Update `EmulatorConfig`\n2. Update main `application.yml`\n3. Update test `application.yml`\n4. Wire through `StorageFactory`\n5. Verify lifecycle integration\n\n---\n\n## Configuration Rules\n\nConfiguration lives under `floci.*`.\n\nWhen adding config:\n\n1. Add it to `EmulatorConfig`\n2. Add it to main `application.yml`\n3. Add it to test `application.yml` if needed\n4. Update documentation if user-facing\n5. Follow `FLOCI_*` environment variable conventions\n\nCritical areas:\n\n- `base-url`\n- `hostname`\n- region and account defaults\n- port ranges\n- persistence paths\n- Docker networking\n\n---\n\n## Build & Run\n\n    ./mvnw quarkus:dev\n    ./mvnw test\n    ./mvnw clean package\n    ./mvnw clean package -DskipTests\n\n### Focused tests\n\n    ./mvnw test -Dtest=SsmIntegrationTest\n    ./mvnw test -Dtest=SsmIntegrationTest#putParameter\n\n---\n\n## Compatibility Project\n\nCompatibility test suite: `./compatibility-tests/`\n\nGuidelines:\n\n- Prefer AWS SDK clients over raw HTTP for management-plane validation\n- Use this suite when changes may affect real SDK behavior\n\n---\n\n## Testing Rules\n\n### Conventions\n\n- Unit tests: `*ServiceTest.java`\n- Integration tests: `*IntegrationTest.java`\n- Prefer package-private constructors for testability\n- Integration tests may use ordered execution when stateful behavior requires it\n\n### Expectations\n\n- Test any behavior affecting AWS compatibility\n- Do not rely only on manual HTTP testing\n- Prefer SDK-based validation where possible\n\n### When touching protocol behavior\n\nIf a change affects request parsing, response shape, error handling, persistence semantics, URL generation, or service enablement:\n\n1. Add or update automated tests\n2. Prefer SDK-based verification where possible\n3. Check compatibility across alternate protocol paths\n4. Document intentional deviations clearly\n\n---\n\n## Error Handling\n\n- Services should throw `AwsException`\n- Query and REST XML flows should use `AwsExceptionMapper`\n- JSON 1.1 flows should return structured AWS error responses where required\n- Controller return types must remain reflection-safe\n\n---\n\n## Service Implementation Pattern\n\nWhen adding functionality:\n\n1. Identify the AWS protocol\n2. Reuse an existing service pattern\n3. Keep controllers thin\n4. Use `AwsException` for domain errors\n5. Reuse shared utilities\n6. Update config, storage, docs, and tests together\n7. Validate behavior against AWS SDK expectations\n\n---\n\n## Adding a New AWS Service\n\n1. Create a package under `services/`\n2. Add:\n   - Controller\n   - Service\n   - `model/`\n3. Register the service in `ServiceRegistry`\n4. Add config to `EmulatorConfig`\n5. Add YAML config in main and test config files\n6. Wire storage through `StorageFactory`\n7. Add tests\n8. Update documentation\n\n---\n\n## Adding a CloudFormation Resource Type\n\n**Do not add cases to `CloudFormationResourceProvisioner`.** That class is a legacy\nmonolith being dismantled; new types go in per-service provisioners under\n`services/cloudformation/provisioners/`.\n\n1. Add the type to the existing `<Service>CfnProvisioner`, or create one:\n   `@ApplicationScoped`, injecting only the service it wraps. CDI discovery via\n   `CloudFormationResourceRegistry` handles registration — no manual wiring, but a\n   missing `@ApplicationScoped` silently means the type is never provisioned.\n2. `resourceTypes()` lists the `AWS::*` types; `provision(resource, props, ctx)`\n   does the work, switching on `resource.getResourceType()` when it serves several.\n3. Set **both** reference mechanisms — they are separate:\n   - `resource.setPhysicalId(...)` backs `Ref`\n   - `resource.getAttributes().put(...)` backs `Fn::GetAtt`, one entry per attribute\n   Omitting an attribute does not fail; `Fn::GetAtt` resolves to the literal\n   `\"LogicalId.Attr\"`. Source the attribute names from the type's registry schema in\n   `local/aws/cfn-resource-schemas/us-east-1/` (`readOnlyProperties`), and validate\n   `required` from the same file.\n4. **`provision` serves create *and* update.** On `UpdateStack` it is re-invoked with\n   the prior physical id and attributes already populated on the resource. Branch on\n   that instead of creating unconditionally.\n5. Override `delete(...)` when the type has a backing delete; tolerate already-deleted.\n6. Tests: focused unit test mocking one service (`SqsCfnProvisionerTest` is the\n   pattern) plus an integration test asserting the **exact `Fn::GetAtt` keys**. An\n   unmapped type is stubbed as `CREATE_COMPLETE` with a fake ARN, so asserting status\n   alone cannot detect a type that was never wired.\n7. Update the resource-type table in `docs/services/cloudformation.md`.\n\nReferences: `SqsCfnProvisioner` (smallest), `Ec2LaunchTemplateCfnProvisioner`\n(update-in-place and replacement).\n\n---\n\n## Code Style\n\n- Use constructor injection\n- Prefer self-explanatory code over comments\n- Avoid unnecessary comments\n- Always use braces in conditionals\n- Never leave a `catch` block empty. If an exception is intentionally tolerated, log it with enough context to diagnose it later.\n- Follow existing project patterns\n- Use modern Java features only when they improve clarity\n\n---\n\n## Logging\n\n- Use JBoss Logging\n- Keep logs structured\n- Avoid noisy logs in hot paths\n\n---\n\n## Pull Request Guidelines\n\n- Keep changes focused\n- Avoid unrelated refactors\n- Preserve behavior unless the task explicitly requires change\n- Update docs when necessary\n- Explain missing tests when behavior changed but no automated coverage was added\n\nConventional commits:\n\n- `feat:`\n- `fix:`\n- `perf:`\n- `docs:`\n- `chore:`\n\nDo not add `Co-Authored-By` trailers for AI tools in commit messages. Keep attribution limited to human contributors.\n\n---\n\n## Release Awareness\n\n- Changes merged into `main` do not automatically imply a stable release\n- Releases are cut from `main` via the \"Release Cut\" workflow (`workflow_dispatch`\n  on `.github/workflows/release-cut.yml`), which runs semantic-release: it bumps\n  `pom.xml`, writes `CHANGELOG.md`, commits, tags, and creates the GitHub Release\n- `release/x.y.x` branches are retired for now\n- Tags still trigger the publishing workflows (`release.yml`)\n\nTreat release workflows as critical infrastructure.\n\n---\n\n## Agent Workflow\n\n### Before editing\n\n1. Identify service and protocol\n2. Locate an existing implementation to mirror\n3. Check config impact\n4. Check storage impact\n5. Check documentation impact\n6. Define the minimal useful test plan\n\n### Before finishing\n\n1. Run relevant tests\n2. Validate protocol behavior\n3. Ensure no custom endpoints were introduced\n4. Verify config and docs updates\n\n---\n\n## Common Mistakes\n\n- Creating non-AWS endpoints\n- Bypassing `StorageFactory`\n- Changing wire formats without tests\n- Forgetting YAML updates\n- Producing inconsistent URLs or ARNs\n- Testing only with raw HTTP\n- Introducing unnecessary new patterns\n- Adding a CloudFormation type to `CloudFormationResourceProvisioner` instead of a\n  per-service provisioner\n- Setting a CloudFormation resource's physical id but not its `Fn::GetAtt`\n  attributes (they are two separate mechanisms, and the miss is silent)\n\n---\n\n## Human Handoff\n\nIf behavior is unclear:\n\n1. Prefer AWS behavior\n2. Then existing Floci behavior\n3. Then compatibility test expectations\n\nIf a task would require broad architectural changes, stop and surface the tradeoffs instead of refactoring across services blindly.\n","category":"root","tokens":2842},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","title":"copilot-instructions.md","content":"# Copilot Instructions for Pull Request Review\n\nReview pull requests in the Floci repository with AWS compatibility as the primary concern.\n\nFloci is a Java-based local AWS emulator built on Quarkus. Its goal is to match AWS SDK and AWS CLI behavior through real AWS wire protocols, not convenience APIs or custom abstractions.\n\n## Review Priorities\n\nEvaluate changes in this order:\n\n1. Preserve AWS protocol compatibility\n2. Match AWS SDK and AWS CLI behavior\n3. Reuse existing Floci patterns\n4. Prefer correctness over convenience\n5. Keep changes focused and testable\n\n## What to Flag\n\nRaise concerns when a PR introduces any of the following without strong justification:\n\n- Non-AWS endpoint shapes\n- Request or response format changes made for convenience\n- Broad refactors unrelated to the PR goal\n- New service patterns where an existing Floci pattern should be reused\n- Direct storage implementation usage instead of `StorageFactory`\n\n## Architecture Expectations\n\nFloci follows a layered design:\n\n- Controllers / handlers parse AWS protocol input and produce AWS-compatible responses\n- Services contain business logic and should throw `AwsException`\n- Models hold domain data\n\nCore infrastructure commonly relevant in reviews:\n\n- `EmulatorConfig`\n- `ServiceRegistry`\n- `StorageFactory`\n- `AwsQueryController`\n- `AwsJson11Controller`\n- `AwsException`\n- `AwsExceptionMapper`\n- `EmulatorLifecycle`\n\nCheck that controllers stay thin, business logic remains in services, and new changes fit existing repository patterns.\n\n## Protocol Review Rules\n\nFloci implements real AWS wire protocols. Review protocol-affecting changes carefully.\n\n- Query services should keep form-encoded POST requests with `Action` and XML responses\n- JSON 1.1 services should keep `X-Amz-Target` requests and AWS-style JSON responses\n- REST JSON and REST XML services should stay aligned with AWS path and payload conventions\n- TCP-based services should not drift into HTTP-style abstractions\n\nPay extra attention to these cases:\n\n- CloudWatch Metrics supports both Query and JSON 1.1 and both paths must stay aligned\n- SQS and SNS may have multiple compatibility paths that must not drift\n- Cognito well-known endpoints are OIDC REST JSON endpoints, not AWS management APIs\n- Management APIs should ideally be validated with AWS SDK clients, not only handcrafted HTTP\n\n## XML and JSON Rules\n\nFlag PRs that:\n\n- Ignore `AwsNamespaces` constants\n- Return JSON errors that do not follow AWS error structures\n- Change controller return types in ways that may break reflection or native-image compatibility\n\n## Config and Storage Review\n\nWhen a PR changes configuration or persistence behavior, verify the change is wired consistently.\n\nCheck for updates to:\n\n- `EmulatorConfig`\n- main `application.yml`\n- test `application.yml`\n- `StorageFactory`\n- lifecycle hooks when relevant\n\nSupported storage modes include:\n\n- `memory`\n- `persistent`\n- `hybrid`\n- `wal`\n\nTreat repository YAML as the source of truth for runtime behavior unless the PR explicitly changes configuration semantics.\n\n## Testing Expectations\n\nExpect automated coverage for changes that affect:\n\n- request parsing\n- response shape\n- error handling\n- persistence semantics\n- URL generation\n- service enablement\n\nPrefer:\n\n- AWS SDK-based validation over raw HTTP-only testing\n- integration tests for compatibility-sensitive behavior\n- existing naming conventions such as `*ServiceTest.java` and `*IntegrationTest.java`\n\nIf behavior changes without automated coverage, call that out explicitly.\n\n## Review Checklist\n\nWhen analyzing a PR, check:\n\n- Is the change focused?\n- Does it preserve AWS-compatible wire behavior?\n- Does it reuse an existing Floci pattern?\n- Are controllers thin and services responsible for domain logic?\n- Are `AwsException` and existing error-mapping patterns used correctly?\n- Are config and YAML updates complete?\n- Are storage changes wired through `StorageFactory`?\n- Are tests added or updated where compatibility is affected?\n- Are docs updated when user-facing behavior changes?\n\n## How to Write Feedback\n\nWrite review comments that are:\n\n- specific\n- repository-aware\n- grounded in AWS compatibility risk\n\nUse severity when helpful:\n\n- `high`: likely breaks AWS SDK / CLI compatibility or protocol behavior\n- `medium`: inconsistent with Floci architecture, wiring, or testing expectations\n- `low`: maintainability, clarity, or minor convention issue\n\nPrefer comments that explain:\n\n- what is risky\n- why it matters in Floci\n- which existing pattern should be followed instead\n\n## If Behavior Is Unclear\n\nUse this fallback order:\n\n1. Prefer AWS behavior\n2. Then existing Floci behavior\n3. Then compatibility test expectations\n\nIf correctness would require a broader architectural change, call out the tradeoff instead of suggesting blind refactoring.\n","category":".github","tokens":1206}]}