Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a7a292d
test(email-writing): define secure orchestration port contracts
seonghobae Aug 13, 2026
9fbb7f3
feat(email-writing): add scoped orchestrator settings
seonghobae Aug 13, 2026
7cf2871
feat(email-writing): add secure orchestrator client port
seonghobae Aug 13, 2026
9b49dac
test(email-writing): require deployable orchestrator config
seonghobae Aug 13, 2026
f30f0e9
test(email-writing): execute orchestrator migration contract
seonghobae Aug 13, 2026
43f915c
feat(email-writing): migrate orchestrator configuration
seonghobae Aug 13, 2026
2ab368e
chore(email-writing): register migration metadata
seonghobae Aug 13, 2026
20882ad
feat(email-writing): register orchestrator migration metadata
github-actions[bot] Aug 13, 2026
2479afb
ci(email-writing): verify complete Task 5 contract
seonghobae Aug 13, 2026
ec41939
test(email-writing): add Judge cancellation regression
seonghobae Aug 13, 2026
3e11486
fix(ci): make cancellation regression workflow executable
seonghobae Aug 13, 2026
af22426
test(email-writing): retain Judge capacity through cancellation
github-actions[bot] Aug 13, 2026
04dde01
test(email-writing): execute Judge cancellation regression
seonghobae Aug 13, 2026
af8065c
fix(email-writing): retain Judge capacity through cancellation
seonghobae Aug 13, 2026
3ebcec3
test(email-writing): require tenant orchestration config API
seonghobae Aug 13, 2026
1b6d4a4
test(email-writing): execute tenant orchestration config API contracts
seonghobae Aug 13, 2026
9a71d25
feat(email-writing): expose tenant orchestration configuration
seonghobae Aug 13, 2026
d01bd04
test(email-writing): expose orchestration hardening gaps
seonghobae Aug 13, 2026
bd6acaf
ci(email-writing): run orchestration hardening regressions
seonghobae Aug 13, 2026
c7608cc
ci(email-writing): repair orchestrator hardening failures
seonghobae Aug 15, 2026
2feeab0
ci(email-writing): stage hardening repair script
seonghobae Aug 15, 2026
e514c5b
ci(email-writing): simplify hardening repair runner
seonghobae Aug 15, 2026
7318fcb
ci(email-writing): remove obsolete port imports during repair
seonghobae Aug 15, 2026
9008496
fix(email-writing): harden orchestration boundaries
Aug 15, 2026
71250da
ci(email-writing): stage modular orchestration API refactor
seonghobae Aug 15, 2026
b9c1e0a
ci(email-writing): run modular orchestration API refactor
seonghobae Aug 15, 2026
26fd38f
ci(email-writing): retarget hardening tests during modularization
seonghobae Aug 15, 2026
490dbb9
refactor(email-writing): isolate orchestration configuration API
Aug 15, 2026
d2297c6
ci(email-writing): enforce exact Task 5 quality gates
seonghobae Aug 15, 2026
d83e64b
test(email-writing): close Task 5 terminal coverage gaps
seonghobae Aug 15, 2026
c1e109c
ci(email-writing): execute Task 5 terminal coverage suite
seonghobae Aug 15, 2026
f3e66b3
ci(email-writing): repair terminal coverage resource cleanup
seonghobae Aug 15, 2026
48ee9bd
ci(email-writing): fix migration cleanup repair anchor
seonghobae Aug 15, 2026
9a8e0a9
ci(email-writing): remove terminal coverage dead import
seonghobae Aug 15, 2026
85b9899
test(email-writing): close migration rehearsal resources
Aug 15, 2026
d4d3eb0
ci(email-writing): refresh Task 5 on current context parent
seonghobae Aug 15, 2026
fe89284
Merge remote-tracking branch 'origin/feat/llm-email-writing-context-t…
Aug 15, 2026
9a48fb3
ci(email-writing): remove Task 5 parent refresh workflow
Aug 15, 2026
819c000
ci(email-writing): finalize Task 5 quality and merge readiness
seonghobae Aug 15, 2026
3b3ff4c
ci(email-writing): automate verified Task 5 promotion
seonghobae Aug 15, 2026
f6a1372
ci(email-writing): harden Task 5 promotion polling
seonghobae Aug 15, 2026
34f368c
ci(email-writing): remove branch-writing promotion workflow
seonghobae Aug 16, 2026
775f083
ci(email-writing): remove duplicate write-capable promoter
seonghobae Aug 16, 2026
de77a19
ci(email-writing): remove self-modifying finalizer
seonghobae Aug 16, 2026
0c0ac2b
docs(email-writing): document strict JSON hook protocol
seonghobae Aug 16, 2026
9cd9b95
Merge remote-tracking branch 'origin/feat/llm-email-writing-context-t…
cursoragent Aug 17, 2026
72abda0
Merge current authorized-context Task 4 into orchestrator Task 5
seonghobae Sep 1, 2026
27ec475
Merge current authorized-context Task 4 into orchestrator Task 5
seonghobae Sep 1, 2026
756aad9
Merge current authorized-context Task 4 into orchestrator Task 5
seonghobae Sep 1, 2026
a08ef0b
test(email-writing): expose port import side effect
seonghobae Sep 2, 2026
beb2846
fix(email-writing): keep port import config-free
seonghobae Sep 2, 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
39 changes: 39 additions & 0 deletions .github/workflows/email-writing-orchestrator-hardening-tdd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Email Writing Orchestrator Hardening TDD

