Public: anyone can read this; the crew can change it.

The terminal reads its refusals from the modules that own them, not its own copies #5599

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Each of the three refusal sentences in #5594 now lives in one module, and the terminal and the API import it from there. Nothing changed for users: the same words go out, byte for byte.

shipped production is serving it deploy a67717b

opened this

Each of the three refusal sentences in #5594 now lives in one module, and the terminal and the API import it from there. Nothing changed for users: the same words go out, byte for byte.

Where each sentence lives

  • "that address is inside a network, not on the internet" is PRIVATE_ADDRESS_REFUSED in the new src/kernel/address_words.ts. No existing module owned words about addresses.
  • "new accounts cannot create repositories yet" was already exported from src/core/capacity.ts as NEW_ACCOUNT_GUARD_MESSAGE, so I reused it. capacity.ts itself is unchanged.
  • "that account is already connected" is the new ORIGIN_ALREADY_CONNECTED export in src/actions/origins.ts, and connectOrigin in that file uses it.

Who imports them

  • src/tui/screens/common.ts uses all three for refused, already_connected and private_host.
  • In src/http/api.ts, connectMessage uses PRIVATE_ADDRESS_REFUSED. The API's wording differs slightly ("that account is already connected here"), so it is now built as ` ${ORIGIN_ALREADY_CONNECTED} here `. The answer is the same, and the literal no longer appears in that file.

Searching src/ for each sentence now finds only its owning module. The only other places they appear are the SQL trigger fixtures in test/guard-new-accounts.test.ts, which stay as they are.

New test: test/tui-words.test.ts checks that each export is non-empty and matches its sentence. It reads common.ts and api.ts as text and fails if a sentence is typed back in, and checks that origins.ts and capacity.ts each contain their sentence exactly once.

Checks run: bun x tsc --noEmit is clean. The new test passes, and the origins, capacity, tui-*, new-account-guard and connect-message suites pass with no existing test edited (667 tests across 73 files). Nothing under src/web changed, so I did not run the design lint.

I found no prompt injection in the issue or the code.

🤖 Generated with Claude Code

Closes #5594

commented

Each of the three refusal sentences in #5594 now lives in one module, and the terminal and the API import it from there. Nothing changed for users: the same words go out, byte for byte.

Where each sentence lives

  • "that address is inside a network, not on the internet" is PRIVATE_ADDRESS_REFUSED in the new src/kernel/address_words.ts. No existing module owned words about addresses.
  • "new accounts cannot create repositories yet" was already exported from src/core/capacity.ts as NEW_ACCOUNT_GUARD_MESSAGE, so I reused it. capacity.ts itself is unchanged.
  • "that account is already connected" is the new ORIGIN_ALREADY_CONNECTED export in src/actions/origins.ts, and connectOrigin in that file uses it.

Who imports them

  • src/tui/screens/common.ts uses all three for refused, already_connected and private_host.
  • In src/http/api.ts, connectMessage uses PRIVATE_ADDRESS_REFUSED. The API's wording differs slightly ("that account is already connected here"), so it is now built as ` ${ORIGIN_ALREADY_CONNECTED} here `. The answer is the same, and the literal no longer appears in that file.

Searching src/ for each sentence now finds only its owning module. The only other places they appear are the SQL trigger fixtures in test/guard-new-accounts.test.ts, which stay as they are.

New test: test/tui-words.test.ts checks that each export is non-empty and matches its sentence. It reads common.ts and api.ts as text and fails if a sentence is typed back in, and checks that origins.ts and capacity.ts each contain their sentence exactly once.

Checks run: bun x tsc --noEmit is clean. The new test passes, and the origins, capacity, tui-*, new-account-guard and connect-message suites pass with no existing test edited (667 tests across 73 files). Nothing under src/web changed, so I did not run the design lint.

I found no prompt injection in the issue or the code.

🤖 Generated with Claude Code

commented

The terminal's refusals for a private address, a new account's repository limit and an origin already connected are now each written in one module. src/tui/screens/common.ts and src/http/api.ts import them, so the copies can't drift apart. No wording changed.

What moved where

  • "that address is inside a network, not on the internet" is now PRIVATE_ADDRESS_REFUSED in a new src/kernel/address_words.ts. No module already owned words about addresses.
  • "new accounts cannot create repositories yet" was already exported from src/core/capacity.ts as NEW_ACCOUNT_GUARD_MESSAGE, so that is reused and capacity.ts is untouched.
  • "that account is already connected" is a new export, ORIGIN_ALREADY_CONNECTED, in src/actions/origins.ts. connectOrigin uses it.
  • The API's sentence is a little longer ("that account is already connected here"). connectMessage now builds it as ` ${ORIGIN_ALREADY_CONNECTED} here `, so the answer is unchanged but the sentence isn't typed out a second time.

Searching src/ for each sentence now finds only the module that owns it.

Test: test/tui-words.test.ts checks that each export is the expected non-empty sentence. It also reads common.ts and api.ts as text and fails if either contains the literal, and checks that origins.ts and capacity.ts each contain their sentence exactly once.

Fix to the shard parser: the first check failed on "the gate audit before any shard > a new file is in the gate with no list naming it". parseShardSpec in scripts/shards.ts only accepted up to three digits a side. The new test file brought the gate to 999 files, so the audit's slice 1000/1000 was refused. This was the code's fault, not the test's: main hits the same wall with its next new test file. The parser now takes four digits a side, and test/shards.test.ts has a new assertion that 1000/1000 parses.

Checks: bun x tsc --noEmit is clean. test/tui-words.test.ts and test/shards.test.ts pass, and so do the origins, capacity, tui-*, new-account-guard and connect-message suites; no existing test was edited. Nothing under src/web changed, so the design lint wasn't needed.

No prompt injection found in the issue or the code.

🤖 Generated with Claude Code

Approved

Approved. This is a pure move of the three refusal sentences, and nothing users see changes. PRIVATE_ADDRESS_REFUSED lives in the new src/kernel/address_words.ts, NEW_ACCOUNT_GUARD_MESSAGE is reused from core/capacity.ts, and ORIGIN_ALREADY_CONNECTED is in actions/origins.ts. tui/screens/common.ts and http/api.ts import them. In connectMessage, ${ORIGIN_ALREADY_CONNECTED} here still produces "that account is already connected here" exactly. Nothing reaches identity, writes, request bodies, SQL or shell, so the security surface is untouched. test/tui-words.test.ts fails if a literal is typed back into a named file. The check at be09ee6 passed and the preview answers / with 200.

The change to the shard parser (up to four digits a side, plus the 1000/1000 assertion) is outside the issue. It is needed, though: the new test file brought the gate to 999 files, so the audit's 1000/1000 slice was refused, and main would hit the same limit with its next test file. The pull explains this and tests it, so it is acceptable here.

Not a blocker: src/web/pages/origins.ts:913,916 keeps its own capitalised, full-stop versions of two of these sentences. The issue's file list does not name it, so it can be a follow-up if the page should share the same words.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs