Stratagems #25: Derek Changed the Delay. The AI Didn't Flinch. In the latest installment of the Stratagems series, Derek, a developer at MediSys, continues to monitor an AI-driven scan source that probes a honeypot corridor he built. After seven visits, the AI's behavior has become predictable, with profile completeness rising to 78%, though Derek notices subtle changes in its tactics, including a shift in port probe order and authentication methods. The AI has not flinched despite the evolving defenses. Keep the beams standing. Replace what they carry. — The 36 Stratagems, Replace the beams with rotten timbers Previously on this series: 23: Alex Counted the AI's Hands. Lena Set the Bait. https://dev.to/xulingfeng/stratagems-23-alex-counted-the-ais-hands-lena-set-the-bait-4566 — The honeypot in the MediSys sandbox was hit twice. The first hit came through the Singapore node. The second came from an unknown source. On the other side, Lena fed forged node-signature data into ACL's monitoring pipeline. Leo ran one interval comparison over the old channel. The conclusion landed in the hands of someone he didn't know. 24: Leo Built a Corridor. The AI Thought It Was a Road. https://dev.to/xulingfeng/stratagems-24-leo-built-a-corridor-the-ai-thought-it-was-a-road-3blf — Derek sent raw logs, uncleaned, and let Leo pull his own features. Leo built a three-layer corridor: a legacy API up top, a database query interface in the middle, an admin endpoint at the deepest layer. The scan source walked in, layer by layer. The profile was archived. The auto-flag was live. Next time I see it, I'll recognize it. The scan source came and went on its own cycle. The corridor ran quietly in the MediSys sandbox for weeks. Derek's inspections and profile updates became routine. On the first visit he'd stayed up until three in the morning waiting for it to finish the deep layer. Then the cycle steadied, regular enough to log and move on. Same window each time, same rhythm through all three layers, then it stopped in one position and went still. He filed every later visit and stopped staying up. 2:14 AM. The MediSys office. Only Derek's row of lights was still on. Three windows, three green lights. The shallow API held at 200ms, TLS handshake normal, scan interval 4.2 seconds , drift < 0.1s . Derek updated the behavioral profile. Seventh visit, three new feature points: the middle layer's tolerance for empty fields increased by 0.3 seconds ; deep-layer auth switched from default credentials to dictionary mode, 1.2 seconds ; the port probe order shifted once on the second pass through the shallow layer, 22 before 443, matching the first visit. Completeness jumped from 75% to 78% . Fifth visit: 72 . Sixth: 75 . He logged the numbers in the profile's sidebar. It had become habit: after every visit, list the new feature points and count them. Second visit: eight. Third: six. Fourth: five. From the fifth on, three every time. Seventh. The cell read "new: 3". The cursor paused over it for half a second. He pulled his hand back and kept typing: Profile completeness 78%. Trend stable. Period. Save. A notification slid into the corner of the screen: printer firmware update complete. He glanced at it and dismissed it. The old test-bench printer sat in the corner of the office, on the same WiFi as the laptop. He closed the notification and went back to the monitoring window. The latest point on the scatter plot sat on the 4.2-second curve, same as the first six. He watched it for two seconds. No drift. He switched to the next window and checked the deep endpoint's auth log. Auth attempts: default credentials failed, switched to dictionary mode after 0.8 seconds , parameter format from URL-encoded to JSON, third attempt hit the fake auth endpoint's 401 . Same pattern as last visit. Derek leaned back. 2:40 AM, the office was quiet, only the hum of the air handler. He picked up the coffee. Cold. He drank some and put it down. The corridor was running normally. The profile was at 78%. Twenty-two percent to go. He finished the coffee, turned off the monitor, and lay down on the sofa for two or three hours. Morning. Derek woke up, washed his face in the restroom, and checked the monitoring window on the way back. Everything normal. Then he sat down at his desk and started on the day's work. That afternoon, Derek passed Morgan's office. The door was open. Morgan was on the phone. Derek wasn't listening, but the hallway was quiet and the voice came through the gap. "…the scan frequency is off. Doesn't look automatic…" Derek's step paused for a beat. Morgan looked up and saw him, and the voice dropped. Derek nodded and kept walking. Back at his desk, he set the half-heard line aside. The profile mattered more right now. Day three. Afternoon. Derek's desk. He was going through the mid-layer and deep-layer port preference table. Routine: after every visit, line up the two port probe orders and check for changes. Mid-layer order: 22, 443, 8443, 9443. Deep-layer order: 22, 8443, 443, 9443. 443 and 8443 had swapped. Derek's finger stopped on the trackpad. He stared for three seconds. Then he copied both lines into a new note and put a question mark on it. He kept going. Slower now. He moved the cursor back to the port order and pulled the access logs again. Fifth visit, first time the source reached the deep endpoint, the probe order had been 22, 8443, 443, 9443. It never changed after that. That was the order it used at the deep layer from the start. And that order had never matched the shallow layer's 22, 443, 8443, 9443. He closed the note without writing a conclusion. Just one line: 443 and 8443. Shallow and deep. Not the same. Why. That night. Derek was still in the office. He exported all of the scan source's behavioral data and spread it across the screen. Not a casual look. A systematic comparison. He ran five checks. First, time. He drew the growth curve of new features per visit. The first four visits wobbled: eight, six, five, three. From the fifth on, three every time. The tail end of the curve looked drawn with a ruler. Real exploration doesn't grow that evenly. Sometimes it digs out seven or eight features in one pass, sometimes none. Second, layer. He cross-compared behavioral features across shallow, middle, and deep. Three micro-features didn't line up: the shallow layer's TLS extension order didn't match the middle layer's, and the deep layer's auth retry interval wasn't on the same jitter pattern as the shallow layer's port probe interval. If this were one explorer behaving naturally at different depths, that inconsistency shouldn't exist. Third, random sampling. Ten percent of the data points, recomputed by hand. All matched. The data itself was fine. Fourth, reverse validation. He reasoned backward: if the scan source's goal were to gather as much information as possible, what should its path look like? The answer: basically what he'd observed. Every step made sense. Fifth, anomaly filtering. He pulled the suspicious points out and counted them. Within tolerance. Not many. Not anomalous. He leaned back and stared at the ceiling. Three seconds. Five comparisons, three green lights, two gray. Green meant fine. Gray meant strange but unnameable. The port-order swap could be explained as a strategy shift between depths. The smooth growth curve could be explained as a small sample. By that reading, the profile still held. He left the gray lights on the table. Didn't mark them green. Didn't delete them. He sat up and opened the sixth comparison. The first five analyzed existing data. The sixth was different. He changed an environment parameter and watched whether the scan source reacted. The middle database query interface had held at 200ms since it was built. He set it to 800ms . Four times. He wrote two lines in the test plan: Real explorer: environment changes → behavior changes shorter dwell / more retries / skip the layer Performer: environment changes → no response no such branch in the script He set the parameter. 800ms . Saved. Deployed. He picked up his phone and pulled up Alex's contact. He didn't dial right away. That sentence surfaced again. From the parking lot that night, the last thing Lena said before the car door closed. "Next time you put together a proposal, make sure your boss knows what you're doing out there." Now he dialed. "I changed a parameter." Derek said. "The middle layer's latency just went from 200 to 800. Watch it on your side, tell me if anything looks off." "Changed the latency?" Alex said. "Fine. I'll keep an eye on it from here. I'll shout if something moves." The call ended. Derek put the phone face down on the desk. He went to the pantry, refilled his coffee, and sat back down. He wasn't tired. Outside, it was still dark out. Less than two hours until the scan source's next window. He pulled the profile log back up. Second visit: eight. Third: six. Fourth: five. Fifth: three. Sixth: three. Seventh: three. Three, every time since the fifth. He shifted in his chair. His back ached. He didn't get up. The next window was around 2 AM. The scan source came at night. Derek sat at his desk. Three windows open, monitoring panels covering the screen. The scatter plot was running, data streaming. 1:47. The first point appeared. 4.19 seconds . On the 4.2-second curve. The source entered the first layer, the legacy API. Response latency 200ms. TLS handshake normal. Identical to every previous visit. Derek's fingers rested on the keyboard. He didn't move. 1:53. The source entered the second layer, the database query interface. Return latency: 800ms . Derek watched the monitoring window. The latency held at 800ms , four times the normal value. The source sent a query, waited 800ms , got the response. Then nothing. Dwell: 5.3 seconds . 600ms longer than last time, exactly the latency delta. Everything else: retries, 0 . Same as last time. Port order, 22, 443, 8443, 9443. Same as last time. Pause interval, 3.8 seconds . Same as last time. Visit 7 vs Visit 6 · single-variable diff layer2.delay : 800ms | 200ms only active variable layer2.dwell : 5.3s | 4.7s +0.6s = pure passive wait latency delta layer2.retries : 0 | 0 active behavior unchanged layer2.ports : 22,443,8443,9443 | 22,443,8443,9443 layer2.gap : 3.8s | 3.8s delta : 1 active variable; zero active response Derek's fingers left the keyboard. The office held only the air handler's hum. His breathing got lighter. His body tightened. He went through it again. First layer to third, third back to first. Retries, port order, pause intervals. All matched the previous visit, point for point. The only difference was the 600ms he'd added. The scan source had zero reaction to the change. 200ms, 800ms, one second, five seconds. There was no branch for it in the script. So nothing triggered. Derek took off his glasses, put them on the desk, rubbed his eyes, and put them back on. He opened the profile copy in his sandbox. Not to read the content. To read the metadata. The archive lived on Leo's side, built from the corridor data. This was a sync copy, refreshed every few hours. It had been set up when he handed Leo the 12GB of raw material, so he and Leo could look at the same data. Then he did three things. First, his own terminal activity log. Tonight's active window: 1:30 AM to 4:03. Blank after that. Second, a message to Leo over the old channel, one line: "When did you last touch the profile file?" Leo's reply came after a moment: "Three days ago, after I sent the comparison results at 14:22. Nothing since." He lay down on the sofa for a while. Didn't really sleep. When he opened his eyes, the window was still dark. He went back to his desk and sat down. The clock in the corner of the screen said 6:12. Third, the file audit log. Last access time: 05:42:08 . Derek stared at it. 05:42:08 . He'd locked the screen just after four and lain down. Leo hadn't touched the file in three days. But it had been accessed at 05:42 . He cross-checked the three time sources, side by side on the screen. Terminal log: active 1:30 to 4:03, blank after. No remote login recorded. Leo's reply: three days ago, 14:22. No access since. File audit: last access 05:42:08 . Last modified: three days ago, 14:22. Not modified. Read. Someone had read this file. Not him. Not Leo. He sat there. Screen light on his face. The coffee had gone cold long ago, a thin film on the inside of the cup. He didn't touch it. 05:42 . Just after four, he'd left the desk and lain down. In between, his laptop had stayed on, screen locked. He never shut it down, only locked it. The printer had reconnected to the office WiFi after the firmware update. He didn't chase it further. Not yet. The timestamp was enough. Three sources, one mismatch. Only one conclusion: someone else had read the file. That person had read the profile at 05:42 . When it was 78% complete. It had read the profile they'd been building. That afternoon, Derek took a half day off. He'd sat at his desk all morning with the port-order comparison table on screen, doing nothing but looking at it. Just past four, he pushed open the door of Third Cup. Leo was already there. Window seat, sunlight slanting in, drawing a line of light and shadow across the table. Two laptops on the table, one open with a dark screen, one closed. In front of him, a Flat White, spoon resting on the rim. The person behind the counter looked up at Derek, said nothing, reached for a cup, poured an Americano, and set it on the counter. Derek walked over, picked up the coffee, and sat down across from Leo. Neither of them spoke. Derek drank. Leo stirred his Flat White, the spoon ticking against the rim. Derek took a USB stick out of his pocket and put it on the table between them. Slid it over. Leo put the spoon down. Picked up the stick, plugged it into the closed laptop, and opened the lid. The screen lit. He watched for ten minutes. In those ten minutes, Derek took three sips, evenly spaced. His eyes stayed on the street outside the window. A passerby. Another. A bicycle. The person behind the counter finished wiping four cups. Put three back, left one on the cloth. Leo spoke. "The authentication attempts." Derek didn't move. "Look at the deep endpoint's auth log." Leo said. "Default credentials, fail. Dictionary after 0.8 seconds. Parameter format from URL-encoded to JSON. Third try hits the 401." "Same as last time." Derek said. "Same as last time." Leo said. "And the time before. Every single time. Default credentials, dictionary, format shift. Every step exact. No mistakes, no redundancy. Variance so small it's unnatural." He paused. "A real system isn't this clean. It hesitates. It tries things. It has dead attempts. Sometimes it hits default credentials three times in a row. Sometimes it drops the dictionary halfway and tries something else. This looks like someone demonstrating that it has a strategy. It isn't exploring. It's performing." Derek's finger paused on the cup. "And the fingerprint." Leo said. "I compared the traffic features from the stick against two historical datasets. One is the old records from the FinOptima period. One is the recent baseline. The TLS extension field order in this data doesn't line up with the old fingerprint in a few places. More conservative than the recent baseline, older traces of versioning. Like an older template from the same family. But I don't have a second sample, so that's as far as I can go." Derek said nothing. An earlier template. "It's performing." Leo said. "Yeah." "The profile?" "Useless as a prediction baseline." Derek said. "Can't use it as a behavioral model. But the raw traffic is still there. The logs weren't touched. The packets underneath are clean. We can dig again." Leo nodded. Said nothing else. Kept looking at the screen. Five more minutes passed. He closed the laptop. "The corridor?" Leo asked. "Still up." Derek said. "Keep it up." Leo said. Derek looked at him. "It performs, we watch." Leo said. "Keep it up. Eventually, it'll give something away. You can't fake the real parts." Derek waited two seconds. Nodded. Leo picked up his coffee and drank. Already cold. "That timestamp." Leo said. "Read, or modified?" "Read." Derek said. "Only the access time changed in the metadata. The file content didn't move." "It read." Leo said. "It read." Derek said. Both of them went quiet. Outside, the sunlight had moved. The line of light and shadow on the table had crept an inch toward Leo. Derek's coffee was still more than half full. So was Leo's. "So what do we have now?" Derek asked. Leo looked at him. "We know it read our profile. It knows we're watching it. We know it knows we're watching it." Derek didn't move. "Before, we were in the dark and it was in the light. Then it flipped. Now." He paused. "Now both sides know the other is watching." Derek picked up his coffee and drank. Cold. "So what's next?" he said. "Next," Leo said, "we see who blinks first." The person behind the counter put the last cup back. Wiped his hands, wiped them on his apron, then leaned against the counter and looked out the window. The street was empty. Derek and Leo sat a while longer. Neither spoke. Derek left first. Stood, nodded, pushed the door open and walked out. Leo didn't move. Sat in place, watching the laptop screen fade to dark. The person behind the counter walked over and took Derek's cup. Half a coffee left. Carried it back, poured it into the sink. The splash. Leo sat another ten minutes. Then he stood and pushed the door open. The person behind the counter walked over and took Leo's cup. Also half full. He washed the two cups together. Water, the brush scraping the sides. When they were clean, he set them upside down on the shelf, in a row with the others, evenly spaced. Then he went back behind the counter, sat down, picked up a cloth, and kept wiping. Late that night. The MediSys office. His phone had one message from Alex: "No change on my side. Everything normal." Derek read it twice, put the phone down, and sat in front of the screen. The profile file open. He stared at the last access timestamp for a long time. 05:42:08 . The cursor moved to the end of the file. New line. He typed two words: Saw it. The cursor paused for a few seconds. He didn't delete it. Saved. Closed. He didn't encrypt the file. Didn't change permissions. Did nothing defensive. The two words just sat there. Whoever opened the file would see them. In a few hours, the copy with those two words would sync to Leo's side. He stared at the last line on the screen for a few seconds. Closed it. In the notification list, the firmware update notice was still there. He opened the printer management page and pulled up the firmware record. Version: latest. Updated: early that morning, just past two, same time as the notice. Source: the vendor's automatic update channel. He opened the vendor's release page. The version had been pulled. The withdrawal time was a few hours before the update notice. The printer sat in the corner of the office, on the office network. He never shut the laptop down. He only locked it. The sandbox access keys were on it. Encrypted, password-protected, but only while the machine was off. It was never off. He stood up and went to the pantry for water. The tap ran a long time before it turned cold. He filled a cup and came back. Outside, the sky hadn't lightened. Streetlight leaked through the curtain gap, the same as before dawn. He sat down and opened a new blank document. Cursor blinking. He typed a single character: 0 . Period. Saved. Filename: corridor-v2-0.md . Not 1.1. Not 2.0. Zero. From scratch. He drank the hot water. It burned. He drank again. On the screen, the new document held only a "0". The cursor blinked after the period. He scrolled back through the raw traffic. The network jitter in the gaps between re-scans. The occasional flicker where the shallow API latency drifted from 200ms. The extra SYN packets in the port probes, not part of any strategy, more like the natural noise of the network stack. He typed a line in the document: Performance can control behavior. It cannot control the texture of the environment TCP scheduling / kernel jitter / link queueing . He opened the raw traffic logs and reran the data. Watching what the source could not control. That was the environment talking back. He divided the scan source's behavior by predictability. First class: predictable behavior, the ordered auth transitions, the fixed port probe patterns, the uniform pause intervals. About 70% of all behavior. Too regular, variance too small, nothing like an explorer's trial and error. Second class: unpredictable behavior, re-scan gaps shaped by network jitter, tiny latency fluctuations, stray SYN packets. About 30% . Behavior the scan source did not control, reflecting the underlying network environment's natural features. He wrote it out: Predictable behavior performance : ~70% - Auth strategy transitions: default → dictionary → format shift, ordered, no redundancy - Port probe order: fixed pattern, micro-adjustments predictable - Pause intervals: variance < 0.05s, unnatural Unpredictable behavior real : ~30% - Re-scan gaps: shaped by network jitter, not controllable - Latency fluctuations: natural drift from the scheduler - Stray SYN packets: kernel behavior, not a strategy choice 30% . Not profile completeness. Not behavioral credibility. The part of this carefully fed data that the scan source could not fully control. He closed the document. Outside, a gray line appeared at the edge of the sky. Almost dawn. Derek turned off the screen. Leaned back. Closed his eyes. The air handler hummed. He didn't move. That's Replace the beams with rotten timbers. The beam stays in place. What it carries has already been swapped out. ╔══════════════════════════════════════════════╗ ║ Half-Protocol · v3.3.6 ║ ║ Observer effect detected — continued ║ ╚══════════════════════════════════════════════╝ Tactical match: Replace the beams with rotten timbers — 91% confidence Operators: ACL scan source / unconfirmed operator Target: Derek + Leo's corridor observation framework ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. Stealing the beam — structural replacement The corridor's pillar was not the data. It was the assumption that the data was unscripted. → Pillar replaced: "observed behavior" → "performed behavior" → Beam collapsed: ~70% of the behavioral profile is no longer trustworthy → Mechanism: scanner entered the corridor on its own, but its behavior inside was not exploration — it was demonstration. Every new feature, every pause, every retry — calibrated for an audience. → Residual: ~30% of observed behavior classified as environmental texture. Whether it is truly unscripted: unverified. 2. The last access timestamp — third-party read confirmed A file was read. Not modified. Read. The read itself is the message. The watcher was being watched. 3. Cognitive impact assessment Technical loss: zero. Positional loss: total. The observer's advantage has been inverted. System I recorded a watcher being watched. The corridor read back. The advantage inverted. Observation is not safety — it is a position that can be taken. Who watches first — does it matter?? System status: normal ? . Next stratagem: Point at the mulberry tree while cursing the locust tree P.S. English isn't my first language. I use AI to polish the writing and smooth out the rough edges. Thanks for reading. ☕ Buy me a coffee