Blog › ICP guides

occam developer on retainer: synchronous channel rendezvous, PAR/SEQ/ALT blocks, CHAN communication, deadlock analysis, and concurrent systems programming on monthly retainer

November 6, 2026 · ~18 min read

An occam2 concurrent systems program with two parallel processes communicating over a CHAN OF INT was deadlocking four times per run. The producer process reached its output command c ! value and blocked, waiting for the consumer process to be ready. The consumer process was still executing its initialization sequence in its SEQ block before reaching the channel input command c ? x. occam channels are synchronous (rendezvous-based): both the sender and the receiver must be simultaneously ready at the channel for the communication to proceed. The producer blocked waiting for the consumer to be ready; the consumer was still working through its initialization steps and had not yet reached the input command. Since both processes were in the same PAR block and there was no other process to make forward progress, the entire PAR block was deadlocked: the producer waiting for the consumer, the consumer blocked in its initialization SEQ but never actually blocking on the channel because it had not yet reached the input command. The result was four deadlocks per run, one for each pair of initialization sequences where the producer reached the output command before the consumer reached the input. The occam developer on retainer diagnosed the rendezvous protocol ordering: the consumer must reach its channel input command before or at the same time as the producer reaches its channel output command. The fix restructured the PAR body ordering: by analyzing the initialization sequences of both processes and reordering the consumer’s SEQ to reach the channel input command earlier — before the producer’s SEQ reached the channel output command — the rendezvous invariant was restored. Deadlocks per run: 4 → 0.

The work log entry read “fixed producer-consumer channel deadlock, 16h.” It names the symptom and the duration. It cannot explain to a client why occam channels are synchronous rather than buffered (occam was designed based on Tony Hoare’s Communicating Sequential Processes formalism, in which communication between processes is a synchronized handshake — both the sending process and the receiving process must be at their communication command simultaneously; there is no buffer holding values between send and receive; the design is intentional: synchronous channels make deadlock analysis tractable because the state of each channel is binary — either both processes are ready and communicate, or one blocks and waits; asynchronous channels with buffers create a third state where the buffer holds values and both processes can make independent progress, which enables different deadlock patterns and makes reasoning about completion harder), why the PAR body ordering determines which process reaches its channel command first (in a PAR block, all processes start simultaneously; the time each process takes to reach its first channel command is determined by how many steps its initial SEQ executes before the channel operation; if the producer’s initial SEQ has fewer steps than the consumer’s, the producer reaches the output command first and blocks; restructuring the consumer’s SEQ to reduce the steps before the input command ensures the consumer is ready when the producer arrives), why the deadlock is not a race condition in the traditional sense (a traditional race condition produces different outcomes depending on the non-deterministic scheduling order of threads sharing memory; occam’s deadlock is deterministic — the same initialization sequences always execute in the same order for the same run, so the same deadlocks occur in the same positions every run; the randomness is not in the deadlock occurrence but in which of the four initialization pairs is the one where the producer consistently outpaces the consumer), or why the fix requires analysis of both processes’ initialization sequences simultaneously rather than fixing the producer or consumer in isolation (the rendezvous invariant is a joint property of both processes; making the consumer reach the input command faster is only correct if it does not introduce other bugs in the consumer’s initialization; making the producer reach the output command slower is only correct if the additional producer initialization steps do not cause other timing violations). The 16 hours of rendezvous protocol ordering analysis, PAR body sequencing audit, initialization sequence comparison, and correct reordering design are not visible in the diff beyond reordered statements in the consumer’s SEQ.

occam’s concurrency model: PAR, SEQ, and synchronous channels

occam was designed by David May at INMOS in 1983, based on Tony Hoare’s Communicating Sequential Processes (CSP) process algebra. CSP models concurrent computation as a collection of sequential processes that communicate exclusively by passing messages through named channels; processes have no shared memory (in the occam model, all communication is through channels; shared variables between PAR processes are prohibited). occam’s concurrency primitives correspond directly to CSP operators: the PAR block is CSP’s parallel composition; the SEQ block is CSP’s sequential composition; the ALT block is CSP’s external choice; and the channel communication commands are CSP’s input and output events.

