The importance of access control on information

Access control on information is becoming much more important now that we are using all these new language-model–based tools. This is especially true when the results are not just for your own use, but are going to other people. Imagine using a copilot to summarise what the board of a housing association has done in 2025, to inform all the co‑owners. The copilot has access to everything stored in the association’s documentation system, plus email, Vibbo messages, Vibbo posts, and other sources. You ask it for a summary, it gives you a nice text, you skim it, think “good enough,” and send it out. It’s just the housing association, how bad can it be?

Then you discover that the summary includes a paragraph saying that the association has been plagued by a lot of noise from a named co‑owner, and that measures for forced sale of the apartment have been initiated. In reality, nothing like that has been formally decided or made official. Maybe there are complaints, maybe someone has mentioned forced sale as a possibility in an internal email, but the tool has mixed together drafts, discussions, and documents and presented it as if it were a fact ready to be communicated to everyone.

This kind of obvious mistake might be caught if someone reads carefully. But it becomes much harder when it is not so clear what information can be given to whom, or when it is unclear what is considered official and what is not. A language model does not understand the difference between internal discussion and official communication. It just sees text and tries to answer the question you asked.

Some organisations try to handle this by forcing all information to be classified. For example, every document must be marked as open, internal, or restricted. In theory this should help, but in practice it is very easy to mix things up. People mislabel or forget to label. Different teams use the labels in different ways. Over time the classification becomes something you click past, not something that is actually trusted. For tool developers and system administrators, it can be even harder, because they often have technical access to everything and must somehow make sure the tools respect labels that are not consistently used.

What really matters is control over which context information belongs to, how it is used, and when it is allowed to be used. Information that belongs in a board context should not automatically be available in a public context. Internal complaints and draft legal assessments should not suddenly show up in a summary meant for all residents. The same piece of information can be appropriate in one context and completely wrong in another.

To handle this, we need more than simple labels. We need to think in terms of contexts and audiences. Is this for the board only, for internal staff, for all residents, or for the general public? Is this a draft or an approved decision? Tools should not have free access to everything just because the data is technically stored in the same system. There should be technical “watertight compartments” between different types of information and different uses. When a user asks for a text to be sent to all residents, the tool should only be allowed to use information that is safe for that audience, and exclude sources that belong to internal discussions.

This is not just a technical problem. It is also about culture and routines. People need to understand that these tools are powerful and can mix information from many places, and that they will not automatically know what is sensitive or unofficial. Generated texts should be treated as drafts that must be read with the same care as anything else you send out. If we combine clear thinking about context and audience with technical separation of data, we can use new tools without accidentally leaking, inventing, or exposing information that should never have left its original context.

Maintaining Flow of Work

Most of us like to finish things completely before we stop working. We close all the loops, tick off the task, and then shut everything down. It feels good in the moment, but it often makes it harder to start again next time.

When you come back to the work, you sit down and have to ask yourself:
Where do I start? What was I thinking last time? What is the next step?
That small resistance can easily lead to delay and distraction.

A simple alternative is this: don’t end a work session by finishing everything. End it by beginning a little bit of the next task or step.

That means you:

  • Stop while you still know exactly what to do next
  • Don’t complete everything in each round
  • Intentionally leave a small “loose thread” you can pick up later

This loose thread can be very small:

  • The first sentence of the next section
  • A few bullet points about what you want to do next
  • A short comment to your future self: “Next: explain X with an example”
  • A function signature in code, or a clear TODO
  • A draft of the next email with just the greeting and one line written

The point is to avoid ending on a full stop. End on a comma. When you return, you don’t have to think hard about how to begin. You just continue what you already started.

There is another benefit: by starting the next step, you give yourself something to mentally and unconsciously work on between sessions. When the next step is clear and written down, your mind can keep turning it over in the background. Ideas and solutions often show up later, when you are not actively working – in the shower, on a walk, or while doing something else.

To use this in daily work, you can make a tiny end-of-session habit:

  • Write down the next concrete step
  • Do a very small piece of it (one sentence, one bullet, one comment)
  • Leave it visible so it is the first thing you see when you come back

This applies to writing, coding, analysis, planning, and creative work. The details differ, but the principle is the same: always leave something small and clear to continue.

The only things to watch out for are:

  • Don’t leave things in a chaotic state with no clear next step
  • Make the next step specific, not vague
  • Don’t create too many loose threads on too many projects at once

The core idea is simple:
End each work session by beginning the next step, and leave yourself a small thread to pull on. You give your future self an easier start, and your mind something to quietly work on in the meantime.