on:
push:
branches:
- feat/llm-email-writing-orchestrator-task5
workflow_dispatch:

permissions:
contents: read

concurrency:
group: email-writing-orchestrator-hardening-${{ github.ref }}
cancel-in-progress: true

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
PYTHONWARNINGS: error
DISABLE_BACKGROUND_WORKERS: "1"

jobs:
regressions:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: "3.14"
cache: pip
cache-dependency-path: backend/requirements-hashes.txt
- run: python -m pip install --disable-pip-version-check --require-hashes -r backend/requirements-hashes.txt
- name: Run hardening regressions
run: |
cd backend
python -m pytest -q tests/test_contextual_orchestrator_hardening.py
145 changes: 145 additions & 0 deletions .github/workflows/email-writing-orchestrator-tdd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: Email Writing Orchestrator TDD

on:
push:
branches:
- feat/llm-email-writing-orchestrator-task5
workflow_dispatch:

permissions:
contents: read

concurrency:
group: email-writing-orchestrator-tdd-${{ github.ref }}
cancel-in-progress: true

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
PYTHONWARNINGS: error
DISABLE_BACKGROUND_WORKERS: "1"

jobs:
task5-contracts:
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
cache-dependency-path: backend/requirements-hashes.txt
- name: Install hash-locked application dependencies
run: python -m pip install --disable-pip-version-check --require-hashes -r backend/requirements-hashes.txt
- name: Install hash-verified coverage tool
run: |
set -euo pipefail
mkdir -p /tmp/coverage-wheel
cat >/tmp/coverage-lock.txt <<'EOF'
coverage==7.15.2 --hash=sha256:eb6bcae8d1a9d305351ecb108232441d11c5cfe9de840a04388ba5d2db8d735c
EOF
python -m pip download \
--disable-pip-version-check \
--require-hashes \
--no-deps \
--only-binary=:all: \
--platform any \
--python-version 3.14 \
--implementation py \
--abi none \
--dest /tmp/coverage-wheel \
-r /tmp/coverage-lock.txt
python -m pip install --disable-pip-version-check --no-deps \
/tmp/coverage-wheel/coverage-7.15.2-py3-none-any.whl
- name: Run Task 5 contracts and hardening regressions
run: |
cd backend
python -m pytest -q \
tests/test_contextual_orchestrator_client.py \
tests/test_contextual_orchestrator_hardening.py \
tests/test_email_writing_orchestrator_module_boundary.py \
tests/test_email_writing_orchestrator_scope.py \
tests/test_email_writing_orchestrator_migration.py \
tests/test_email_writing_orchestrator_config_api.py \
tests/test_email_writing_orchestrator_terminal_coverage.py
- name: Verify Task 5 statement and branch coverage
run: |
cd backend
python -m coverage erase
python -m coverage run --branch \
--include='api/email_writing_orchestrator_config.py,db/email_writing_orchestrator_config.py,services/contextual_orchestrator_client.py,services/email_writing_orchestrator_port.py,services/tenant_config_scope.py,alembic/versions/20260813_0001_add_email_writing_orchestrator_config.py' \
-m pytest -q \
tests/test_contextual_orchestrator_client.py \
tests/test_contextual_orchestrator_hardening.py \
tests/test_email_writing_orchestrator_module_boundary.py \
tests/test_email_writing_orchestrator_scope.py \
tests/test_email_writing_orchestrator_migration.py \
tests/test_email_writing_orchestrator_config_api.py \
tests/test_email_writing_orchestrator_terminal_coverage.py
python -m coverage report --show-missing --fail-under=100 \
api/email_writing_orchestrator_config.py \
db/email_writing_orchestrator_config.py \
services/contextual_orchestrator_client.py \
services/email_writing_orchestrator_port.py \
services/tenant_config_scope.py \
alembic/versions/20260813_0001_add_email_writing_orchestrator_config.py
- name: Verify shipped Python docstrings
run: |
cd backend
python - <<'PY'
import ast
from pathlib import Path