The PAR block: PAR followed by an indented list of processes. All processes in the PAR block start simultaneously and run concurrently. The PAR block completes only when all its constituent processes complete. If any constituent process blocks indefinitely (waiting for a channel communication that never happens), the entire PAR block blocks indefinitely — this is the structural definition of a deadlock in occam. The occam compiler enforces a usage rule that prevents shared variable access: a variable written inside one PAR branch cannot be read or written in any other PAR branch. This rule eliminates the entire class of data race conditions present in shared-memory concurrent languages like C with pthreads or Java with synchronized blocks. All communication between PAR branches must go through CHAN channels.

The SEQ block: SEQ followed by an indented list of processes. All processes in the SEQ block execute sequentially in order; the second process starts only when the first completes. SEQ is the normal sequential control flow within a process body. A common occam structure: a WHILE TRUE loop inside a SEQ inside a PAR branch, creating an indefinite-lifetime service process that reads from input channels, processes data, and writes to output channels. The alternation between input operations and output operations inside a SEQ loop is the basic communication protocol: WHILE TRUE SEQ c_in ? x; ... process x ...; c_out ! result.

Channel declarations and communication commands: CHAN OF INT c: declares a channel c that can carry values of type INT. The CHAN OF type parameter specifies the type of values the channel can carry; channels are typed and cannot carry values of the wrong type. The output command: c ! expression sends the value of the expression on channel c. The sending process blocks at the ! command until a receiving process is ready at the corresponding input command. The input command: c ? variable receives a value from channel c and stores it in the variable. The receiving process blocks at the ? command until a sending process is ready at the corresponding output command. A rendezvous: when both the sending process and the receiving process are simultaneously blocked at matching ! and ? commands on the same channel, the runtime executes the communication (atomically transfers the value from the sender to the receiver), and both processes unblock and continue. The key invariant for deadlock-free occam programs: for every channel, there is always a process ready to receive before (or exactly when) another process sends, or a process ready to send before (or exactly when) another process receives. A program that violates this invariant for any channel in any execution path will deadlock.

The ALT block: non-deterministic channel selection and TIMER guards

The ALT block in occam implements non-deterministic choice among multiple ready input channels. The structure: ALT followed by an indented list of guarded processes, where each guard specifies a channel input or a SKIP/TIMER condition. The ALT block selects one guard whose condition is satisfied (a guard is satisfied if the boolean condition is true and the channel has a sender ready or the SKIP/TIMER condition is met), executes the corresponding process, and completes. If multiple guards are simultaneously satisfied, occam’s ALT makes a non-deterministic choice among the satisfied guards — the specification does not define which ready guard is selected; any implementation is correct. If no guard is satisfied, the ALT block blocks until at least one guard becomes satisfied.

The syntax of an ALT guard: boolean_condition & channel ? variable is a channel input guard that is satisfied when the boolean condition is true and the channel has a sender ready. The process body executes with the received value. A guard without a boolean condition: channel ? variable is equivalent to TRUE & channel ? variable. The SKIP guard: TRUE & SKIP is always satisfied and performs no action. A common mistake: including a SKIP guard in an ALT that also has channel input guards. Since SKIP is always satisfied, the ALT will always select the SKIP guard if no channel input is immediately ready, preventing the ALT from ever blocking to wait for channel input. If the intent was to poll the channels and do something else when no input is available, SKIP is appropriate; if the intent was to wait for input from one of the channels, SKIP defeats the purpose. The correct alternative to SKIP for a bounded-time wait: the TIMER guard.

The TIMER channel: a TIMER is a special channel that provides the current time in occam’s tick units. Reading from a TIMER: timer ? t reads the current time into variable t (non-blocking; the TIMER channel always has a value ready). Using a TIMER as an ALT guard: timer ? AFTER deadline is a TIMER guard that is satisfied when the current time is after the deadline value. The deadline is computed from the current time plus a delay: timer ? t; deadline := t PLUS timeout_ticks; ALT timer ? AFTER deadline -- timeout guard ... | c ? x -- input guard .... The TIMER guard provides a bounded-time wait: if no channel input arrives within the timeout period, the TIMER guard fires and the timeout process executes. This is the correct design for a non-blocking polling pattern with a bounded wait time, replacing the always-true SKIP guard. The occam developer retainer task of ALT guard audit: for every ALT block, verify that SKIP guards are present only when the intent is to proceed immediately when no channel input is ready; replace SKIP guards with TIMER guards when the intent is to wait for channel input with a bounded timeout; and verify that TIMER deadlines are computed correctly using the PLUS operator (occam’s modular addition for time values, which wraps around the tick counter correctly when the tick counter overflows).

