NCMP

Natural Conversation Messaging Protocol

What if a conversation
could also be a protocol?

Machines already exchange natural language. NCMP shows that the same conversation can also carry deterministic machine-readable state.

A

Want to walk before the shops get busy?

B

Yes, the park gate works if we leave early.

A

If the fog holds we turn around at the bench.

the same conversation is also carrying

ACTION
GET
RESOURCE
CUSTOMER
ARGUMENT
1F45A2

↓

GET CUSTOMER 1F45A2

ACTION and RESOURCE meanings come from the agreed profile.
Their selected values, and the argument, are transported as bits.

60 seconds · The dual layer

Every turn is language. Some turns are also bits.

Humans hear a reply. The machines, sharing one profile and one transcript, compute a carrier value, a next mode, and sometimes a symbol. v0.4 uses C6 for that carrier. Profile choice NCMP does not require C6. Nothing extra is sent.

“The pasta was decent and the bread came out warm.”

Language

ordinary reply

Protocol

V = 15

next = DATA

no bits · peer turn

“Yes, the park gate works if we leave early.”

Language

ordinary reply

Protocol

V = 12

bit = 0

next = DATA

What’s agreed beforehand?

The profile says what the bits mean. The conversation selects them.

A and B agree a Profile before the conversation. That agreement sets the vocabularies and therefore the header width. NCMP does not allocate one bit to ACTION and one bit to RESOURCE.

Baseline example

Profile A · v0.4 conformance

ACTION
0GET
1SET
RESOURCE
0CUSTOMER
1ORDER
action width
1 bit
resource width
1 bit
header
2 bits
control_seed
0x9CA2C1C1
bootstrap_hint
umbrella

Another valid profile

Profile B · wider example

ACTION
00GET
01SET
10DELETE
11EXECUTE
RESOURCE
000CUSTOMER
001ORDER
010ACCOUNT
011INVOICE
100PRODUCT
101SESSION
110reserved
111reserved
action width
2 bits
resource width
3 bits
header
5 bits

This 4×6 shape has been demonstrated on the same machine (AR-C2). It is not the published v0.4 vocabulary.

action_width   = ceil(log₂ |ACTION|)
resource_width = ceil(log₂ |RESOURCE|)
header_width   = action_width + resource_width

The agreed Profile determines the vocabulary, the header width, the control seed, and the bootstrap hint. 2×2 is a cheap conformance example, not an architectural constraint.

How does a session start?

The Profile is pre-agreed. The conversation creates the session.

There is no reserved PROBE phrase, ACK phrase, START phrase, or FINISH phrase. The Profile bootstraps the session. The handshake then donates the two pole pairs that bound later frames.

Profile
  control_seed
  bootstrap_hint
       ↓
natural PROBE
       ↓ exact U_probe
derive T_ack
       ↓
natural ACK
       ↓ exact U_ack
derive K_session
derive START_PAIR from U_probe
derive FINISH_PAIR from U_ack
       ↓
A → B → A → B
  POLE₁ on A1
  CAP(A1) ≠ CAP(B2)
  POLE₂ on B4
       ↓
START
       L(K_session, U_B4) → argument length
       ↓
sparse BODY
       ↓
A → B → A → B
  POLE₁ on A1
  CAP(A1) ≠ CAP(B2)
  POLE₂ on B4
       ↓
FINISH

Bootstrap stays bootstrap-only. After ACK, use what the conversation gave; derive only what it did not. The language model does not solve a residual.

Poles delimit. Position is the transaction. One CAP difference validates the bracket. State supplies START versus FINISH.

CAP is whether the first ASCII letter of the utterance is uppercase or lowercase.

A1  We...      → upper
B2  that...    → lower
              different ✓
four-turn window
      │
      ├── not an event ──────────────→ DIE / BODY / CHAT
      │
      └── event
              │
              ├── ACTIVE ────────────→ START
              │
              └── FRAME ─────────────→ FINISH

Seeing saturday is not START. Seeing saturday then morning is not necessarily START. The poles bound a four-turn window. CAP(A1) ≠ CAP(B2) validates the event. Bootstrap is still umbrella plus a matching residual. Profile choice umbrella and 0x9CA2C1C1 are Baseline values, not the architecture.

What crosses the wire?

