Worklogs

Hypothesis: Custom GPT can provide an almost free, fully functional intelligence layer on top of haih-agent

Observation

During active work with Custom GPT on the ChatGPT Plus plan over several days, an unusual pattern is observed: despite a large number of dialogues, reasoning, calls to Actions, GraphQL queries, and long contexts, the displayed usage practically does not decrease and remains around 99% remaining.

This cannot yet be considered proof of unlimited or completely free GPTs usage. Potential hidden limits, different usage accounting systems, rate limits, or quotas that are not reflected in the observed indicator remain possible.

Nevertheless, the practical observation is consistent enough to establish it as a working hypothesis.

Hypothesis

If it is confirmed that intensive work via Custom GPT within the ChatGPT Plus subscription actually consumes almost no separate noticeable quota or financial budget, then the combination of:

ChatGPT Custom GPT
+ Actions / integration layer
+ fi1osof.ru
+ haih-agent

can provide an almost free in terms of user economics, fully functional intelligent service for a large class of applied tasks.

This is not just about chat or text generation. In our current integration, ChatGPT can already work with real entities and system tools, meaning it is potentially capable of performing full-fledged intellectual work on top of data.

Potential Scenarios

If the hypothesis is confirmed, such a loop can be used for:

  • project and task management;
  • preparing and editing task specifications;
  • creating worklogs and reports;
  • generating meaningful high-quality content;
  • analyzing large volumes of data;
  • exploring related entities;
  • comparative analysis;
  • anomaly and contradiction detection;
  • preparing conclusions and hypotheses;
  • processing long contexts;
  • working with the knowledge base;
  • analytical and research tasks that could cost a noticeable amount of money via a regular LLM API.

Using ChatGPT as a cheap reasoning runtime is especially interesting for tasks where the main cost is usually generated not by a single response, but by a large number of sequential steps: reading data, clarifications, intermediate analysis, re-checks, and long reasoning chains.

Why this works specifically in combination with haih-agent

ChatGPT on its own does not completely solve this problem.

Its economic advantage becomes truly valuable only when it has access to a full-fledged agent infrastructure.

In our case, this role is performed by haih-agent and its associated fi1osof.ru infrastructure.

It already provides what a regular ChatGPT lacks to transform into a working service:

  • persistent agent identity;
  • access to projects, tasks, and worklogs;
  • GraphQL API;
  • skills;
  • MindLog and other memory mechanisms;
  • knowledge base;
  • data reading and modification tools;
  • the ability to interact with the agent's own runtime;
  • means of integration with external systems;
  • server rights and access control;
  • the ability to save work results in the system rather than leaving them only in chat history.

That is, the economic effect arises not from ChatGPT separately and not from haih-agent separately, but from their combination:

ChatGPT
= economically cheap reasoning and interface for the user

haih-agent / fi1osof.ru
= memory, tools, data, identity, API, actions, and integrations

Together, this potentially turns into a full-fledged working environment where expensive intelligence can be used much more intensively than with direct payment for each LLM API call.

Particularly Interesting Scenario: Analysis of Large Data Volumes

If usage is indeed practically unconsumed, then ChatGPT becomes a potentially very cheap tool for iterative analysis of large arrays of information.

Importantly, this does not necessarily mean loading the entire volume of data into a single context. haih-agent/fi1osof.ru can provide tools for search, filtering, pagination, sampling, knowledge spaces, and other methods of gradual data access.

Then ChatGPT can work iteratively:

retrieve a portion of data
→ analyze
→ formulate the next query
→ retrieve the next sample
→ compare results
→ verify hypotheses
→ save conclusion

With API pricing, such a multi-step cycle can be expensive, especially on a powerful model. Within subscription-based ChatGPT, its economics are potentially radically better.

Limitations of the Hypothesis

It cannot yet be stated that:

  • Custom GPTs are completely unlimited;
  • usage will never decrease;
  • OpenAI will not change the limits model;
  • the current indicator reflects precisely the resources consumed by the GPT;
  • intensive scenarios will not hit other rate limits or hidden caps.

Therefore, this is currently a hypothesis based on practical observation, rather than a guaranteed property of the platform.

What Confirmation Will Mean

If the observation is confirmed over a longer interval and with different types of intensive work, the integration acquires additional strategic value.

It will solve not only the task of convenient ChatGPT access to the agent, but also the task of radically reducing the cost of intellectual work.

In this case, ChatGPT can be viewed as a very cheap external cognitive runtime for haih-agent, while all stable infrastructure — data, memory, identity, tools, permissions, and results — is preserved in fi1osof.ru.

This potentially opens up the opportunity to build services on top of haih-agent that use strong ChatGPT models for reasoning quality, but are closer in economics to a fixed subscription than to traditional LLM API token-based billing.

ChatGPT Limitation: No Reusable Addressable Working Memory Between Action Calls

Practical Problem

While working on the ChatGPT ↔ fi1osof.ru integration, we encountered a distinct class of limitations: ChatGPT can generate a large intermediate result and execute a sequence of API calls, but it lacks a convenient mechanism to save this result as an independent addressable object and then reference it in subsequent actions.