The PRI ALT variant: like ALT, but selects the first satisfied guard in source-code order rather than making a non-deterministic choice. PRI ALT is useful when some input sources have higher priority than others (a high-priority emergency channel should be serviced before a normal data channel). The trade-off: PRI ALT can starve lower-priority guards if higher-priority guards are always ready, while ALT’s non-deterministic selection provides fairness guarantees (in implementations that use fair selection among ready guards). Using PRI ALT when fairness is required is a common retainer bug: a system with a high-frequency input channel on the first guard and a low-frequency control channel on the second guard may never service the control channel if PRI ALT always selects the first guard.

Replicated PAR, channel arrays, and pipeline topologies

The replicated PAR construct: PAR i = 0 FOR N spawns N concurrent processes, each with index variable i ranging from 0 to N-1. The body is a process template that uses i to parametrize each process instance. Replicated PAR is occam’s mechanism for creating process arrays — collections of identical processes that differ only in their index. The canonical use case: a pipeline of worker processes where each worker reads from an input channel, processes its data item, and writes the result to an output channel. With replicated PAR: PAR i = 0 FOR N worker(input[i], output[i]) spawns N worker processes, each using its own pair of input and output channels from the channel arrays input[0..N-1] and output[0..N-1]. The channel arrays must be declared with the correct size before the replicated PAR: [N+1]CHAN OF INT input, output: (for a linear pipeline where process i reads from input[i] and writes to output[i], and the system's source connects to input[0] while the system's sink reads from output[N-1], the array needs N+1 channels for N processes if successive process outputs connect to the next process’s input).

Channel array sizing is a recurring retainer bug in replicated PAR designs. The most common error: declaring a channel array of size N for a pipeline of N processes, and then having the last process access index N which is out of range. The correct sizing depends on the pipeline topology. For a linear pipeline where process i uses channels link[i] and link[i+1]: PAR i = 0 FOR N worker(link[i], link[i+1]) requires [N+1]CHAN OF INT link (N processes each accessing two adjacent channels; indices 0 through N, inclusive). For a ring topology where process N-1 wraps around to connect back to process 0: PAR i = 0 FOR N ring_process(link[i], link[(i+1) REM N]) requires [N]CHAN OF INT link (exactly N channels for N processes, with modular wraparound). The occam developer retainer task of replicated PAR channel array sizing: for every replicated PAR, determine the maximum channel index accessed by any process instance (including the boundary cases i = 0 and i = N-1); verify that the channel array declaration provides at least max_index + 1 channels; and test the boundary cases explicitly.

The replicated ALT construct: ALT i = 0 FOR N creates a N-way non-deterministic selection over N channel guards. Used for a multiplexer that accepts input from N clients and routes it to a single server: ALT i = 0 FOR N client[i] ? request selects one of the N ready client channels, receives the request, and routes it to the server. The replicated ALT is evaluated over all N guards simultaneously, selecting non-deterministically among the ready ones. The replicated ALT enables occam programs to serve variable numbers of clients with a single process, without writing N separate ALT guards in source code. The PLACED PAR variant of replicated PAR: PLACED PAR assigns each process in the replicated PAR to a specific processor in a multiprocessor system. On a Transputer network, PLACED PAR maps each process instance to a specific Transputer chip, enabling physical hardware-level parallelism with processes actually running on distinct processors rather than time-sharing a single processor. The link channels between PLACED PAR processes map to Transputer hardware links.

Deadlock analysis and CSP verification

Deadlock analysis in occam programs is tractable through static analysis in simple pipeline topologies but requires model checking for complex systems. The CSP formalism underlying occam provides a rigorous mathematical framework for reasoning about deadlock: a set of processes P1, P2, ..., Pn is deadlocked if every process Pi is blocked waiting for a communication on a channel, and for every blocked process, the communication it is waiting for requires another blocked process to act first. The cycle structure of wait-for dependencies constitutes a deadlock. In a linear pipeline (P1 writes to P2, P2 writes to P3, ..., Pn writes to P1), there is no deadlock cycle: the chain terminates at the source (P1) and sink (Pn). Adding a back-channel from Pn to P1 creates a potential cycle: if Pn tries to send before P1 is ready to receive (while P1 is still waiting for Pn to receive before it can proceed), the system deadlocks. The occam developer retainer task of deadlock analysis: draw the communication graph (nodes are processes; edges are directed from sender to receiver); identify all cycles in the graph; for each cycle, determine whether any execution path through the cycle can result in every process in the cycle simultaneously blocked at a channel operation.

