Skip to content

feat: gate-enforcement plan — flat-tts fix + doc red-list burn + wire quartet (python reference)#57

Merged
mjerris merged 2 commits into
mainfrom
feat/gate-enforcement
Jul 15, 2026
Merged

feat: gate-enforcement plan — flat-tts fix + doc red-list burn + wire quartet (python reference)#57
mjerris merged 2 commits into
mainfrom
feat/gate-enforcement

Conversation

@mjerris

@mjerris mjerris commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

The single python PR for the gate-enforcement plan (GATE_ENFORCEMENT_PLAN_2026-07-14). Python is the reference oracle; this burns its red list and flips its gates to blocking. Full PORTING_SDK=... SW_CI_TIER=all bash scripts/run-ci.sh is GREEN with every gate blocking (SW_WAVE_A_REPORT_ONLY=0) — 34 gates PASS, exit 0.

Part A — flat-tts reference fix (python is the oracle java/ruby/php drift against)

Adjudicated against the RELAY server + the OpenAPI spec — both agree a play array TTS item is { "type": "tts", "params": { "text": "..." } }, text inside params:

  • server: relay_apis.c:997-1002, relay.c:7692 reject anything without type and read text only from params
  • spec: calling/openapi.yaml CallPlayRequest.params.play items = {type, params}

calling.play(play=[...]) passes the play arg through verbatim (no shape transform), so this is a test + doc + example fixture fix, not codegen. Fixed 5 flat {type, text} sites to nested params:

  • tests/unit/rest/test_calling.py (the call and the assertion)
  • README.md, examples/quickstart_rest.py
  • rest/docs/calling.md, rest/examples/rest_calling_play_and_record.py, rest/examples/rest_calling_ivr_and_ai.py

The RELAY-side examples/tests already used the nested shape (a tts() helper) — unchanged.

Oracle: NO regen required. After re-enumerating, both python_signatures.json and python_surface.json are byte-identical — the fix is fixture/doc/test text; the enumerated surface (play: list[dict[str, Any]]) is unchanged. java/ruby/php do NOT need an oracle bump.

Caveat: the REST HTTP->RELAY gateway is a separate service not in mod_infrastructure, so the REST-surface confirmation is spec + RELAY-server based (strong, but noted).

Part B — doc red-list burn + root hygiene

DOC-AUDIT (newly wired for python): 164 raw findings (118 blocking + 46 wave-A) were all false-positives — stdlib/asyncio/aiohttp/asyncpg/redis, user-tutorial-defined helpers, competitor-API comparison prose (livekit/pipecat STT/TTS/LLM), and refs inside the non-shipping analysis files. Zero real SDK doc lies. Curated DOC_AUDIT_IGNORE.md (added a tutorial/ section for the multi_agents lessons + tutorial/fred). DOC-AUDIT now clean and blocking.

area_code doc lies (real, fixed): the spec query param is areacode (relay-rest/openapi.yaml:1606), and phone_numbers.search(**params) forwards verbatim, so area_code= is silently dropped by the server. Fixed 4 sites: rest/README.md, rest/docs/namespaces.md, rest/examples/rest_manage_resources.py, rest/examples/rest_phone_number_management.py. (number_type is correct per spec.)

Root hygiene (plan 3.2): deleted from the published root —

  • FIXES.md (public auth-bypass / SQLi / path-traversal write-ups on the package root)
  • one_sdk.md, formatted_version.md, signalwire_ai_blog.md (internal analysis docs)
  • the broken root swaig-test shim (execs a non-existent signalwire_agents/cli/test_swaig.py; the real entry is the swaig-test console script -> signalwire.cli.swaig_test_wrapper:main)
  • the livewire/livewire/ byte-identical duplicate subtree

Moved validate_schema.py -> eng/. Added ROOT_HYGIENE_ALLOW.md for the 7 load-bearing gate-config files kept at root. ROOT-HYGIENE now clean and blocking.

Part C — wire the quartet at the right tier

  • Per-PR (cheap): DOC-WIRE (new scripts/doc_wire_runner.py replays the documented REST fixtures against the strict-flag mock — verified to catch area_code as unknown_query_param), STATUS-CLAIM, DOC-AUDIT, DOC-LINKS, ROOT-HYGIENE, GATE-INVENTORY (gen_gate_inventory --check, plan 1.11b).
  • Nightly: WAIT-LIVENESS (wait_liveness corpus -> golden classification on the reference), STRICT-MOCKS (MOCK_RELAY_STRICT=1 on EXAMPLES-RUN + SNIPPET-RUN).

Part D — flip python's gates to blocking

scripts/run-ci.sh exports SW_WAVE_A_REPORT_ONLY=0 (default), so python's widened gates block. So when this merges, python is fully-enforced and clean.

Version: unchanged at 3.2.0 (SEMVER-DIFF green; surface unchanged).

🤖 Generated with Claude Code

https://claude.ai/code/session_01PqshDQajCmDHD3xPo4CXMC

