Skip to content

v1.1.0: Security hardening, reliability fixes, OpenAI support#53

Merged
xmpuspus merged 10 commits intomainfrom
fix/v110-audit
Apr 4, 2026
Merged

v1.1.0: Security hardening, reliability fixes, OpenAI support#53
xmpuspus merged 10 commits intomainfrom
fix/v110-audit

Conversation

@xmpuspus
Copy link
Copy Markdown
Owner

@xmpuspus xmpuspus commented Apr 4, 2026

Summary

Full implementation of all v1.1.0 audit findings (56 issues identified, 38 fixes applied across 6 phases, 28 files changed).

Phase 1: Security hardening + deployment

  • Require CLOUDWRIGHT_API_KEY for web server startup (fail-fast)
  • Add SecurityHeadersMiddleware (X-Frame-Options, CSP, X-Content-Type-Options, Referrer-Policy)
  • Add Retry-After header to 429 rate limit responses
  • Parse X-Forwarded-For with CLOUDWRIGHT_TRUST_PROXY env var
  • Call configure_logging() in CLI and web entrypoints
  • Add Dockerfile (python:3.12-slim) + docker-compose.yml
  • Fix publish.yml to require passing CI before PyPI publish
  • Fix architecture-review.yml actions/checkout@v6 -> @v4
  • Add --cov-fail-under=70 to CI pytest

Phase 2: Reliability + intelligence

  • Fix _trim_history: append summary to system prompt, not as user message (fixes Anthropic 400 on 50+ turns)
  • Add try/except to send() and send_stream(), pop orphaned history on LLM failure
  • Add retry loop to generate_stream for both Anthropic and OpenAI providers
  • Add estimated usage tracking to send_stream
  • Set cost_estimate=None after modify(), add metadata.cost_stale flag
  • Fix GDPR region check for GCP (europe-*) and Azure (northeurope, westeurope, etc.)
  • Add provider-aware SERVICE_NORMALIZATION with normalize_service(raw, provider)

Phase 3: IaC security defaults

  • Terraform AWS: username -> var.db_username, skip_final_snapshot -> false, ECR IMMUTABLE
  • Terraform Azure: admin_username -> var.db_username for VMs and SQL
  • CloudFormation: MasterUsername -> !Ref DBUsername parameter
  • Apply validate_export_config to ALL export formats, not just IaC

Phase 4: Wire up dead features

  • Call create_version(old_spec) before modify() applies changes
  • MCP session lock: only hold across store.load()/save(), not session.send()
  • Wire complete_provider/complete_compliance to design command
  • Health endpoint returns 503 when LLM API keys missing
  • SSE queue: add maxsize=256 to prevent unbounded growth
  • Chat router: reject client-supplied assistant-role messages in history

Phase 5: OpenAI provider + model selection

  • Add CLOUDWRIGHT_MODEL env var for model override (both providers)
  • Fix OpenAI API: max_tokens -> max_completion_tokens (GPT-5 compat)
  • Add 11 tests for provider routing, model override, OpenAI LLM

Phase 6: Version bump + release

  • Bump all 4 packages to v1.1.0
  • Update tests for new cost_stale and trim behaviors
  • ruff lint + format clean (zero warnings)

Test plan

  • 969 core unit tests pass (excluding known terraform_validate timeout)
  • 99 CLI tests pass
  • 48 web API tests pass
  • 11 new OpenAI provider tests pass
  • ruff check + format: zero warnings
  • CI green on this PR
  • Tag v1.1.0 and push to trigger PyPI publish