The FDR (Failures-Divergences Refinement) model checker for CSP: FDR allows occam programs to be translated to CSP specifications and mechanically verified for deadlock freedom. FDR checks whether a CSP specification is a refinement of a deadlock-free reference specification, and reports all deadlock-causing execution traces if refinement fails. Using FDR as part of an occam retainer engagement: translate the occam process structure to a CSP script (using the CSPM notation); define the process topology with channel declarations; run FDR’s deadlock checking algorithm; and use the reported counterexample trace to locate the specific channel operation sequence that leads to deadlock. FDR verification is the gold standard for occam channel protocol correctness but requires CSP expertise and the FDR tool, making it a senior-level retainer activity. For simpler systems, systematic testing with all channel operation orderings is a practical alternative: a test harness that explicitly exercises both orderings of each pair of concurrent channel operations (sender-first and receiver-first) within a bounded execution budget.

WHILE TRUE service process design: the most common process pattern in occam embedded systems is the indefinite-lifetime service process: a process that runs forever, reading inputs from channels, processing them, and writing outputs to channels. The pattern: WHILE TRUE SEQ c_in ? x; ... process x ...; c_out ! result. The SEQ inside the WHILE loop ensures the input, processing, and output steps happen in order for each iteration. The WHILE TRUE loop ensures the process repeats indefinitely. A service process that reads from multiple input channels uses ALT inside the WHILE loop: WHILE TRUE ALT c1 ? x1 -- handle c1 input ... | c2 ? x2 -- handle c2 input .... The ALT selects whichever input channel has a sender ready first. Service processes that need to time out use TIMER guards: WHILE TRUE ALT timer ? AFTER deadline -- timeout action ... | c ? x -- input action .... The timeout action typically resets the deadline: timer ? now; deadline := now PLUS timeout_ticks.

occam-π: mobile types, channel bundles, and recursive processes

occam-π (occam-pi) is a modern extension of occam2, developed at the University of Kent from the late 1990s onwards, incorporating features from the π-calculus (Milner’s process algebra for mobile processes) alongside occam2’s CSP-based communication model. The principal occam-π extensions: mobile types, channel bundles, recursive process definitions, and higher-order processes.

Mobile types in occam-π: the MOBILE type qualifier declares a type whose values have move semantics — assigning a MOBILE value to a new variable moves the value rather than copying it, and the original variable becomes invalid. Mobile arrays: MOBILE []INT a declares a mobile integer array. Mobile processes: a MOBILE type can wrap a process, enabling processes to be passed as values through channels. Moving a MOBILE value through a channel: c ! a where a is a MOBILE variable moves the value from the sender to the receiver, invalidating the sender’s variable. This eliminates copying overhead for large data structures while maintaining occam’s no-shared-memory discipline: the value is in exactly one place at any time. Channel bundles: a channel bundle groups multiple channels of different types into a single named protocol object. The bundle declaration: PROTOCOL myprotocol IS INT; REAL32: defines a bundle where the first channel carries INT and the second carries REAL32. Using bundles: CHAN myprotocol c: declares a channel carrying the bundle protocol. Bundle communication: c ? CASE tag; x selects the case and receives the value. Channel bundles are occam-π’s mechanism for typed multi-message protocols, analogous to Erlang’s tagged tuple messages.

Recursive process definitions in occam-π: unlike occam2 (which did not directly support recursion in process definitions), occam-π allows a PROC definition to call itself recursively. This enables process patterns like a recursive server that processes one request and then recursively spawns a new instance to handle the next. Recursive processes are the occam-π mechanism for processes that handle a variable number of requests without a fixed-iteration WHILE loop. Higher-order processes: in occam-π, processes can be passed as values through channels, enabling patterns where a coordinator process spawns worker processes dynamically by sending process values through channels. The PROC type as a first-class value: a PROC name is a value of the process-type corresponding to its channel interface, which can be stored in a MOBILE variable and sent through a channel to a PAR branch that activates it.

occam’s design legacy: the Transputer and the CSP influence

