Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b3c7209
Add Zod request validation and remove reorder endpoints
claude May 6, 2026
57932a4
Add Rule.status, rename position→priorityOrder, add GSI to accounts t…
claude May 6, 2026
7ca7b74
Add GET /signals?status= endpoint for quarantined and blocked signals
claude May 6, 2026
f4ef87c
Add PUT /signals/:id/status to allow or block quarantined/blocked sig…
claude May 6, 2026
524e75f
Rename to quarantineResponse, drop filter mode side-effects
claude May 6, 2026
7016682
Change quarantineResponse endpoint to POST
claude May 6, 2026
2e8f277
Write matchedRules to Signal during rule evaluation
claude May 6, 2026
f8972c6
Derive ProcessingOutcome from matchedRules instead of building in par…
claude May 6, 2026
1954480
Trim MatchedRuleResult: drop ruleName, strip disabled from actions
claude May 6, 2026
ec7d2fb
Block status/notice emails by default; align classifier with type system
claude May 6, 2026
4c45306
Mark block phishing/notice emails task as done in TODO.md
claude May 6, 2026
c8551be
First-rule-wins for status actions; restore SR-06; reorder SR-05 befo…
claude May 7, 2026
7f21ce3
Split block/quarantine handling into two explicit branches
claude May 7, 2026
774f360
Implement spec-correct urgency for conversation, crm, and support wor…
claude May 7, 2026
52be532
Mark WORKFLOW_UX_SPEC.md review as done in TODO.md
claude May 7, 2026
032ae62
Move conversation/crm/support urgency logic into system rules (SR-15–…
claude May 7, 2026
7112824
Urgency is a first-class field on Signal and Arc, not a label
claude May 7, 2026
861f0cb
Simplify SR-16: conversation low urgency when user has never replied
claude May 7, 2026
f62e257
Update TODO.md to reflect current state
claude May 7, 2026
99b0b92
Add TODO: rule tags (key/value annotation, no functional effect)
claude May 7, 2026
2eb822c
Add tags to Rule — key/value annotation with no functional effect
claude May 7, 2026
56c75c9
Implement all open TODO items: A1-A3, B1-B6, C, D, E, F, G
claude May 7, 2026
0cd9fcd
Redesign SenderFilterMode as a post-rule fallback
claude May 7, 2026
f5bbed5
Replace quarantined status with quarantine_visible / quarantine_hidden
claude May 7, 2026
7f39e5b
Remove SR-02 system rule; use filter-mode fallback for untrusted senders
claude May 7, 2026
ccf48f9
Filter quarantine sub-status in memory after GSI fetch
claude May 7, 2026
7f5ea4f
Redesign audit keys, enforce accountId in all GSI PKs, replace Web Pu…
claude May 7, 2026
35ba37f
Handle WebSocket routes in the existing Lambda; remove HTTP connectio…
claude May 7, 2026
ac7af2a
Wire audit table and WebSocket management API into Lambda infra
claude May 7, 2026
a927b0e
Add WebSocket Lambda authorizer for \$connect
claude May 7, 2026
e989a1e
Fix infra gaps from audit: hardcoded regions, missing outputs, DLQ, K…
claude May 7, 2026
39e67a5
Revert bad audit fixes; add CF origin header validation in app
claude May 7, 2026
61b11b8
Include envelope fields in arc-matching embedding text
claude May 8, 2026
04b35b2
Include accountId as first field in arc-matching embedding text
claude May 8, 2026
de1c8ec
Add RLS-based tenant isolation for pgvector queries
claude May 8, 2026
123809c
Switch Aurora connection from RDS Proxy to Data API
claude May 8, 2026
d2877e6
Remove Lambda from VPC — no longer needed without RDS Proxy
claude May 8, 2026
16bb61c
Mark infra wired and WebSocket migration complete in TODO.md
claude May 8, 2026
fb0392f
Fix bulid.
wparad May 8, 2026
b272535
Fix type check.
wparad May 8, 2026
9f602f5
Cleanup build.
wparad May 8, 2026
42b1012
Setup deployment.
wparad May 9, 2026
f9426ec
convert to using the correct role.
wparad May 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: 'Setup Environment'
description: 'Sets up Node, OpenTofu, AWS credentials, and installs dependencies'
inputs:
aws_account_id:
description: 'AWS Account ID for STS AssumeRole'
required: true
aws_region:
description: 'AWS Region'
required: true
runs:
using: "composite"
steps:
- name: Setup Node.js 24
uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'

- name: Setup OpenTofu
uses: opentofu/setup-opentofu@v1
with:
tofu_version: '1.8.8'

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/GitHubActionsRole
aws-region: ${{ inputs.aws_region }}

- name: Install Node dependencies
run: npm ci
shell: bash
149 changes: 149 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: CI/CD Pipeline

on:
pull_request:
push:
branches:
- main
workflow_dispatch:

env:
AWS_DEFAULT_REGION: "eu-west-1"
STATE_BUCKET: "rhosys-opentofu-${{ secrets.AWS_ACCOUNT_ID }}-eu-west-1"
STATE_KEY: "${{ github.event.repository.name }}/terraform.tfstate"
TF_VAR_aws_account_id: "${{ secrets.AWS_ACCOUNT_ID }}"
TF_VAR_service_name: "${{ github.event.repository.name }}"

permissions:
id-token: write
contents: read

jobs:
# ==========================================
# PATH A: PULL REQUEST VALIDATION
# ==========================================
pr_validate:
name: Validate PR
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Environment
uses: ./.github/actions/setup
with:
aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
aws_region: ${{ env.AWS_DEFAULT_REGION }}

- name: Build Code
run: npm run build

- name: Test Code
run: npm test

- name: Tofu Init
run: tofu -chdir=deploy init -input=false -backend-config="bucket=${STATE_BUCKET}" -backend-config="key=${STATE_KEY}"

- name: Tofu Plan
run: tofu -chdir=deploy plan -out=plan.cache

# ==========================================
# PATH B: PRODUCTION BUILD & PLAN
# ==========================================
prod_build_and_plan:
name: Prod Build & Plan
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
outputs:
requires_approval: ${{ steps.plan_check.outputs.requires_approval }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Environment
uses: ./.github/actions/setup
with:
aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
aws_region: ${{ env.AWS_DEFAULT_REGION }}

- name: Build Code
run: npm run build

- name: Test Code
run: npm test

- name: Tofu Init
run: tofu -chdir=deploy init -input=false -backend-config="bucket=${STATE_BUCKET}" -backend-config="key=${STATE_KEY}"

- name: Tofu Plan
run: tofu -chdir=deploy plan -out=plan.cache

- name: Convert Plan to JSON
run: tofu -chdir=deploy show -json plan.cache > deploy/plan.json

- name: Check for Destructive Changes
id: plan_check
run: |
DESTROYS=$(jq '[.resource_changes[]? | select(.change.actions | contains(["delete"]))] | length' deploy/plan.json)

echo "Found $DESTROYS destructive changes."

if [ "$DESTROYS" -gt 0 ]; then
echo "requires_approval=true" >> $GITHUB_OUTPUT
echo "⚠️ DESTRUCTIVE CHANGES DETECTED. Routing to manual approval." >> $GITHUB_STEP_SUMMARY
else
echo "requires_approval=false" >> $GITHUB_OUTPUT
echo "✅ No destructive changes. Routing to auto-deploy." >> $GITHUB_STEP_SUMMARY
fi

- name: Pass Artifacts to Deploy Job
uses: actions/upload-artifact@v4
with:
name: prod-artifacts
path: |
deploy/plan.cache
deploy/plan.json
dist/
retention-days: 1

# ==========================================
# PATH B: PRODUCTION DEPLOY (Gated)
# ==========================================
prod_deploy:
name: Prod Deploy
needs: prod_build_and_plan
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
concurrency: production
environment:
name: ${{ needs.prod_build_and_plan.outputs.requires_approval == 'true' && 'production-gated' || 'production-auto' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Environment
uses: ./.github/actions/setup
with:
aws_account_id: ${{ secrets.AWS_ACCOUNT_ID }}
aws_region: ${{ env.AWS_DEFAULT_REGION }}

- name: Retrieve Artifacts
uses: actions/download-artifact@v4
with:
name: prod-artifacts

- name: Show Plan Summary
if: needs.prod_build_and_plan.outputs.requires_approval == 'true'
run: |
curl -sL https://github.com/dineshba/tf-summarize/releases/latest/download/tf-summarize_linux_amd64.tar.gz | tar xz
./tf-summarize -json deploy/plan.json >> $GITHUB_STEP_SUMMARY

- name: Tofu Init
run: tofu -chdir=deploy init -input=false -backend-config="bucket=${STATE_BUCKET}" -backend-config="key=${STATE_KEY}"

- name: Tofu Apply
run: tofu -chdir=deploy apply -input=false -auto-approve plan.cache

- name: Deploy Application Code
run: npm run deploy
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules/
dist/
*.tsbuildinfo
package-lock.json
*.tsbuildinfo
Loading
Loading