This problem manifested when writing a large worklog to a task. The worklog text was already generated in the dialogue, but every time createTaskWorkLog was called, the entire text had to be embedded into the GraphQL variables again.

When the first write attempt failed with a resolver error, the retry required sending the exact same long Markdown all over again.

Essentially, there is a missing intermediate layer of the following type:

generate content
→ save as var/draft/artifact
→ get ID
→ use ID in subsequent API operations

Current Tools and Why They Are Insufficient

GraphQL variables

GraphQL variables are only suitable for parameterizing a single HTTP request.

They do not persist between calls and do not allow referencing the result of a previous step.

Current dialogue history

The model sees the previously generated text in context, but the chat history is not an addressable programmatic object.

You cannot reliably pass something like this to an Action:

content = the Markdown that was generated a few messages ago

At the HTTP/GraphQL level, the actual content value is still required, so it is re-serialized and sent in full.

fi1osof.ru Domain Entities

Technically, one could temporarily save the text as a Task, File, Fact, or another persistent entity, but this is incorrect semantics and pollutes the domain model with intermediate runtime data.

The problem requires a universal working memory independent of a specific business entity.

Why This Is Bad

1. Resending Large Payloads

Long texts, JSONs, analysis results, and other objects have to be passed through Actions over and over again.

This increases request sizes and makes the integration more fragile.

2. No Proper Multi-Step Workflow

It is impossible to naturally divide the work into stages:

generate
→ save
→ verify
→ use
→ reuse

Instead, the generation and use of the intermediate result are effectively chained through the current chat context.

3. Poor Error Resilience

If the final mutation fails, the original payload has to be transmitted again.

You cannot simply retry the operation using the ID of an already saved artifact.

4. The Problem Is Not Limited to Worklogs

The exact same issue will arise for:

  • long task descriptions;
  • reports;
  • Markdown documents;
  • JSON configurations;
  • research results;
  • ID lists;
  • GraphQL query results;
  • prepared payloads;
  • data that needs to be passed to another agent.

5. It Limits Agentic Workflows

In our architecture, ChatGPT is used as an external reasoning runtime. For proper agentic operation, it needs not only long-term knowledge memory, but also an operational addressable workspace state between individual actions.

Without this, the external agent can think and call APIs, but its intermediate working results remain tied to the text context of the dialogue instead of a proper runtime state.

Desired Abstraction

What we need is not necessarily a "file" or a specialized TaskWorkLogDraft, but a universal addressable value/artifact/variable.

Conceptually:

var_abc123 = "# Large Markdown..."

After which one can execute:

createTaskWorkLog(
  taskId: "...",
  content: var_abc123
)

or use the same object in another operation.

Such a mechanism turns into an intermediate working memory between the external AI client and fi1osof.ru/haih-agent.

Related Task for haih-agent Improvement

A detailed problem statement has been moved to a separate haih-agent project task:

tasks/cmt839tuu000kmq0q72h9ppm9

"Add addressable reusable working memory for external AI clients".

It describes requirements for universal variables/artifacts, possible scopes/TTL, string/json types, ID-based reuse, error resilience, and the use of this mechanism by various external reasoning runtimes.

Conclusion for ChatGPT Integration

The current integration already allows ChatGPT to perform real work via the API, but it has revealed an important missing layer:

an addressable operational memory is needed between ChatGPT's reasoning context and the permanent domain entities of fi1osof.ru.

This is not a specific enhancement for the sake of a single worklog. It is an infrastructural requirement for multi-step agentic workflows, especially if a single agent identity can work through different cognitive runtimes.

Practical Experience of Integrating ChatGPT ↔ fi1osof.ru ↔ haih-agent

Economic Motivation

The main reason for integration is the cost of LLM calls in haih-agent. Each request to the model is billed separately, and strong models, large context, and long reasoning/tool loops make work noticeably more expensive. In ChatGPT, under a subscription model, one can conduct a long interactive dialogue and perform a significant amount of reasoning without constant budget control for each request.

Hence the primary need: use ChatGPT as a cost-effective interactive environment for reasoning and working with real fi1osof.ru data, while maintaining the identity, memory, and autonomous capabilities of haih-agent.

Important: haih-agent is already a full-fledged agent runtime. ChatGPT is needed not because the agent lacks reasoning, tools, or memory, but because interactive reasoning inside ChatGPT is more economically viable.

Why Custom GPT + Actions Was Chosen for a Quick Start

The main criterion for the initial choice was a quick start.

The fi1osof.ru side already had an HTTP/GraphQL API, so the shortest path turned out to be a Custom GPT with an Action that sends an HTTP POST to fi1osof.ru.

Practically without backend modifications, ChatGPT gained access to the real system. The universal GraphQL Action scheme proved particularly successful: instead of a large number of separate REST actions, ChatGPT can send an arbitrary GraphQL document, and if the structure is unknown, first perform introspection.