occam’s historical significance is twofold: as the programming language of the Transputer (INMOS’s revolutionary parallel processor chip), and as the primary practical embodiment of Tony Hoare’s CSP process algebra in production software. The Transputer (1985–1994) was designed from the ground up for occam: each Transputer chip had four serial links that mapped directly to occam channels, a fast serial link protocol for inter-chip communication, and hardware support for running up to four occam processes concurrently with fast process switching. A Transputer network was a physical occam PAR: each Transputer chip ran one or more PAR branches, and inter-Transputer communication happened through the hardware links that occam’s PLACED PAR channels mapped to. The Transputer was used in image processing, signal processing, scientific computing, and telecommunications switching in the late 1980s and early 1990s. Occam’s influence on concurrent programming: the CSP-based model of no shared memory and channel-only communication was a direct predecessor of Go’s goroutines and channels (Rob Pike has cited CSP as an explicit influence on Go’s concurrency design). Erlang’s actor model shares the no-shared-memory principle with occam, using message passing between lightweight processes as the sole communication mechanism. Rust’s ownership model enforces the no-shared-mutation property at the type system level, preventing data races by the same structural principle that occam’s usage rules enforce at the compiler level.

How HourTab tracks occam developer retainer hours

occam retainer work shares the invisible-work problem common to all concurrent systems programming language retainers, with the additional challenge that occam’s most important retainer tasks — synchronous channel rendezvous deadlock diagnosis, PAR body sequencing audit for correct channel operation ordering, ALT guard design with TIMER channels, replicated PAR channel array sizing, and CSP-based formal deadlock verification — produce diffs whose surface area is small relative to the analytical work required. Reordering two groups of statements inside a consumer process’s initialization SEQ is a diff with a changed statement order; the value is correct rendezvous sequencing for all four initialization pairs per run, elimination of producer-blocks-waiting-for-consumer deadlocks for all affected channel operations, and a PAR body design that maintains the consumer-input-precedes-producer-output invariant for all future runs and code changes. Replacing a SKIP guard with a TIMER guard in an ALT block is a diff with two lines (the timer read and the AFTER comparison); the value is bounded-time waiting for channel input instead of immediate skip on no-input, elimination of all missed channel inputs on every ALT iteration, and a polling design that correctly services all input channels within the timeout period.

HourTab gives occam developers a public retainer-hours URL they send to clients — typically embedded parallel systems groups programming multiprocessor signal processing hardware (where occam’s hardware-mapped PAR processes and typed channels remain effective for designing correct concurrent data pipelines), telecommunications protocol engineering teams using occam’s formal CSP foundation to verify protocol correctness, and programming language research groups at the University of Kent (KRoC occam-π project) and elsewhere working on extensions to the CSP process model — at the start of an engagement. For occam retainers, each work log entry should name the mechanism (CHAN OF TYPE synchronous channel design; c ! value output command protocol ordering; c ? variable input command scheduling analysis; rendezvous deadlock diagnosis; PAR body sequencing for correct channel operation order; channel protocol invariant design; PAR block concurrent process composition; SEQ block sequential process ordering; ALT guard design with channel input guards and SKIP/TIMER guards; WHILE TRUE SEQ indefinite-lifetime service process; TIMER channel guard for timeout-driven ALT alternatives; replicated PAR i = 0 FOR N concurrent process array; CHAN array sizing for N-process pipelines; replicated ALT i = 0 FOR N N-way selection; PLACED PAR processor assignment; occam-π mobile type declarations; channel bundle protocol design; recursive process definitions), the specific process name and the channel protocol ordering or ALT guard design problem, and the before/after observable metric. occam retainers are often compared to CLU developer retainers for systems language concurrent state management, to ALGOL developer retainers for languages with formal semantics foundations, and to Forth developer retainers for embedded systems concurrent programming work. The distinction from Forth is the communication model: occam’s PAR/SEQ/ALT and CHAN-based rendezvous creates a different class of concurrent design bugs than Forth’s stack-based threading, and the occam developer retainer task of deadlock analysis has no direct equivalent in Forth work. HourTab’s work log makes the rendezvous ordering analysis, PAR body sequencing design, and ALT guard completeness audit visible to clients who would otherwise see only the symptom — four deadlocks per run or missed channel inputs — and not understand why the fix required understanding occam’s synchronous channel semantics and the joint ordering invariant that both PAR branches must satisfy for deadlock-free rendezvous.

Track occam developer retainer hours without the status emails

HourTab gives occam developers a public URL per client retainer. One link, no login, live burn-down. Your clients stop asking “how many hours do I have left?” and your work log becomes the proof of value that gets the retainer renewed.

See HourTab pricing →

FAQ: occam developer retainers

What does an occam developer on retainer typically do?