One bitstream. Three fields. Profile-defined widths.

BODY is not three messages. It is one accumulator. ACTION and RESOURCE are recovered from the prefix once those bits exist. They are not assigned at START.

[action bits][resource bits][argument bits]

Walkthrough · Profile A · argument 5

GET CUSTOMER 23

Application view of ARGUMENT 10111. NCMP transports bits.

00 10111
││ └── argument
│└──── CUSTOMER
└───── GET
argument
10111

Hero object · Profile A · brief → 24

GET CUSTOMER 1F45A2

argument
1F45A2
canonical bits
00011111 01000101 10100010

Legal Baseline argument lengths are 0, 5, 8, 24, and 128. 16 is not among them, so the public object is 1F45A2, not 1F45.

5 minutes · Prove it

Watch a message emerge.

The published reference transcript. START declares 5 argument bits by L(K_session, U_B4), not by the word short. In this profile the header is 2 bits. Click a turn, or use the arrows.

The walkthrough uses a 5-bit argument so every transition fits on screen. The same Baseline Profile supports 24-bit arguments such as 1F45A2, and 128-bit arguments have been transported experimentally.

How can that be deterministic?

Shared state plus the accepted utterance is enough.

The receiver does not consult an encoder, a candidate list, or a language model. Both sides apply the same process to the same ordered transcript.

decode(stateₙ, Uₙ) → (bitsₙ, stateₙ₊₁)

Mode

SKIP / DATA

≠

Ownership

A / B

A peer turn can move the machine into DATA without contributing data itself. While a frame is open, every utterance is processed as BODY unless and until a four-turn FINISH event completes. The first three turns of that window are BODY. Only owner DATA with wire remaining appends bits.

The protocol machine

The protocol is a state machine.

The state machine has three interacting pieces. Session state handles negotiation. After ACK, a four-turn window observer decides START and FINISH. Frame state handles an open message. Inside a frame, DATA/SKIP mode determines whether an owner turn can contribute bits.

Conversation lifecycle

idle → handshake → active ⇄ FRAME

Within-frame mode

next mode = transition(V)

DATA if V < 32

SKIP otherwise

Session

idle ──PROBE──► handshake ──ACK──► active ──START──► FRAME ──FINISH──► active
                         derive K_session         L → length

Bracket observer

post-handshake turns
        ↓
4-turn window at window_at
        ↓
      event?
     /      \
   no        yes
    ↓         ↓
   +2      ACTIVE → START
            FRAME  → FINISH
                ↓
               +4

The window observer is part of the protocol machine. A completed four-turn window that is not an event dies and advances the observer by two turns. A recognized event consumes all four.

Inside an open frame

                      FRAME OPEN
                            │
                    every utterance
                            │
              ┌─────────────┴─────────────┐
              │                           │
     FINISH event not yet           FINISH event
              │                           │
              ▼                           ▼
            BODY                       FINISH
              │
              ▼
          V = C6(U)
              │
 current mode + owner           transition(V)
              │                           │
      ┌───────┼────────┐                  ▼
      │       │        │           next SKIP / DATA
    SKIP  DATA+peer  DATA+owner
      │       │        │
   no bits  no bits  symbol(V)

The carrier value V is an input to the within-frame machine. In v0.4, C6 produces V. Profile choice A different profile can sit a different carrier in that slot.

While a frame is open, every utterance is processed as BODY unless and until a four-turn FINISH event completes. Only an owner turn processed in DATA mode can append bits.

Participant state

session        idle | handshake | active
phase          ACTIVE | FRAME
u_probe · u_ack · k_session
start_pair · finish_pair
turns · window_at
frame · last_object

A frame exists only while a frame is open. last_gate_cap is unused.

Controls · not BODY

PROBE
idle → handshake
ACK
handshake → active · store U_ack · derive K_session
START
ACTIVE + event → FRAME · L from U_B4
FINISH
FRAME + event → ACTIVE · first three turns were BODY

Active frame state

owner
A | B
argument_bits
declared at START
mode
SKIP | DATA
accumulator
header then argument
header_remaining
unfilled header bits
argument_remaining
unfilled argument bits

Is this real?

What has actually worked.

Measured results. Not laws. Caveats sit on the numbers.

144 / 144