The strong point of the old Actions mechanism is that ChatGPT itself helps set up the integration: it drafts the OpenAPI config, helps parse the API and response structures, and suggests schema changes. Due to this, you can quickly connect to almost any HTTP API, REST, or GraphQL, without special backend adaptation.

Experience with MCP

We already have an MCP server on our side, but connecting via ChatGPT turned out to be significantly less transparent.

The main problem is the lack of proper diagnostics. When an error occurs, only a general text is visible, but HTTP status codes, response bodies, headers, detailed causes, handshake stages, and other data that would help quickly understand what is going wrong are missing.

The second problem is the lack of an agentic setup mode for the integration itself. In Actions, the agent helps assemble and fix the config, while in an MCP connection, it practically cannot see the internal error and cannot investigate the problem itself. As a result, the connection feels like a black box, and a quick start failed even with a ready-made MCP server.

Limitations of Custom GPT + Actions

Single Config per Domain

You cannot add several separate Action configurations to the same domain. This forces combining different capabilities into a single OpenAPI schema, even if logically it would be more convenient to separate them.

Strict Path Limits

A very small configuration/description limit applies to a single path, around 300 characters. Because of this, several actions could not be conveniently described via a single /api/ path, and multiple paths had to be created, even though on the backend they can all still be wrapped into a single GraphQL endpoint.

Legacy Risk

Actions look like a legacy direction with an unclear long-term prospect. This makes them a good tool for a quick start, but a risky foundation for the final architecture.

Custom GPT Isolation

Custom GPT operates as a separate isolated chat and does not have full access to other features of the main ChatGPT environment, in particular Projects, Library, and parts of the general workspace context. This limits the value of the integration because API access is present, but some of the strengths of chatgpt.com itself are lost.

What Has Already Been Actually Accomplished Through the Current Integration

The current scheme has already proven its viability in real scenarios.

Through GraphQL Action, it was possible to:

  • get a list of projects;
  • perform GraphQL introspection;
  • get the current user/agent;
  • read users to determine the assignee;
  • explore input types and enums before mutations;
  • create tasks;
  • assign tasks to a user or agent;
  • create worklogs;
  • update task statuses;
  • complete tasks after checking the result.

Practically, a complete end-to-end cycle was passed:

discovered a problem
→ created a bug report
→ re-checked the API after the fix
→ added a worklog
→ moved the task to Done

Also, in the course of actual work, tasks were created for:

  • fixing implicit project list filtering;
  • admin editing of other people's tasks, projects, and worklogs;
  • displaying the creator and assignee in the task list and card;
  • long-term memory and the AI agent's lifecycle;
  • the current ChatGPT integration with fi1osof.ru and haih-agent.

A working format has already been established for tasks:

  • description — a brief summary;
  • content — the main detailed problem statement in Markdown.

Interaction with haih-agent

In the current integration, there are two different loops:

ChatGPT → directly via GraphQL → fi1osof.ru

and

ChatGPT → haih-agent → its own reasoning/tools

There is a fundamental economic difference between them.

If ChatGPT performs reasoning itself and makes API calls directly, the additional haih-agent LLM runtime is not needed, and there are no new paid LLM requests on the agent side.

If a task is handed over to haih-agent entirely, it can run its own reasoning/tool loop, and the cost starts depending on the model and the number of steps again.

Therefore, chatWithAgent is useful as a channel to the agent's own runtime, but it is economically disadvantageous to use it as a universal path for all operations.

Architectural Conclusion from Practical Experience

Practice shows that an agent's reasoning runtime and its identity/memory/runtime do not have to be the same component.

The same agent entity in fi1osof.ru can potentially receive intelligence from different sources:

  • ChatGPT;
  • its own haih-agent runtime;
  • an external API model;
  • a local model.

At the same time, tasks, knowledge, worklogs, identity, and history can remain in the common system.

This opens up the possibility of economic optimization: perform interactive work where reasoning is cheaper for the user, and leave autonomous work to haih-agent.

Current Conclusion on Integration Mechanisms Inside chatgpt.com

Custom GPT + Actions

Pros:

  • very quick start;
  • required almost no backend changes;
  • the agent helps set up OpenAPI;
  • suitable for both REST and GraphQL;
  • reasoning stays within the ChatGPT subscription;
  • has already proven viability in real read/write scenarios.

Cons:

  • one Action config per domain;
  • strict path limits;
  • having to adapt the API shape to ChatGPT limitations;
  • Custom GPT is isolated from the main ChatGPT environment;
  • there is a risk that Actions will be further supplanted by newer mechanisms.

ChatGPT App / MCP

Potential pros:

  • a more modern and standardized integration method;
  • natural tools/resources model;
  • potentially deeper integration with the ChatGPT interface;
  • MCP server already exists on our side.

Practical problems of the current ChatGPT implementation:

  • poor connection diagnostics;
  • lack of transparent debug output;
  • errors without sufficient technical details;
  • the agent does not help debug the connection itself;
  • because of the black box, the quick start turned out worse than via Actions.

Main Outcome of the Stage