Trust but verify

Trust is good. Control is better.

Most of us know why. A report that looks fine but contains one critical error. A deployment that “should work” but breaks in production. A language model that gives a confident answer that turns out to be wrong. We want to trust our colleagues, our systems, and our tools. But everyone can make mistakes, both humans and machines. To have real trust in ourselves and others, we need to check and double‑check.

Controls can be difficult to carry out everywhere. They cost time and resources, often without any immediate visible benefit. People experience them as extra work and bureaucracy. Under time pressure, checks can be rushed or skipped. At the same time, we know that the lack of control can be even more costly: errors in production, wrong decisions, compliance issues, and loss of trust.

The goal is not to remove control, but to make it more effective. That means focusing checks where the risk is highest, keeping them as lean as possible, and building them into normal workflows. Instead of many manual reviews and repeated approvals, we need efficient, automatic ways to perform verification.

Automation can handle a large part of routine control. Systems can validate inputs and outputs, apply standard rules, and monitor for unusual patterns. Data quality can be checked continuously. For language models and agents, we can structure requests, ask for reasoning, and automatically validate formats and basic facts, while still using human review where the risk is higher.

When control is integrated and to a large extent automated, people don’t experience it as a separate layer. It becomes part of how work happens. That way, “trust, but verify” is not about distrust, but about accepting that mistakes are normal and using smart verification to catch them early.

Trust is good. Control is better. Real trust is built on checking, not on hoping nothing goes wrong.

When language models remember too much and context gets sticky

Many language model tools have some form of memory or long‑term context. They store previous conversations and information you’ve worked with, so they can pick up the thread where you left off. This makes the agent feel like a conversation partner that remembers what you’ve talked about earlier. That can be very useful in many situations.

But it quickly gets messy. The context that has been built up for one purpose can be completely useless—or even harmful—in another. What was helpful memory in one situation becomes plagsomt sticky in another. When you switch tasks or projects, the agent still drags in old assumptions, documents, and details that don’t belong in the new setting.

Often you don’t have a good way to get rid of this. You can’t easily clear only the parts of the memory that are in the way. In many tools your choice is either to keep everything or delete everything permanently. There is no real possibility for proper context switching—not just for the language model, but also for everything around it. Projects and other groupings help to some extent, but even there, information is easily mixed together and ends up in the wrong place.

In practice this leads to common problems. You move from one project to another, but the agent still assumes the first project is relevant. You change role from casual brainstorming to formal documentation, but the tone and assumptions from the earlier work bleed into the new task. Old information keeps showing up, even after it has become outdated. The result is that the tool feels less predictable and harder to trust, because you never quite know what context it is actually using.

What we really need is a more deliberate way of handling context. Instead of one sticky memory that grows over time, you should be able to define what context applies right now: the current goal, which information and documents are relevant, and which constraints (tone, audience, domain, privacy) should apply. You should be able to start a new task with a clean slate, attach only the information you want, pause one context and resume it later, and throw away or archive a context when you’re done with it.

There are ways to solve this. The “context” concept in kontext.cloud is one example. Here, a context is a first‑class object: something you explicitly create, switch, and manage. Each context has its own documents, instructions, and conversation history. When you switch context, the agent only sees what belongs to the active context. Other projects, clients, or personal notes are invisible by default.

This reduces unwanted stickiness and cross‑contamination of information. You avoid mixing data between clients and projects. You get better separation between work and personal material. And you get a clearer understanding of what the agent “knows” in each situation, instead of depending on a fuzzy, hidden memory that you can’t really control.

Memory in language model tools can be very useful, but without proper context switching it turns sticky and annoying. Treating context as something explicit—rather than a side effect of past chats—gives you more control, less confusion, and a tool that behaves more like a reliable partner than a forgetful one.

From Demo Code to Production Quality

With modern language model tools for coding, it’s very quick to get something up and running. You describe what you want, generate some code, add a few features in a partially working state, and before long you have a decent demo. The workflow is straightforward and follows the normal use of the app: you focus on the main user journey, tweak things here and there until it works “well enough,” and you stay mostly on the happy path. For a demo, that’s perfectly fine.

The situation changes completely when you need software that is good enough for production. Especially production at larger scale, with many users or critical functionality. This includes systems that handle important data, affect life and health, control physical devices, or involve a lot of money. In those cases, it’s not enough to stay on the happy path in your development flow. You have to go into the details, consider variants and edge cases, and build real robustness. You need to ask: do the transactions hold under failure and concurrency? Does the performance hold up under real load? Is the security actually good enough against realistic threats? “What if this happens?” becomes the question you ask everywhere.