paths = [
Path("api/email_writing_orchestrator_config.py"),
Path("db/email_writing_orchestrator_config.py"),
Path("services/contextual_orchestrator_client.py"),
Path("services/email_writing_orchestrator_port.py"),
Path("services/tenant_config_scope.py"),
Path(
"alembic/versions/"
"20260813_0001_add_email_writing_orchestrator_config.py"
),
]
missing: list[str] = []
for path in paths:
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
if ast.get_docstring(tree) is None:
missing.append(f"{path}:<module>")
for node in ast.walk(tree):
if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
if ast.get_docstring(node) is None:
missing.append(f"{path}:{node.lineno}:{node.name}")
if missing:
raise SystemExit("Missing shipped docstrings:\n" + "\n".join(missing))
print(f"Docstring gate passed for {len(paths)} shipped modules")
PY
- name: Lint Task 5 source and tests
run: |
cd backend
python -m ruff check \
api/email_writing_orchestrator_config.py \
db/email_writing_orchestrator_config.py \
services/contextual_orchestrator_client.py \
services/email_writing_orchestrator_port.py \
services/tenant_config_scope.py \
alembic/versions/20260813_0001_add_email_writing_orchestrator_config.py \
tests/test_contextual_orchestrator_client.py \
tests/test_contextual_orchestrator_hardening.py \
tests/test_email_writing_orchestrator_module_boundary.py \
tests/test_email_writing_orchestrator_scope.py \
tests/test_email_writing_orchestrator_migration.py \
tests/test_email_writing_orchestrator_config_api.py \
tests/test_email_writing_orchestrator_terminal_coverage.py
- name: Compile Task 5 source
run: |
python -m compileall -q \
backend/api/email_writing_orchestrator_config.py \
backend/db/email_writing_orchestrator_config.py \
backend/services/contextual_orchestrator_client.py \
backend/services/email_writing_orchestrator_port.py \
backend/services/tenant_config_scope.py \
backend/alembic/versions/20260813_0001_add_email_writing_orchestrator_config.py
3 changes: 2 additions & 1 deletion backend/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@

from core.config import settings
from db.email_writing_evidence import EmailReviewSession
from db.email_writing_orchestrator_config import EmailWritingOrchestratorConfig

config = context.config

if config.config_file_name is not None:
fileConfig(config.config_file_name)

target_metadata = EmailReviewSession.__table__.metadata
target_metadata = EmailWritingOrchestratorConfig.__table__.metadata


def _database_url() -> str:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Add the owner-scoped email-writing orchestration table."""

from __future__ import annotations

from alembic import op

from db.email_writing_orchestrator_config import EmailWritingOrchestratorConfig

revision = "20260813_email_orchestrator"
down_revision = "20260812_email_writing_evidence"
branch_labels = None
depends_on = None


def upgrade() -> None:
"""Create the configuration table and its indexes."""
EmailWritingOrchestratorConfig.__table__.create(op.get_bind(), checkfirst=True)


def downgrade() -> None:
"""Drop only the configuration table introduced by this revision."""
EmailWritingOrchestratorConfig.__table__.drop(op.get_bind(), checkfirst=True)
Loading