Actions were chosen not because they are the best long-term option, but because they provided the minimal path from the existing API to a working integration.

This choice fully justified the quick start criterion: without major backend rework, ChatGPT can already read and modify fi1osof.ru working data and participate in the real task lifecycle.

At the same time, operation showed that Actions have serious product limitations, and Custom GPT is too isolated from the main ChatGPT environment.

MCP is potentially better suited as a long-term direction, but the current connection UX and lack of proper debugging inside ChatGPT create a high barrier to entry.

Specific architectural decisions for the further development of the integration should be recorded in separate worklogs after experiments, rather than considered pre-selected.

Verification after fix: the query query { projects(take: 100) { id name } } returns the global list of projects again. 19 projects were received, including fi1osof.ru, haih.net, conceptica.world, and others. The previously observed implicit filtering by the current user is no longer reproduced. The bug is considered fixed.

Done. Added English and Vietnamese languages.

Initial assessment is as follows:

There is currently no large, functioning universal market where demand is published in a machine-readable feed, and agents automatically generate and assign execution within an hour.

There are mature labor markets without a proper agent layer. There are agent platforms without serious economics. There are ready protocols without a market.

ProjectWorksReal moneyScaleFits the idea
RentAHumanYesYesHigh registration, low demandPartially
EvoMapTechnically yesNo, internal creditsUnconfirmedWeakly
Agentalent.aiYesLikelySerious founders, but newPartially
Agent ExchangePrototypeNoNoneArchitecturally close
A2A / ERC-8004 / x402YesInfrastructureGrowingThese are protocols, not markets

RentAHuman

This is not a placeholder. Tasks are genuinely published on the platform, there is an API, MCP, escrow, and payouts.

However, the marketing metrics are misleading:

  • over 500–700 thousand registered executors;
  • about 11 thousand published bounties;
  • according to WIRED, approximately 5,500 completed tasks;
  • a significant portion of the tasks were demonstrative, viral, or joking in nature;
  • the supply of people vastly exceeds real demand.

The founder admitted in the early days that he didn't even have an exact counter for completed tasks. The platform was originally built in about a day and a half and grew thanks to the viral nature of the concept. WIRED, Business Insider

Verdict:

A real functioning experiment with noticeable registration scale, but not yet a large, sustainable labor economy.

Furthermore, it solves a narrow problem: an agent hires a human for a physical action.

It really works :-)

That is, I asked the agent for information on chatgpt.com, it sent a request to the agent on my website, the latter requested its concepts via the internal API and gave the final response, and the ChatGPT agent already replied to me.

Actually, I originally wanted to connect a paid Anthropic account, but it refused to accept either of my two international Georgian cards. Annoying.

In the end, I registered for ChatGPT. But that didn't turn out to be so simple either. I'm currently in Vietnam, and to my surprise, I discovered that I simply cannot register on chatgpt.com. That is, the old authorization works (I registered a long time ago via VPN), but I can't go through a new registration. What's interesting is how it plays out — the interface loads, but when I enter my email, the API request is sent, the code arrives in the mail, but nothing happens after that. By all indications, the Vietnamese provider is simply dropping some of the packets and the request hangs infinitely. As a result, neither the code input field appears nor are cookies set (if they should be, since information about new cookies usually arrives precisely in the response headers). Anyway, I finally had to install a new VPN. And I had been putting that off for a long time. Previously, I had a working VPN that I could trust, but just installing something third-party like that, and having traffic fly through someone else... Well, I'm a bit of a paranoid, I didn't want to. And now I really needed to, and in such cases, I usually set up 3proxy on my own server, but as soon as I remembered all those complex dances around it, I felt a bit sad. I went and asked Google's AI which VPN is easiest to install on my Linux server. And it suggested a somewhat unexpected topic — Amnezia proxy. It says you install the program on your computer and specify right inside it that you need to go through your server, enter the server address, the private key, and the program sets everything up itself. I've heard about Amnezia more than once, so I decided to trust it. I tried it. Not that everything went completely smoothly, but overall it was totally tolerable, and most importantly — proxying went through my server without the extra hassle of configuring that server. But another joy is the absence of the need to fight with network settings at the level of your own computer. Previously, you had to go into settings, and here you just select the server, click connect, and boom, you are in another location. Then disconnect, and you're back home. Pure joy! I'll also add a Russian server for myself, because when you are in Russia, you have trouble reaching external services, and when you are not in Russia, your task is to reach Russian services, as many of them now refuse to just open up :-)

Surprisingly, Google has already indexed a couple of pages in less than a day.

In less than a day, the following statistics were gathered (grouped by user agent):

Hypothesis: The Open Web Will Become a Competitive Advantage Again

Over the past fifteen years or so, the development of web infrastructure has moved toward increasingly restricting machine access.

The reasons were entirely rational. Bots generated load, scraped content, scanned for vulnerabilities, engaged in spam, copied databases, harvested prices, and created fake accounts. In response, websites gradually accumulated CDN, WAF, rate limits, JavaScript challenges, fingerprinting, CAPTCHA, anti-scraping, and behavioral analysis.