Language model tools can be excellent for this kind of work as well. You can use them systematically to go through all components, methods, functions, and calculations. You can look for obvious errors and missing checks, find logical weaknesses, and identify improvements at the component level. You can also use them to think about how components work together: where data can get out of sync, how errors propagate through the system, and where you need stronger guarantees.

The important point is that the tool does not decide how you work or what you focus on. The developer does. You set the quality bar. You choose whether to stop at a demo that works on the happy path, or to go further and build something that can handle real-world conditions. Being satisfied with a happy-path demo version is completely fine, as long as you treat it as a demo. What you should not do is present that demo as finished, production-quality software—especially not when there are many users, critical functions, or real consequences involved.

System instructions versus other instructions for a language model

Many APIs and tools for language models expose a special place for “system instructions” or something similar. It is usually separated from normal messages, labeled clearly, and highlighted in documentation.

This easily gives the impression that system instructions are a higher level of authority: that they always take precedence, that they define what the model must follow, and that other instructions are secondary. Users start to think there is some strong technical guarantee behind that separation.

In practice, there might not be such a big difference. In some cases, there might be no real difference at all.

From the model’s point of view, everything ends up as text in a single prompt. System instructions, user instructions, previous messages: it is all just context the model reads and then uses to guess what it should do next. The model is not applying a fixed rule engine where “system beats user” in all cases. It is pattern matching on the combined text.

That also means it does not really matter where the instructions are given to the model. They can be sent in a separate “system” field, or they can be written into the first user message. Either way, they become part of the same input. The separation exists mostly for humans and tools, not as a hard technical boundary inside the model.

When instructions conflict, this becomes very visible. You might have a system instruction saying “Always answer in Norwegian,” and later a user message saying “Answer in English instead.” Or a framework might inject one set of system rules, while the application or end user adds different or even opposite instructions in normal messages.

In those situations, the model does not strictly enforce a priority based on where each instruction came from. It tries to guess what it is supposed to do overall. Often, it will lean toward what seems most likely or most recent in the conversation. Sometimes it follows the system instruction, sometimes the user, sometimes it ends up in between. The result is that you cannot rely on the location alone to resolve conflicts.

So what can you actually do with system instructions?

They are still useful as a way to define shared baseline behavior: things like role, tone, and general constraints you want across many conversations. They are also a convenient place for tools and frameworks to inject their own configuration. But you should not assume that “because it is in the system field, the model will always obey it.”

The practical takeaway is: think of all instructions together, not as layers with strict power. Avoid contradictory instructions if you want predictable behavior. If something really matters, make it clear, simple, and repeat it where necessary, instead of trusting that a single system instruction will always win.

Hands-on Automation

Many automation efforts fail because nobody really understands the task in enough detail. People jump straight to tools and agents and try to automate based on assumptions. A hands-on, “manual first” approach starts from how the work is actually done in real life and gives you both learning and documentation before you automate anything.

Start by doing the task that should be automated manually several times. Click through the systems, fill out the forms, send the messages, move the files. If you cannot do it yourself, do it together with someone who has the domain expertise. Ask them to talk through what they are doing and why at each step. This is how you uncover the small rules and decisions that are usually not written down anywhere.

While you perform the task, write down the details of what is done, step by step. For each step, note what you look at, what you decide, and what the result is. Capture which tools or systems are used and who is involved. Do not worry about perfect structure at this point; focus on capturing what actually happens.

Then look at which variations of the task can occur. Real processes are rarely linear. Identify different paths: what happens if something is missing, delayed, in the wrong format, or unusual? List these variations and try each one manually at least once. This shows you how the process changes and which conditions and branches exist.

The result of this work is both learning and documentation. You get a clearer understanding of what needs to be done and a written description of what is done and how it is done. You can turn your notes into a simple description, checklist, or flow with the key steps, decision points, rules, and exceptions. If you worked with a domain expert, review this together and adjust it until it matches reality.

The next step is to identify what can be automated. Go through the documented process and separate repetitive, rule-based steps from judgment-heavy or unclear steps. Some parts are good candidates for full automation, some are better suited for human-in-the-loop, and some are not worth automating at all. How the automation should be solved must be evaluated based on the concrete task: sometimes a simple script or integration is enough, other times you might use a workflow tool or a language model or agent to assist with unstructured parts like text or documents.