mjerris and others added 2 commits July 15, 2026 09:39
… quartet (python reference)

The single python PR for the gate-enforcement plan (GATE_ENFORCEMENT_PLAN_2026-07-14).
Python is the reference oracle; this burns its red list and flips its gates to BLOCKING.

Part A — flat-tts reference fix (python is the oracle for java/ruby/php)
  Adjudicated: a play array TTS item is {type:"tts", params:{text:"..."}} — text INSIDE
  params — per the RELAY server (relay_apis.c:997-1002, relay.c:7692) and the OpenAPI
  spec (CallPlayRequest.params.play). calling.play(play=[...]) passes the arg through
  verbatim (no shape transform), so this is a TEST + DOC + EXAMPLE fixture fix, not codegen.
  Fixed 5 flat {type,text} sites to nested params:
    - tests/unit/rest/test_calling.py (call + assertion)
    - README.md, examples/quickstart_rest.py
    - rest/docs/calling.md, rest/examples/rest_calling_play_and_record.py,
      rest/examples/rest_calling_ivr_and_ai.py
  The RELAY-side examples/tests already used the nested shape (unchanged).
  ORACLE: no regen required. Confirmed python_signatures.json AND python_surface.json are
  byte-identical after re-enumerate — the fix is fixture/doc/test text, the enumerated
  surface (play: list[dict[str, Any]]) is unchanged. java/ruby/php do NOT need an oracle bump.
  CAVEAT: the REST HTTP->RELAY gateway is a separate service not in mod_infrastructure, so
  the REST-surface confirmation is spec+RELAY-server based (strong, with this caveat noted).

Part B — doc red-list burn + root hygiene
  DOC-AUDIT: 164 raw findings (118 blocking + 46 wave-A) were ALL false-positives
  (stdlib/asyncio/aiohttp/asyncpg/redis, user-tutorial-defined helpers, competitor-API
  comparison prose, and refs inside non-shipping analysis files) — ZERO real SDK doc lies.
  Curated DOC_AUDIT_IGNORE.md (added a tutorial/ section for the multi_agents lessons +
  tutorial/fred). DOC-AUDIT now clean and BLOCKING.
  area_code doc lies (real): the spec query param is `areacode` (relay-rest openapi:1606),
  and phone_numbers.search(**params) forwards verbatim, so `area_code=` is silently dropped
  by the server. Fixed 4 sites: rest/README.md, rest/docs/namespaces.md,
  rest/examples/rest_manage_resources.py, rest/examples/rest_phone_number_management.py.
  Root hygiene (plan 3.2): deleted from the published root — FIXES.md (public auth-bypass/
  SQLi/path-traversal write-ups), one_sdk.md, formatted_version.md, signalwire_ai_blog.md
  (internal analysis docs), the broken root `swaig-test` shim (execs a non-existent
  signalwire_agents/cli/test_swaig.py; the real entry is the swaig-test console script),
  and the livewire/livewire/ byte-identical dup subtree. Moved validate_schema.py -> eng/.
  Added ROOT_HYGIENE_ALLOW.md for the 7 load-bearing gate-config files kept at root.
  ROOT-HYGIENE now clean and BLOCKING.

Part C — wire the quartet at the right tier
  Per-PR (cheap): DOC-WIRE (new scripts/doc_wire_runner.py replays documented REST fixtures
  against the strict-flag mock — proven to catch area_code as unknown_query_param),
  STATUS-CLAIM, DOC-AUDIT, DOC-LINKS, ROOT-HYGIENE, GATE-INVENTORY (gen_gate_inventory
  --check, plan 1.11b).
  Nightly: WAIT-LIVENESS (wait_liveness corpus -> golden classification on the reference),
  STRICT-MOCKS (MOCK_RELAY_STRICT=1 on EXAMPLES-RUN + SNIPPET-RUN).

Part D — flip to blocking
  scripts/run-ci.sh exports SW_WAVE_A_REPORT_ONLY=0 (default), so python's widened gates
  BLOCK. Full `PORTING_SDK=... SW_CI_TIER=all bash scripts/run-ci.sh` is GREEN with every
  gate blocking (34 gates PASS, exit 0).

Version: unchanged at 3.2.0 (SEMVER-DIFF green; the surface is unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PqshDQajCmDHD3xPo4CXMC
…heck)

gen_gate_inventory.py --check resolves its reference port as a sibling checkout
(DEFAULT_REFERENCE=signalwire-typescript). In a port's CI, porting-sdk is a
subdir of the port workspace, so ../signalwire-typescript is absent → exit 2
"reference run-ci.sh not found". The check is inherently porting-sdk-side and
already runs in porting-sdk's own CI (test.yml, --reference ./signalwire-typescript),
so removing the per-port wiring loses zero coverage. Fixes the §1.11b mis-scoping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PqshDQajCmDHD3xPo4CXMC
@mjerris
mjerris merged commit e245ddc into main Jul 15, 2026
5 checks passed
@mjerris
mjerris deleted the feat/gate-enforcement branch July 15, 2026 13:57
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