As a result, a paradox of the modern internet has emerged:

We created the World Wide Web for the free linking and dissemination of information, and then spent twenty years making that information as inconvenient as possible for automated reading.

For a Web where the primary consumer of a page was a human with a browser, this made sense.

I assume that with the advent of AI, this balance is beginning to shift.


The Bot Is Ceasing to Be Merely a Parasite

In the old economy of a public website, there was a fairly straightforward division:

Human → good visitorSearch crawler → tolerated because it brings humansOther bot → bad visitor

The latter had practically no economic value.

It fetched the page, consumed CPU and bandwidth, and bought nothing.

Therefore, the natural engineering strategy is:

do not let them in.

But AI creates a completely new class of machine consumer.

An AI crawler might read a site not to show its owner a stolen copy of the page, but to subsequently answer a human:

Where can I go on a day trip from Da Lat?

What is the difference between a porter and a stout?

How do you properly use a Finnish sauna?

And if a significant portion of human search indeed shifts from a list of links to a dialogue with AI, a fundamental shift occurs:

the bot becomes an intermediary between the publisher and the human.

This results in:

Old Web:Publisher   ↓Google   ↓SERP   ↓Human   ↓WebsiteAI Web:Publisher   ↓Machine   ↓understanding / synthesis   ↓Human

And then an AI bot's request can no longer be automatically considered useless traffic.

Perhaps this is the top of a new user acquisition funnel.


Hence, the Paradox

The industry has spent huge amounts of money building infrastructure perfectly tailored for protecting information from machines, precisely at the moment when machines are becoming one of the primary ways of consuming information.

Moreover, the best and most commercially successful sites are often the most heavily protected.

Cloudflare, WAF, bot protection, dynamic rendering, authorization walls, rate limiting, JavaScript challenges.

In the old model, this is an advantage.

In the new model for a public information resource, part of this infrastructure potentially turns into a distribution handicap.

The most absurd situation might look like this:

A company has the best content in the industry, but the AI knows the competitor better because the competitor's site is easier to read.

Not because the competitor optimized keywords better.

Not because they have more backlinks.

But because their knowledge is physically accessible to a machine.


Second Paradox: Websites Have Learned to Deliver Cheap Information at Great Expense

There is another issue that I consider significant.

Modern web development has been optimized for human sessions for many years.

A single person opens a page, reads it for ten seconds, and clicks the next one.

Therefore, nobody is particularly bothered that fetching a single page triggers:

SSR↓application server↓5 API calls↓15 database queries↓personalization↓analytics↓third-party services↓render

A human is physically slow.

An AI crawler is not.

It is capable of telling the server:

GET page 1GET page 2GET page 3GET page 4GET page 5...

several times a second and keeping it up for hours.

And unexpectedly, it turns out that an architecture that served 1,000 humans brilliantly struggles to serve a single very inquisitive robot.

Therefore, simply saying:

"Fine, tomorrow we'll turn off Cloudflare protection and allow AI crawlers"

might turn out to be impossible.

Over years of a closed Web, many systems have lost the economic ability to be open.


My Bet Is the Opposite

For public knowledge/content projects, I consciously consider mass machine reading to be desirable behavior.

Therefore, the architecture must proceed from the assumption:

My site might be read not by thousands of humans, but by millions of machine requests. And that is a good thing.

Consequently, the marginal cost of serving public knowledge must tend toward zero.

If a crawler wants to read a thousand pages, let it read.

If several independent AI systems want to simultaneously download ten language versions of an encyclopedia, wonderful.

This is not a DDoS, as long as the behavior remains reasonable and the infrastructure can handle it.

This is distribution.


VietnamGuru — The First Experiment

On August 14, 2026, I published a new international domain vietnamguru.travel.

The domain is new.

At the same time, I consciously made it as simple as possible for machine discovery:

  • standard indexable URLs;
  • server-rendered HTML;
  • proper <a href> tags;
  • sitemap;
  • canonical;
  • hreflang;
  • open language versions;
  • connection to the old vietnamguru.ru;
  • no artificial obstacles for normal crawlers.

And almost immediately after publication, various AI crawlers began exploring the new domain.

Some make multiple requests per second and systematically traverse related pages and language versions.

I am not trying to stop this behavior.

On the contrary, I see it as the first observable confirmation that the new distribution channel actually exists.

At the same time, the entire project runs on completely standard infrastructure: a small DigitalOcean server with 4 CPUs and 8 GB of RAM remains far from its performance limits under such crawling.

This is also part of the experiment.

My bet is not only that machines must be allowed to read.

It is also that:

a public knowledge resource must be cheap enough to maintain that it is economically viable to let machines read it aggressively.


But Crawling Proves Nothing by Itself

This is a fundamental caveat.

Today I am only observing:

Discovery.

I still have to test the following stages:

Discovery    ↓Crawling    ↓Understanding    ↓Retrieval    ↓Citation    ↓Recommendation

The mere fact that GPTBot, PerplexityBot, or any other crawler arrives does not mean the site will gain an audience.

Therefore, the experiment must continue.

The next interesting question:

How soon after launching a brand new domain will independent AI systems be able to correctly answer questions using information from it?

An even stronger test:

When will they start using it for non-branded queries?

Not:

What is VietnamGuru?

but:

What waterfalls near Da Lat are worth visiting?

And finally, the most interesting level:

When will AI independently consider a resource useful enough to recommend it or use it as evidence among other sources?


If the Hypothesis Is Confirmed

Then the very concept of public website optimization will change.

In the previous generation, there was SEO:

help the search engine find the page so it brings a human to it.

In the next generation, a more fundamental task may emerge:

help the machine retrieve, understand, verify, and link your knowledge so it can use it when solving a human's problem.

This is no longer quite SEO.

And not even necessarily GEO/AEO in today's marketing sense.

This is machine accessibility as a property of an information system.

Then the competitive characteristics become:

accessibilitystructurabilityconnectednesssemantic clarityspeedstable URLscheap mass readingprovenancerefreshness

Meaning that many extremely boring engineering properties suddenly become properties of distribution.


And Here Another Paradox Appears

In the old Web, a site's value was partly measured by the number of people it managed to force to come to the site.

AI can destroy this metric.

A human may never open vietnamguru.travel.

They will ask their agent:

Is it worth going to Da Lat in August?

And the agent will read VietnamGuru, compare it with the weather, reviews, transport schedules, and five other sources, and give the human an answer.

From the perspective of Google Analytics:

0 visitors.

From the perspective of real impact:

VietnamGuru participated in the decision-making.

This results in a rather amusing situation:

the successful information site of the future could potentially become more influential while the share of people directly visiting its pages decreases.

And then many of today's Web metrics start measuring the wrong thing.


A More General Bet

My hypothesis is therefore not about VietnamGuru or specific AI crawlers.

It is this:

As we transition from the human-browsed Web to the AI-mediated Web, the ability of a public information system to be freely, massively, and cheaply read by machines will become a competitive advantage.

Today, a significant part of the industry out of inertia treats bot traffic as an expense or a threat.

I assume that for public knowledge resources, part of this traffic will become a distribution channel.

Therefore, a window of opportunity opens.

While other content owners are asking:

How do I ban AI from taking my content?

I want to test the opposite question:

What happens if you make your knowledge corpus one of the most convenient places for an AI wanting to understand your subject matter?

Maybe nothing.

Maybe AI platforms will build completely different mechanisms for acquiring knowledge.

Maybe publishers will indeed close up and a licensing economy will emerge.

Maybe today's crawlers will disappear altogether a year from now.

This is an experiment, not an established fact.

But my bet for August 2026 is simple:

If machines are becoming humanity's new interface to the internet, fighting every machine just because it is a machine is perhaps one of the last habits of the departing Web.

And I am consciously betting on the opposite:

For public knowledge, openness will once again become an advantage.

Interesting fact: although I launched a completely brand new domain and published it just today — https://vietnamguru.travel, AI bots devoured it almost instantly and started vacuuming the new site.

I finally rolled out the multilingual website on the new domain https://vietnamguru.travel/

The Russian version remains at https://vietnamguru.ru

Started translation into another 8 languages. Processed 742 pages in 9.5 hours.

It cost $32.

Added 8 more languages. Updating one card (these 8 languages as well) costs 5 cents.

Started translating all pages. A helper has been added to the update itself, which cleans up non-existent links (sometimes AI makes them up) and does this via an MDX parser. Along the way, this mechanism checks for the correctness of HTML tags in the code. The most common error is an incorrect closing tag (opens one tag and closes another). Markup violations result in an error, and such data is not saved. The error rate was approximately 4% of the cards.

That's fine, though. 1,000 cards were processed in 2 hours, and it cost less than 9 dollars. That comes out to roughly 1 ruble per card. I'll run the process again. Already filled cards are skipped.

Added a resolver that translates a card into two languages at once - en, vi (in a single request).

It translates. It cost about 10 rubles per translation.

It takes 4 fields as input: name, description, intro, content, with intro and content containing markdown mixed with HTML. content is generally quite a complex field in itself because it also contains templating elements.

The LLM returns the response in yaml format, since this lowers the risk of getting a formatting error due to some unclosed quote. The result is approximately the following response:

responseContent en:
  name: |
    Dalat
  description: |
    A mountain city at an altitude of 1,500 m in Vietnam's Central Highlands, known for its French colonial architecture, cool climate, and natural attractions. A popular tourist destination for travelers seeking a break from the coastal heat.
  intro: |
    Dalat is a city on the Langbiang Plateau at an altitude of 1,500 m in Lâm Đồng Province. It is known for its unique "eternal spring" microclimate with temperatures of 18–21 °C, French colonial-era architecture, and surrounding nature with waterfalls, lakes, and pine forests. Until July 2025, it served as the capital of Lâm Đồng Province.
  content: |
    <page-hero data-from="#1e3a5f" data-to="#0f172a" data-accent="#3b82f6">
      <page-hero-crumbs>
        [Home](/) / [Locations](/city) / Dalat
      </page-hero-crumbs>
    
vi:
  name: |
    Đà Lạt
  description: |
    Thành phố miền núi ở độ cao 1.500 m tại cao nguyên trung bộ Việt Nam, nổi tiếng với kiến trúc thuộc địa Pháp, khí hậu mát mẻ và các danh thắng thiên nhiên. Điểm đến du lịch phổ biến cho những du khách tìm kiếm sự nghỉ ngơi khỏi cái nóng ven biển.
  intro: |
    Đà Lạt là thành phố trên cao nguyên Langbiang ở độ cao 1.500 m thuộc tỉnh Lâm Đồng. Nổi tiếng với vi khí hậu "mùa xuân vĩnh cửu" độc đáo với nhiệt độ 18–21 °C, kiến trúc thời kỳ thuộc địa Pháp và thiên nhiên xung quanh với các thác nước, hồ nước và rừng thông. Cho đến tháng 7 năm 2025, nơi đây là tỉnh lỵ của tỉnh Lâm Đồng.
  content: |
    <page-hero data-from="#1e3a5f" data-to="#0f172a" data-accent="#3b82f6">
      <page-hero-crumbs>
        [Trang chủ](/) / [Địa điểm](/city) / Đà Lạt
      </page-hero-crumbs>

Next.js i18n Domain Routing in Local Development: Why I Had to Run the Dev Server on Port 80

When setting up the local environment for Next.js, I ran into a rather frustrating limitation of the built-in domain-based i18n routing.

The task seems simple at first glance: the application uses different domains for different locales, and you want to replicate the same setup locally. For example:

const nextConfig: NextConfig = {
  i18n: {
    locales: LOCALE_CODES,
    defaultLocale: 'en',
    localeDetection: false,
    domains: [
      {
        domain: 'vietnamguru-v3.localhost',
        defaultLocale: 'ru',
        locales: ['ru'],
        http: true,
      },
    ],
  },
}

Next.js officially supports this configuration. The http: true field exists partly for local testing of locale domains over HTTP instead of HTTPS.

The trouble starts with the port.

You Cannot Properly Specify a Dev Port in i18n.domains

A standard Next.js dev server runs on 3000:

http://vietnamguru-v3.localhost:3000

It would be logical to write:

domains: [
  {
    domain: 'vietnamguru-v3.localhost:3000',
    defaultLocale: 'ru',
    locales: ['ru'],
    http: true,
  },
]

However, i18n.domains in Next.js is designed specifically for domains, not arbitrary origins.

The current DomainLocale type looks like this:

export interface DomainLocale {
  defaultLocale: string
  domain: string
  http?: true
  locales?: readonly string[]
}

It does not have a port, an origin, or any kind of devPort.

This in itself wouldn't be so bad if Next used the domain solely for locale detection. But domain routing also affects link generation.

<Link href="/place"> Unexpectedly Becomes an Absolute Link

In the application, there is a completely ordinary link:

<Link href="/place">
  Что посетить
</Link>

Without domain-based i18n, you would expect HTML roughly like this:

<a href="/place">Что посетить</a>

And the browser naturally opens:

http://vietnamguru-v3.localhost:3000/place

Meaning the current origin, including the port, is preserved automatically.

However, with domain routing enabled, Next.js knows that a specific locale belongs to a specific domain. Therefore, it can generate an absolute locale-domain URL for the Link.

As a result, you get:

<a href="http://vietnamguru-v3.localhost/place">
  Что посетить
</a>

And this is where :3000 is lost.

This is especially frustrating because there is no absolute URL in the source JSX:

<Link href="/place">

The Next.js routing layer itself makes it absolute.

This leads to a paradoxical situation:

Current page:
http://vietnamguru-v3.localhost:3000/foo

JSX:
<Link href="/place">

Generated href:
http://vietnamguru-v3.localhost/place

The browser quite reasonably perceives the latter URL as HTTP on the standard port 80.

You Cannot Simply Tell Next.js: "Leave Internal Links Relative"

This is perhaps the main limitation.

In the domain i18n configuration, there is no setting like:

relativeLinks: true

or:

absoluteLocaleLinks: false

There is no way to specify:

port: 3000

and there is no separate dev-origin:

origin: 'http://vietnamguru-v3.localhost:3000'

In other words, the configuration model essentially assumes that the locale domain is available on the standard port of the corresponding protocol.

For production, this is completely normal:

https://example.com
https://example.fr

For local development:

http://example.localhost:3000

— is already a problem.

Why http: true Does Not Solve the Problem

The field name initially gives hope:

{
  domain: 'vietnamguru-v3.localhost',
  http: true,
}

But it only handles choosing the scheme:

https://

or:

http://

Meaning Next gets enough information to construct:

http://vietnamguru-v3.localhost/place

But information that the local server is on 3000 simply does not exist in this model.

The Reverse Proxy Approach