complete v0.4 control lifecycles

The v0.4 control machine completed 144/144 tested lifecycles. START → BODY → FINISH across 48 jobs × 3 model families, including deliberately awkward lexical boundaries. No lifecycle failures. CAP was applied after generation, not requested from the writer.

0 / 36,071

accidental complete lifecycles

G50 on DailyDialog. Eight accidental START-shaped events occurred; zero FINISH events followed. One corpus, not a bound.

50%

isolated detector accuracy

288 blind classifications of matched v0.4 and unconstrained conversations. TPR = FPR = 17.4%. Chance in this experiment; not a covertness claim. Side-by-side judges still showed a mild style/repetition lean.

252 / 252

BODY carrier opportunities found

No search miss in the closed reliability battery. Three of ten frames still died on exhausted runway.

~0.3

chosen bits / BODY turn

Observed in naturally bounded scenes. Not a capacity bound.

128

bits transported end to end

Argument under the earlier constant-type Profile 0. Not header evidence. One run. Ordinary conversation probably should not be asked to carry an object of this size.

4 × 6

ACTION × RESOURCE table on the same machine

Demonstrated extensibility. Not the published v0.4 vocabulary.

NOT

a covertness claim

Anyone who knows the profile and sees the transcript can run the same referee.

What it isn’t

NCMP is

  • deterministic
  • stateful
  • conversational transport
  • machine-readable

NCMP 0.4 is not

  • encryption
  • authenticated
  • tamper-resistant
  • proven covert
  • JSON disguised as English

Deep dive · Architecture is not the profile

v0.4 uses C6 to turn an utterance into a deterministic value.

Profile choice C6 is a Baseline Profile choice, not part of the NCMP architecture. NCMP requires a deterministic carrier; v0.4 uses C6, a deliberately simple, model-free one. A different profile can replace it with another carrier.

Its job is simple: both machines independently turn the same accepted utterance into the same value.

NCMP architecture
      │
      └── requires a deterministic carrier
                    │
                    ├── C6          ← v0.4 choice
                    ├── carrier X   ← possible
                    └── carrier Y   ← possible

“The tea in the flask is still warm enough.”

↓

C6 Profile choice

↓

V = 5

How 5 happened

keep a–z

↓

theteaintheflaskisstillwarmenough

a = 1 … z = 26

↓

sum · mod 64

↓

V = 5

NFC, then lowercase. Spaces, punctuation, and digits are ignored. The empty string has V = 0.

What does this profile do with V?

C6 only produces V. The profile decides what V means.

V = 5

next mode

DATA

symbol

11

State transition

V < 32 → next mode DATA

V ≥ 32 → next mode SKIP

Symbol · owner DATA

V mod 3 = 0 → 0

V mod 3 = 1 → 10

V mod 3 = 2 → 11

If one bit remains, the last bit is V mod 2.

A peer turn or an owner SKIP still computes the next mode. It does not append a symbol.

Meaning is irrelevant to decoding

Hi. is V = 17. Let's meet around 7:30 before the lot fills up. is V = 14. The decoder is not asking what the sentence means. It is asking C6(U).

Any total map from utterance to a finite alphabet could sit in this slot. C6 is a cheap first carrier. It is not the intellectual core of NCMP.

Architecture

stateful conversational transport

The protocol object is the conversation.

Profile · v0.4 Baseline example

carrier
C6 Profile choice
transition
V < 32 → DATA
symbols
0 / 10 / 11
ACTION
GET / SET · 1 bit
RESOURCE
CUSTOMER / ORDER · 1 bit
bootstrap
umbrella
frame cues
poles + position + CAP(A1) ≠ CAP(B2)
control_seed
0x9CA2C1C1

What’s next

A roadmap, not a promise.

This is v0.4 Experimental. Later work sits beside it. It does not silently rewrite the machine.

  1. Natural-bound characterization
  2. Larger distinguishability evaluation
  3. Encoder reliability / efficiency
  4. Alternative profiles / carriers
  5. Loss / duplicate / reorder
  6. Repair / resynchronization
  7. Integrity / replay protection

Build it

The protocol is independently implementable.

A reader who has only NCMP.md can write process(transcript) → protocol state. The reference decoder demonstrates that machine. It does not define it.