By starting with manual execution, detailed notes, and explicit variations, you avoid automating based on guesswork. You build automation on a solid understanding of the real process, which makes the result more robust, useful, and easier to improve over time.

LLM Tools as Expert Systems

Most tools built on large language models today are generic. They are more like frameworks than finished solutions. They are designed to be flexible, configurable, and reusable across many different domains.

Because of this, they can be set up to generate text that looks like expertise in almost any area. With the right instructions, a model can be told to act like a lawyer, a doctor, an engineer, or a consultant. On the surface, it will often look and sound like a real expert system.

You can instruct a language model to present itself as an expert in a specific field, and it will produce answers that non-specialists are likely to believe. The output uses the right language, has the right structure, and appears confident. For many people, this is enough to trust it.

This illusion is very attractive for companies that develop these tools. By keeping the core product generic, they can sell the same tool to many different customers in many different industries. With some light configuration or domain-specific prompts, it can be marketed as a solution for almost any field.

The vendors also avoid the heavy work of really understanding each professional domain and making sure the tool is actually good enough for that domain. They do not need to take responsibility for the difficult part: guaranteeing quality and reliability for specific tasks. It is easy to leave that burden to the users.

Customers, however, often want something different. Many of them do not want to develop their own solution on top of a tool. They have a concrete problem they want solved. They want a solution, not a flexible framework they have to shape into a solution themselves.

So the shortcut to building a real solution is not to make a language model appear as if it can solve the task. Making the tool look and sound like an expert system does not turn it into a proper, domain-ready system. It only changes the surface. The harder, more important work remains: understanding the domain, defining what “good enough” means, and building something that actually solves a specific problem in a reliable way.

Why Productivity Gains from Language Models Are Hard to See

Most tools based on language models today are about individual productivity. People use them to find information, improve text, correct errors, draft suggestions, write code, and so on. These things absolutely create efficiency gains for the individual.

But they do not automatically create efficiency gains for the whole organization or the overall system.

Even if someone gets their job done faster by using a tool like ChatGPT, that doesn’t necessarily mean that person gets more done in total. The gain can be taken out in several ways. One possibility is that the person simply spends more time on other things, maybe tasks that are not very important, or even things that have nothing to do with work at all.

Another possibility is that the time is spent on over-improving the result. Because it’s easy to generate and refine text or code, you can keep polishing endlessly. You can spend just as much time as before, but now on fine-tuning details that don’t really matter for the outcome. You can polish forever, long after the point where there is any real benefit.

So when you try to measure the effect of language-model tools in a company, it can be hard to find it. The gains are real at the individual level, but they can quietly disappear. Time savings are not necessarily used to increase output, shorten lead times, or improve something that shows up in the company’s metrics. They are often absorbed into other activities or into unnecessary extra quality.

This is why leaders often hear that people like the tools and feel more productive, while the organization as a whole does not see a clear productivity boost. The system is the same as before. The work processes, bottlenecks, and priorities are unchanged. Only the individual has a new tool.

Without changing how work is organized and without being explicit about what should happen with the time saved, the effect of language models will mostly stay hidden at the system level, even if many employees experience that their personal work has become easier and faster.

Accepting Delay and Inaccuracy

When we run a process or a traditional program, we expect certain things. We expect a fast answer. We expect an accurate answer. And we expect that the same input will always give the same result. If a calculator takes several seconds to answer 2 + 2, or sometimes says 5, we don’t think “close enough” – we think it’s broken.

This is how we normally relate to software: as tools that should be deterministic and reliable. A banking app should always show the correct balance. A ticket booking system should clearly confirm or reject your order. Speed, precision, and consistency are the baseline expectations.

Something interesting happens when we start giving programs more human-like qualities and call them “agents”, often powered by a language model. We stop thinking of them only as tools and begin to relate to them more like we relate to people. We “ask” them for help. We say they “didn’t understand” or that they “misinterpreted” something.

With that small shift in language and framing, our expectations change. It suddenly feels more acceptable that the agent takes a bit longer to respond, as if it is “thinking”. We tolerate that it might be less precise, giving approximate or partial answers. And we accept that it does not always give exactly the same result every time, even for the same question.

In other words, when we see something as a traditional program, we expect fast, accurate, and consistent answers. When we see it as an agent built on a language model, we open up for slower, more imprecise, and less consistent behavior. The core functionality might not have changed that much, but the way we talk about it and think about it makes delay and inaccuracy easier to accept.