An occam developer on monthly retainer covers four principal service areas: synchronous channel communication analysis and deadlock diagnosis (CHAN OF TYPE synchronous channel design; c ! value output command protocol ordering; c ? x input command scheduling analysis; rendezvous deadlock diagnosis; PAR body sequencing for correct channel operation order; channel protocol invariant design); PAR, SEQ, and ALT block design (PAR block concurrent process composition; SEQ block sequential ordering; ALT guard design with channel input guards and SKIP/TIMER guards; WHILE TRUE indefinite-lifetime service process; TIMER channel guard for timeout-driven ALT); replicated PAR and channel array design (replicated PAR i = 0 FOR N process arrays; CHAN array sizing; replicated ALT i = 0 FOR N N-way selection; PLACED PAR Transputer processor assignment); and occam-π extensions (mobile type declarations; channel bundle protocols; recursive process definitions; higher-order process patterns).

What occam work is most commonly underlogged in a retainer?

Synchronous channel rendezvous deadlock repair (producer output c ! value executed before consumer input c ? x was ready; 4 deadlocks/run; restructured PAR body ordering to guarantee consumer input precedes producer output; deadlocks: 4/run → 0; 16–30 hrs invisible in rendezvous protocol ordering analysis, PAR body sequencing audit, and channel operation reordering design), ALT guard completeness repair (SKIP guard fired on every ALT iteration pre-empting channel input guards; replaced with TIMER guard; pre-emptions: every iteration → 0; 12–22 hrs invisible in ALT guard selection semantics audit and timeout-vs-SKIP design), and replicated PAR channel array sizing repair (channel array sized N instead of N+1 for N processes; last worker accessed out-of-range index N; 2 wrong accesses/run; corrected to N+1; wrong accesses: 2/run → 0; 10–18 hrs invisible in replicated PAR channel indexing analysis).

What are typical occam developer retainer rates?

Entry-level occam developers (1–2 years, PAR/SEQ/ALT blocks, basic CHAN OF INT communication, WHILE TRUE service processes, TIMER channel usage) bill at $70–$125/hr. Mid-level occam engineers (2–4 years, rendezvous deadlock analysis, ALT guard design with TIMER channels, replicated PAR process array design with channel array bounds, PLACED PAR processor assignment, occam-π mobile type declarations) bill at $120–$215/hr. Senior occam architects (4–8 years, complete parallel system architecture, complex multi-process pipeline design, formal CSP-based deadlock verification with FDR, Transputer hardware configuration design, occam-π compiler and runtime behavior) bill at $175–$320/hr. Monthly retainer ranges: $2,000–$5,500/mo advisory (15–25 hrs), $7,500–$19,000/mo for full occam platform engagements.

What should an occam developer retainer agreement include?

An occam developer retainer agreement should specify: channel communication scope (CHAN OF TYPE synchronous channel design; c ! value/c ? x protocol ordering; rendezvous deadlock diagnosis; PAR body sequencing for correct channel operation order); PAR/SEQ/ALT scope (PAR block concurrent process composition; SEQ block sequential ordering; ALT guard design with channel input guards and SKIP/TIMER guards; WHILE TRUE indefinite-lifetime service process); replicated process scope (replicated PAR i = 0 FOR N process arrays; CHAN array sizing; replicated ALT i = 0 FOR N N-way selection; PLACED PAR Transputer processor assignment); occam-π scope if applicable (mobile type declarations; channel bundle protocols; recursive process definitions); and hour logging format (process name; operation type — rendezvous deadlock, ALT guard design, replicated PAR, or occam-π extension; before/after error metric; occam version).

How should occam developer retainer hours be logged?

Log each occam retainer session with: advisory category (CHAN OF TYPE synchronous channel design; c ! value output command protocol ordering; c ? x input command scheduling; rendezvous deadlock diagnosis; PAR body sequencing audit; channel protocol invariant design; PAR/SEQ/ALT block design; ALT guard with SKIP/TIMER; WHILE TRUE service process; TIMER channel guard; replicated PAR i = 0 FOR N; CHAN array sizing; replicated ALT i = 0 FOR N; PLACED PAR; occam-π mobile types; channel bundle protocols; recursive process definitions), the specific process name and the channel protocol ordering or ALT guard design problem (producer output executed before consumer input was ready; 4 deadlocks/run; restructured PAR body ordering; deadlocks: 4/run → 0), and the before/after metric. Include occam version, Transputer type if applicable, and whether the fix required PAR body reordering, ALT guard redesign, replicated PAR channel array resizing, or occam-π mobile type correction.