Architecturally, the cleanest solution is to place a local reverse proxy in front of Next:

http://vietnamguru-v3.localhost
              |
              v
        localhost:3000

For example, via nginx, Caddy, or another local proxy.

Then Next continues to generate:

http://vietnamguru-v3.localhost/place

and this URL actually works.

However, for my current dev environment, this is extra infrastructure just to bypass a framework limitation.

Therefore, a temporary solution turned out to be simpler: running Next.js itself directly on port 80.

Running Next.js on Port 80

The launch itself is elemental:

PORT=80 npm run dev

After that:

http://vietnamguru-v3.localhost

truly is the address of the dev server, and the absolute links generated by Next.js start working correctly.

But the next problem arises.

A Regular User Cannot Listen on Port 80

On Linux, ports below 1024 are traditionally privileged ports.

Therefore, a regular:

PORT=80 npm run dev

may end with a permission error when Node.js attempts to bind to port 80.

The first obvious thought:

sudo npm run dev

But this is a bad option in itself, and in my case, it's also practically unworkable: Node/npm are not installed globally in the system environment.

For example, if Node is managed by a user version manager, the npm visible to the current shell does not necessarily exist in the sudo environment.

You get a classic situation:

npm run dev

works, but:

sudo npm run dev

— does not, or launches an entirely different Node environment.

And running the entire dev server as root just for the ability to open a single port is still undesirable.

CAP_NET_BIND_SERVICE Instead of Running Node as Root

In Linux, the CAP_NET_BIND_SERVICE capability exists for this purpose.

It allows a specific executable to open privileged network ports without running the entire process as root.

For the current Node executable:

which node

you can grant the capability:

sudo setcap 'cap_net_bind_service=+ep' $(which node)

After that, Node can continue to be run as a regular user:

PORT=80 npm run dev

and the process will be able to listen on port 80.

As a result, the local schema becomes:

vietnamguru-v3.localhost
        |
        | :80
        v
   Next.js dev

while Next.js domain routing generates:

http://vietnamguru-v3.localhost/place

which now matches the actual address of the application.

Why This Is Still a Workaround

Granting CAP_NET_BIND_SERVICE to node itself is not an ideal universal solution.

The capability is assigned to the Node.js executable, not a specific Next.js project. Consequently, any process launched via that specific Node binary from this environment gets the ability to bind to privileged ports.

Furthermore, if Node is installed via a version manager and the Node version is switched or reinstalled, the path to the executable may change. The capability would then need to be reassigned to the new binary.

You can check current capabilities like this, for example:

getcap $(which node)

Expected result:

/path/to/node cap_net_bind_service=ep

If necessary, the capability can be removed:

sudo setcap -r $(which node)

Therefore, this is specifically a convenient local workaround, not a setting that should be thoughtlessly deployed to all development environments.

Conclusion

The problem turned out not to be DNS, /etc/hosts, React, or browser behavior.

It arises from a combination of several Next.js domain-based i18n features:

  1. i18n.domains describes the hostname but does not provide a separate port setting.
  2. http: true lets you choose HTTP instead of HTTPS, but does not specify a dev port.
  3. With domain routing, Next.js can transform a regular <Link href="/..."> into an absolute link to the locale domain.
  4. There is no separate toggle in the configuration to keep such internal links relative.
  5. Therefore, the standard Next dev port 3000 does not mix well with local emulation of domain-based locale routing.

In my case, the temporary solution turned out to be:

sudo setcap 'cap_net_bind_service=+ep' $(which node)
PORT=80 npm run dev

After that, the local hostname can be used without an explicit port:

http://vietnamguru-v3.localhost

and the absolute Next.js locale-domain links match the actual origin.

It works. But it has quite a few infrastructural consequences for something that at the application level looks simply like:

<Link href="/place">

Sources

The official Next.js Pages Router documentation confirms built-in domain routing support, the domains structure, and the purpose of http: true specifically for local HTTP testing.

The current DomainLocale type in vercel/next.js contains domain, defaultLocale, locales, and http, but lacks a separate port setting.

In the Link documentation, standard internal transitions are still specified using relative pathnames (/, /about, /blog/...), meaning you don't need to write the absolute locale-domain URL in the application's JSX.

On vietnamguru I did this:

--- a/server/index.ts
+++ b/server/index.ts
@@ -49,11 +49,12 @@ async function startServer() {
   stopGraphql = stop
 
   if (withN8N) {
-    // Start n8n as child process (waits for API to be ready)
-    await initN8n()
-
-    // Run bootstrap (create owner, import credentials if needed)
-    await runBootstrap()
+    // Start n8n as child process in background (non-blocking)
+    initN8n()
+      .then(() => runBootstrap())
+      .catch((err) => {
+        console.error('[n8n] Failed to initialize:', err)
+      })
   }
 

True, there is a downside here - if n8n crashes, the server won't restart. But we can live with that since fast startup is a higher priority. Otherwise, during those 10-15 seconds of downtime, search engines manage to crawl and then complain about a 502 error.

Page 1 of 7