Xavier Puspus added 7 commits April 4, 2026 19:00
- Require CLOUDWRIGHT_API_KEY for web server startup (fail-fast)
- Add SecurityHeadersMiddleware (X-Frame-Options, CSP, X-Content-Type-Options)
- Add Retry-After header to 429 responses
- Parse X-Forwarded-For with CLOUDWRIGHT_TRUST_PROXY env var
- Call configure_logging() in CLI and web entrypoints
- Add Dockerfile (python:3.12-slim) + docker-compose.yml
- Fix publish.yml to require passing tests before PyPI publish
- Fix architecture-review.yml actions/checkout@v6 -> @v4
- Add --cov-fail-under=70 to CI pytest
- Fix _trim_history: append summary to system prompt, not as user message
- Add try/except to send() and send_stream(), pop orphaned history on error
- Add retry loop to generate_stream for both Anthropic and OpenAI providers
- Add estimated usage tracking to send_stream
- Set cost_estimate=None after modify, add metadata.cost_stale flag
- Fix GDPR region check for GCP (europe-*) and Azure regions
- Make SERVICE_NORMALIZATION provider-aware with normalize_service()
- Terraform AWS: username -> var.db_username, skip_final_snapshot -> false, ECR IMMUTABLE
- Terraform Azure: admin_username -> var.db_username for VMs and SQL
- CloudFormation: MasterUsername -> !Ref DBUsername parameter
- Apply validate_export_config to ALL export formats, not just IaC
- Call create_version(old_spec) before modify() applies changes
- MCP session lock: only hold across store.load()/save(), not session.send()
- Wire complete_provider/complete_compliance to design command
- Health endpoint returns 503 when LLM API keys missing
- SSE queue: add maxsize=256 to prevent unbounded growth
- Chat router: reject client-supplied assistant-role messages in history
- Add CLOUDWRIGHT_MODEL env var for model override (both providers)
- Add comprehensive tests for provider routing, model override, OpenAI LLM
- OpenAI provider already fully implemented (generate, generate_fast, stream, retry)
- get_llm() already routes based on CLOUDWRIGHT_LLM_PROVIDER
- Bump all 4 packages to v1.1.0
- Fix OpenAI provider: max_tokens -> max_completion_tokens (GPT-5 API)
- Update test_modify_preserves_cost_estimate -> test_modify_marks_cost_stale
- Update test_trimmed_history_has_summary for system prompt trim behavior
- ruff lint + format clean (zero warnings)
- Update health tests to set mock LLM key (503 is correct without key)
- Fix action.yml YAML parse error: multiline strings at col 1 broke block scalar
- Replace inline heredoc RESULTS with _append() helper function
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 4, 2026

Cloudwright Architecture Review

Validation

�[33mUsage: �[0mcloudwright validate [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright validate �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Cost Estimate

�[33mUsage: �[0mcloudwright cost [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright cost �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Score

�[33mUsage: �[0mcloudwright score [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright score �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Lint

�[33mUsage: �[0mcloudwright lint [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright lint �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Diff

�[33mUsage: �[0mcloudwright diff [OPTIONS] SPEC_A SPEC_B
�[2mTry �[0m�[2;34m'cloudwright diff �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m


Generated by Cloudwright architecture intelligence

Xavier Puspus added 2 commits April 4, 2026 19:38
- Bump all 4 packages to v1.1.0
- Fix OpenAI provider: max_tokens -> max_completion_tokens (GPT-5.x API change)
- Update test_modify_preserves_cost_estimate to match new cost_stale behavior
- Update test_trimmed_history_has_summary for system prompt summary location
- Update test_chat_stream_with_history for assistant-role message filtering
- All lint checks pass, all tests pass
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 4, 2026

Cloudwright Architecture Review

Validation

�[33mUsage: �[0mcloudwright validate [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright validate �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Cost Estimate

�[33mUsage: �[0mcloudwright cost [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright cost �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Score

�[33mUsage: �[0mcloudwright score [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright score �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Lint

�[33mUsage: �[0mcloudwright lint [OPTIONS] SPEC_FILE
�[2mTry �[0m�[2;34m'cloudwright lint �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m

Diff

�[33mUsage: �[0mcloudwright diff [OPTIONS] SPEC_A SPEC_B
�[2mTry �[0m�[2;34m'cloudwright diff �[0m�[1;2;34m-�[0m�[1;2;34m-help�[0m�[2;34m'�[0m�[2m for help.�[0m
�[31m╭─�[0m�[31m Error �[0m�[31m─────────────────────────────────────────────────────────────────────�[0m�[31m─╮�[0m
�[31m│�[0m No such option: �[1;36m-�[0m�[1;36m-json�[0m �[31m│�[0m
�[31m╰──────────────────────────────────────────────────────────────────────────────╯�[0m


Generated by Cloudwright architecture intelligence

@xmpuspus xmpuspus merged commit 22721d3 into main Apr 4, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant